s3: Fix a typo
[Samba/gebeck_regimport.git] / source3 / param / loadparm.c
blob41c29cb0b8925ac0cf5772b04cede0319fb6685e
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 bool bLoaded = false;
83 extern userdom_struct current_user_info;
85 /* the special value for the include parameter
86 * to be interpreted not as a file name but to
87 * trigger loading of the global smb.conf options
88 * from registry. */
89 #ifndef INCLUDE_REGISTRY_NAME
90 #define INCLUDE_REGISTRY_NAME "registry"
91 #endif
93 static bool in_client = false; /* Not in the client by default */
94 static struct smbconf_csn conf_last_csn;
96 #define CONFIG_BACKEND_FILE 0
97 #define CONFIG_BACKEND_REGISTRY 1
99 static int config_backend = CONFIG_BACKEND_FILE;
101 /* some helpful bits */
102 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
103 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
105 #define USERSHARE_VALID 1
106 #define USERSHARE_PENDING_DELETE 2
108 static bool defaults_saved = false;
110 #define LOADPARM_EXTRA_GLOBALS \
111 struct parmlist_entry *param_opt; \
112 char *szRealm; \
113 char *szLogLevel; \
114 int iminreceivefile; \
115 char *szPrintcapname; \
116 int CupsEncrypt; \
117 int iPreferredMaster; \
118 int iDomainMaster; \
119 char *szLdapMachineSuffix; \
120 char *szLdapUserSuffix; \
121 char *szLdapIdmapSuffix; \
122 char *szLdapGroupSuffix; \
123 char *szStateDir; \
124 char *szCacheDir; \
125 char *szSocketAddress; \
126 char *szUsershareTemplateShare; \
127 char *szIdmapUID; \
128 char *szIdmapGID; \
129 int winbindMaxDomainConnections; \
130 int ismb2_max_credits;
132 #include "param/param_global.h"
134 static struct loadparm_global Globals;
136 /* This is a default service used to prime a services structure */
137 static struct loadparm_service sDefault =
139 .valid = true,
140 .autoloaded = false,
141 .usershare = 0,
142 .usershare_last_mod = {0, 0},
143 .szService = NULL,
144 .szPath = NULL,
145 .szUsername = NULL,
146 .szInvalidUsers = NULL,
147 .szValidUsers = NULL,
148 .szAdminUsers = NULL,
149 .szCopy = NULL,
150 .szInclude = NULL,
151 .szPreExec = NULL,
152 .szPostExec = NULL,
153 .szRootPreExec = NULL,
154 .szRootPostExec = NULL,
155 .szCupsOptions = NULL,
156 .szPrintcommand = NULL,
157 .szLpqcommand = NULL,
158 .szLprmcommand = NULL,
159 .szLppausecommand = NULL,
160 .szLpresumecommand = NULL,
161 .szQueuepausecommand = NULL,
162 .szQueueresumecommand = NULL,
163 .szPrintername = NULL,
164 .szPrintjobUsername = NULL,
165 .szDontdescend = NULL,
166 .szHostsallow = NULL,
167 .szHostsdeny = NULL,
168 .szMagicScript = NULL,
169 .szMagicOutput = NULL,
170 .szVetoFiles = NULL,
171 .szHideFiles = NULL,
172 .szVetoOplockFiles = NULL,
173 .comment = NULL,
174 .force_user = NULL,
175 .force_group = NULL,
176 .readlist = NULL,
177 .writelist = NULL,
178 .printer_admin = NULL,
179 .volume = NULL,
180 .fstype = NULL,
181 .szVfsObjects = NULL,
182 .szMSDfsProxy = NULL,
183 .szAioWriteBehind = NULL,
184 .szDfree = NULL,
185 .iMinPrintSpace = 0,
186 .iMaxPrintJobs = 1000,
187 .iMaxReportedPrintJobs = 0,
188 .iWriteCacheSize = 0,
189 .iCreate_mask = 0744,
190 .iCreate_force_mode = 0,
191 .iSecurity_mask = 0777,
192 .iSecurity_force_mode = 0,
193 .iDir_mask = 0755,
194 .iDir_force_mode = 0,
195 .iDir_Security_mask = 0777,
196 .iDir_Security_force_mode = 0,
197 .iMaxConnections = 0,
198 .iDefaultCase = CASE_LOWER,
199 .iPrinting = DEFAULT_PRINTING,
200 .iOplockContentionLimit = 2,
201 .iCSCPolicy = 0,
202 .iBlock_size = 1024,
203 .iDfreeCacheTime = 0,
204 .bPreexecClose = false,
205 .bRootpreexecClose = false,
206 .iCaseSensitive = Auto,
207 .bCasePreserve = true,
208 .bShortCasePreserve = true,
209 .bHideDotFiles = true,
210 .bHideSpecialFiles = false,
211 .bHideUnReadable = false,
212 .bHideUnWriteableFiles = false,
213 .bBrowseable = true,
214 .bAccessBasedShareEnum = false,
215 .bAvailable = true,
216 .bRead_only = true,
217 .bNo_set_dir = true,
218 .bGuest_only = false,
219 .bAdministrative_share = false,
220 .bGuest_ok = false,
221 .bPrint_ok = false,
222 .bPrintNotifyBackchannel = true,
223 .bMap_system = false,
224 .bMap_hidden = false,
225 .bMap_archive = true,
226 .bStoreDosAttributes = false,
227 .bDmapiSupport = false,
228 .bLocking = true,
229 .iStrictLocking = Auto,
230 .bPosixLocking = true,
231 .bShareModes = true,
232 .bOpLocks = true,
233 .bKernelOplocks = true,
234 .bLevel2OpLocks = true,
235 .bOnlyUser = false,
236 .bMangledNames = true,
237 .bWidelinks = false,
238 .bSymlinks = true,
239 .bSyncAlways = false,
240 .bStrictAllocate = false,
241 .bStrictSync = false,
242 .magic_char = '~',
243 .copymap = NULL,
244 .bDeleteReadonly = false,
245 .bFakeOplocks = false,
246 .bDeleteVetoFiles = false,
247 .bDosFilemode = false,
248 .bDosFiletimes = true,
249 .bDosFiletimeResolution = false,
250 .bFakeDirCreateTimes = false,
251 .bBlockingLocks = true,
252 .bInheritPerms = false,
253 .bInheritACLS = false,
254 .bInheritOwner = false,
255 .bMSDfsRoot = false,
256 .bUseClientDriver = false,
257 .bDefaultDevmode = true,
258 .bForcePrintername = false,
259 .bNTAclSupport = true,
260 .bForceUnknownAclUser = false,
261 .bUseSendfile = false,
262 .bProfileAcls = false,
263 .bMap_acl_inherit = false,
264 .bAfs_Share = false,
265 .bEASupport = false,
266 .bAclCheckPermissions = true,
267 .bAclMapFullControl = true,
268 .bAclGroupControl = false,
269 .bChangeNotify = true,
270 .bKernelChangeNotify = true,
271 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
272 .iAioReadSize = 0,
273 .iAioWriteSize = 0,
274 .iMap_readonly = MAP_READONLY_YES,
275 #ifdef BROKEN_DIRECTORY_HANDLING
276 .iDirectoryNameCacheSize = 0,
277 #else
278 .iDirectoryNameCacheSize = 100,
279 #endif
280 .ismb_encrypt = Auto,
281 .param_opt = NULL,
282 .dummy = ""
285 /* local variables */
286 static struct loadparm_service **ServicePtrs = NULL;
287 static int iNumServices = 0;
288 static int iServiceIndex = 0;
289 static struct db_context *ServiceHash;
290 static int *invalid_services = NULL;
291 static int num_invalid_services = 0;
292 static bool bInGlobalSection = true;
293 static bool bGlobalOnly = false;
295 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
297 /* prototypes for the special type handlers */
298 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
299 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
300 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
301 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
302 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
303 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
304 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
305 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
306 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
307 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
308 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
309 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
311 static void set_allowed_client_auth(void);
313 static void add_to_file_list(const char *fname, const char *subfname);
314 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
315 static void free_param_opts(struct parmlist_entry **popts);
317 #include "lib/param/param_enums.c"
319 static const struct enum_list enum_printing[] = {
320 {PRINT_SYSV, "sysv"},
321 {PRINT_AIX, "aix"},
322 {PRINT_HPUX, "hpux"},
323 {PRINT_BSD, "bsd"},
324 {PRINT_QNX, "qnx"},
325 {PRINT_PLP, "plp"},
326 {PRINT_LPRNG, "lprng"},
327 {PRINT_CUPS, "cups"},
328 {PRINT_IPRINT, "iprint"},
329 {PRINT_LPRNT, "nt"},
330 {PRINT_LPROS2, "os2"},
331 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
332 {PRINT_TEST, "test"},
333 {PRINT_VLP, "vlp"},
334 #endif /* DEVELOPER */
335 {-1, NULL}
338 static const struct enum_list enum_ldap_sasl_wrapping[] = {
339 {0, "plain"},
340 {ADS_AUTH_SASL_SIGN, "sign"},
341 {ADS_AUTH_SASL_SEAL, "seal"},
342 {-1, NULL}
345 static const struct enum_list enum_ldap_ssl[] = {
346 {LDAP_SSL_OFF, "no"},
347 {LDAP_SSL_OFF, "off"},
348 {LDAP_SSL_START_TLS, "start tls"},
349 {LDAP_SSL_START_TLS, "start_tls"},
350 {-1, NULL}
353 /* LDAP Dereferencing Alias types */
354 #define SAMBA_LDAP_DEREF_NEVER 0
355 #define SAMBA_LDAP_DEREF_SEARCHING 1
356 #define SAMBA_LDAP_DEREF_FINDING 2
357 #define SAMBA_LDAP_DEREF_ALWAYS 3
359 static const struct enum_list enum_ldap_deref[] = {
360 {SAMBA_LDAP_DEREF_NEVER, "never"},
361 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
362 {SAMBA_LDAP_DEREF_FINDING, "finding"},
363 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
364 {-1, "auto"}
367 static const struct enum_list enum_ldap_passwd_sync[] = {
368 {LDAP_PASSWD_SYNC_OFF, "no"},
369 {LDAP_PASSWD_SYNC_OFF, "off"},
370 {LDAP_PASSWD_SYNC_ON, "yes"},
371 {LDAP_PASSWD_SYNC_ON, "on"},
372 {LDAP_PASSWD_SYNC_ONLY, "only"},
373 {-1, NULL}
376 static const struct enum_list enum_map_readonly[] = {
377 {MAP_READONLY_NO, "no"},
378 {MAP_READONLY_NO, "false"},
379 {MAP_READONLY_NO, "0"},
380 {MAP_READONLY_YES, "yes"},
381 {MAP_READONLY_YES, "true"},
382 {MAP_READONLY_YES, "1"},
383 {MAP_READONLY_PERMISSIONS, "permissions"},
384 {MAP_READONLY_PERMISSIONS, "perms"},
385 {-1, NULL}
388 static const struct enum_list enum_case[] = {
389 {CASE_LOWER, "lower"},
390 {CASE_UPPER, "upper"},
391 {-1, NULL}
395 /* ACL compatibility options. */
396 static const struct enum_list enum_acl_compat_vals[] = {
397 { ACL_COMPAT_AUTO, "auto" },
398 { ACL_COMPAT_WINNT, "winnt" },
399 { ACL_COMPAT_WIN2K, "win2k" },
400 { -1, NULL}
404 Do you want session setups at user level security with a invalid
405 password to be rejected or allowed in as guest? WinNT rejects them
406 but it can be a pain as it means "net view" needs to use a password
408 You have 3 choices in the setting of map_to_guest:
410 "Never" means session setups with an invalid password
411 are rejected. This is the default.
413 "Bad User" means session setups with an invalid password
414 are rejected, unless the username does not exist, in which case it
415 is treated as a guest login
417 "Bad Password" means session setups with an invalid password
418 are treated as a guest login
420 Note that map_to_guest only has an effect in user or server
421 level security.
424 static const struct enum_list enum_map_to_guest[] = {
425 {NEVER_MAP_TO_GUEST, "Never"},
426 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
427 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
428 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
429 {-1, NULL}
432 /* Config backend options */
434 static const struct enum_list enum_config_backend[] = {
435 {CONFIG_BACKEND_FILE, "file"},
436 {CONFIG_BACKEND_REGISTRY, "registry"},
437 {-1, NULL}
440 /* ADS kerberos ticket verification options */
442 static const struct enum_list enum_kerberos_method[] = {
443 {KERBEROS_VERIFY_SECRETS, "default"},
444 {KERBEROS_VERIFY_SECRETS, "secrets only"},
445 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
446 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
447 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
448 {-1, NULL}
451 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
453 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
454 * screen in SWAT. This is used to exclude parameters as well as to squash all
455 * parameters that have been duplicated by pseudonyms.
457 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
458 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
459 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
460 * respective views.
462 * NOTE2: Handling of duplicated (synonym) parameters:
463 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
464 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
465 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
466 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
469 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
470 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
472 static struct parm_struct parm_table[] = {
473 {N_("Base Options"), P_SEP, P_SEPARATOR},
476 .label = "dos charset",
477 .type = P_STRING,
478 .p_class = P_GLOBAL,
479 .offset = GLOBAL_VAR(dos_charset),
480 .special = handle_dos_charset,
481 .enum_list = NULL,
482 .flags = FLAG_ADVANCED
485 .label = "unix charset",
486 .type = P_STRING,
487 .p_class = P_GLOBAL,
488 .offset = GLOBAL_VAR(unix_charset),
489 .special = handle_charset,
490 .enum_list = NULL,
491 .flags = FLAG_ADVANCED
494 .label = "comment",
495 .type = P_STRING,
496 .p_class = P_LOCAL,
497 .offset = LOCAL_VAR(comment),
498 .special = NULL,
499 .enum_list = NULL,
500 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
503 .label = "path",
504 .type = P_STRING,
505 .p_class = P_LOCAL,
506 .offset = LOCAL_VAR(szPath),
507 .special = NULL,
508 .enum_list = NULL,
509 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
512 .label = "directory",
513 .type = P_STRING,
514 .p_class = P_LOCAL,
515 .offset = LOCAL_VAR(szPath),
516 .special = NULL,
517 .enum_list = NULL,
518 .flags = FLAG_HIDE,
521 .label = "workgroup",
522 .type = P_USTRING,
523 .p_class = P_GLOBAL,
524 .offset = GLOBAL_VAR(szWorkgroup),
525 .special = NULL,
526 .enum_list = NULL,
527 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
530 .label = "realm",
531 .type = P_USTRING,
532 .p_class = P_GLOBAL,
533 .offset = GLOBAL_VAR(szRealm),
534 .special = handle_realm,
535 .enum_list = NULL,
536 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
539 .label = "netbios name",
540 .type = P_USTRING,
541 .p_class = P_GLOBAL,
542 .offset = GLOBAL_VAR(szNetbiosName),
543 .special = NULL,
544 .enum_list = NULL,
545 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
548 .label = "netbios aliases",
549 .type = P_LIST,
550 .p_class = P_GLOBAL,
551 .offset = GLOBAL_VAR(szNetbiosAliases),
552 .special = handle_netbios_aliases,
553 .enum_list = NULL,
554 .flags = FLAG_ADVANCED,
557 .label = "netbios scope",
558 .type = P_USTRING,
559 .p_class = P_GLOBAL,
560 .offset = GLOBAL_VAR(szNetbiosScope),
561 .special = NULL,
562 .enum_list = NULL,
563 .flags = FLAG_ADVANCED,
566 .label = "server string",
567 .type = P_STRING,
568 .p_class = P_GLOBAL,
569 .offset = GLOBAL_VAR(szServerString),
570 .special = NULL,
571 .enum_list = NULL,
572 .flags = FLAG_BASIC | FLAG_ADVANCED,
575 .label = "interfaces",
576 .type = P_LIST,
577 .p_class = P_GLOBAL,
578 .offset = GLOBAL_VAR(szInterfaces),
579 .special = NULL,
580 .enum_list = NULL,
581 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
584 .label = "bind interfaces only",
585 .type = P_BOOL,
586 .p_class = P_GLOBAL,
587 .offset = GLOBAL_VAR(bBindInterfacesOnly),
588 .special = NULL,
589 .enum_list = NULL,
590 .flags = FLAG_ADVANCED | FLAG_WIZARD,
593 .label = "config backend",
594 .type = P_ENUM,
595 .p_class = P_GLOBAL,
596 .offset = GLOBAL_VAR(ConfigBackend),
597 .special = NULL,
598 .enum_list = enum_config_backend,
599 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
602 .label = "server role",
603 .type = P_ENUM,
604 .p_class = P_GLOBAL,
605 .offset = GLOBAL_VAR(ServerRole),
606 .special = NULL,
607 .enum_list = enum_server_role,
608 .flags = FLAG_BASIC | FLAG_ADVANCED,
611 {N_("Security Options"), P_SEP, P_SEPARATOR},
614 .label = "security",
615 .type = P_ENUM,
616 .p_class = P_GLOBAL,
617 .offset = GLOBAL_VAR(security),
618 .special = NULL,
619 .enum_list = enum_security,
620 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
623 .label = "auth methods",
624 .type = P_LIST,
625 .p_class = P_GLOBAL,
626 .offset = GLOBAL_VAR(AuthMethods),
627 .special = NULL,
628 .enum_list = NULL,
629 .flags = FLAG_ADVANCED,
632 .label = "encrypt passwords",
633 .type = P_BOOL,
634 .p_class = P_GLOBAL,
635 .offset = GLOBAL_VAR(bEncryptPasswords),
636 .special = NULL,
637 .enum_list = NULL,
638 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
641 .label = "client schannel",
642 .type = P_ENUM,
643 .p_class = P_GLOBAL,
644 .offset = GLOBAL_VAR(clientSchannel),
645 .special = NULL,
646 .enum_list = enum_bool_auto,
647 .flags = FLAG_BASIC | FLAG_ADVANCED,
650 .label = "server schannel",
651 .type = P_ENUM,
652 .p_class = P_GLOBAL,
653 .offset = GLOBAL_VAR(serverSchannel),
654 .special = NULL,
655 .enum_list = enum_bool_auto,
656 .flags = FLAG_BASIC | FLAG_ADVANCED,
659 .label = "allow trusted domains",
660 .type = P_BOOL,
661 .p_class = P_GLOBAL,
662 .offset = GLOBAL_VAR(bAllowTrustedDomains),
663 .special = NULL,
664 .enum_list = NULL,
665 .flags = FLAG_ADVANCED,
668 .label = "map to guest",
669 .type = P_ENUM,
670 .p_class = P_GLOBAL,
671 .offset = GLOBAL_VAR(map_to_guest),
672 .special = NULL,
673 .enum_list = enum_map_to_guest,
674 .flags = FLAG_ADVANCED,
677 .label = "null passwords",
678 .type = P_BOOL,
679 .p_class = P_GLOBAL,
680 .offset = GLOBAL_VAR(bNullPasswords),
681 .special = NULL,
682 .enum_list = NULL,
683 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
686 .label = "obey pam restrictions",
687 .type = P_BOOL,
688 .p_class = P_GLOBAL,
689 .offset = GLOBAL_VAR(bObeyPamRestrictions),
690 .special = NULL,
691 .enum_list = NULL,
692 .flags = FLAG_ADVANCED,
695 .label = "password server",
696 .type = P_STRING,
697 .p_class = P_GLOBAL,
698 .offset = GLOBAL_VAR(szPasswordServer),
699 .special = NULL,
700 .enum_list = NULL,
701 .flags = FLAG_ADVANCED | FLAG_WIZARD,
704 .label = "smb passwd file",
705 .type = P_STRING,
706 .p_class = P_GLOBAL,
707 .offset = GLOBAL_VAR(szSMBPasswdFile),
708 .special = NULL,
709 .enum_list = NULL,
710 .flags = FLAG_ADVANCED,
713 .label = "private dir",
714 .type = P_STRING,
715 .p_class = P_GLOBAL,
716 .offset = GLOBAL_VAR(szPrivateDir),
717 .special = NULL,
718 .enum_list = NULL,
719 .flags = FLAG_ADVANCED,
722 .label = "passdb backend",
723 .type = P_STRING,
724 .p_class = P_GLOBAL,
725 .offset = GLOBAL_VAR(szPassdbBackend),
726 .special = NULL,
727 .enum_list = NULL,
728 .flags = FLAG_ADVANCED | FLAG_WIZARD,
731 .label = "algorithmic rid base",
732 .type = P_INTEGER,
733 .p_class = P_GLOBAL,
734 .offset = GLOBAL_VAR(AlgorithmicRidBase),
735 .special = NULL,
736 .enum_list = NULL,
737 .flags = FLAG_ADVANCED,
740 .label = "root directory",
741 .type = P_STRING,
742 .p_class = P_GLOBAL,
743 .offset = GLOBAL_VAR(szRootdir),
744 .special = NULL,
745 .enum_list = NULL,
746 .flags = FLAG_ADVANCED,
749 .label = "root dir",
750 .type = P_STRING,
751 .p_class = P_GLOBAL,
752 .offset = GLOBAL_VAR(szRootdir),
753 .special = NULL,
754 .enum_list = NULL,
755 .flags = FLAG_HIDE,
758 .label = "root",
759 .type = P_STRING,
760 .p_class = P_GLOBAL,
761 .offset = GLOBAL_VAR(szRootdir),
762 .special = NULL,
763 .enum_list = NULL,
764 .flags = FLAG_HIDE,
767 .label = "guest account",
768 .type = P_STRING,
769 .p_class = P_GLOBAL,
770 .offset = GLOBAL_VAR(szGuestaccount),
771 .special = NULL,
772 .enum_list = NULL,
773 .flags = FLAG_BASIC | FLAG_ADVANCED,
776 .label = "enable privileges",
777 .type = P_BOOL,
778 .p_class = P_GLOBAL,
779 .offset = GLOBAL_VAR(bEnablePrivileges),
780 .special = NULL,
781 .enum_list = NULL,
782 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
786 .label = "pam password change",
787 .type = P_BOOL,
788 .p_class = P_GLOBAL,
789 .offset = GLOBAL_VAR(bPamPasswordChange),
790 .special = NULL,
791 .enum_list = NULL,
792 .flags = FLAG_ADVANCED,
795 .label = "passwd program",
796 .type = P_STRING,
797 .p_class = P_GLOBAL,
798 .offset = GLOBAL_VAR(szPasswdProgram),
799 .special = NULL,
800 .enum_list = NULL,
801 .flags = FLAG_ADVANCED,
804 .label = "passwd chat",
805 .type = P_STRING,
806 .p_class = P_GLOBAL,
807 .offset = GLOBAL_VAR(szPasswdChat),
808 .special = NULL,
809 .enum_list = NULL,
810 .flags = FLAG_ADVANCED,
813 .label = "passwd chat debug",
814 .type = P_BOOL,
815 .p_class = P_GLOBAL,
816 .offset = GLOBAL_VAR(bPasswdChatDebug),
817 .special = NULL,
818 .enum_list = NULL,
819 .flags = FLAG_ADVANCED,
822 .label = "passwd chat timeout",
823 .type = P_INTEGER,
824 .p_class = P_GLOBAL,
825 .offset = GLOBAL_VAR(iPasswdChatTimeout),
826 .special = NULL,
827 .enum_list = NULL,
828 .flags = FLAG_ADVANCED,
831 .label = "check password script",
832 .type = P_STRING,
833 .p_class = P_GLOBAL,
834 .offset = GLOBAL_VAR(szCheckPasswordScript),
835 .special = NULL,
836 .enum_list = NULL,
837 .flags = FLAG_ADVANCED,
840 .label = "username map",
841 .type = P_STRING,
842 .p_class = P_GLOBAL,
843 .offset = GLOBAL_VAR(szUsernameMap),
844 .special = NULL,
845 .enum_list = NULL,
846 .flags = FLAG_ADVANCED,
849 .label = "password level",
850 .type = P_INTEGER,
851 .p_class = P_GLOBAL,
852 .offset = GLOBAL_VAR(pwordlevel),
853 .special = NULL,
854 .enum_list = NULL,
855 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
858 .label = "username level",
859 .type = P_INTEGER,
860 .p_class = P_GLOBAL,
861 .offset = GLOBAL_VAR(unamelevel),
862 .special = NULL,
863 .enum_list = NULL,
864 .flags = FLAG_ADVANCED,
867 .label = "unix password sync",
868 .type = P_BOOL,
869 .p_class = P_GLOBAL,
870 .offset = GLOBAL_VAR(bUnixPasswdSync),
871 .special = NULL,
872 .enum_list = NULL,
873 .flags = FLAG_ADVANCED,
876 .label = "restrict anonymous",
877 .type = P_INTEGER,
878 .p_class = P_GLOBAL,
879 .offset = GLOBAL_VAR(restrict_anonymous),
880 .special = NULL,
881 .enum_list = NULL,
882 .flags = FLAG_ADVANCED,
885 .label = "lanman auth",
886 .type = P_BOOL,
887 .p_class = P_GLOBAL,
888 .offset = GLOBAL_VAR(bLanmanAuth),
889 .special = NULL,
890 .enum_list = NULL,
891 .flags = FLAG_ADVANCED,
894 .label = "ntlm auth",
895 .type = P_BOOL,
896 .p_class = P_GLOBAL,
897 .offset = GLOBAL_VAR(bNTLMAuth),
898 .special = NULL,
899 .enum_list = NULL,
900 .flags = FLAG_ADVANCED,
903 .label = "client NTLMv2 auth",
904 .type = P_BOOL,
905 .p_class = P_GLOBAL,
906 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
907 .special = NULL,
908 .enum_list = NULL,
909 .flags = FLAG_ADVANCED,
912 .label = "client lanman auth",
913 .type = P_BOOL,
914 .p_class = P_GLOBAL,
915 .offset = GLOBAL_VAR(bClientLanManAuth),
916 .special = NULL,
917 .enum_list = NULL,
918 .flags = FLAG_ADVANCED,
921 .label = "client plaintext auth",
922 .type = P_BOOL,
923 .p_class = P_GLOBAL,
924 .offset = GLOBAL_VAR(bClientPlaintextAuth),
925 .special = NULL,
926 .enum_list = NULL,
927 .flags = FLAG_ADVANCED,
930 .label = "client use spnego principal",
931 .type = P_BOOL,
932 .p_class = P_GLOBAL,
933 .offset = GLOBAL_VAR(client_use_spnego_principal),
934 .special = NULL,
935 .enum_list = NULL,
936 .flags = FLAG_ADVANCED,
939 .label = "username",
940 .type = P_STRING,
941 .p_class = P_LOCAL,
942 .offset = LOCAL_VAR(szUsername),
943 .special = NULL,
944 .enum_list = NULL,
945 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
948 .label = "user",
949 .type = P_STRING,
950 .p_class = P_LOCAL,
951 .offset = LOCAL_VAR(szUsername),
952 .special = NULL,
953 .enum_list = NULL,
954 .flags = FLAG_HIDE,
957 .label = "users",
958 .type = P_STRING,
959 .p_class = P_LOCAL,
960 .offset = LOCAL_VAR(szUsername),
961 .special = NULL,
962 .enum_list = NULL,
963 .flags = FLAG_HIDE,
966 .label = "invalid users",
967 .type = P_LIST,
968 .p_class = P_LOCAL,
969 .offset = LOCAL_VAR(szInvalidUsers),
970 .special = NULL,
971 .enum_list = NULL,
972 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
975 .label = "valid users",
976 .type = P_LIST,
977 .p_class = P_LOCAL,
978 .offset = LOCAL_VAR(szValidUsers),
979 .special = NULL,
980 .enum_list = NULL,
981 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
984 .label = "admin users",
985 .type = P_LIST,
986 .p_class = P_LOCAL,
987 .offset = LOCAL_VAR(szAdminUsers),
988 .special = NULL,
989 .enum_list = NULL,
990 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
993 .label = "read list",
994 .type = P_LIST,
995 .p_class = P_LOCAL,
996 .offset = LOCAL_VAR(readlist),
997 .special = NULL,
998 .enum_list = NULL,
999 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1002 .label = "write list",
1003 .type = P_LIST,
1004 .p_class = P_LOCAL,
1005 .offset = LOCAL_VAR(writelist),
1006 .special = NULL,
1007 .enum_list = NULL,
1008 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1011 .label = "printer admin",
1012 .type = P_LIST,
1013 .p_class = P_LOCAL,
1014 .offset = LOCAL_VAR(printer_admin),
1015 .special = NULL,
1016 .enum_list = NULL,
1017 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1020 .label = "force user",
1021 .type = P_STRING,
1022 .p_class = P_LOCAL,
1023 .offset = LOCAL_VAR(force_user),
1024 .special = NULL,
1025 .enum_list = NULL,
1026 .flags = FLAG_ADVANCED | FLAG_SHARE,
1029 .label = "force group",
1030 .type = P_STRING,
1031 .p_class = P_LOCAL,
1032 .offset = LOCAL_VAR(force_group),
1033 .special = NULL,
1034 .enum_list = NULL,
1035 .flags = FLAG_ADVANCED | FLAG_SHARE,
1038 .label = "group",
1039 .type = P_STRING,
1040 .p_class = P_LOCAL,
1041 .offset = LOCAL_VAR(force_group),
1042 .special = NULL,
1043 .enum_list = NULL,
1044 .flags = FLAG_ADVANCED,
1047 .label = "read only",
1048 .type = P_BOOL,
1049 .p_class = P_LOCAL,
1050 .offset = LOCAL_VAR(bRead_only),
1051 .special = NULL,
1052 .enum_list = NULL,
1053 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1056 .label = "write ok",
1057 .type = P_BOOLREV,
1058 .p_class = P_LOCAL,
1059 .offset = LOCAL_VAR(bRead_only),
1060 .special = NULL,
1061 .enum_list = NULL,
1062 .flags = FLAG_HIDE,
1065 .label = "writeable",
1066 .type = P_BOOLREV,
1067 .p_class = P_LOCAL,
1068 .offset = LOCAL_VAR(bRead_only),
1069 .special = NULL,
1070 .enum_list = NULL,
1071 .flags = FLAG_HIDE,
1074 .label = "writable",
1075 .type = P_BOOLREV,
1076 .p_class = P_LOCAL,
1077 .offset = LOCAL_VAR(bRead_only),
1078 .special = NULL,
1079 .enum_list = NULL,
1080 .flags = FLAG_HIDE,
1083 .label = "acl check permissions",
1084 .type = P_BOOL,
1085 .p_class = P_LOCAL,
1086 .offset = LOCAL_VAR(bAclCheckPermissions),
1087 .special = NULL,
1088 .enum_list = NULL,
1089 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1092 .label = "acl group control",
1093 .type = P_BOOL,
1094 .p_class = P_LOCAL,
1095 .offset = LOCAL_VAR(bAclGroupControl),
1096 .special = NULL,
1097 .enum_list = NULL,
1098 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1101 .label = "acl map full control",
1102 .type = P_BOOL,
1103 .p_class = P_LOCAL,
1104 .offset = LOCAL_VAR(bAclMapFullControl),
1105 .special = NULL,
1106 .enum_list = NULL,
1107 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1110 .label = "create mask",
1111 .type = P_OCTAL,
1112 .p_class = P_LOCAL,
1113 .offset = LOCAL_VAR(iCreate_mask),
1114 .special = NULL,
1115 .enum_list = NULL,
1116 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1119 .label = "create mode",
1120 .type = P_OCTAL,
1121 .p_class = P_LOCAL,
1122 .offset = LOCAL_VAR(iCreate_mask),
1123 .special = NULL,
1124 .enum_list = NULL,
1125 .flags = FLAG_HIDE,
1128 .label = "force create mode",
1129 .type = P_OCTAL,
1130 .p_class = P_LOCAL,
1131 .offset = LOCAL_VAR(iCreate_force_mode),
1132 .special = NULL,
1133 .enum_list = NULL,
1134 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1137 .label = "security mask",
1138 .type = P_OCTAL,
1139 .p_class = P_LOCAL,
1140 .offset = LOCAL_VAR(iSecurity_mask),
1141 .special = NULL,
1142 .enum_list = NULL,
1143 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1146 .label = "force security mode",
1147 .type = P_OCTAL,
1148 .p_class = P_LOCAL,
1149 .offset = LOCAL_VAR(iSecurity_force_mode),
1150 .special = NULL,
1151 .enum_list = NULL,
1152 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1155 .label = "directory mask",
1156 .type = P_OCTAL,
1157 .p_class = P_LOCAL,
1158 .offset = LOCAL_VAR(iDir_mask),
1159 .special = NULL,
1160 .enum_list = NULL,
1161 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1164 .label = "directory mode",
1165 .type = P_OCTAL,
1166 .p_class = P_LOCAL,
1167 .offset = LOCAL_VAR(iDir_mask),
1168 .special = NULL,
1169 .enum_list = NULL,
1170 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1173 .label = "force directory mode",
1174 .type = P_OCTAL,
1175 .p_class = P_LOCAL,
1176 .offset = LOCAL_VAR(iDir_force_mode),
1177 .special = NULL,
1178 .enum_list = NULL,
1179 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1182 .label = "directory security mask",
1183 .type = P_OCTAL,
1184 .p_class = P_LOCAL,
1185 .offset = LOCAL_VAR(iDir_Security_mask),
1186 .special = NULL,
1187 .enum_list = NULL,
1188 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1191 .label = "force directory security mode",
1192 .type = P_OCTAL,
1193 .p_class = P_LOCAL,
1194 .offset = LOCAL_VAR(iDir_Security_force_mode),
1195 .special = NULL,
1196 .enum_list = NULL,
1197 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1200 .label = "force unknown acl user",
1201 .type = P_BOOL,
1202 .p_class = P_LOCAL,
1203 .offset = LOCAL_VAR(bForceUnknownAclUser),
1204 .special = NULL,
1205 .enum_list = NULL,
1206 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1209 .label = "inherit permissions",
1210 .type = P_BOOL,
1211 .p_class = P_LOCAL,
1212 .offset = LOCAL_VAR(bInheritPerms),
1213 .special = NULL,
1214 .enum_list = NULL,
1215 .flags = FLAG_ADVANCED | FLAG_SHARE,
1218 .label = "inherit acls",
1219 .type = P_BOOL,
1220 .p_class = P_LOCAL,
1221 .offset = LOCAL_VAR(bInheritACLS),
1222 .special = NULL,
1223 .enum_list = NULL,
1224 .flags = FLAG_ADVANCED | FLAG_SHARE,
1227 .label = "inherit owner",
1228 .type = P_BOOL,
1229 .p_class = P_LOCAL,
1230 .offset = LOCAL_VAR(bInheritOwner),
1231 .special = NULL,
1232 .enum_list = NULL,
1233 .flags = FLAG_ADVANCED | FLAG_SHARE,
1236 .label = "guest only",
1237 .type = P_BOOL,
1238 .p_class = P_LOCAL,
1239 .offset = LOCAL_VAR(bGuest_only),
1240 .special = NULL,
1241 .enum_list = NULL,
1242 .flags = FLAG_ADVANCED | FLAG_SHARE,
1245 .label = "only guest",
1246 .type = P_BOOL,
1247 .p_class = P_LOCAL,
1248 .offset = LOCAL_VAR(bGuest_only),
1249 .special = NULL,
1250 .enum_list = NULL,
1251 .flags = FLAG_HIDE,
1254 .label = "administrative share",
1255 .type = P_BOOL,
1256 .p_class = P_LOCAL,
1257 .offset = LOCAL_VAR(bAdministrative_share),
1258 .special = NULL,
1259 .enum_list = NULL,
1260 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1264 .label = "guest ok",
1265 .type = P_BOOL,
1266 .p_class = P_LOCAL,
1267 .offset = LOCAL_VAR(bGuest_ok),
1268 .special = NULL,
1269 .enum_list = NULL,
1270 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1273 .label = "public",
1274 .type = P_BOOL,
1275 .p_class = P_LOCAL,
1276 .offset = LOCAL_VAR(bGuest_ok),
1277 .special = NULL,
1278 .enum_list = NULL,
1279 .flags = FLAG_HIDE,
1282 .label = "only user",
1283 .type = P_BOOL,
1284 .p_class = P_LOCAL,
1285 .offset = LOCAL_VAR(bOnlyUser),
1286 .special = NULL,
1287 .enum_list = NULL,
1288 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1291 .label = "hosts allow",
1292 .type = P_LIST,
1293 .p_class = P_LOCAL,
1294 .offset = LOCAL_VAR(szHostsallow),
1295 .special = NULL,
1296 .enum_list = NULL,
1297 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1300 .label = "allow hosts",
1301 .type = P_LIST,
1302 .p_class = P_LOCAL,
1303 .offset = LOCAL_VAR(szHostsallow),
1304 .special = NULL,
1305 .enum_list = NULL,
1306 .flags = FLAG_HIDE,
1309 .label = "hosts deny",
1310 .type = P_LIST,
1311 .p_class = P_LOCAL,
1312 .offset = LOCAL_VAR(szHostsdeny),
1313 .special = NULL,
1314 .enum_list = NULL,
1315 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1318 .label = "deny hosts",
1319 .type = P_LIST,
1320 .p_class = P_LOCAL,
1321 .offset = LOCAL_VAR(szHostsdeny),
1322 .special = NULL,
1323 .enum_list = NULL,
1324 .flags = FLAG_HIDE,
1327 .label = "preload modules",
1328 .type = P_LIST,
1329 .p_class = P_GLOBAL,
1330 .offset = GLOBAL_VAR(szPreloadModules),
1331 .special = NULL,
1332 .enum_list = NULL,
1333 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1336 .label = "dedicated keytab file",
1337 .type = P_STRING,
1338 .p_class = P_GLOBAL,
1339 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1340 .special = NULL,
1341 .enum_list = NULL,
1342 .flags = FLAG_ADVANCED,
1345 .label = "kerberos method",
1346 .type = P_ENUM,
1347 .p_class = P_GLOBAL,
1348 .offset = GLOBAL_VAR(iKerberosMethod),
1349 .special = NULL,
1350 .enum_list = enum_kerberos_method,
1351 .flags = FLAG_ADVANCED,
1354 .label = "map untrusted to domain",
1355 .type = P_BOOL,
1356 .p_class = P_GLOBAL,
1357 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1358 .special = NULL,
1359 .enum_list = NULL,
1360 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1364 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1367 .label = "log level",
1368 .type = P_STRING,
1369 .p_class = P_GLOBAL,
1370 .offset = GLOBAL_VAR(szLogLevel),
1371 .special = handle_debug_list,
1372 .enum_list = NULL,
1373 .flags = FLAG_ADVANCED,
1376 .label = "debuglevel",
1377 .type = P_STRING,
1378 .p_class = P_GLOBAL,
1379 .offset = GLOBAL_VAR(szLogLevel),
1380 .special = handle_debug_list,
1381 .enum_list = NULL,
1382 .flags = FLAG_HIDE,
1385 .label = "syslog",
1386 .type = P_INTEGER,
1387 .p_class = P_GLOBAL,
1388 .offset = GLOBAL_VAR(syslog),
1389 .special = NULL,
1390 .enum_list = NULL,
1391 .flags = FLAG_ADVANCED,
1394 .label = "syslog only",
1395 .type = P_BOOL,
1396 .p_class = P_GLOBAL,
1397 .offset = GLOBAL_VAR(bSyslogOnly),
1398 .special = NULL,
1399 .enum_list = NULL,
1400 .flags = FLAG_ADVANCED,
1403 .label = "log file",
1404 .type = P_STRING,
1405 .p_class = P_GLOBAL,
1406 .offset = GLOBAL_VAR(szLogFile),
1407 .special = NULL,
1408 .enum_list = NULL,
1409 .flags = FLAG_ADVANCED,
1412 .label = "max log size",
1413 .type = P_BYTES,
1414 .p_class = P_GLOBAL,
1415 .offset = GLOBAL_VAR(max_log_size),
1416 .special = NULL,
1417 .enum_list = NULL,
1418 .flags = FLAG_ADVANCED,
1421 .label = "debug timestamp",
1422 .type = P_BOOL,
1423 .p_class = P_GLOBAL,
1424 .offset = GLOBAL_VAR(bTimestampLogs),
1425 .special = NULL,
1426 .enum_list = NULL,
1427 .flags = FLAG_ADVANCED,
1430 .label = "timestamp logs",
1431 .type = P_BOOL,
1432 .p_class = P_GLOBAL,
1433 .offset = GLOBAL_VAR(bTimestampLogs),
1434 .special = NULL,
1435 .enum_list = NULL,
1436 .flags = FLAG_ADVANCED,
1439 .label = "debug prefix timestamp",
1440 .type = P_BOOL,
1441 .p_class = P_GLOBAL,
1442 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1443 .special = NULL,
1444 .enum_list = NULL,
1445 .flags = FLAG_ADVANCED,
1448 .label = "debug hires timestamp",
1449 .type = P_BOOL,
1450 .p_class = P_GLOBAL,
1451 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1452 .special = NULL,
1453 .enum_list = NULL,
1454 .flags = FLAG_ADVANCED,
1457 .label = "debug pid",
1458 .type = P_BOOL,
1459 .p_class = P_GLOBAL,
1460 .offset = GLOBAL_VAR(bDebugPid),
1461 .special = NULL,
1462 .enum_list = NULL,
1463 .flags = FLAG_ADVANCED,
1466 .label = "debug uid",
1467 .type = P_BOOL,
1468 .p_class = P_GLOBAL,
1469 .offset = GLOBAL_VAR(bDebugUid),
1470 .special = NULL,
1471 .enum_list = NULL,
1472 .flags = FLAG_ADVANCED,
1475 .label = "debug class",
1476 .type = P_BOOL,
1477 .p_class = P_GLOBAL,
1478 .offset = GLOBAL_VAR(bDebugClass),
1479 .special = NULL,
1480 .enum_list = NULL,
1481 .flags = FLAG_ADVANCED,
1484 .label = "enable core files",
1485 .type = P_BOOL,
1486 .p_class = P_GLOBAL,
1487 .offset = GLOBAL_VAR(bEnableCoreFiles),
1488 .special = NULL,
1489 .enum_list = NULL,
1490 .flags = FLAG_ADVANCED,
1493 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1496 .label = "allocation roundup size",
1497 .type = P_BYTES,
1498 .p_class = P_LOCAL,
1499 .offset = LOCAL_VAR(iallocation_roundup_size),
1500 .special = NULL,
1501 .enum_list = NULL,
1502 .flags = FLAG_ADVANCED,
1505 .label = "aio read size",
1506 .type = P_BYTES,
1507 .p_class = P_LOCAL,
1508 .offset = LOCAL_VAR(iAioReadSize),
1509 .special = NULL,
1510 .enum_list = NULL,
1511 .flags = FLAG_ADVANCED,
1514 .label = "aio write size",
1515 .type = P_BYTES,
1516 .p_class = P_LOCAL,
1517 .offset = LOCAL_VAR(iAioWriteSize),
1518 .special = NULL,
1519 .enum_list = NULL,
1520 .flags = FLAG_ADVANCED,
1523 .label = "aio write behind",
1524 .type = P_STRING,
1525 .p_class = P_LOCAL,
1526 .offset = LOCAL_VAR(szAioWriteBehind),
1527 .special = NULL,
1528 .enum_list = NULL,
1529 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1532 .label = "smb ports",
1533 .type = P_STRING,
1534 .p_class = P_GLOBAL,
1535 .offset = GLOBAL_VAR(smb_ports),
1536 .special = NULL,
1537 .enum_list = NULL,
1538 .flags = FLAG_ADVANCED,
1541 .label = "large readwrite",
1542 .type = P_BOOL,
1543 .p_class = P_GLOBAL,
1544 .offset = GLOBAL_VAR(bLargeReadwrite),
1545 .special = NULL,
1546 .enum_list = NULL,
1547 .flags = FLAG_ADVANCED,
1550 .label = "max protocol",
1551 .type = P_ENUM,
1552 .p_class = P_GLOBAL,
1553 .offset = GLOBAL_VAR(srv_maxprotocol),
1554 .special = NULL,
1555 .enum_list = enum_protocol,
1556 .flags = FLAG_ADVANCED,
1559 .label = "server max protocol",
1560 .type = P_ENUM,
1561 .p_class = P_GLOBAL,
1562 .offset = GLOBAL_VAR(srv_maxprotocol),
1563 .special = NULL,
1564 .enum_list = enum_protocol,
1565 .flags = FLAG_ADVANCED,
1568 .label = "protocol",
1569 .type = P_ENUM,
1570 .p_class = P_GLOBAL,
1571 .offset = GLOBAL_VAR(srv_maxprotocol),
1572 .special = NULL,
1573 .enum_list = enum_protocol,
1574 .flags = FLAG_ADVANCED,
1577 .label = "min protocol",
1578 .type = P_ENUM,
1579 .p_class = P_GLOBAL,
1580 .offset = GLOBAL_VAR(srv_minprotocol),
1581 .special = NULL,
1582 .enum_list = enum_protocol,
1583 .flags = FLAG_ADVANCED,
1586 .label = "server min protocol",
1587 .type = P_ENUM,
1588 .p_class = P_GLOBAL,
1589 .offset = GLOBAL_VAR(srv_minprotocol),
1590 .special = NULL,
1591 .enum_list = enum_protocol,
1592 .flags = FLAG_ADVANCED,
1595 .label = "min receivefile size",
1596 .type = P_BYTES,
1597 .p_class = P_GLOBAL,
1598 .offset = GLOBAL_VAR(iminreceivefile),
1599 .special = NULL,
1600 .enum_list = NULL,
1601 .flags = FLAG_ADVANCED,
1604 .label = "read raw",
1605 .type = P_BOOL,
1606 .p_class = P_GLOBAL,
1607 .offset = GLOBAL_VAR(bReadRaw),
1608 .special = NULL,
1609 .enum_list = NULL,
1610 .flags = FLAG_ADVANCED,
1613 .label = "write raw",
1614 .type = P_BOOL,
1615 .p_class = P_GLOBAL,
1616 .offset = GLOBAL_VAR(bWriteRaw),
1617 .special = NULL,
1618 .enum_list = NULL,
1619 .flags = FLAG_ADVANCED,
1622 .label = "disable netbios",
1623 .type = P_BOOL,
1624 .p_class = P_GLOBAL,
1625 .offset = GLOBAL_VAR(bDisableNetbios),
1626 .special = NULL,
1627 .enum_list = NULL,
1628 .flags = FLAG_ADVANCED,
1631 .label = "reset on zero vc",
1632 .type = P_BOOL,
1633 .p_class = P_GLOBAL,
1634 .offset = GLOBAL_VAR(bResetOnZeroVC),
1635 .special = NULL,
1636 .enum_list = NULL,
1637 .flags = FLAG_ADVANCED,
1640 .label = "log writeable files on exit",
1641 .type = P_BOOL,
1642 .p_class = P_GLOBAL,
1643 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1644 .special = NULL,
1645 .enum_list = NULL,
1646 .flags = FLAG_ADVANCED,
1649 .label = "acl compatibility",
1650 .type = P_ENUM,
1651 .p_class = P_GLOBAL,
1652 .offset = GLOBAL_VAR(iAclCompat),
1653 .special = NULL,
1654 .enum_list = enum_acl_compat_vals,
1655 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1658 .label = "defer sharing violations",
1659 .type = P_BOOL,
1660 .p_class = P_GLOBAL,
1661 .offset = GLOBAL_VAR(bDeferSharingViolations),
1662 .special = NULL,
1663 .enum_list = NULL,
1664 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1667 .label = "ea support",
1668 .type = P_BOOL,
1669 .p_class = P_LOCAL,
1670 .offset = LOCAL_VAR(bEASupport),
1671 .special = NULL,
1672 .enum_list = NULL,
1673 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1676 .label = "nt acl support",
1677 .type = P_BOOL,
1678 .p_class = P_LOCAL,
1679 .offset = LOCAL_VAR(bNTAclSupport),
1680 .special = NULL,
1681 .enum_list = NULL,
1682 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1685 .label = "nt pipe support",
1686 .type = P_BOOL,
1687 .p_class = P_GLOBAL,
1688 .offset = GLOBAL_VAR(bNTPipeSupport),
1689 .special = NULL,
1690 .enum_list = NULL,
1691 .flags = FLAG_ADVANCED,
1694 .label = "nt status support",
1695 .type = P_BOOL,
1696 .p_class = P_GLOBAL,
1697 .offset = GLOBAL_VAR(bNTStatusSupport),
1698 .special = NULL,
1699 .enum_list = NULL,
1700 .flags = FLAG_ADVANCED,
1703 .label = "profile acls",
1704 .type = P_BOOL,
1705 .p_class = P_LOCAL,
1706 .offset = LOCAL_VAR(bProfileAcls),
1707 .special = NULL,
1708 .enum_list = NULL,
1709 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1712 .label = "map acl inherit",
1713 .type = P_BOOL,
1714 .p_class = P_LOCAL,
1715 .offset = LOCAL_VAR(bMap_acl_inherit),
1716 .special = NULL,
1717 .enum_list = NULL,
1718 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1721 .label = "afs share",
1722 .type = P_BOOL,
1723 .p_class = P_LOCAL,
1724 .offset = LOCAL_VAR(bAfs_Share),
1725 .special = NULL,
1726 .enum_list = NULL,
1727 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1730 .label = "max mux",
1731 .type = P_INTEGER,
1732 .p_class = P_GLOBAL,
1733 .offset = GLOBAL_VAR(max_mux),
1734 .special = NULL,
1735 .enum_list = NULL,
1736 .flags = FLAG_ADVANCED,
1739 .label = "max xmit",
1740 .type = P_BYTES,
1741 .p_class = P_GLOBAL,
1742 .offset = GLOBAL_VAR(max_xmit),
1743 .special = NULL,
1744 .enum_list = NULL,
1745 .flags = FLAG_ADVANCED,
1748 .label = "name resolve order",
1749 .type = P_STRING,
1750 .p_class = P_GLOBAL,
1751 .offset = GLOBAL_VAR(szNameResolveOrder),
1752 .special = NULL,
1753 .enum_list = NULL,
1754 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1757 .label = "max ttl",
1758 .type = P_INTEGER,
1759 .p_class = P_GLOBAL,
1760 .offset = GLOBAL_VAR(max_ttl),
1761 .special = NULL,
1762 .enum_list = NULL,
1763 .flags = FLAG_ADVANCED,
1766 .label = "max wins ttl",
1767 .type = P_INTEGER,
1768 .p_class = P_GLOBAL,
1769 .offset = GLOBAL_VAR(max_wins_ttl),
1770 .special = NULL,
1771 .enum_list = NULL,
1772 .flags = FLAG_ADVANCED,
1775 .label = "min wins ttl",
1776 .type = P_INTEGER,
1777 .p_class = P_GLOBAL,
1778 .offset = GLOBAL_VAR(min_wins_ttl),
1779 .special = NULL,
1780 .enum_list = NULL,
1781 .flags = FLAG_ADVANCED,
1784 .label = "time server",
1785 .type = P_BOOL,
1786 .p_class = P_GLOBAL,
1787 .offset = GLOBAL_VAR(bTimeServer),
1788 .special = NULL,
1789 .enum_list = NULL,
1790 .flags = FLAG_ADVANCED,
1793 .label = "unix extensions",
1794 .type = P_BOOL,
1795 .p_class = P_GLOBAL,
1796 .offset = GLOBAL_VAR(bUnixExtensions),
1797 .special = NULL,
1798 .enum_list = NULL,
1799 .flags = FLAG_ADVANCED,
1802 .label = "use spnego",
1803 .type = P_BOOL,
1804 .p_class = P_GLOBAL,
1805 .offset = GLOBAL_VAR(bUseSpnego),
1806 .special = NULL,
1807 .enum_list = NULL,
1808 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1811 .label = "client signing",
1812 .type = P_ENUM,
1813 .p_class = P_GLOBAL,
1814 .offset = GLOBAL_VAR(client_signing),
1815 .special = NULL,
1816 .enum_list = enum_smb_signing_vals,
1817 .flags = FLAG_ADVANCED,
1820 .label = "server signing",
1821 .type = P_ENUM,
1822 .p_class = P_GLOBAL,
1823 .offset = GLOBAL_VAR(server_signing),
1824 .special = NULL,
1825 .enum_list = enum_smb_signing_vals,
1826 .flags = FLAG_ADVANCED,
1829 .label = "smb encrypt",
1830 .type = P_ENUM,
1831 .p_class = P_LOCAL,
1832 .offset = LOCAL_VAR(ismb_encrypt),
1833 .special = NULL,
1834 .enum_list = enum_smb_signing_vals,
1835 .flags = FLAG_ADVANCED,
1838 .label = "client use spnego",
1839 .type = P_BOOL,
1840 .p_class = P_GLOBAL,
1841 .offset = GLOBAL_VAR(bClientUseSpnego),
1842 .special = NULL,
1843 .enum_list = NULL,
1844 .flags = FLAG_ADVANCED,
1847 .label = "client ldap sasl wrapping",
1848 .type = P_ENUM,
1849 .p_class = P_GLOBAL,
1850 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1851 .special = NULL,
1852 .enum_list = enum_ldap_sasl_wrapping,
1853 .flags = FLAG_ADVANCED,
1856 .label = "enable asu support",
1857 .type = P_BOOL,
1858 .p_class = P_GLOBAL,
1859 .offset = GLOBAL_VAR(bASUSupport),
1860 .special = NULL,
1861 .enum_list = NULL,
1862 .flags = FLAG_ADVANCED,
1865 .label = "svcctl list",
1866 .type = P_LIST,
1867 .p_class = P_GLOBAL,
1868 .offset = GLOBAL_VAR(szServicesList),
1869 .special = NULL,
1870 .enum_list = NULL,
1871 .flags = FLAG_ADVANCED,
1874 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1877 .label = "block size",
1878 .type = P_BYTES,
1879 .p_class = P_LOCAL,
1880 .offset = LOCAL_VAR(iBlock_size),
1881 .special = NULL,
1882 .enum_list = NULL,
1883 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1886 .label = "deadtime",
1887 .type = P_INTEGER,
1888 .p_class = P_GLOBAL,
1889 .offset = GLOBAL_VAR(deadtime),
1890 .special = NULL,
1891 .enum_list = NULL,
1892 .flags = FLAG_ADVANCED,
1895 .label = "getwd cache",
1896 .type = P_BOOL,
1897 .p_class = P_GLOBAL,
1898 .offset = GLOBAL_VAR(getwd_cache),
1899 .special = NULL,
1900 .enum_list = NULL,
1901 .flags = FLAG_ADVANCED,
1904 .label = "keepalive",
1905 .type = P_INTEGER,
1906 .p_class = P_GLOBAL,
1907 .offset = GLOBAL_VAR(iKeepalive),
1908 .special = NULL,
1909 .enum_list = NULL,
1910 .flags = FLAG_ADVANCED,
1913 .label = "change notify",
1914 .type = P_BOOL,
1915 .p_class = P_LOCAL,
1916 .offset = LOCAL_VAR(bChangeNotify),
1917 .special = NULL,
1918 .enum_list = NULL,
1919 .flags = FLAG_ADVANCED | FLAG_SHARE,
1922 .label = "directory name cache size",
1923 .type = P_INTEGER,
1924 .p_class = P_LOCAL,
1925 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
1926 .special = NULL,
1927 .enum_list = NULL,
1928 .flags = FLAG_ADVANCED | FLAG_SHARE,
1931 .label = "kernel change notify",
1932 .type = P_BOOL,
1933 .p_class = P_LOCAL,
1934 .offset = LOCAL_VAR(bKernelChangeNotify),
1935 .special = NULL,
1936 .enum_list = NULL,
1937 .flags = FLAG_ADVANCED | FLAG_SHARE,
1940 .label = "lpq cache time",
1941 .type = P_INTEGER,
1942 .p_class = P_GLOBAL,
1943 .offset = GLOBAL_VAR(lpqcachetime),
1944 .special = NULL,
1945 .enum_list = NULL,
1946 .flags = FLAG_ADVANCED,
1949 .label = "max smbd processes",
1950 .type = P_INTEGER,
1951 .p_class = P_GLOBAL,
1952 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
1953 .special = NULL,
1954 .enum_list = NULL,
1955 .flags = FLAG_ADVANCED,
1958 .label = "max connections",
1959 .type = P_INTEGER,
1960 .p_class = P_LOCAL,
1961 .offset = LOCAL_VAR(iMaxConnections),
1962 .special = NULL,
1963 .enum_list = NULL,
1964 .flags = FLAG_ADVANCED | FLAG_SHARE,
1967 .label = "paranoid server security",
1968 .type = P_BOOL,
1969 .p_class = P_GLOBAL,
1970 .offset = GLOBAL_VAR(paranoid_server_security),
1971 .special = NULL,
1972 .enum_list = NULL,
1973 .flags = FLAG_ADVANCED,
1976 .label = "max disk size",
1977 .type = P_BYTES,
1978 .p_class = P_GLOBAL,
1979 .offset = GLOBAL_VAR(maxdisksize),
1980 .special = NULL,
1981 .enum_list = NULL,
1982 .flags = FLAG_ADVANCED,
1985 .label = "max open files",
1986 .type = P_INTEGER,
1987 .p_class = P_GLOBAL,
1988 .offset = GLOBAL_VAR(max_open_files),
1989 .special = NULL,
1990 .enum_list = NULL,
1991 .flags = FLAG_ADVANCED,
1994 .label = "min print space",
1995 .type = P_INTEGER,
1996 .p_class = P_LOCAL,
1997 .offset = LOCAL_VAR(iMinPrintSpace),
1998 .special = NULL,
1999 .enum_list = NULL,
2000 .flags = FLAG_ADVANCED | FLAG_PRINT,
2003 .label = "socket options",
2004 .type = P_STRING,
2005 .p_class = P_GLOBAL,
2006 .offset = GLOBAL_VAR(szSocketOptions),
2007 .special = NULL,
2008 .enum_list = NULL,
2009 .flags = FLAG_ADVANCED,
2012 .label = "strict allocate",
2013 .type = P_BOOL,
2014 .p_class = P_LOCAL,
2015 .offset = LOCAL_VAR(bStrictAllocate),
2016 .special = NULL,
2017 .enum_list = NULL,
2018 .flags = FLAG_ADVANCED | FLAG_SHARE,
2021 .label = "strict sync",
2022 .type = P_BOOL,
2023 .p_class = P_LOCAL,
2024 .offset = LOCAL_VAR(bStrictSync),
2025 .special = NULL,
2026 .enum_list = NULL,
2027 .flags = FLAG_ADVANCED | FLAG_SHARE,
2030 .label = "sync always",
2031 .type = P_BOOL,
2032 .p_class = P_LOCAL,
2033 .offset = LOCAL_VAR(bSyncAlways),
2034 .special = NULL,
2035 .enum_list = NULL,
2036 .flags = FLAG_ADVANCED | FLAG_SHARE,
2039 .label = "use mmap",
2040 .type = P_BOOL,
2041 .p_class = P_GLOBAL,
2042 .offset = GLOBAL_VAR(bUseMmap),
2043 .special = NULL,
2044 .enum_list = NULL,
2045 .flags = FLAG_ADVANCED,
2048 .label = "use sendfile",
2049 .type = P_BOOL,
2050 .p_class = P_LOCAL,
2051 .offset = LOCAL_VAR(bUseSendfile),
2052 .special = NULL,
2053 .enum_list = NULL,
2054 .flags = FLAG_ADVANCED | FLAG_SHARE,
2057 .label = "hostname lookups",
2058 .type = P_BOOL,
2059 .p_class = P_GLOBAL,
2060 .offset = GLOBAL_VAR(bHostnameLookups),
2061 .special = NULL,
2062 .enum_list = NULL,
2063 .flags = FLAG_ADVANCED,
2066 .label = "write cache size",
2067 .type = P_BYTES,
2068 .p_class = P_LOCAL,
2069 .offset = LOCAL_VAR(iWriteCacheSize),
2070 .special = NULL,
2071 .enum_list = NULL,
2072 .flags = FLAG_ADVANCED | FLAG_SHARE,
2075 .label = "name cache timeout",
2076 .type = P_INTEGER,
2077 .p_class = P_GLOBAL,
2078 .offset = GLOBAL_VAR(name_cache_timeout),
2079 .special = NULL,
2080 .enum_list = NULL,
2081 .flags = FLAG_ADVANCED,
2084 .label = "ctdbd socket",
2085 .type = P_STRING,
2086 .p_class = P_GLOBAL,
2087 .offset = GLOBAL_VAR(ctdbdSocket),
2088 .special = NULL,
2089 .enum_list = NULL,
2090 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2093 .label = "cluster addresses",
2094 .type = P_LIST,
2095 .p_class = P_GLOBAL,
2096 .offset = GLOBAL_VAR(szClusterAddresses),
2097 .special = NULL,
2098 .enum_list = NULL,
2099 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2102 .label = "clustering",
2103 .type = P_BOOL,
2104 .p_class = P_GLOBAL,
2105 .offset = GLOBAL_VAR(clustering),
2106 .special = NULL,
2107 .enum_list = NULL,
2108 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2111 .label = "ctdb timeout",
2112 .type = P_INTEGER,
2113 .p_class = P_GLOBAL,
2114 .offset = GLOBAL_VAR(ctdb_timeout),
2115 .special = NULL,
2116 .enum_list = NULL,
2117 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2120 .label = "ctdb locktime warn threshold",
2121 .type = P_INTEGER,
2122 .p_class = P_GLOBAL,
2123 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2124 .special = NULL,
2125 .enum_list = NULL,
2126 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2129 .label = "smb2 max read",
2130 .type = P_BYTES,
2131 .p_class = P_GLOBAL,
2132 .offset = GLOBAL_VAR(ismb2_max_read),
2133 .special = NULL,
2134 .enum_list = NULL,
2135 .flags = FLAG_ADVANCED,
2138 .label = "smb2 max write",
2139 .type = P_BYTES,
2140 .p_class = P_GLOBAL,
2141 .offset = GLOBAL_VAR(ismb2_max_write),
2142 .special = NULL,
2143 .enum_list = NULL,
2144 .flags = FLAG_ADVANCED,
2147 .label = "smb2 max trans",
2148 .type = P_BYTES,
2149 .p_class = P_GLOBAL,
2150 .offset = GLOBAL_VAR(ismb2_max_trans),
2151 .special = NULL,
2152 .enum_list = NULL,
2153 .flags = FLAG_ADVANCED,
2156 .label = "smb2 max credits",
2157 .type = P_INTEGER,
2158 .p_class = P_GLOBAL,
2159 .offset = GLOBAL_VAR(ismb2_max_credits),
2160 .special = NULL,
2161 .enum_list = NULL,
2162 .flags = FLAG_ADVANCED,
2165 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2168 .label = "max reported print jobs",
2169 .type = P_INTEGER,
2170 .p_class = P_LOCAL,
2171 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2172 .special = NULL,
2173 .enum_list = NULL,
2174 .flags = FLAG_ADVANCED | FLAG_PRINT,
2177 .label = "max print jobs",
2178 .type = P_INTEGER,
2179 .p_class = P_LOCAL,
2180 .offset = LOCAL_VAR(iMaxPrintJobs),
2181 .special = NULL,
2182 .enum_list = NULL,
2183 .flags = FLAG_ADVANCED | FLAG_PRINT,
2186 .label = "load printers",
2187 .type = P_BOOL,
2188 .p_class = P_GLOBAL,
2189 .offset = GLOBAL_VAR(bLoadPrinters),
2190 .special = NULL,
2191 .enum_list = NULL,
2192 .flags = FLAG_ADVANCED | FLAG_PRINT,
2195 .label = "printcap cache time",
2196 .type = P_INTEGER,
2197 .p_class = P_GLOBAL,
2198 .offset = GLOBAL_VAR(PrintcapCacheTime),
2199 .special = NULL,
2200 .enum_list = NULL,
2201 .flags = FLAG_ADVANCED | FLAG_PRINT,
2204 .label = "printcap name",
2205 .type = P_STRING,
2206 .p_class = P_GLOBAL,
2207 .offset = GLOBAL_VAR(szPrintcapname),
2208 .special = NULL,
2209 .enum_list = NULL,
2210 .flags = FLAG_ADVANCED | FLAG_PRINT,
2213 .label = "printcap",
2214 .type = P_STRING,
2215 .p_class = P_GLOBAL,
2216 .offset = GLOBAL_VAR(szPrintcapname),
2217 .special = NULL,
2218 .enum_list = NULL,
2219 .flags = FLAG_HIDE,
2222 .label = "printable",
2223 .type = P_BOOL,
2224 .p_class = P_LOCAL,
2225 .offset = LOCAL_VAR(bPrint_ok),
2226 .special = NULL,
2227 .enum_list = NULL,
2228 .flags = FLAG_ADVANCED | FLAG_PRINT,
2231 .label = "print notify backchannel",
2232 .type = P_BOOL,
2233 .p_class = P_LOCAL,
2234 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2235 .special = NULL,
2236 .enum_list = NULL,
2237 .flags = FLAG_ADVANCED,
2240 .label = "print ok",
2241 .type = P_BOOL,
2242 .p_class = P_LOCAL,
2243 .offset = LOCAL_VAR(bPrint_ok),
2244 .special = NULL,
2245 .enum_list = NULL,
2246 .flags = FLAG_HIDE,
2249 .label = "printing",
2250 .type = P_ENUM,
2251 .p_class = P_LOCAL,
2252 .offset = LOCAL_VAR(iPrinting),
2253 .special = handle_printing,
2254 .enum_list = enum_printing,
2255 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2258 .label = "cups options",
2259 .type = P_STRING,
2260 .p_class = P_LOCAL,
2261 .offset = LOCAL_VAR(szCupsOptions),
2262 .special = NULL,
2263 .enum_list = NULL,
2264 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2267 .label = "cups server",
2268 .type = P_STRING,
2269 .p_class = P_GLOBAL,
2270 .offset = GLOBAL_VAR(szCupsServer),
2271 .special = NULL,
2272 .enum_list = NULL,
2273 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2276 .label = "cups encrypt",
2277 .type = P_ENUM,
2278 .p_class = P_GLOBAL,
2279 .offset = GLOBAL_VAR(CupsEncrypt),
2280 .special = NULL,
2281 .enum_list = enum_bool_auto,
2282 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2286 .label = "cups connection timeout",
2287 .type = P_INTEGER,
2288 .p_class = P_GLOBAL,
2289 .offset = GLOBAL_VAR(cups_connection_timeout),
2290 .special = NULL,
2291 .enum_list = NULL,
2292 .flags = FLAG_ADVANCED,
2295 .label = "iprint server",
2296 .type = P_STRING,
2297 .p_class = P_GLOBAL,
2298 .offset = GLOBAL_VAR(szIPrintServer),
2299 .special = NULL,
2300 .enum_list = NULL,
2301 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2304 .label = "print command",
2305 .type = P_STRING,
2306 .p_class = P_LOCAL,
2307 .offset = LOCAL_VAR(szPrintcommand),
2308 .special = NULL,
2309 .enum_list = NULL,
2310 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2313 .label = "disable spoolss",
2314 .type = P_BOOL,
2315 .p_class = P_GLOBAL,
2316 .offset = GLOBAL_VAR(bDisableSpoolss),
2317 .special = NULL,
2318 .enum_list = NULL,
2319 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2322 .label = "enable spoolss",
2323 .type = P_BOOLREV,
2324 .p_class = P_GLOBAL,
2325 .offset = GLOBAL_VAR(bDisableSpoolss),
2326 .special = NULL,
2327 .enum_list = NULL,
2328 .flags = FLAG_HIDE,
2331 .label = "lpq command",
2332 .type = P_STRING,
2333 .p_class = P_LOCAL,
2334 .offset = LOCAL_VAR(szLpqcommand),
2335 .special = NULL,
2336 .enum_list = NULL,
2337 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2340 .label = "lprm command",
2341 .type = P_STRING,
2342 .p_class = P_LOCAL,
2343 .offset = LOCAL_VAR(szLprmcommand),
2344 .special = NULL,
2345 .enum_list = NULL,
2346 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2349 .label = "lppause command",
2350 .type = P_STRING,
2351 .p_class = P_LOCAL,
2352 .offset = LOCAL_VAR(szLppausecommand),
2353 .special = NULL,
2354 .enum_list = NULL,
2355 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2358 .label = "lpresume command",
2359 .type = P_STRING,
2360 .p_class = P_LOCAL,
2361 .offset = LOCAL_VAR(szLpresumecommand),
2362 .special = NULL,
2363 .enum_list = NULL,
2364 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2367 .label = "queuepause command",
2368 .type = P_STRING,
2369 .p_class = P_LOCAL,
2370 .offset = LOCAL_VAR(szQueuepausecommand),
2371 .special = NULL,
2372 .enum_list = NULL,
2373 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2376 .label = "queueresume command",
2377 .type = P_STRING,
2378 .p_class = P_LOCAL,
2379 .offset = LOCAL_VAR(szQueueresumecommand),
2380 .special = NULL,
2381 .enum_list = NULL,
2382 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2385 .label = "addport command",
2386 .type = P_STRING,
2387 .p_class = P_GLOBAL,
2388 .offset = GLOBAL_VAR(szAddPortCommand),
2389 .special = NULL,
2390 .enum_list = NULL,
2391 .flags = FLAG_ADVANCED,
2394 .label = "enumports command",
2395 .type = P_STRING,
2396 .p_class = P_GLOBAL,
2397 .offset = GLOBAL_VAR(szEnumPortsCommand),
2398 .special = NULL,
2399 .enum_list = NULL,
2400 .flags = FLAG_ADVANCED,
2403 .label = "addprinter command",
2404 .type = P_STRING,
2405 .p_class = P_GLOBAL,
2406 .offset = GLOBAL_VAR(szAddPrinterCommand),
2407 .special = NULL,
2408 .enum_list = NULL,
2409 .flags = FLAG_ADVANCED,
2412 .label = "deleteprinter command",
2413 .type = P_STRING,
2414 .p_class = P_GLOBAL,
2415 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2416 .special = NULL,
2417 .enum_list = NULL,
2418 .flags = FLAG_ADVANCED,
2421 .label = "show add printer wizard",
2422 .type = P_BOOL,
2423 .p_class = P_GLOBAL,
2424 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2425 .special = NULL,
2426 .enum_list = NULL,
2427 .flags = FLAG_ADVANCED,
2430 .label = "os2 driver map",
2431 .type = P_STRING,
2432 .p_class = P_GLOBAL,
2433 .offset = GLOBAL_VAR(szOs2DriverMap),
2434 .special = NULL,
2435 .enum_list = NULL,
2436 .flags = FLAG_ADVANCED,
2440 .label = "printer name",
2441 .type = P_STRING,
2442 .p_class = P_LOCAL,
2443 .offset = LOCAL_VAR(szPrintername),
2444 .special = NULL,
2445 .enum_list = NULL,
2446 .flags = FLAG_ADVANCED | FLAG_PRINT,
2449 .label = "printer",
2450 .type = P_STRING,
2451 .p_class = P_LOCAL,
2452 .offset = LOCAL_VAR(szPrintername),
2453 .special = NULL,
2454 .enum_list = NULL,
2455 .flags = FLAG_HIDE,
2458 .label = "use client driver",
2459 .type = P_BOOL,
2460 .p_class = P_LOCAL,
2461 .offset = LOCAL_VAR(bUseClientDriver),
2462 .special = NULL,
2463 .enum_list = NULL,
2464 .flags = FLAG_ADVANCED | FLAG_PRINT,
2467 .label = "default devmode",
2468 .type = P_BOOL,
2469 .p_class = P_LOCAL,
2470 .offset = LOCAL_VAR(bDefaultDevmode),
2471 .special = NULL,
2472 .enum_list = NULL,
2473 .flags = FLAG_ADVANCED | FLAG_PRINT,
2476 .label = "force printername",
2477 .type = P_BOOL,
2478 .p_class = P_LOCAL,
2479 .offset = LOCAL_VAR(bForcePrintername),
2480 .special = NULL,
2481 .enum_list = NULL,
2482 .flags = FLAG_ADVANCED | FLAG_PRINT,
2485 .label = "printjob username",
2486 .type = P_STRING,
2487 .p_class = P_LOCAL,
2488 .offset = LOCAL_VAR(szPrintjobUsername),
2489 .special = NULL,
2490 .enum_list = NULL,
2491 .flags = FLAG_ADVANCED | FLAG_PRINT,
2494 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2497 .label = "mangling method",
2498 .type = P_STRING,
2499 .p_class = P_GLOBAL,
2500 .offset = GLOBAL_VAR(szManglingMethod),
2501 .special = NULL,
2502 .enum_list = NULL,
2503 .flags = FLAG_ADVANCED,
2506 .label = "mangle prefix",
2507 .type = P_INTEGER,
2508 .p_class = P_GLOBAL,
2509 .offset = GLOBAL_VAR(mangle_prefix),
2510 .special = NULL,
2511 .enum_list = NULL,
2512 .flags = FLAG_ADVANCED,
2516 .label = "default case",
2517 .type = P_ENUM,
2518 .p_class = P_LOCAL,
2519 .offset = LOCAL_VAR(iDefaultCase),
2520 .special = NULL,
2521 .enum_list = enum_case,
2522 .flags = FLAG_ADVANCED | FLAG_SHARE,
2525 .label = "case sensitive",
2526 .type = P_ENUM,
2527 .p_class = P_LOCAL,
2528 .offset = LOCAL_VAR(iCaseSensitive),
2529 .special = NULL,
2530 .enum_list = enum_bool_auto,
2531 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2534 .label = "casesignames",
2535 .type = P_ENUM,
2536 .p_class = P_LOCAL,
2537 .offset = LOCAL_VAR(iCaseSensitive),
2538 .special = NULL,
2539 .enum_list = enum_bool_auto,
2540 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2543 .label = "preserve case",
2544 .type = P_BOOL,
2545 .p_class = P_LOCAL,
2546 .offset = LOCAL_VAR(bCasePreserve),
2547 .special = NULL,
2548 .enum_list = NULL,
2549 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2552 .label = "short preserve case",
2553 .type = P_BOOL,
2554 .p_class = P_LOCAL,
2555 .offset = LOCAL_VAR(bShortCasePreserve),
2556 .special = NULL,
2557 .enum_list = NULL,
2558 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2561 .label = "mangling char",
2562 .type = P_CHAR,
2563 .p_class = P_LOCAL,
2564 .offset = LOCAL_VAR(magic_char),
2565 .special = NULL,
2566 .enum_list = NULL,
2567 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2570 .label = "hide dot files",
2571 .type = P_BOOL,
2572 .p_class = P_LOCAL,
2573 .offset = LOCAL_VAR(bHideDotFiles),
2574 .special = NULL,
2575 .enum_list = NULL,
2576 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2579 .label = "hide special files",
2580 .type = P_BOOL,
2581 .p_class = P_LOCAL,
2582 .offset = LOCAL_VAR(bHideSpecialFiles),
2583 .special = NULL,
2584 .enum_list = NULL,
2585 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2588 .label = "hide unreadable",
2589 .type = P_BOOL,
2590 .p_class = P_LOCAL,
2591 .offset = LOCAL_VAR(bHideUnReadable),
2592 .special = NULL,
2593 .enum_list = NULL,
2594 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2597 .label = "hide unwriteable files",
2598 .type = P_BOOL,
2599 .p_class = P_LOCAL,
2600 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2601 .special = NULL,
2602 .enum_list = NULL,
2603 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2606 .label = "delete veto files",
2607 .type = P_BOOL,
2608 .p_class = P_LOCAL,
2609 .offset = LOCAL_VAR(bDeleteVetoFiles),
2610 .special = NULL,
2611 .enum_list = NULL,
2612 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2615 .label = "veto files",
2616 .type = P_STRING,
2617 .p_class = P_LOCAL,
2618 .offset = LOCAL_VAR(szVetoFiles),
2619 .special = NULL,
2620 .enum_list = NULL,
2621 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2624 .label = "hide files",
2625 .type = P_STRING,
2626 .p_class = P_LOCAL,
2627 .offset = LOCAL_VAR(szHideFiles),
2628 .special = NULL,
2629 .enum_list = NULL,
2630 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2633 .label = "veto oplock files",
2634 .type = P_STRING,
2635 .p_class = P_LOCAL,
2636 .offset = LOCAL_VAR(szVetoOplockFiles),
2637 .special = NULL,
2638 .enum_list = NULL,
2639 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2642 .label = "map archive",
2643 .type = P_BOOL,
2644 .p_class = P_LOCAL,
2645 .offset = LOCAL_VAR(bMap_archive),
2646 .special = NULL,
2647 .enum_list = NULL,
2648 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2651 .label = "map hidden",
2652 .type = P_BOOL,
2653 .p_class = P_LOCAL,
2654 .offset = LOCAL_VAR(bMap_hidden),
2655 .special = NULL,
2656 .enum_list = NULL,
2657 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2660 .label = "map system",
2661 .type = P_BOOL,
2662 .p_class = P_LOCAL,
2663 .offset = LOCAL_VAR(bMap_system),
2664 .special = NULL,
2665 .enum_list = NULL,
2666 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2669 .label = "map readonly",
2670 .type = P_ENUM,
2671 .p_class = P_LOCAL,
2672 .offset = LOCAL_VAR(iMap_readonly),
2673 .special = NULL,
2674 .enum_list = enum_map_readonly,
2675 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2678 .label = "mangled names",
2679 .type = P_BOOL,
2680 .p_class = P_LOCAL,
2681 .offset = LOCAL_VAR(bMangledNames),
2682 .special = NULL,
2683 .enum_list = NULL,
2684 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2687 .label = "max stat cache size",
2688 .type = P_INTEGER,
2689 .p_class = P_GLOBAL,
2690 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2691 .special = NULL,
2692 .enum_list = NULL,
2693 .flags = FLAG_ADVANCED,
2696 .label = "stat cache",
2697 .type = P_BOOL,
2698 .p_class = P_GLOBAL,
2699 .offset = GLOBAL_VAR(bStatCache),
2700 .special = NULL,
2701 .enum_list = NULL,
2702 .flags = FLAG_ADVANCED,
2705 .label = "store dos attributes",
2706 .type = P_BOOL,
2707 .p_class = P_LOCAL,
2708 .offset = LOCAL_VAR(bStoreDosAttributes),
2709 .special = NULL,
2710 .enum_list = NULL,
2711 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2714 .label = "dmapi support",
2715 .type = P_BOOL,
2716 .p_class = P_LOCAL,
2717 .offset = LOCAL_VAR(bDmapiSupport),
2718 .special = NULL,
2719 .enum_list = NULL,
2720 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2724 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2727 .label = "machine password timeout",
2728 .type = P_INTEGER,
2729 .p_class = P_GLOBAL,
2730 .offset = GLOBAL_VAR(machine_password_timeout),
2731 .special = NULL,
2732 .enum_list = NULL,
2733 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2736 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2739 .label = "add user script",
2740 .type = P_STRING,
2741 .p_class = P_GLOBAL,
2742 .offset = GLOBAL_VAR(szAddUserScript),
2743 .special = NULL,
2744 .enum_list = NULL,
2745 .flags = FLAG_ADVANCED,
2748 .label = "rename user script",
2749 .type = P_STRING,
2750 .p_class = P_GLOBAL,
2751 .offset = GLOBAL_VAR(szRenameUserScript),
2752 .special = NULL,
2753 .enum_list = NULL,
2754 .flags = FLAG_ADVANCED,
2757 .label = "delete user script",
2758 .type = P_STRING,
2759 .p_class = P_GLOBAL,
2760 .offset = GLOBAL_VAR(szDelUserScript),
2761 .special = NULL,
2762 .enum_list = NULL,
2763 .flags = FLAG_ADVANCED,
2766 .label = "add group script",
2767 .type = P_STRING,
2768 .p_class = P_GLOBAL,
2769 .offset = GLOBAL_VAR(szAddGroupScript),
2770 .special = NULL,
2771 .enum_list = NULL,
2772 .flags = FLAG_ADVANCED,
2775 .label = "delete group script",
2776 .type = P_STRING,
2777 .p_class = P_GLOBAL,
2778 .offset = GLOBAL_VAR(szDelGroupScript),
2779 .special = NULL,
2780 .enum_list = NULL,
2781 .flags = FLAG_ADVANCED,
2784 .label = "add user to group script",
2785 .type = P_STRING,
2786 .p_class = P_GLOBAL,
2787 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2788 .special = NULL,
2789 .enum_list = NULL,
2790 .flags = FLAG_ADVANCED,
2793 .label = "delete user from group script",
2794 .type = P_STRING,
2795 .p_class = P_GLOBAL,
2796 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2797 .special = NULL,
2798 .enum_list = NULL,
2799 .flags = FLAG_ADVANCED,
2802 .label = "set primary group script",
2803 .type = P_STRING,
2804 .p_class = P_GLOBAL,
2805 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2806 .special = NULL,
2807 .enum_list = NULL,
2808 .flags = FLAG_ADVANCED,
2811 .label = "add machine script",
2812 .type = P_STRING,
2813 .p_class = P_GLOBAL,
2814 .offset = GLOBAL_VAR(szAddMachineScript),
2815 .special = NULL,
2816 .enum_list = NULL,
2817 .flags = FLAG_ADVANCED,
2820 .label = "shutdown script",
2821 .type = P_STRING,
2822 .p_class = P_GLOBAL,
2823 .offset = GLOBAL_VAR(szShutdownScript),
2824 .special = NULL,
2825 .enum_list = NULL,
2826 .flags = FLAG_ADVANCED,
2829 .label = "abort shutdown script",
2830 .type = P_STRING,
2831 .p_class = P_GLOBAL,
2832 .offset = GLOBAL_VAR(szAbortShutdownScript),
2833 .special = NULL,
2834 .enum_list = NULL,
2835 .flags = FLAG_ADVANCED,
2838 .label = "username map script",
2839 .type = P_STRING,
2840 .p_class = P_GLOBAL,
2841 .offset = GLOBAL_VAR(szUsernameMapScript),
2842 .special = NULL,
2843 .enum_list = NULL,
2844 .flags = FLAG_ADVANCED,
2847 .label = "username map cache time",
2848 .type = P_INTEGER,
2849 .p_class = P_GLOBAL,
2850 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2851 .special = NULL,
2852 .enum_list = NULL,
2853 .flags = FLAG_ADVANCED,
2856 .label = "logon script",
2857 .type = P_STRING,
2858 .p_class = P_GLOBAL,
2859 .offset = GLOBAL_VAR(szLogonScript),
2860 .special = NULL,
2861 .enum_list = NULL,
2862 .flags = FLAG_ADVANCED,
2865 .label = "logon path",
2866 .type = P_STRING,
2867 .p_class = P_GLOBAL,
2868 .offset = GLOBAL_VAR(szLogonPath),
2869 .special = NULL,
2870 .enum_list = NULL,
2871 .flags = FLAG_ADVANCED,
2874 .label = "logon drive",
2875 .type = P_STRING,
2876 .p_class = P_GLOBAL,
2877 .offset = GLOBAL_VAR(szLogonDrive),
2878 .special = NULL,
2879 .enum_list = NULL,
2880 .flags = FLAG_ADVANCED,
2883 .label = "logon home",
2884 .type = P_STRING,
2885 .p_class = P_GLOBAL,
2886 .offset = GLOBAL_VAR(szLogonHome),
2887 .special = NULL,
2888 .enum_list = NULL,
2889 .flags = FLAG_ADVANCED,
2892 .label = "domain logons",
2893 .type = P_BOOL,
2894 .p_class = P_GLOBAL,
2895 .offset = GLOBAL_VAR(bDomainLogons),
2896 .special = NULL,
2897 .enum_list = NULL,
2898 .flags = FLAG_ADVANCED,
2902 .label = "init logon delayed hosts",
2903 .type = P_LIST,
2904 .p_class = P_GLOBAL,
2905 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2906 .special = NULL,
2907 .enum_list = NULL,
2908 .flags = FLAG_ADVANCED,
2912 .label = "init logon delay",
2913 .type = P_INTEGER,
2914 .p_class = P_GLOBAL,
2915 .offset = GLOBAL_VAR(InitLogonDelay),
2916 .special = NULL,
2917 .enum_list = NULL,
2918 .flags = FLAG_ADVANCED,
2922 {N_("Browse Options"), P_SEP, P_SEPARATOR},
2925 .label = "os level",
2926 .type = P_INTEGER,
2927 .p_class = P_GLOBAL,
2928 .offset = GLOBAL_VAR(os_level),
2929 .special = NULL,
2930 .enum_list = NULL,
2931 .flags = FLAG_BASIC | FLAG_ADVANCED,
2934 .label = "lm announce",
2935 .type = P_ENUM,
2936 .p_class = P_GLOBAL,
2937 .offset = GLOBAL_VAR(lm_announce),
2938 .special = NULL,
2939 .enum_list = enum_bool_auto,
2940 .flags = FLAG_ADVANCED,
2943 .label = "lm interval",
2944 .type = P_INTEGER,
2945 .p_class = P_GLOBAL,
2946 .offset = GLOBAL_VAR(lm_interval),
2947 .special = NULL,
2948 .enum_list = NULL,
2949 .flags = FLAG_ADVANCED,
2952 .label = "preferred master",
2953 .type = P_ENUM,
2954 .p_class = P_GLOBAL,
2955 .offset = GLOBAL_VAR(iPreferredMaster),
2956 .special = NULL,
2957 .enum_list = enum_bool_auto,
2958 .flags = FLAG_BASIC | FLAG_ADVANCED,
2961 .label = "prefered master",
2962 .type = P_ENUM,
2963 .p_class = P_GLOBAL,
2964 .offset = GLOBAL_VAR(iPreferredMaster),
2965 .special = NULL,
2966 .enum_list = enum_bool_auto,
2967 .flags = FLAG_HIDE,
2970 .label = "local master",
2971 .type = P_BOOL,
2972 .p_class = P_GLOBAL,
2973 .offset = GLOBAL_VAR(bLocalMaster),
2974 .special = NULL,
2975 .enum_list = NULL,
2976 .flags = FLAG_BASIC | FLAG_ADVANCED,
2979 .label = "domain master",
2980 .type = P_ENUM,
2981 .p_class = P_GLOBAL,
2982 .offset = GLOBAL_VAR(iDomainMaster),
2983 .special = NULL,
2984 .enum_list = enum_bool_auto,
2985 .flags = FLAG_BASIC | FLAG_ADVANCED,
2988 .label = "browse list",
2989 .type = P_BOOL,
2990 .p_class = P_GLOBAL,
2991 .offset = GLOBAL_VAR(bBrowseList),
2992 .special = NULL,
2993 .enum_list = NULL,
2994 .flags = FLAG_ADVANCED,
2997 .label = "browseable",
2998 .type = P_BOOL,
2999 .p_class = P_LOCAL,
3000 .offset = LOCAL_VAR(bBrowseable),
3001 .special = NULL,
3002 .enum_list = NULL,
3003 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3006 .label = "browsable",
3007 .type = P_BOOL,
3008 .p_class = P_LOCAL,
3009 .offset = LOCAL_VAR(bBrowseable),
3010 .special = NULL,
3011 .enum_list = NULL,
3012 .flags = FLAG_HIDE,
3015 .label = "access based share enum",
3016 .type = P_BOOL,
3017 .p_class = P_LOCAL,
3018 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3019 .special = NULL,
3020 .enum_list = NULL,
3021 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3024 .label = "enhanced browsing",
3025 .type = P_BOOL,
3026 .p_class = P_GLOBAL,
3027 .offset = GLOBAL_VAR(enhanced_browsing),
3028 .special = NULL,
3029 .enum_list = NULL,
3030 .flags = FLAG_ADVANCED,
3033 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3036 .label = "dns proxy",
3037 .type = P_BOOL,
3038 .p_class = P_GLOBAL,
3039 .offset = GLOBAL_VAR(bDNSproxy),
3040 .special = NULL,
3041 .enum_list = NULL,
3042 .flags = FLAG_ADVANCED,
3045 .label = "wins proxy",
3046 .type = P_BOOL,
3047 .p_class = P_GLOBAL,
3048 .offset = GLOBAL_VAR(bWINSproxy),
3049 .special = NULL,
3050 .enum_list = NULL,
3051 .flags = FLAG_ADVANCED,
3054 .label = "wins server",
3055 .type = P_LIST,
3056 .p_class = P_GLOBAL,
3057 .offset = GLOBAL_VAR(szWINSservers),
3058 .special = NULL,
3059 .enum_list = NULL,
3060 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3063 .label = "wins support",
3064 .type = P_BOOL,
3065 .p_class = P_GLOBAL,
3066 .offset = GLOBAL_VAR(bWINSsupport),
3067 .special = NULL,
3068 .enum_list = NULL,
3069 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3072 .label = "wins hook",
3073 .type = P_STRING,
3074 .p_class = P_GLOBAL,
3075 .offset = GLOBAL_VAR(szWINSHook),
3076 .special = NULL,
3077 .enum_list = NULL,
3078 .flags = FLAG_ADVANCED,
3081 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3084 .label = "blocking locks",
3085 .type = P_BOOL,
3086 .p_class = P_LOCAL,
3087 .offset = LOCAL_VAR(bBlockingLocks),
3088 .special = NULL,
3089 .enum_list = NULL,
3090 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3093 .label = "csc policy",
3094 .type = P_ENUM,
3095 .p_class = P_LOCAL,
3096 .offset = LOCAL_VAR(iCSCPolicy),
3097 .special = NULL,
3098 .enum_list = enum_csc_policy,
3099 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3102 .label = "fake oplocks",
3103 .type = P_BOOL,
3104 .p_class = P_LOCAL,
3105 .offset = LOCAL_VAR(bFakeOplocks),
3106 .special = NULL,
3107 .enum_list = NULL,
3108 .flags = FLAG_ADVANCED | FLAG_SHARE,
3111 .label = "kernel oplocks",
3112 .type = P_BOOL,
3113 .p_class = P_LOCAL,
3114 .offset = LOCAL_VAR(bKernelOplocks),
3115 .special = NULL,
3116 .enum_list = NULL,
3117 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3120 .label = "locking",
3121 .type = P_BOOL,
3122 .p_class = P_LOCAL,
3123 .offset = LOCAL_VAR(bLocking),
3124 .special = NULL,
3125 .enum_list = NULL,
3126 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3129 .label = "lock spin time",
3130 .type = P_INTEGER,
3131 .p_class = P_GLOBAL,
3132 .offset = GLOBAL_VAR(iLockSpinTime),
3133 .special = NULL,
3134 .enum_list = NULL,
3135 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3138 .label = "oplocks",
3139 .type = P_BOOL,
3140 .p_class = P_LOCAL,
3141 .offset = LOCAL_VAR(bOpLocks),
3142 .special = NULL,
3143 .enum_list = NULL,
3144 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3147 .label = "level2 oplocks",
3148 .type = P_BOOL,
3149 .p_class = P_LOCAL,
3150 .offset = LOCAL_VAR(bLevel2OpLocks),
3151 .special = NULL,
3152 .enum_list = NULL,
3153 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3156 .label = "oplock break wait time",
3157 .type = P_INTEGER,
3158 .p_class = P_GLOBAL,
3159 .offset = GLOBAL_VAR(oplock_break_wait_time),
3160 .special = NULL,
3161 .enum_list = NULL,
3162 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3165 .label = "oplock contention limit",
3166 .type = P_INTEGER,
3167 .p_class = P_LOCAL,
3168 .offset = LOCAL_VAR(iOplockContentionLimit),
3169 .special = NULL,
3170 .enum_list = NULL,
3171 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3174 .label = "posix locking",
3175 .type = P_BOOL,
3176 .p_class = P_LOCAL,
3177 .offset = LOCAL_VAR(bPosixLocking),
3178 .special = NULL,
3179 .enum_list = NULL,
3180 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3183 .label = "strict locking",
3184 .type = P_ENUM,
3185 .p_class = P_LOCAL,
3186 .offset = LOCAL_VAR(iStrictLocking),
3187 .special = NULL,
3188 .enum_list = enum_bool_auto,
3189 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3192 .label = "share modes",
3193 .type = P_BOOL,
3194 .p_class = P_LOCAL,
3195 .offset = LOCAL_VAR(bShareModes),
3196 .special = NULL,
3197 .enum_list = NULL,
3198 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3201 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3204 .label = "ldap admin dn",
3205 .type = P_STRING,
3206 .p_class = P_GLOBAL,
3207 .offset = GLOBAL_VAR(szLdapAdminDn),
3208 .special = NULL,
3209 .enum_list = NULL,
3210 .flags = FLAG_ADVANCED,
3213 .label = "ldap delete dn",
3214 .type = P_BOOL,
3215 .p_class = P_GLOBAL,
3216 .offset = GLOBAL_VAR(ldap_delete_dn),
3217 .special = NULL,
3218 .enum_list = NULL,
3219 .flags = FLAG_ADVANCED,
3222 .label = "ldap group suffix",
3223 .type = P_STRING,
3224 .p_class = P_GLOBAL,
3225 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3226 .special = NULL,
3227 .enum_list = NULL,
3228 .flags = FLAG_ADVANCED,
3231 .label = "ldap idmap suffix",
3232 .type = P_STRING,
3233 .p_class = P_GLOBAL,
3234 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3235 .special = NULL,
3236 .enum_list = NULL,
3237 .flags = FLAG_ADVANCED,
3240 .label = "ldap machine suffix",
3241 .type = P_STRING,
3242 .p_class = P_GLOBAL,
3243 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3244 .special = NULL,
3245 .enum_list = NULL,
3246 .flags = FLAG_ADVANCED,
3249 .label = "ldap passwd sync",
3250 .type = P_ENUM,
3251 .p_class = P_GLOBAL,
3252 .offset = GLOBAL_VAR(ldap_passwd_sync),
3253 .special = NULL,
3254 .enum_list = enum_ldap_passwd_sync,
3255 .flags = FLAG_ADVANCED,
3258 .label = "ldap password sync",
3259 .type = P_ENUM,
3260 .p_class = P_GLOBAL,
3261 .offset = GLOBAL_VAR(ldap_passwd_sync),
3262 .special = NULL,
3263 .enum_list = enum_ldap_passwd_sync,
3264 .flags = FLAG_HIDE,
3267 .label = "ldap replication sleep",
3268 .type = P_INTEGER,
3269 .p_class = P_GLOBAL,
3270 .offset = GLOBAL_VAR(ldap_replication_sleep),
3271 .special = NULL,
3272 .enum_list = NULL,
3273 .flags = FLAG_ADVANCED,
3276 .label = "ldap suffix",
3277 .type = P_STRING,
3278 .p_class = P_GLOBAL,
3279 .offset = GLOBAL_VAR(szLdapSuffix),
3280 .special = NULL,
3281 .enum_list = NULL,
3282 .flags = FLAG_ADVANCED,
3285 .label = "ldap ssl",
3286 .type = P_ENUM,
3287 .p_class = P_GLOBAL,
3288 .offset = GLOBAL_VAR(ldap_ssl),
3289 .special = NULL,
3290 .enum_list = enum_ldap_ssl,
3291 .flags = FLAG_ADVANCED,
3294 .label = "ldap ssl ads",
3295 .type = P_BOOL,
3296 .p_class = P_GLOBAL,
3297 .offset = GLOBAL_VAR(ldap_ssl_ads),
3298 .special = NULL,
3299 .enum_list = NULL,
3300 .flags = FLAG_ADVANCED,
3303 .label = "ldap deref",
3304 .type = P_ENUM,
3305 .p_class = P_GLOBAL,
3306 .offset = GLOBAL_VAR(ldap_deref),
3307 .special = NULL,
3308 .enum_list = enum_ldap_deref,
3309 .flags = FLAG_ADVANCED,
3312 .label = "ldap follow referral",
3313 .type = P_ENUM,
3314 .p_class = P_GLOBAL,
3315 .offset = GLOBAL_VAR(ldap_follow_referral),
3316 .special = NULL,
3317 .enum_list = enum_bool_auto,
3318 .flags = FLAG_ADVANCED,
3321 .label = "ldap timeout",
3322 .type = P_INTEGER,
3323 .p_class = P_GLOBAL,
3324 .offset = GLOBAL_VAR(ldap_timeout),
3325 .special = NULL,
3326 .enum_list = NULL,
3327 .flags = FLAG_ADVANCED,
3330 .label = "ldap connection timeout",
3331 .type = P_INTEGER,
3332 .p_class = P_GLOBAL,
3333 .offset = GLOBAL_VAR(ldap_connection_timeout),
3334 .special = NULL,
3335 .enum_list = NULL,
3336 .flags = FLAG_ADVANCED,
3339 .label = "ldap page size",
3340 .type = P_INTEGER,
3341 .p_class = P_GLOBAL,
3342 .offset = GLOBAL_VAR(ldap_page_size),
3343 .special = NULL,
3344 .enum_list = NULL,
3345 .flags = FLAG_ADVANCED,
3348 .label = "ldap user suffix",
3349 .type = P_STRING,
3350 .p_class = P_GLOBAL,
3351 .offset = GLOBAL_VAR(szLdapUserSuffix),
3352 .special = NULL,
3353 .enum_list = NULL,
3354 .flags = FLAG_ADVANCED,
3357 .label = "ldap debug level",
3358 .type = P_INTEGER,
3359 .p_class = P_GLOBAL,
3360 .offset = GLOBAL_VAR(ldap_debug_level),
3361 .special = handle_ldap_debug_level,
3362 .enum_list = NULL,
3363 .flags = FLAG_ADVANCED,
3366 .label = "ldap debug threshold",
3367 .type = P_INTEGER,
3368 .p_class = P_GLOBAL,
3369 .offset = GLOBAL_VAR(ldap_debug_threshold),
3370 .special = NULL,
3371 .enum_list = NULL,
3372 .flags = FLAG_ADVANCED,
3375 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3378 .label = "eventlog list",
3379 .type = P_LIST,
3380 .p_class = P_GLOBAL,
3381 .offset = GLOBAL_VAR(szEventLogs),
3382 .special = NULL,
3383 .enum_list = NULL,
3384 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3387 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3390 .label = "add share command",
3391 .type = P_STRING,
3392 .p_class = P_GLOBAL,
3393 .offset = GLOBAL_VAR(szAddShareCommand),
3394 .special = NULL,
3395 .enum_list = NULL,
3396 .flags = FLAG_ADVANCED,
3399 .label = "change share command",
3400 .type = P_STRING,
3401 .p_class = P_GLOBAL,
3402 .offset = GLOBAL_VAR(szChangeShareCommand),
3403 .special = NULL,
3404 .enum_list = NULL,
3405 .flags = FLAG_ADVANCED,
3408 .label = "delete share command",
3409 .type = P_STRING,
3410 .p_class = P_GLOBAL,
3411 .offset = GLOBAL_VAR(szDeleteShareCommand),
3412 .special = NULL,
3413 .enum_list = NULL,
3414 .flags = FLAG_ADVANCED,
3417 .label = "config file",
3418 .type = P_STRING,
3419 .p_class = P_GLOBAL,
3420 .offset = GLOBAL_VAR(szConfigFile),
3421 .special = NULL,
3422 .enum_list = NULL,
3423 .flags = FLAG_HIDE|FLAG_META,
3426 .label = "preload",
3427 .type = P_STRING,
3428 .p_class = P_GLOBAL,
3429 .offset = GLOBAL_VAR(szAutoServices),
3430 .special = NULL,
3431 .enum_list = NULL,
3432 .flags = FLAG_ADVANCED,
3435 .label = "auto services",
3436 .type = P_STRING,
3437 .p_class = P_GLOBAL,
3438 .offset = GLOBAL_VAR(szAutoServices),
3439 .special = NULL,
3440 .enum_list = NULL,
3441 .flags = FLAG_ADVANCED,
3444 .label = "lock directory",
3445 .type = P_STRING,
3446 .p_class = P_GLOBAL,
3447 .offset = GLOBAL_VAR(szLockDir),
3448 .special = NULL,
3449 .enum_list = NULL,
3450 .flags = FLAG_ADVANCED,
3453 .label = "lock dir",
3454 .type = P_STRING,
3455 .p_class = P_GLOBAL,
3456 .offset = GLOBAL_VAR(szLockDir),
3457 .special = NULL,
3458 .enum_list = NULL,
3459 .flags = FLAG_HIDE,
3462 .label = "state directory",
3463 .type = P_STRING,
3464 .p_class = P_GLOBAL,
3465 .offset = GLOBAL_VAR(szStateDir),
3466 .special = NULL,
3467 .enum_list = NULL,
3468 .flags = FLAG_ADVANCED,
3471 .label = "cache directory",
3472 .type = P_STRING,
3473 .p_class = P_GLOBAL,
3474 .offset = GLOBAL_VAR(szCacheDir),
3475 .special = NULL,
3476 .enum_list = NULL,
3477 .flags = FLAG_ADVANCED,
3480 .label = "pid directory",
3481 .type = P_STRING,
3482 .p_class = P_GLOBAL,
3483 .offset = GLOBAL_VAR(szPidDir),
3484 .special = NULL,
3485 .enum_list = NULL,
3486 .flags = FLAG_ADVANCED,
3488 #ifdef WITH_UTMP
3490 .label = "utmp directory",
3491 .type = P_STRING,
3492 .p_class = P_GLOBAL,
3493 .offset = GLOBAL_VAR(szUtmpDir),
3494 .special = NULL,
3495 .enum_list = NULL,
3496 .flags = FLAG_ADVANCED,
3499 .label = "wtmp directory",
3500 .type = P_STRING,
3501 .p_class = P_GLOBAL,
3502 .offset = GLOBAL_VAR(szWtmpDir),
3503 .special = NULL,
3504 .enum_list = NULL,
3505 .flags = FLAG_ADVANCED,
3508 .label = "utmp",
3509 .type = P_BOOL,
3510 .p_class = P_GLOBAL,
3511 .offset = GLOBAL_VAR(bUtmp),
3512 .special = NULL,
3513 .enum_list = NULL,
3514 .flags = FLAG_ADVANCED,
3516 #endif
3518 .label = "default service",
3519 .type = P_STRING,
3520 .p_class = P_GLOBAL,
3521 .offset = GLOBAL_VAR(szDefaultService),
3522 .special = NULL,
3523 .enum_list = NULL,
3524 .flags = FLAG_ADVANCED,
3527 .label = "default",
3528 .type = P_STRING,
3529 .p_class = P_GLOBAL,
3530 .offset = GLOBAL_VAR(szDefaultService),
3531 .special = NULL,
3532 .enum_list = NULL,
3533 .flags = FLAG_ADVANCED,
3536 .label = "message command",
3537 .type = P_STRING,
3538 .p_class = P_GLOBAL,
3539 .offset = GLOBAL_VAR(szMsgCommand),
3540 .special = NULL,
3541 .enum_list = NULL,
3542 .flags = FLAG_ADVANCED,
3545 .label = "dfree cache time",
3546 .type = P_INTEGER,
3547 .p_class = P_LOCAL,
3548 .offset = LOCAL_VAR(iDfreeCacheTime),
3549 .special = NULL,
3550 .enum_list = NULL,
3551 .flags = FLAG_ADVANCED,
3554 .label = "dfree command",
3555 .type = P_STRING,
3556 .p_class = P_LOCAL,
3557 .offset = LOCAL_VAR(szDfree),
3558 .special = NULL,
3559 .enum_list = NULL,
3560 .flags = FLAG_ADVANCED,
3563 .label = "get quota command",
3564 .type = P_STRING,
3565 .p_class = P_GLOBAL,
3566 .offset = GLOBAL_VAR(szGetQuota),
3567 .special = NULL,
3568 .enum_list = NULL,
3569 .flags = FLAG_ADVANCED,
3572 .label = "set quota command",
3573 .type = P_STRING,
3574 .p_class = P_GLOBAL,
3575 .offset = GLOBAL_VAR(szSetQuota),
3576 .special = NULL,
3577 .enum_list = NULL,
3578 .flags = FLAG_ADVANCED,
3581 .label = "remote announce",
3582 .type = P_STRING,
3583 .p_class = P_GLOBAL,
3584 .offset = GLOBAL_VAR(szRemoteAnnounce),
3585 .special = NULL,
3586 .enum_list = NULL,
3587 .flags = FLAG_ADVANCED,
3590 .label = "remote browse sync",
3591 .type = P_STRING,
3592 .p_class = P_GLOBAL,
3593 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3594 .special = NULL,
3595 .enum_list = NULL,
3596 .flags = FLAG_ADVANCED,
3599 .label = "socket address",
3600 .type = P_STRING,
3601 .p_class = P_GLOBAL,
3602 .offset = GLOBAL_VAR(szSocketAddress),
3603 .special = NULL,
3604 .enum_list = NULL,
3605 .flags = FLAG_ADVANCED,
3608 .label = "nmbd bind explicit broadcast",
3609 .type = P_BOOL,
3610 .p_class = P_GLOBAL,
3611 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3612 .special = NULL,
3613 .enum_list = NULL,
3614 .flags = FLAG_ADVANCED,
3617 .label = "homedir map",
3618 .type = P_STRING,
3619 .p_class = P_GLOBAL,
3620 .offset = GLOBAL_VAR(szNISHomeMapName),
3621 .special = NULL,
3622 .enum_list = NULL,
3623 .flags = FLAG_ADVANCED,
3626 .label = "afs username map",
3627 .type = P_STRING,
3628 .p_class = P_GLOBAL,
3629 .offset = GLOBAL_VAR(szAfsUsernameMap),
3630 .special = NULL,
3631 .enum_list = NULL,
3632 .flags = FLAG_ADVANCED,
3635 .label = "afs token lifetime",
3636 .type = P_INTEGER,
3637 .p_class = P_GLOBAL,
3638 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3639 .special = NULL,
3640 .enum_list = NULL,
3641 .flags = FLAG_ADVANCED,
3644 .label = "log nt token command",
3645 .type = P_STRING,
3646 .p_class = P_GLOBAL,
3647 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3648 .special = NULL,
3649 .enum_list = NULL,
3650 .flags = FLAG_ADVANCED,
3653 .label = "NIS homedir",
3654 .type = P_BOOL,
3655 .p_class = P_GLOBAL,
3656 .offset = GLOBAL_VAR(bNISHomeMap),
3657 .special = NULL,
3658 .enum_list = NULL,
3659 .flags = FLAG_ADVANCED,
3662 .label = "-valid",
3663 .type = P_BOOL,
3664 .p_class = P_LOCAL,
3665 .offset = LOCAL_VAR(valid),
3666 .special = NULL,
3667 .enum_list = NULL,
3668 .flags = FLAG_HIDE,
3671 .label = "copy",
3672 .type = P_STRING,
3673 .p_class = P_LOCAL,
3674 .offset = LOCAL_VAR(szCopy),
3675 .special = handle_copy,
3676 .enum_list = NULL,
3677 .flags = FLAG_HIDE,
3680 .label = "include",
3681 .type = P_STRING,
3682 .p_class = P_LOCAL,
3683 .offset = LOCAL_VAR(szInclude),
3684 .special = handle_include,
3685 .enum_list = NULL,
3686 .flags = FLAG_HIDE|FLAG_META,
3689 .label = "preexec",
3690 .type = P_STRING,
3691 .p_class = P_LOCAL,
3692 .offset = LOCAL_VAR(szPreExec),
3693 .special = NULL,
3694 .enum_list = NULL,
3695 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3698 .label = "exec",
3699 .type = P_STRING,
3700 .p_class = P_LOCAL,
3701 .offset = LOCAL_VAR(szPreExec),
3702 .special = NULL,
3703 .enum_list = NULL,
3704 .flags = FLAG_ADVANCED,
3707 .label = "preexec close",
3708 .type = P_BOOL,
3709 .p_class = P_LOCAL,
3710 .offset = LOCAL_VAR(bPreexecClose),
3711 .special = NULL,
3712 .enum_list = NULL,
3713 .flags = FLAG_ADVANCED | FLAG_SHARE,
3716 .label = "postexec",
3717 .type = P_STRING,
3718 .p_class = P_LOCAL,
3719 .offset = LOCAL_VAR(szPostExec),
3720 .special = NULL,
3721 .enum_list = NULL,
3722 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3725 .label = "root preexec",
3726 .type = P_STRING,
3727 .p_class = P_LOCAL,
3728 .offset = LOCAL_VAR(szRootPreExec),
3729 .special = NULL,
3730 .enum_list = NULL,
3731 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3734 .label = "root preexec close",
3735 .type = P_BOOL,
3736 .p_class = P_LOCAL,
3737 .offset = LOCAL_VAR(bRootpreexecClose),
3738 .special = NULL,
3739 .enum_list = NULL,
3740 .flags = FLAG_ADVANCED | FLAG_SHARE,
3743 .label = "root postexec",
3744 .type = P_STRING,
3745 .p_class = P_LOCAL,
3746 .offset = LOCAL_VAR(szRootPostExec),
3747 .special = NULL,
3748 .enum_list = NULL,
3749 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3752 .label = "available",
3753 .type = P_BOOL,
3754 .p_class = P_LOCAL,
3755 .offset = LOCAL_VAR(bAvailable),
3756 .special = NULL,
3757 .enum_list = NULL,
3758 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3761 .label = "registry shares",
3762 .type = P_BOOL,
3763 .p_class = P_GLOBAL,
3764 .offset = GLOBAL_VAR(bRegistryShares),
3765 .special = NULL,
3766 .enum_list = NULL,
3767 .flags = FLAG_ADVANCED,
3770 .label = "usershare allow guests",
3771 .type = P_BOOL,
3772 .p_class = P_GLOBAL,
3773 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3774 .special = NULL,
3775 .enum_list = NULL,
3776 .flags = FLAG_ADVANCED,
3779 .label = "usershare max shares",
3780 .type = P_INTEGER,
3781 .p_class = P_GLOBAL,
3782 .offset = GLOBAL_VAR(iUsershareMaxShares),
3783 .special = NULL,
3784 .enum_list = NULL,
3785 .flags = FLAG_ADVANCED,
3788 .label = "usershare owner only",
3789 .type = P_BOOL,
3790 .p_class = P_GLOBAL,
3791 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3792 .special = NULL,
3793 .enum_list = NULL,
3794 .flags = FLAG_ADVANCED,
3797 .label = "usershare path",
3798 .type = P_STRING,
3799 .p_class = P_GLOBAL,
3800 .offset = GLOBAL_VAR(szUsersharePath),
3801 .special = NULL,
3802 .enum_list = NULL,
3803 .flags = FLAG_ADVANCED,
3806 .label = "usershare prefix allow list",
3807 .type = P_LIST,
3808 .p_class = P_GLOBAL,
3809 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3810 .special = NULL,
3811 .enum_list = NULL,
3812 .flags = FLAG_ADVANCED,
3815 .label = "usershare prefix deny list",
3816 .type = P_LIST,
3817 .p_class = P_GLOBAL,
3818 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3819 .special = NULL,
3820 .enum_list = NULL,
3821 .flags = FLAG_ADVANCED,
3824 .label = "usershare template share",
3825 .type = P_STRING,
3826 .p_class = P_GLOBAL,
3827 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3828 .special = NULL,
3829 .enum_list = NULL,
3830 .flags = FLAG_ADVANCED,
3833 .label = "volume",
3834 .type = P_STRING,
3835 .p_class = P_LOCAL,
3836 .offset = LOCAL_VAR(volume),
3837 .special = NULL,
3838 .enum_list = NULL,
3839 .flags = FLAG_ADVANCED | FLAG_SHARE,
3842 .label = "fstype",
3843 .type = P_STRING,
3844 .p_class = P_LOCAL,
3845 .offset = LOCAL_VAR(fstype),
3846 .special = NULL,
3847 .enum_list = NULL,
3848 .flags = FLAG_ADVANCED | FLAG_SHARE,
3851 .label = "set directory",
3852 .type = P_BOOLREV,
3853 .p_class = P_LOCAL,
3854 .offset = LOCAL_VAR(bNo_set_dir),
3855 .special = NULL,
3856 .enum_list = NULL,
3857 .flags = FLAG_ADVANCED | FLAG_SHARE,
3860 .label = "allow insecure wide links",
3861 .type = P_BOOL,
3862 .p_class = P_GLOBAL,
3863 .offset = GLOBAL_VAR(bAllowInsecureWidelinks),
3864 .special = NULL,
3865 .enum_list = NULL,
3866 .flags = FLAG_ADVANCED,
3869 .label = "wide links",
3870 .type = P_BOOL,
3871 .p_class = P_LOCAL,
3872 .offset = LOCAL_VAR(bWidelinks),
3873 .special = NULL,
3874 .enum_list = NULL,
3875 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3878 .label = "follow symlinks",
3879 .type = P_BOOL,
3880 .p_class = P_LOCAL,
3881 .offset = LOCAL_VAR(bSymlinks),
3882 .special = NULL,
3883 .enum_list = NULL,
3884 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3887 .label = "dont descend",
3888 .type = P_STRING,
3889 .p_class = P_LOCAL,
3890 .offset = LOCAL_VAR(szDontdescend),
3891 .special = NULL,
3892 .enum_list = NULL,
3893 .flags = FLAG_ADVANCED | FLAG_SHARE,
3896 .label = "magic script",
3897 .type = P_STRING,
3898 .p_class = P_LOCAL,
3899 .offset = LOCAL_VAR(szMagicScript),
3900 .special = NULL,
3901 .enum_list = NULL,
3902 .flags = FLAG_ADVANCED | FLAG_SHARE,
3905 .label = "magic output",
3906 .type = P_STRING,
3907 .p_class = P_LOCAL,
3908 .offset = LOCAL_VAR(szMagicOutput),
3909 .special = NULL,
3910 .enum_list = NULL,
3911 .flags = FLAG_ADVANCED | FLAG_SHARE,
3914 .label = "delete readonly",
3915 .type = P_BOOL,
3916 .p_class = P_LOCAL,
3917 .offset = LOCAL_VAR(bDeleteReadonly),
3918 .special = NULL,
3919 .enum_list = NULL,
3920 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3923 .label = "dos filemode",
3924 .type = P_BOOL,
3925 .p_class = P_LOCAL,
3926 .offset = LOCAL_VAR(bDosFilemode),
3927 .special = NULL,
3928 .enum_list = NULL,
3929 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3932 .label = "dos filetimes",
3933 .type = P_BOOL,
3934 .p_class = P_LOCAL,
3935 .offset = LOCAL_VAR(bDosFiletimes),
3936 .special = NULL,
3937 .enum_list = NULL,
3938 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3941 .label = "dos filetime resolution",
3942 .type = P_BOOL,
3943 .p_class = P_LOCAL,
3944 .offset = LOCAL_VAR(bDosFiletimeResolution),
3945 .special = NULL,
3946 .enum_list = NULL,
3947 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3950 .label = "fake directory create times",
3951 .type = P_BOOL,
3952 .p_class = P_LOCAL,
3953 .offset = LOCAL_VAR(bFakeDirCreateTimes),
3954 .special = NULL,
3955 .enum_list = NULL,
3956 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3959 .label = "async smb echo handler",
3960 .type = P_BOOL,
3961 .p_class = P_GLOBAL,
3962 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
3963 .special = NULL,
3964 .enum_list = NULL,
3965 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3968 .label = "multicast dns register",
3969 .type = P_BOOL,
3970 .p_class = P_GLOBAL,
3971 .offset = GLOBAL_VAR(bMulticastDnsRegister),
3972 .special = NULL,
3973 .enum_list = NULL,
3974 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3977 .label = "panic action",
3978 .type = P_STRING,
3979 .p_class = P_GLOBAL,
3980 .offset = GLOBAL_VAR(szPanicAction),
3981 .special = NULL,
3982 .enum_list = NULL,
3983 .flags = FLAG_ADVANCED,
3986 .label = "perfcount module",
3987 .type = P_STRING,
3988 .p_class = P_GLOBAL,
3989 .offset = GLOBAL_VAR(szSMBPerfcountModule),
3990 .special = NULL,
3991 .enum_list = NULL,
3992 .flags = FLAG_ADVANCED,
3995 {N_("VFS module options"), P_SEP, P_SEPARATOR},
3998 .label = "vfs objects",
3999 .type = P_LIST,
4000 .p_class = P_LOCAL,
4001 .offset = LOCAL_VAR(szVfsObjects),
4002 .special = NULL,
4003 .enum_list = NULL,
4004 .flags = FLAG_ADVANCED | FLAG_SHARE,
4007 .label = "vfs object",
4008 .type = P_LIST,
4009 .p_class = P_LOCAL,
4010 .offset = LOCAL_VAR(szVfsObjects),
4011 .special = NULL,
4012 .enum_list = NULL,
4013 .flags = FLAG_HIDE,
4017 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4020 .label = "msdfs root",
4021 .type = P_BOOL,
4022 .p_class = P_LOCAL,
4023 .offset = LOCAL_VAR(bMSDfsRoot),
4024 .special = NULL,
4025 .enum_list = NULL,
4026 .flags = FLAG_ADVANCED | FLAG_SHARE,
4029 .label = "msdfs proxy",
4030 .type = P_STRING,
4031 .p_class = P_LOCAL,
4032 .offset = LOCAL_VAR(szMSDfsProxy),
4033 .special = NULL,
4034 .enum_list = NULL,
4035 .flags = FLAG_ADVANCED | FLAG_SHARE,
4038 .label = "host msdfs",
4039 .type = P_BOOL,
4040 .p_class = P_GLOBAL,
4041 .offset = GLOBAL_VAR(bHostMSDfs),
4042 .special = NULL,
4043 .enum_list = NULL,
4044 .flags = FLAG_ADVANCED,
4047 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4050 .label = "passdb expand explicit",
4051 .type = P_BOOL,
4052 .p_class = P_GLOBAL,
4053 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4054 .special = NULL,
4055 .enum_list = NULL,
4056 .flags = FLAG_ADVANCED,
4059 .label = "idmap backend",
4060 .type = P_STRING,
4061 .p_class = P_GLOBAL,
4062 .offset = GLOBAL_VAR(szIdmapBackend),
4063 .special = handle_idmap_backend,
4064 .enum_list = NULL,
4065 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4068 .label = "idmap cache time",
4069 .type = P_INTEGER,
4070 .p_class = P_GLOBAL,
4071 .offset = GLOBAL_VAR(iIdmapCacheTime),
4072 .special = NULL,
4073 .enum_list = NULL,
4074 .flags = FLAG_ADVANCED,
4077 .label = "idmap negative cache time",
4078 .type = P_INTEGER,
4079 .p_class = P_GLOBAL,
4080 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4081 .special = NULL,
4082 .enum_list = NULL,
4083 .flags = FLAG_ADVANCED,
4086 .label = "idmap uid",
4087 .type = P_STRING,
4088 .p_class = P_GLOBAL,
4089 .offset = GLOBAL_VAR(szIdmapUID),
4090 .special = handle_idmap_uid,
4091 .enum_list = NULL,
4092 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4095 .label = "winbind uid",
4096 .type = P_STRING,
4097 .p_class = P_GLOBAL,
4098 .offset = GLOBAL_VAR(szIdmapUID),
4099 .special = handle_idmap_uid,
4100 .enum_list = NULL,
4101 .flags = FLAG_HIDE,
4104 .label = "idmap gid",
4105 .type = P_STRING,
4106 .p_class = P_GLOBAL,
4107 .offset = GLOBAL_VAR(szIdmapGID),
4108 .special = handle_idmap_gid,
4109 .enum_list = NULL,
4110 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4113 .label = "winbind gid",
4114 .type = P_STRING,
4115 .p_class = P_GLOBAL,
4116 .offset = GLOBAL_VAR(szIdmapGID),
4117 .special = handle_idmap_gid,
4118 .enum_list = NULL,
4119 .flags = FLAG_HIDE,
4122 .label = "template homedir",
4123 .type = P_STRING,
4124 .p_class = P_GLOBAL,
4125 .offset = GLOBAL_VAR(szTemplateHomedir),
4126 .special = NULL,
4127 .enum_list = NULL,
4128 .flags = FLAG_ADVANCED,
4131 .label = "template shell",
4132 .type = P_STRING,
4133 .p_class = P_GLOBAL,
4134 .offset = GLOBAL_VAR(szTemplateShell),
4135 .special = NULL,
4136 .enum_list = NULL,
4137 .flags = FLAG_ADVANCED,
4140 .label = "winbind separator",
4141 .type = P_STRING,
4142 .p_class = P_GLOBAL,
4143 .offset = GLOBAL_VAR(szWinbindSeparator),
4144 .special = NULL,
4145 .enum_list = NULL,
4146 .flags = FLAG_ADVANCED,
4149 .label = "winbind cache time",
4150 .type = P_INTEGER,
4151 .p_class = P_GLOBAL,
4152 .offset = GLOBAL_VAR(winbind_cache_time),
4153 .special = NULL,
4154 .enum_list = NULL,
4155 .flags = FLAG_ADVANCED,
4158 .label = "winbind reconnect delay",
4159 .type = P_INTEGER,
4160 .p_class = P_GLOBAL,
4161 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4162 .special = NULL,
4163 .enum_list = NULL,
4164 .flags = FLAG_ADVANCED,
4167 .label = "winbind max clients",
4168 .type = P_INTEGER,
4169 .p_class = P_GLOBAL,
4170 .offset = GLOBAL_VAR(winbind_max_clients),
4171 .special = NULL,
4172 .enum_list = NULL,
4173 .flags = FLAG_ADVANCED,
4176 .label = "winbind enum users",
4177 .type = P_BOOL,
4178 .p_class = P_GLOBAL,
4179 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4180 .special = NULL,
4181 .enum_list = NULL,
4182 .flags = FLAG_ADVANCED,
4185 .label = "winbind enum groups",
4186 .type = P_BOOL,
4187 .p_class = P_GLOBAL,
4188 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4189 .special = NULL,
4190 .enum_list = NULL,
4191 .flags = FLAG_ADVANCED,
4194 .label = "winbind use default domain",
4195 .type = P_BOOL,
4196 .p_class = P_GLOBAL,
4197 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4198 .special = NULL,
4199 .enum_list = NULL,
4200 .flags = FLAG_ADVANCED,
4203 .label = "winbind trusted domains only",
4204 .type = P_BOOL,
4205 .p_class = P_GLOBAL,
4206 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4207 .special = NULL,
4208 .enum_list = NULL,
4209 .flags = FLAG_ADVANCED,
4212 .label = "winbind nested groups",
4213 .type = P_BOOL,
4214 .p_class = P_GLOBAL,
4215 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4216 .special = NULL,
4217 .enum_list = NULL,
4218 .flags = FLAG_ADVANCED,
4221 .label = "winbind expand groups",
4222 .type = P_INTEGER,
4223 .p_class = P_GLOBAL,
4224 .offset = GLOBAL_VAR(winbind_expand_groups),
4225 .special = NULL,
4226 .enum_list = NULL,
4227 .flags = FLAG_ADVANCED,
4230 .label = "winbind nss info",
4231 .type = P_LIST,
4232 .p_class = P_GLOBAL,
4233 .offset = GLOBAL_VAR(szWinbindNssInfo),
4234 .special = NULL,
4235 .enum_list = NULL,
4236 .flags = FLAG_ADVANCED,
4239 .label = "winbind refresh tickets",
4240 .type = P_BOOL,
4241 .p_class = P_GLOBAL,
4242 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4243 .special = NULL,
4244 .enum_list = NULL,
4245 .flags = FLAG_ADVANCED,
4248 .label = "winbind offline logon",
4249 .type = P_BOOL,
4250 .p_class = P_GLOBAL,
4251 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4252 .special = NULL,
4253 .enum_list = NULL,
4254 .flags = FLAG_ADVANCED,
4257 .label = "winbind normalize names",
4258 .type = P_BOOL,
4259 .p_class = P_GLOBAL,
4260 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4261 .special = NULL,
4262 .enum_list = NULL,
4263 .flags = FLAG_ADVANCED,
4266 .label = "winbind rpc only",
4267 .type = P_BOOL,
4268 .p_class = P_GLOBAL,
4269 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4270 .special = NULL,
4271 .enum_list = NULL,
4272 .flags = FLAG_ADVANCED,
4275 .label = "create krb5 conf",
4276 .type = P_BOOL,
4277 .p_class = P_GLOBAL,
4278 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4279 .special = NULL,
4280 .enum_list = NULL,
4281 .flags = FLAG_ADVANCED,
4284 .label = "ncalrpc dir",
4285 .type = P_STRING,
4286 .p_class = P_GLOBAL,
4287 .offset = GLOBAL_VAR(ncalrpc_dir),
4288 .special = NULL,
4289 .enum_list = NULL,
4290 .flags = FLAG_ADVANCED,
4293 .label = "winbind max domain connections",
4294 .type = P_INTEGER,
4295 .p_class = P_GLOBAL,
4296 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4297 .special = NULL,
4298 .enum_list = NULL,
4299 .flags = FLAG_ADVANCED,
4302 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4305 /***************************************************************************
4306 Initialise the sDefault parameter structure for the printer values.
4307 ***************************************************************************/
4309 static void init_printer_values(struct loadparm_service *pService)
4311 /* choose defaults depending on the type of printing */
4312 switch (pService->iPrinting) {
4313 case PRINT_BSD:
4314 case PRINT_AIX:
4315 case PRINT_LPRNT:
4316 case PRINT_LPROS2:
4317 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4318 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4319 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4320 break;
4322 case PRINT_LPRNG:
4323 case PRINT_PLP:
4324 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4325 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4326 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4327 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4328 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4329 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4330 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4331 break;
4333 case PRINT_CUPS:
4334 case PRINT_IPRINT:
4335 #ifdef HAVE_CUPS
4336 /* set the lpq command to contain the destination printer
4337 name only. This is used by cups_queue_get() */
4338 string_set(&pService->szLpqcommand, "%p");
4339 string_set(&pService->szLprmcommand, "");
4340 string_set(&pService->szPrintcommand, "");
4341 string_set(&pService->szLppausecommand, "");
4342 string_set(&pService->szLpresumecommand, "");
4343 string_set(&pService->szQueuepausecommand, "");
4344 string_set(&pService->szQueueresumecommand, "");
4345 #else
4346 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4347 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4348 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4349 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4350 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4351 string_set(&pService->szQueuepausecommand, "disable '%p'");
4352 string_set(&pService->szQueueresumecommand, "enable '%p'");
4353 #endif /* HAVE_CUPS */
4354 break;
4356 case PRINT_SYSV:
4357 case PRINT_HPUX:
4358 string_set(&pService->szLpqcommand, "lpstat -o%p");
4359 string_set(&pService->szLprmcommand, "cancel %p-%j");
4360 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4361 string_set(&pService->szQueuepausecommand, "disable %p");
4362 string_set(&pService->szQueueresumecommand, "enable %p");
4363 #ifndef HPUX
4364 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4365 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4366 #endif /* HPUX */
4367 break;
4369 case PRINT_QNX:
4370 string_set(&pService->szLpqcommand, "lpq -P%p");
4371 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4372 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4373 break;
4375 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4377 case PRINT_TEST:
4378 case PRINT_VLP: {
4379 const char *tdbfile;
4380 char *tmp;
4382 tdbfile = talloc_asprintf(
4383 talloc_tos(), "tdbfile=%s",
4384 lp_parm_const_string(-1, "vlp", "tdbfile",
4385 "/tmp/vlp.tdb"));
4386 if (tdbfile == NULL) {
4387 tdbfile="tdbfile=/tmp/vlp.tdb";
4390 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4391 tdbfile);
4392 string_set(&pService->szPrintcommand,
4393 tmp ? tmp : "vlp print %p %s");
4394 TALLOC_FREE(tmp);
4396 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4397 tdbfile);
4398 string_set(&pService->szLpqcommand,
4399 tmp ? tmp : "vlp lpq %p");
4400 TALLOC_FREE(tmp);
4402 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4403 tdbfile);
4404 string_set(&pService->szLprmcommand,
4405 tmp ? tmp : "vlp lprm %p %j");
4406 TALLOC_FREE(tmp);
4408 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4409 tdbfile);
4410 string_set(&pService->szLppausecommand,
4411 tmp ? tmp : "vlp lppause %p %j");
4412 TALLOC_FREE(tmp);
4414 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4415 tdbfile);
4416 string_set(&pService->szLpresumecommand,
4417 tmp ? tmp : "vlp lpresume %p %j");
4418 TALLOC_FREE(tmp);
4420 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4421 tdbfile);
4422 string_set(&pService->szQueuepausecommand,
4423 tmp ? tmp : "vlp queuepause %p");
4424 TALLOC_FREE(tmp);
4426 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4427 tdbfile);
4428 string_set(&pService->szQueueresumecommand,
4429 tmp ? tmp : "vlp queueresume %p");
4430 TALLOC_FREE(tmp);
4432 break;
4434 #endif /* DEVELOPER */
4439 * Function to return the default value for the maximum number of open
4440 * file descriptors permitted. This function tries to consult the
4441 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4442 * the smaller of those.
4444 static int max_open_files(void)
4446 int sysctl_max = MAX_OPEN_FILES;
4447 int rlimit_max = MAX_OPEN_FILES;
4449 #ifdef HAVE_SYSCTLBYNAME
4451 size_t size = sizeof(sysctl_max);
4452 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4455 #endif
4457 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4459 struct rlimit rl;
4461 ZERO_STRUCT(rl);
4463 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4464 rlimit_max = rl.rlim_cur;
4466 #if defined(RLIM_INFINITY)
4467 if(rl.rlim_cur == RLIM_INFINITY)
4468 rlimit_max = MAX_OPEN_FILES;
4469 #endif
4471 #endif
4473 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4474 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4475 "minimum Windows limit (%d)\n",
4476 sysctl_max,
4477 MIN_OPEN_FILES_WINDOWS));
4478 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4481 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4482 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4483 "minimum Windows limit (%d)\n",
4484 rlimit_max,
4485 MIN_OPEN_FILES_WINDOWS));
4486 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4489 return MIN(sysctl_max, rlimit_max);
4493 * Common part of freeing allocated data for one parameter.
4495 static void free_one_parameter_common(void *parm_ptr,
4496 struct parm_struct parm)
4498 if ((parm.type == P_STRING) ||
4499 (parm.type == P_USTRING))
4501 string_free((char**)parm_ptr);
4502 } else if (parm.type == P_LIST) {
4503 TALLOC_FREE(*((char***)parm_ptr));
4508 * Free the allocated data for one parameter for a share
4509 * given as a service struct.
4511 static void free_one_parameter(struct loadparm_service *service,
4512 struct parm_struct parm)
4514 void *parm_ptr;
4516 if (parm.p_class != P_LOCAL) {
4517 return;
4520 parm_ptr = lp_parm_ptr(service, &parm);
4522 free_one_parameter_common(parm_ptr, parm);
4526 * Free the allocated parameter data of a share given
4527 * as a service struct.
4529 static void free_parameters(struct loadparm_service *service)
4531 uint32_t i;
4533 for (i=0; parm_table[i].label; i++) {
4534 free_one_parameter(service, parm_table[i]);
4539 * Free the allocated data for one parameter for a given share
4540 * specified by an snum.
4542 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4544 void *parm_ptr;
4546 if (snum < 0) {
4547 parm_ptr = lp_parm_ptr(NULL, &parm);
4548 } else if (parm.p_class != P_LOCAL) {
4549 return;
4550 } else {
4551 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4554 free_one_parameter_common(parm_ptr, parm);
4558 * Free the allocated parameter data for a share specified
4559 * by an snum.
4561 static void free_parameters_by_snum(int snum)
4563 uint32_t i;
4565 for (i=0; parm_table[i].label; i++) {
4566 free_one_parameter_by_snum(snum, parm_table[i]);
4571 * Free the allocated global parameters.
4573 static void free_global_parameters(void)
4575 free_param_opts(&Globals.param_opt);
4576 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4579 static int map_parameter(const char *pszParmName);
4581 struct lp_stored_option {
4582 struct lp_stored_option *prev, *next;
4583 const char *label;
4584 const char *value;
4587 static struct lp_stored_option *stored_options;
4590 save options set by lp_set_cmdline() into a list. This list is
4591 re-applied when we do a globals reset, so that cmdline set options
4592 are sticky across reloads of smb.conf
4594 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4596 struct lp_stored_option *entry, *entry_next;
4597 for (entry = stored_options; entry != NULL; entry = entry_next) {
4598 entry_next = entry->next;
4599 if (strcmp(pszParmName, entry->label) == 0) {
4600 DLIST_REMOVE(stored_options, entry);
4601 talloc_free(entry);
4602 break;
4606 entry = talloc(NULL, struct lp_stored_option);
4607 if (!entry) {
4608 return false;
4611 entry->label = talloc_strdup(entry, pszParmName);
4612 if (!entry->label) {
4613 talloc_free(entry);
4614 return false;
4617 entry->value = talloc_strdup(entry, pszParmValue);
4618 if (!entry->value) {
4619 talloc_free(entry);
4620 return false;
4623 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4625 return true;
4628 static bool apply_lp_set_cmdline(void)
4630 struct lp_stored_option *entry = NULL;
4631 for (entry = stored_options; entry != NULL; entry = entry->next) {
4632 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
4633 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4634 entry->label, entry->value));
4635 return false;
4638 return true;
4641 /***************************************************************************
4642 Initialise the global parameter structure.
4643 ***************************************************************************/
4645 static void init_globals(bool reinit_globals)
4647 static bool done_init = false;
4648 char *s = NULL;
4649 int i;
4651 /* If requested to initialize only once and we've already done it... */
4652 if (!reinit_globals && done_init) {
4653 /* ... then we have nothing more to do */
4654 return;
4657 if (!done_init) {
4658 /* The logfile can be set before this is invoked. Free it if so. */
4659 if (Globals.szLogFile != NULL) {
4660 string_free(&Globals.szLogFile);
4661 Globals.szLogFile = NULL;
4663 done_init = true;
4664 } else {
4665 free_global_parameters();
4668 /* This memset and the free_global_parameters() above will
4669 * wipe out smb.conf options set with lp_set_cmdline(). The
4670 * apply_lp_set_cmdline() call puts these values back in the
4671 * table once the defaults are set */
4672 ZERO_STRUCT(Globals);
4674 for (i = 0; parm_table[i].label; i++) {
4675 if ((parm_table[i].type == P_STRING ||
4676 parm_table[i].type == P_USTRING))
4678 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
4683 string_set(&sDefault.fstype, FSTYPE_STRING);
4684 string_set(&sDefault.szPrintjobUsername, "%U");
4686 init_printer_values(&sDefault);
4689 DEBUG(3, ("Initialising global parameters\n"));
4691 /* Must manually force to upper case here, as this does not go via the handler */
4692 string_set(&Globals.szNetbiosName, myhostname_upper());
4694 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4695 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4697 /* use the new 'hash2' method by default, with a prefix of 1 */
4698 string_set(&Globals.szManglingMethod, "hash2");
4699 Globals.mangle_prefix = 1;
4701 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4703 /* using UTF8 by default allows us to support all chars */
4704 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4706 /* Use codepage 850 as a default for the dos character set */
4707 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4710 * Allow the default PASSWD_CHAT to be overridden in local.h.
4712 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4714 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
4716 string_set(&Globals.szPasswdProgram, "");
4717 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4718 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4719 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4720 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4721 string_set(&Globals.szSocketAddress, "0.0.0.0");
4723 * By default support explicit binding to broadcast
4724 * addresses.
4726 Globals.bNmbdBindExplicitBroadcast = true;
4728 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4729 smb_panic("init_globals: ENOMEM");
4731 string_set(&Globals.szServerString, s);
4732 SAFE_FREE(s);
4733 #ifdef DEVELOPER
4734 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4735 #endif
4737 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4739 string_set(&Globals.szLogonDrive, "");
4740 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4741 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4742 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4744 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4745 string_set(&Globals.szPasswordServer, "*");
4747 Globals.AlgorithmicRidBase = BASE_RID;
4749 Globals.bLoadPrinters = true;
4750 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4752 Globals.ConfigBackend = config_backend;
4753 Globals.ServerRole = ROLE_AUTO;
4755 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4756 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4757 Globals.max_xmit = 0x4104;
4758 Globals.max_mux = 50; /* This is *needed* for profile support. */
4759 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4760 Globals.bDisableSpoolss = false;
4761 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4762 Globals.pwordlevel = 0;
4763 Globals.unamelevel = 0;
4764 Globals.deadtime = 0;
4765 Globals.getwd_cache = true;
4766 Globals.bLargeReadwrite = true;
4767 Globals.max_log_size = 5000;
4768 Globals.max_open_files = max_open_files();
4769 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4770 Globals.srv_maxprotocol = PROTOCOL_SMB2_02;
4771 Globals.srv_minprotocol = PROTOCOL_CORE;
4772 Globals.security = SEC_USER;
4773 Globals.paranoid_server_security = true;
4774 Globals.bEncryptPasswords = true;
4775 Globals.clientSchannel = Auto;
4776 Globals.serverSchannel = Auto;
4777 Globals.bReadRaw = true;
4778 Globals.bWriteRaw = true;
4779 Globals.bNullPasswords = false;
4780 Globals.bObeyPamRestrictions = false;
4781 Globals.syslog = 1;
4782 Globals.bSyslogOnly = false;
4783 Globals.bTimestampLogs = true;
4784 string_set(&Globals.szLogLevel, "0");
4785 Globals.bDebugPrefixTimestamp = false;
4786 Globals.bDebugHiresTimestamp = true;
4787 Globals.bDebugPid = false;
4788 Globals.bDebugUid = false;
4789 Globals.bDebugClass = false;
4790 Globals.bEnableCoreFiles = true;
4791 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4792 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4793 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4794 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4795 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
4796 Globals.lm_interval = 60;
4797 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4798 Globals.bNISHomeMap = false;
4799 #ifdef WITH_NISPLUS_HOME
4800 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4801 #else
4802 string_set(&Globals.szNISHomeMapName, "auto.home");
4803 #endif
4804 #endif
4805 Globals.bTimeServer = false;
4806 Globals.bBindInterfacesOnly = false;
4807 Globals.bUnixPasswdSync = false;
4808 Globals.bPamPasswordChange = false;
4809 Globals.bPasswdChatDebug = false;
4810 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4811 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
4812 Globals.bNTStatusSupport = true; /* Use NT status by default. */
4813 Globals.bStatCache = true; /* use stat cache by default */
4814 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4815 Globals.restrict_anonymous = 0;
4816 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
4817 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
4818 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
4819 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4820 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4821 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4823 Globals.map_to_guest = 0; /* By Default, "Never" */
4824 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4825 Globals.enhanced_browsing = true;
4826 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4827 #ifdef MMAP_BLACKLIST
4828 Globals.bUseMmap = false;
4829 #else
4830 Globals.bUseMmap = true;
4831 #endif
4832 Globals.bUnixExtensions = true;
4833 Globals.bResetOnZeroVC = false;
4834 Globals.bLogWriteableFilesOnExit = false;
4835 Globals.bCreateKrb5Conf = true;
4836 Globals.winbindMaxDomainConnections = 1;
4838 /* hostname lookups can be very expensive and are broken on
4839 a large number of sites (tridge) */
4840 Globals.bHostnameLookups = false;
4842 string_set(&Globals.szPassdbBackend, "tdbsam");
4843 string_set(&Globals.szLdapSuffix, "");
4844 string_set(&Globals.szLdapMachineSuffix, "");
4845 string_set(&Globals.szLdapUserSuffix, "");
4846 string_set(&Globals.szLdapGroupSuffix, "");
4847 string_set(&Globals.szLdapIdmapSuffix, "");
4849 string_set(&Globals.szLdapAdminDn, "");
4850 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4851 Globals.ldap_ssl_ads = false;
4852 Globals.ldap_deref = -1;
4853 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4854 Globals.ldap_delete_dn = false;
4855 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4856 Globals.ldap_follow_referral = Auto;
4857 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4858 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4859 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4861 Globals.ldap_debug_level = 0;
4862 Globals.ldap_debug_threshold = 10;
4864 /* This is what we tell the afs client. in reality we set the token
4865 * to never expire, though, when this runs out the afs client will
4866 * forget the token. Set to 0 to get NEVERDATE.*/
4867 Globals.iAfsTokenLifetime = 604800;
4868 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4870 /* these parameters are set to defaults that are more appropriate
4871 for the increasing samba install base:
4873 as a member of the workgroup, that will possibly become a
4874 _local_ master browser (lm = true). this is opposed to a forced
4875 local master browser startup (pm = true).
4877 doesn't provide WINS server service by default (wsupp = false),
4878 and doesn't provide domain master browser services by default, either.
4882 Globals.bMsAddPrinterWizard = true;
4883 Globals.os_level = 20;
4884 Globals.bLocalMaster = true;
4885 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4886 Globals.bDomainLogons = false;
4887 Globals.bBrowseList = true;
4888 Globals.bWINSsupport = false;
4889 Globals.bWINSproxy = false;
4891 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4892 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4894 Globals.bDNSproxy = true;
4896 Globals.bAllowTrustedDomains = true;
4897 string_set(&Globals.szIdmapBackend, "tdb");
4899 string_set(&Globals.szTemplateShell, "/bin/false");
4900 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4901 string_set(&Globals.szWinbindSeparator, "\\");
4903 string_set(&Globals.szCupsServer, "");
4904 string_set(&Globals.szIPrintServer, "");
4906 string_set(&Globals.ctdbdSocket, "");
4907 Globals.szClusterAddresses = NULL;
4908 Globals.clustering = false;
4909 Globals.ctdb_timeout = 0;
4910 Globals.ctdb_locktime_warn_threshold = 0;
4912 Globals.winbind_cache_time = 300; /* 5 minutes */
4913 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4914 Globals.winbind_max_clients = 200;
4915 Globals.bWinbindEnumUsers = false;
4916 Globals.bWinbindEnumGroups = false;
4917 Globals.bWinbindUseDefaultDomain = false;
4918 Globals.bWinbindTrustedDomainsOnly = false;
4919 Globals.bWinbindNestedGroups = true;
4920 Globals.winbind_expand_groups = 1;
4921 Globals.szWinbindNssInfo = (const char **)str_list_make_v3(NULL, "template", NULL);
4922 Globals.bWinbindRefreshTickets = false;
4923 Globals.bWinbindOfflineLogon = false;
4925 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4926 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4928 Globals.bPassdbExpandExplicit = false;
4930 Globals.name_cache_timeout = 660; /* In seconds */
4932 Globals.bUseSpnego = true;
4933 Globals.bClientUseSpnego = true;
4935 Globals.client_signing = SMB_SIGNING_DEFAULT;
4936 Globals.server_signing = SMB_SIGNING_DEFAULT;
4938 Globals.bDeferSharingViolations = true;
4939 string_set(&Globals.smb_ports, SMB_PORTS);
4941 Globals.bEnablePrivileges = true;
4942 Globals.bHostMSDfs = true;
4943 Globals.bASUSupport = false;
4945 /* User defined shares. */
4946 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4947 smb_panic("init_globals: ENOMEM");
4949 string_set(&Globals.szUsersharePath, s);
4950 SAFE_FREE(s);
4951 string_set(&Globals.szUsershareTemplateShare, "");
4952 Globals.iUsershareMaxShares = 0;
4953 /* By default disallow sharing of directories not owned by the sharer. */
4954 Globals.bUsershareOwnerOnly = true;
4955 /* By default disallow guest access to usershares. */
4956 Globals.bUsershareAllowGuests = false;
4958 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4960 /* By default no shares out of the registry */
4961 Globals.bRegistryShares = false;
4963 Globals.iminreceivefile = 0;
4965 Globals.bMapUntrustedToDomain = false;
4966 Globals.bMulticastDnsRegister = true;
4968 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
4969 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
4970 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
4971 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
4973 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
4975 /* Now put back the settings that were set with lp_set_cmdline() */
4976 apply_lp_set_cmdline();
4979 /*******************************************************************
4980 Convenience routine to grab string parameters into temporary memory
4981 and run standard_sub_basic on them. The buffers can be written to by
4982 callers without affecting the source string.
4983 ********************************************************************/
4985 static char *lp_string(const char *s)
4987 char *ret;
4988 TALLOC_CTX *ctx = talloc_tos();
4990 /* The follow debug is useful for tracking down memory problems
4991 especially if you have an inner loop that is calling a lp_*()
4992 function that returns a string. Perhaps this debug should be
4993 present all the time? */
4995 #if 0
4996 DEBUG(10, ("lp_string(%s)\n", s));
4997 #endif
4998 if (!s) {
4999 return NULL;
5002 ret = talloc_sub_basic(ctx,
5003 get_current_username(),
5004 current_user_info.domain,
5006 if (trim_char(ret, '\"', '\"')) {
5007 if (strchr(ret,'\"') != NULL) {
5008 TALLOC_FREE(ret);
5009 ret = talloc_sub_basic(ctx,
5010 get_current_username(),
5011 current_user_info.domain,
5015 return ret;
5019 In this section all the functions that are used to access the
5020 parameters from the rest of the program are defined
5023 #define FN_GLOBAL_STRING(fn_name,ptr) \
5024 char *fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5025 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5026 const char *fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5027 #define FN_GLOBAL_LIST(fn_name,ptr) \
5028 const char **fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5029 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5030 bool fn_name(void) {return(*(bool *)(&Globals.ptr));}
5031 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5032 char fn_name(void) {return(*(char *)(&Globals.ptr));}
5033 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5034 int fn_name(void) {return(*(int *)(&Globals.ptr));}
5036 #define FN_LOCAL_STRING(fn_name,val) \
5037 char *lp_ ## fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5038 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5039 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5040 #define FN_LOCAL_LIST(fn_name,val) \
5041 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5042 #define FN_LOCAL_BOOL(fn_name,val) \
5043 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5044 #define FN_LOCAL_INTEGER(fn_name,val) \
5045 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5047 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5048 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5049 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5050 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5051 #define FN_LOCAL_CHAR(fn_name,val) \
5052 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5054 FN_GLOBAL_CONST_STRING(lp_smb_ports, smb_ports)
5055 FN_GLOBAL_CONST_STRING(lp_dos_charset, dos_charset)
5056 FN_GLOBAL_CONST_STRING(lp_unix_charset, unix_charset)
5057 FN_GLOBAL_STRING(lp_logfile, szLogFile)
5058 FN_GLOBAL_STRING(lp_configfile, szConfigFile)
5059 FN_GLOBAL_CONST_STRING(lp_smb_passwd_file, szSMBPasswdFile)
5060 FN_GLOBAL_CONST_STRING(lp_private_dir, szPrivateDir)
5061 FN_GLOBAL_STRING(lp_serverstring, szServerString)
5062 FN_GLOBAL_INTEGER(lp_printcap_cache_time, PrintcapCacheTime)
5063 FN_GLOBAL_STRING(lp_addport_cmd, szAddPortCommand)
5064 FN_GLOBAL_STRING(lp_enumports_cmd, szEnumPortsCommand)
5065 FN_GLOBAL_STRING(lp_addprinter_cmd, szAddPrinterCommand)
5066 FN_GLOBAL_STRING(lp_deleteprinter_cmd, szDeletePrinterCommand)
5067 FN_GLOBAL_STRING(lp_os2_driver_map, szOs2DriverMap)
5068 FN_GLOBAL_CONST_STRING(lp_lockdir, szLockDir)
5069 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5070 * build process or in smb.conf, we use that value. Otherwise they
5071 * default to the value of lp_lockdir(). */
5072 const char *lp_statedir(void) {
5073 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5074 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5075 return(*(char **)(&Globals.szStateDir) ?
5076 *(char **)(&Globals.szStateDir) : "");
5077 else
5078 return(*(char **)(&Globals.szLockDir) ?
5079 *(char **)(&Globals.szLockDir) : "");
5081 const char *lp_cachedir(void) {
5082 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5083 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5084 return(*(char **)(&Globals.szCacheDir) ?
5085 *(char **)(&Globals.szCacheDir) : "");
5086 else
5087 return(*(char **)(&Globals.szLockDir) ?
5088 *(char **)(&Globals.szLockDir) : "");
5090 FN_GLOBAL_CONST_STRING(lp_piddir, szPidDir)
5091 FN_GLOBAL_STRING(lp_mangling_method, szManglingMethod)
5092 FN_GLOBAL_INTEGER(lp_mangle_prefix, mangle_prefix)
5093 FN_GLOBAL_CONST_STRING(lp_utmpdir, szUtmpDir)
5094 FN_GLOBAL_CONST_STRING(lp_wtmpdir, szWtmpDir)
5095 FN_GLOBAL_BOOL(lp_utmp, bUtmp)
5096 FN_GLOBAL_STRING(lp_rootdir, szRootdir)
5097 FN_GLOBAL_STRING(lp_perfcount_module, szSMBPerfcountModule)
5098 FN_GLOBAL_STRING(lp_defaultservice, szDefaultService)
5099 FN_GLOBAL_STRING(lp_msg_command, szMsgCommand)
5100 FN_GLOBAL_STRING(lp_get_quota_command, szGetQuota)
5101 FN_GLOBAL_STRING(lp_set_quota_command, szSetQuota)
5102 FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
5103 FN_GLOBAL_STRING(lp_passwd_program, szPasswdProgram)
5104 FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
5105 FN_GLOBAL_CONST_STRING(lp_passwordserver, szPasswordServer)
5106 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, szNameResolveOrder)
5107 FN_GLOBAL_CONST_STRING(lp_workgroup, szWorkgroup)
5108 FN_GLOBAL_CONST_STRING(lp_netbios_name, szNetbiosName)
5109 FN_GLOBAL_CONST_STRING(lp_netbios_scope, szNetbiosScope)
5110 FN_GLOBAL_CONST_STRING(lp_realm, szRealmUpper)
5111 FN_GLOBAL_CONST_STRING(lp_dnsdomain, szDnsDomain)
5112 FN_GLOBAL_CONST_STRING(lp_afs_username_map, szAfsUsernameMap)
5113 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, iAfsTokenLifetime)
5114 FN_GLOBAL_STRING(lp_log_nt_token_command, szLogNtTokenCommand)
5115 FN_GLOBAL_STRING(lp_username_map, szUsernameMap)
5116 FN_GLOBAL_CONST_STRING(lp_logon_script, szLogonScript)
5117 FN_GLOBAL_CONST_STRING(lp_logon_path, szLogonPath)
5118 FN_GLOBAL_CONST_STRING(lp_logon_drive, szLogonDrive)
5119 FN_GLOBAL_CONST_STRING(lp_logon_home, szLogonHome)
5120 FN_GLOBAL_STRING(lp_remote_announce, szRemoteAnnounce)
5121 FN_GLOBAL_STRING(lp_remote_browse_sync, szRemoteBrowseSync)
5122 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, bNmbdBindExplicitBroadcast)
5123 FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
5124 FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
5125 FN_GLOBAL_STRING(lp_nis_home_map_name, szNISHomeMapName)
5126 FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
5127 FN_GLOBAL_CONST_STRING(lp_passdb_backend, szPassdbBackend)
5128 FN_GLOBAL_LIST(lp_preload_modules, szPreloadModules)
5129 FN_GLOBAL_STRING(lp_panic_action, szPanicAction)
5130 FN_GLOBAL_STRING(lp_adduser_script, szAddUserScript)
5131 FN_GLOBAL_STRING(lp_renameuser_script, szRenameUserScript)
5132 FN_GLOBAL_STRING(lp_deluser_script, szDelUserScript)
5134 FN_GLOBAL_CONST_STRING(lp_guestaccount, szGuestaccount)
5135 FN_GLOBAL_STRING(lp_addgroup_script, szAddGroupScript)
5136 FN_GLOBAL_STRING(lp_delgroup_script, szDelGroupScript)
5137 FN_GLOBAL_STRING(lp_addusertogroup_script, szAddUserToGroupScript)
5138 FN_GLOBAL_STRING(lp_deluserfromgroup_script, szDelUserFromGroupScript)
5139 FN_GLOBAL_STRING(lp_setprimarygroup_script, szSetPrimaryGroupScript)
5141 FN_GLOBAL_STRING(lp_addmachine_script, szAddMachineScript)
5143 FN_GLOBAL_STRING(lp_shutdown_script, szShutdownScript)
5144 FN_GLOBAL_STRING(lp_abort_shutdown_script, szAbortShutdownScript)
5145 FN_GLOBAL_STRING(lp_username_map_script, szUsernameMapScript)
5146 FN_GLOBAL_INTEGER(lp_username_map_cache_time, iUsernameMapCacheTime)
5148 FN_GLOBAL_STRING(lp_check_password_script, szCheckPasswordScript)
5150 FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
5151 FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
5152 FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
5153 FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
5154 FN_GLOBAL_INTEGER(lp_acl_compatibility, iAclCompat)
5155 FN_GLOBAL_BOOL(lp_winbind_enum_users, bWinbindEnumUsers)
5156 FN_GLOBAL_BOOL(lp_winbind_enum_groups, bWinbindEnumGroups)
5157 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, bWinbindUseDefaultDomain)
5158 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5159 FN_GLOBAL_BOOL(lp_winbind_nested_groups, bWinbindNestedGroups)
5160 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, winbind_expand_groups)
5161 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, bWinbindRefreshTickets)
5162 FN_GLOBAL_BOOL(lp_winbind_offline_logon, bWinbindOfflineLogon)
5163 FN_GLOBAL_BOOL(lp_winbind_normalize_names, bWinbindNormalizeNames)
5164 FN_GLOBAL_BOOL(lp_winbind_rpc_only, bWinbindRpcOnly)
5165 FN_GLOBAL_BOOL(lp_create_krb5_conf, bCreateKrb5Conf)
5166 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5167 winbindMaxDomainConnections)
5169 int lp_winbind_max_domain_connections(void)
5171 if (lp_winbind_offline_logon() &&
5172 lp_winbind_max_domain_connections_int() > 1) {
5173 DEBUG(1, ("offline logons active, restricting max domain "
5174 "connections to 1\n"));
5175 return 1;
5177 return MAX(1, lp_winbind_max_domain_connections_int());
5180 FN_GLOBAL_CONST_STRING(lp_idmap_backend, szIdmapBackend)
5181 FN_GLOBAL_INTEGER(lp_idmap_cache_time, iIdmapCacheTime)
5182 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, iIdmapNegativeCacheTime)
5183 FN_GLOBAL_INTEGER(lp_keepalive, iKeepalive)
5184 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, bPassdbExpandExplicit)
5186 FN_GLOBAL_STRING(lp_ldap_suffix, szLdapSuffix)
5187 FN_GLOBAL_STRING(lp_ldap_admin_dn, szLdapAdminDn)
5188 FN_GLOBAL_INTEGER(lp_ldap_ssl, ldap_ssl)
5189 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, ldap_ssl_ads)
5190 FN_GLOBAL_INTEGER(lp_ldap_deref, ldap_deref)
5191 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, ldap_follow_referral)
5192 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, ldap_passwd_sync)
5193 FN_GLOBAL_BOOL(lp_ldap_delete_dn, ldap_delete_dn)
5194 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, ldap_replication_sleep)
5195 FN_GLOBAL_INTEGER(lp_ldap_timeout, ldap_timeout)
5196 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, ldap_connection_timeout)
5197 FN_GLOBAL_INTEGER(lp_ldap_page_size, ldap_page_size)
5198 FN_GLOBAL_INTEGER(lp_ldap_debug_level, ldap_debug_level)
5199 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, ldap_debug_threshold)
5200 FN_GLOBAL_STRING(lp_add_share_cmd, szAddShareCommand)
5201 FN_GLOBAL_STRING(lp_change_share_cmd, szChangeShareCommand)
5202 FN_GLOBAL_STRING(lp_delete_share_cmd, szDeleteShareCommand)
5203 FN_GLOBAL_STRING(lp_usershare_path, szUsersharePath)
5204 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, szUsersharePrefixAllowList)
5205 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, szUsersharePrefixDenyList)
5207 FN_GLOBAL_LIST(lp_eventlog_list, szEventLogs)
5209 FN_GLOBAL_BOOL(lp_registry_shares, bRegistryShares)
5210 FN_GLOBAL_BOOL(lp_usershare_allow_guests, bUsershareAllowGuests)
5211 FN_GLOBAL_BOOL(lp_usershare_owner_only, bUsershareOwnerOnly)
5212 FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
5213 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, bResetOnZeroVC)
5214 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit, bLogWriteableFilesOnExit)
5215 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, bMsAddPrinterWizard)
5216 FN_GLOBAL_BOOL(lp_dns_proxy, bDNSproxy)
5217 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, bWINSsupport)
5218 FN_GLOBAL_BOOL(lp_wins_proxy, bWINSproxy)
5219 FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
5220 static FN_GLOBAL_BOOL(lp_domain_logons, bDomainLogons)
5221 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, szInitLogonDelayedHosts)
5222 FN_GLOBAL_INTEGER(lp_init_logon_delay, InitLogonDelay)
5223 FN_GLOBAL_BOOL(lp_load_printers, bLoadPrinters)
5224 FN_GLOBAL_BOOL(_lp_readraw, bReadRaw)
5225 FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
5226 FN_GLOBAL_BOOL(_lp_writeraw, bWriteRaw)
5227 FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
5228 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
5229 FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
5230 FN_GLOBAL_INTEGER(lp_client_schannel, clientSchannel)
5231 FN_GLOBAL_INTEGER(lp_server_schannel, serverSchannel)
5232 FN_GLOBAL_BOOL(lp_syslog_only, bSyslogOnly)
5233 FN_GLOBAL_BOOL(lp_timestamp_logs, bTimestampLogs)
5234 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, bDebugPrefixTimestamp)
5235 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, bDebugHiresTimestamp)
5236 FN_GLOBAL_BOOL(lp_debug_pid, bDebugPid)
5237 FN_GLOBAL_BOOL(lp_debug_uid, bDebugUid)
5238 FN_GLOBAL_BOOL(lp_debug_class, bDebugClass)
5239 FN_GLOBAL_BOOL(lp_enable_core_files, bEnableCoreFiles)
5240 FN_GLOBAL_BOOL(lp_browse_list, bBrowseList)
5241 FN_GLOBAL_BOOL(lp_nis_home_map, bNISHomeMap)
5242 static FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
5243 FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
5244 FN_GLOBAL_BOOL(lp_pam_password_change, bPamPasswordChange)
5245 FN_GLOBAL_BOOL(lp_unix_password_sync, bUnixPasswdSync)
5246 FN_GLOBAL_BOOL(lp_passwd_chat_debug, bPasswdChatDebug)
5247 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, iPasswdChatTimeout)
5248 FN_GLOBAL_BOOL(lp_nt_pipe_support, bNTPipeSupport)
5249 FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
5250 FN_GLOBAL_BOOL(lp_stat_cache, bStatCache)
5251 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, iMaxStatCacheSize)
5252 FN_GLOBAL_BOOL(lp_allow_trusted_domains, bAllowTrustedDomains)
5253 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, bMapUntrustedToDomain)
5254 FN_GLOBAL_INTEGER(lp_restrict_anonymous, restrict_anonymous)
5255 FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
5256 FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
5257 FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
5258 FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
5259 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
5260 FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
5261 FN_GLOBAL_BOOL(lp_enhanced_browsing, enhanced_browsing)
5262 FN_GLOBAL_BOOL(lp_use_mmap, bUseMmap)
5263 FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
5264 FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
5265 FN_GLOBAL_BOOL(lp_client_use_spnego, bClientUseSpnego)
5266 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
5267 FN_GLOBAL_BOOL(lp_hostname_lookups, bHostnameLookups)
5268 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, szDedicatedKeytabFile)
5269 FN_GLOBAL_INTEGER(lp_kerberos_method, iKerberosMethod)
5270 FN_GLOBAL_BOOL(lp_defer_sharing_violations, bDeferSharingViolations)
5271 FN_GLOBAL_BOOL(lp_enable_privileges, bEnablePrivileges)
5272 FN_GLOBAL_BOOL(lp_enable_asu_support, bASUSupport)
5273 FN_GLOBAL_INTEGER(lp_os_level, os_level)
5274 FN_GLOBAL_INTEGER(lp_max_ttl, max_ttl)
5275 FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
5276 FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
5277 FN_GLOBAL_INTEGER(lp_max_log_size, max_log_size)
5278 FN_GLOBAL_INTEGER(lp_max_open_files, max_open_files)
5279 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, open_files_db_hash_size)
5280 FN_GLOBAL_INTEGER(lp_maxxmit, max_xmit)
5281 FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
5282 FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
5283 FN_GLOBAL_INTEGER(lp_usernamelevel, unamelevel)
5284 FN_GLOBAL_INTEGER(lp_deadtime, deadtime)
5285 FN_GLOBAL_BOOL(lp_getwd_cache, getwd_cache)
5286 FN_GLOBAL_INTEGER(lp_srv_maxprotocol, srv_maxprotocol)
5287 FN_GLOBAL_INTEGER(lp_srv_minprotocol, srv_minprotocol)
5288 FN_GLOBAL_INTEGER(lp_security, security)
5289 FN_GLOBAL_LIST(lp_auth_methods, AuthMethods)
5290 FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
5291 FN_GLOBAL_INTEGER(lp_maxdisksize, maxdisksize)
5292 FN_GLOBAL_INTEGER(lp_lpqcachetime, lpqcachetime)
5293 FN_GLOBAL_INTEGER(lp_max_smbd_processes, iMaxSmbdProcesses)
5294 FN_GLOBAL_BOOL(_lp_disable_spoolss, bDisableSpoolss)
5295 FN_GLOBAL_INTEGER(lp_syslog, syslog)
5296 FN_GLOBAL_INTEGER(lp_lm_announce, lm_announce)
5297 FN_GLOBAL_INTEGER(lp_lm_interval, lm_interval)
5298 FN_GLOBAL_INTEGER(lp_machine_password_timeout, machine_password_timeout)
5299 FN_GLOBAL_INTEGER(lp_map_to_guest, map_to_guest)
5300 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, oplock_break_wait_time)
5301 FN_GLOBAL_INTEGER(lp_lock_spin_time, iLockSpinTime)
5302 FN_GLOBAL_INTEGER(lp_usershare_max_shares, iUsershareMaxShares)
5303 FN_GLOBAL_CONST_STRING(lp_socket_options, szSocketOptions)
5304 FN_GLOBAL_INTEGER(lp_config_backend, ConfigBackend)
5305 static FN_GLOBAL_INTEGER(lp__server_role, ServerRole)
5306 FN_GLOBAL_INTEGER(lp_smb2_max_read, ismb2_max_read)
5307 FN_GLOBAL_INTEGER(lp_smb2_max_write, ismb2_max_write)
5308 FN_GLOBAL_INTEGER(lp_smb2_max_trans, ismb2_max_trans)
5309 int lp_smb2_max_credits(void)
5311 if (Globals.ismb2_max_credits == 0) {
5312 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5314 return Globals.ismb2_max_credits;
5316 FN_GLOBAL_LIST(lp_svcctl_list, szServicesList)
5317 FN_GLOBAL_STRING(lp_cups_server, szCupsServer)
5318 int lp_cups_encrypt(void)
5320 int result = 0;
5321 #ifdef HAVE_HTTPCONNECTENCRYPT
5322 switch (Globals.CupsEncrypt) {
5323 case Auto:
5324 result = HTTP_ENCRYPT_REQUIRED;
5325 break;
5326 case true:
5327 result = HTTP_ENCRYPT_ALWAYS;
5328 break;
5329 case false:
5330 result = HTTP_ENCRYPT_NEVER;
5331 break;
5333 #endif
5334 return result;
5336 FN_GLOBAL_STRING(lp_iprint_server, szIPrintServer)
5337 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, cups_connection_timeout)
5338 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, ctdbdSocket)
5339 FN_GLOBAL_LIST(lp_cluster_addresses, szClusterAddresses)
5340 FN_GLOBAL_BOOL(lp_clustering, clustering)
5341 FN_GLOBAL_INTEGER(lp_ctdb_timeout, ctdb_timeout)
5342 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5343 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, bAsyncSMBEchoHandler)
5344 FN_GLOBAL_BOOL(lp_multicast_dns_register, bMulticastDnsRegister)
5345 FN_GLOBAL_BOOL(lp_allow_insecure_widelinks, bAllowInsecureWidelinks)
5346 FN_GLOBAL_INTEGER(lp_winbind_cache_time, winbind_cache_time)
5347 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, winbind_reconnect_delay)
5348 FN_GLOBAL_INTEGER(lp_winbind_max_clients, winbind_max_clients)
5349 FN_GLOBAL_LIST(lp_winbind_nss_info, szWinbindNssInfo)
5350 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, AlgorithmicRidBase)
5351 FN_GLOBAL_INTEGER(lp_name_cache_timeout, name_cache_timeout)
5352 FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
5353 FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
5354 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5356 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, ncalrpc_dir)
5358 #include "lib/param/param_functions.c"
5360 FN_LOCAL_STRING(servicename, szService)
5361 FN_LOCAL_CONST_STRING(const_servicename, szService)
5363 /* local prototypes */
5365 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5366 static const char *get_boolean(bool bool_value);
5367 static int getservicebyname(const char *pszServiceName,
5368 struct loadparm_service *pserviceDest);
5369 static void copy_service(struct loadparm_service *pserviceDest,
5370 struct loadparm_service *pserviceSource,
5371 struct bitmap *pcopymapDest);
5372 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5373 void *userdata);
5374 static bool do_section(const char *pszSectionName, void *userdata);
5375 static void init_copymap(struct loadparm_service *pservice);
5376 static bool hash_a_service(const char *name, int number);
5377 static void free_service_byindex(int iService);
5378 static void show_parameter(int parmIndex);
5379 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5382 * This is a helper function for parametrical options support. It returns a
5383 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5384 * parametrical functions are quite simple
5386 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
5387 const char *option)
5389 bool global_section = false;
5390 char* param_key;
5391 struct parmlist_entry *data;
5393 if (service == NULL) {
5394 data = Globals.param_opt;
5395 global_section = true;
5396 } else {
5397 data = service->param_opt;
5400 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5401 DEBUG(0,("asprintf failed!\n"));
5402 return NULL;
5405 while (data) {
5406 if (strwicmp(data->key, param_key) == 0) {
5407 string_free(&param_key);
5408 return data;
5410 data = data->next;
5413 if (!global_section) {
5414 /* Try to fetch the same option but from globals */
5415 /* but only if we are not already working with Globals */
5416 data = Globals.param_opt;
5417 while (data) {
5418 if (strwicmp(data->key, param_key) == 0) {
5419 string_free(&param_key);
5420 return data;
5422 data = data->next;
5426 string_free(&param_key);
5428 return NULL;
5432 * This is a helper function for parametrical options support. It returns a
5433 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5434 * parametrical functions are quite simple
5436 static struct parmlist_entry *get_parametrics(int snum, const char *type,
5437 const char *option)
5439 if (snum >= iNumServices) return NULL;
5441 if (snum < 0) {
5442 return get_parametrics_by_service(NULL, type, option);
5443 } else {
5444 return get_parametrics_by_service(ServicePtrs[snum], type, option);
5449 #define MISSING_PARAMETER(name) \
5450 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5452 /*******************************************************************
5453 convenience routine to return int parameters.
5454 ********************************************************************/
5455 static int lp_int(const char *s)
5458 if (!s || !*s) {
5459 MISSING_PARAMETER(lp_int);
5460 return (-1);
5463 return (int)strtol(s, NULL, 0);
5466 /*******************************************************************
5467 convenience routine to return unsigned long parameters.
5468 ********************************************************************/
5469 static unsigned long lp_ulong(const char *s)
5472 if (!s || !*s) {
5473 MISSING_PARAMETER(lp_ulong);
5474 return (0);
5477 return strtoul(s, NULL, 0);
5480 /*******************************************************************
5481 convenience routine to return boolean parameters.
5482 ********************************************************************/
5483 static bool lp_bool(const char *s)
5485 bool ret = false;
5487 if (!s || !*s) {
5488 MISSING_PARAMETER(lp_bool);
5489 return false;
5492 if (!set_boolean(s, &ret)) {
5493 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5494 return false;
5497 return ret;
5500 /*******************************************************************
5501 convenience routine to return enum parameters.
5502 ********************************************************************/
5503 static int lp_enum(const char *s,const struct enum_list *_enum)
5505 int i;
5507 if (!s || !*s || !_enum) {
5508 MISSING_PARAMETER(lp_enum);
5509 return (-1);
5512 for (i=0; _enum[i].name; i++) {
5513 if (strequal(_enum[i].name,s))
5514 return _enum[i].value;
5517 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5518 return (-1);
5521 #undef MISSING_PARAMETER
5523 /* Return parametric option from a given service. Type is a part of option before ':' */
5524 /* Parametric option has following syntax: 'Type: option = value' */
5525 /* the returned value is talloced on the talloc_tos() */
5526 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5528 struct parmlist_entry *data = get_parametrics(snum, type, option);
5530 if (data == NULL||data->value==NULL) {
5531 if (def) {
5532 return lp_string(def);
5533 } else {
5534 return NULL;
5538 return lp_string(data->value);
5541 /* Return parametric option from a given service. Type is a part of option before ':' */
5542 /* Parametric option has following syntax: 'Type: option = value' */
5543 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5545 struct parmlist_entry *data = get_parametrics(snum, type, option);
5547 if (data == NULL||data->value==NULL)
5548 return def;
5550 return data->value;
5553 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
5555 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
5557 if (data == NULL||data->value==NULL)
5558 return NULL;
5560 return data->value;
5564 /* Return parametric option from a given service. Type is a part of option before ':' */
5565 /* Parametric option has following syntax: 'Type: option = value' */
5567 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5569 struct parmlist_entry *data = get_parametrics(snum, type, option);
5571 if (data == NULL||data->value==NULL)
5572 return (const char **)def;
5574 if (data->list==NULL) {
5575 data->list = str_list_make_v3(NULL, data->value, NULL);
5578 return (const char **)data->list;
5581 /* Return parametric option from a given service. Type is a part of option before ':' */
5582 /* Parametric option has following syntax: 'Type: option = value' */
5584 int lp_parm_int(int snum, const char *type, const char *option, int def)
5586 struct parmlist_entry *data = get_parametrics(snum, type, option);
5588 if (data && data->value && *data->value)
5589 return lp_int(data->value);
5591 return def;
5594 /* Return parametric option from a given service. Type is a part of option before ':' */
5595 /* Parametric option has following syntax: 'Type: option = value' */
5597 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5599 struct parmlist_entry *data = get_parametrics(snum, type, option);
5601 if (data && data->value && *data->value)
5602 return lp_ulong(data->value);
5604 return def;
5607 /* Return parametric option from a given service. Type is a part of option before ':' */
5608 /* Parametric option has following syntax: 'Type: option = value' */
5610 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5612 struct parmlist_entry *data = get_parametrics(snum, type, option);
5614 if (data && data->value && *data->value)
5615 return lp_bool(data->value);
5617 return def;
5620 /* Return parametric option from a given service. Type is a part of option before ':' */
5621 /* Parametric option has following syntax: 'Type: option = value' */
5623 int lp_parm_enum(int snum, const char *type, const char *option,
5624 const struct enum_list *_enum, int def)
5626 struct parmlist_entry *data = get_parametrics(snum, type, option);
5628 if (data && data->value && *data->value && _enum)
5629 return lp_enum(data->value, _enum);
5631 return def;
5635 /***************************************************************************
5636 Initialise a service to the defaults.
5637 ***************************************************************************/
5639 static void init_service(struct loadparm_service *pservice)
5641 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
5642 copy_service(pservice, &sDefault, NULL);
5647 * free a param_opts structure.
5648 * param_opts handling should be moved to talloc;
5649 * then this whole functions reduces to a TALLOC_FREE().
5652 static void free_param_opts(struct parmlist_entry **popts)
5654 struct parmlist_entry *opt, *next_opt;
5656 if (popts == NULL) {
5657 return;
5660 if (*popts != NULL) {
5661 DEBUG(5, ("Freeing parametrics:\n"));
5663 opt = *popts;
5664 while (opt != NULL) {
5665 string_free(&opt->key);
5666 string_free(&opt->value);
5667 TALLOC_FREE(opt->list);
5668 next_opt = opt->next;
5669 SAFE_FREE(opt);
5670 opt = next_opt;
5672 *popts = NULL;
5675 /***************************************************************************
5676 Free the dynamically allocated parts of a service struct.
5677 ***************************************************************************/
5679 static void free_service(struct loadparm_service *pservice)
5681 if (!pservice)
5682 return;
5684 if (pservice->szService)
5685 DEBUG(5, ("free_service: Freeing service %s\n",
5686 pservice->szService));
5688 free_parameters(pservice);
5690 string_free(&pservice->szService);
5691 TALLOC_FREE(pservice->copymap);
5693 free_param_opts(&pservice->param_opt);
5695 ZERO_STRUCTP(pservice);
5699 /***************************************************************************
5700 remove a service indexed in the ServicePtrs array from the ServiceHash
5701 and free the dynamically allocated parts
5702 ***************************************************************************/
5704 static void free_service_byindex(int idx)
5706 if ( !LP_SNUM_OK(idx) )
5707 return;
5709 ServicePtrs[idx]->valid = false;
5710 invalid_services[num_invalid_services++] = idx;
5712 /* we have to cleanup the hash record */
5714 if (ServicePtrs[idx]->szService) {
5715 char *canon_name = canonicalize_servicename(
5716 talloc_tos(),
5717 ServicePtrs[idx]->szService );
5719 dbwrap_delete_bystring(ServiceHash, canon_name );
5720 TALLOC_FREE(canon_name);
5723 free_service(ServicePtrs[idx]);
5726 /***************************************************************************
5727 Add a new service to the services array initialising it with the given
5728 service.
5729 ***************************************************************************/
5731 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5733 int i;
5734 struct loadparm_service tservice;
5735 int num_to_alloc = iNumServices + 1;
5737 tservice = *pservice;
5739 /* it might already exist */
5740 if (name) {
5741 i = getservicebyname(name, NULL);
5742 if (i >= 0) {
5743 return (i);
5747 /* find an invalid one */
5748 i = iNumServices;
5749 if (num_invalid_services > 0) {
5750 i = invalid_services[--num_invalid_services];
5753 /* if not, then create one */
5754 if (i == iNumServices) {
5755 struct loadparm_service **tsp;
5756 int *tinvalid;
5758 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5759 if (tsp == NULL) {
5760 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5761 return (-1);
5763 ServicePtrs = tsp;
5764 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5765 if (!ServicePtrs[iNumServices]) {
5766 DEBUG(0,("add_a_service: out of memory!\n"));
5767 return (-1);
5769 iNumServices++;
5771 /* enlarge invalid_services here for now... */
5772 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5773 num_to_alloc);
5774 if (tinvalid == NULL) {
5775 DEBUG(0,("add_a_service: failed to enlarge "
5776 "invalid_services!\n"));
5777 return (-1);
5779 invalid_services = tinvalid;
5780 } else {
5781 free_service_byindex(i);
5784 ServicePtrs[i]->valid = true;
5786 init_service(ServicePtrs[i]);
5787 copy_service(ServicePtrs[i], &tservice, NULL);
5788 if (name)
5789 string_set(&ServicePtrs[i]->szService, name);
5791 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5792 i, ServicePtrs[i]->szService));
5794 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5795 return (-1);
5798 return (i);
5801 /***************************************************************************
5802 Convert a string to uppercase and remove whitespaces.
5803 ***************************************************************************/
5805 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5807 char *result;
5809 if ( !src ) {
5810 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5811 return NULL;
5814 result = talloc_strdup(ctx, src);
5815 SMB_ASSERT(result != NULL);
5817 strlower_m(result);
5818 return result;
5821 /***************************************************************************
5822 Add a name/index pair for the services array to the hash table.
5823 ***************************************************************************/
5825 static bool hash_a_service(const char *name, int idx)
5827 char *canon_name;
5829 if ( !ServiceHash ) {
5830 DEBUG(10,("hash_a_service: creating servicehash\n"));
5831 ServiceHash = db_open_rbt(NULL);
5832 if ( !ServiceHash ) {
5833 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5834 return false;
5838 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5839 idx, name));
5841 canon_name = canonicalize_servicename(talloc_tos(), name );
5843 dbwrap_store_bystring(ServiceHash, canon_name,
5844 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5845 TDB_REPLACE);
5847 TALLOC_FREE(canon_name);
5849 return true;
5852 /***************************************************************************
5853 Add a new home service, with the specified home directory, defaults coming
5854 from service ifrom.
5855 ***************************************************************************/
5857 bool lp_add_home(const char *pszHomename, int iDefaultService,
5858 const char *user, const char *pszHomedir)
5860 int i;
5862 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5863 pszHomedir[0] == '\0') {
5864 return false;
5867 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5869 if (i < 0)
5870 return false;
5872 if (!(*(ServicePtrs[iDefaultService]->szPath))
5873 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5874 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5877 if (!(*(ServicePtrs[i]->comment))) {
5878 char *comment = NULL;
5879 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5880 return false;
5882 string_set(&ServicePtrs[i]->comment, comment);
5883 SAFE_FREE(comment);
5886 /* set the browseable flag from the global default */
5888 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5889 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
5891 ServicePtrs[i]->autoloaded = true;
5893 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5894 user, ServicePtrs[i]->szPath ));
5896 return true;
5899 /***************************************************************************
5900 Add a new service, based on an old one.
5901 ***************************************************************************/
5903 int lp_add_service(const char *pszService, int iDefaultService)
5905 if (iDefaultService < 0) {
5906 return add_a_service(&sDefault, pszService);
5909 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5912 /***************************************************************************
5913 Add the IPC service.
5914 ***************************************************************************/
5916 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5918 char *comment = NULL;
5919 int i = add_a_service(&sDefault, ipc_name);
5921 if (i < 0)
5922 return false;
5924 if (asprintf(&comment, "IPC Service (%s)",
5925 Globals.szServerString) < 0) {
5926 return false;
5929 string_set(&ServicePtrs[i]->szPath, tmpdir());
5930 string_set(&ServicePtrs[i]->szUsername, "");
5931 string_set(&ServicePtrs[i]->comment, comment);
5932 string_set(&ServicePtrs[i]->fstype, "IPC");
5933 ServicePtrs[i]->iMaxConnections = 0;
5934 ServicePtrs[i]->bAvailable = true;
5935 ServicePtrs[i]->bRead_only = true;
5936 ServicePtrs[i]->bGuest_only = false;
5937 ServicePtrs[i]->bAdministrative_share = true;
5938 ServicePtrs[i]->bGuest_ok = guest_ok;
5939 ServicePtrs[i]->bPrint_ok = false;
5940 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5942 DEBUG(3, ("adding IPC service\n"));
5944 SAFE_FREE(comment);
5945 return true;
5948 /***************************************************************************
5949 Add a new printer service, with defaults coming from service iFrom.
5950 ***************************************************************************/
5952 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5954 const char *comment = "From Printcap";
5955 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5957 if (i < 0)
5958 return false;
5960 /* note that we do NOT default the availability flag to true - */
5961 /* we take it from the default service passed. This allows all */
5962 /* dynamic printers to be disabled by disabling the [printers] */
5963 /* entry (if/when the 'available' keyword is implemented!). */
5965 /* the printer name is set to the service name. */
5966 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5967 string_set(&ServicePtrs[i]->comment, comment);
5969 /* set the browseable flag from the gloabl default */
5970 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5972 /* Printers cannot be read_only. */
5973 ServicePtrs[i]->bRead_only = false;
5974 /* No share modes on printer services. */
5975 ServicePtrs[i]->bShareModes = false;
5976 /* No oplocks on printer services. */
5977 ServicePtrs[i]->bOpLocks = false;
5978 /* Printer services must be printable. */
5979 ServicePtrs[i]->bPrint_ok = true;
5981 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5983 return true;
5987 /***************************************************************************
5988 Check whether the given parameter name is valid.
5989 Parametric options (names containing a colon) are considered valid.
5990 ***************************************************************************/
5992 bool lp_parameter_is_valid(const char *pszParmName)
5994 return ((map_parameter(pszParmName) != -1) ||
5995 (strchr(pszParmName, ':') != NULL));
5998 /***************************************************************************
5999 Check whether the given name is the name of a global parameter.
6000 Returns true for strings belonging to parameters of class
6001 P_GLOBAL, false for all other strings, also for parametric options
6002 and strings not belonging to any option.
6003 ***************************************************************************/
6005 bool lp_parameter_is_global(const char *pszParmName)
6007 int num = map_parameter(pszParmName);
6009 if (num >= 0) {
6010 return (parm_table[num].p_class == P_GLOBAL);
6013 return false;
6016 /**************************************************************************
6017 Check whether the given name is the canonical name of a parameter.
6018 Returns false if it is not a valid parameter Name.
6019 For parametric options, true is returned.
6020 **************************************************************************/
6022 bool lp_parameter_is_canonical(const char *parm_name)
6024 if (!lp_parameter_is_valid(parm_name)) {
6025 return false;
6028 return (map_parameter(parm_name) ==
6029 map_parameter_canonical(parm_name, NULL));
6032 /**************************************************************************
6033 Determine the canonical name for a parameter.
6034 Indicate when it is an inverse (boolean) synonym instead of a
6035 "usual" synonym.
6036 **************************************************************************/
6038 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6039 bool *inverse)
6041 int num;
6043 if (!lp_parameter_is_valid(parm_name)) {
6044 *canon_parm = NULL;
6045 return false;
6048 num = map_parameter_canonical(parm_name, inverse);
6049 if (num < 0) {
6050 /* parametric option */
6051 *canon_parm = parm_name;
6052 } else {
6053 *canon_parm = parm_table[num].label;
6056 return true;
6060 /**************************************************************************
6061 Determine the canonical name for a parameter.
6062 Turn the value given into the inverse boolean expression when
6063 the synonym is an invers boolean synonym.
6065 Return true if parm_name is a valid parameter name and
6066 in case it is an invers boolean synonym, if the val string could
6067 successfully be converted to the reverse bool.
6068 Return false in all other cases.
6069 **************************************************************************/
6071 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6072 const char *val,
6073 const char **canon_parm,
6074 const char **canon_val)
6076 int num;
6077 bool inverse;
6079 if (!lp_parameter_is_valid(parm_name)) {
6080 *canon_parm = NULL;
6081 *canon_val = NULL;
6082 return false;
6085 num = map_parameter_canonical(parm_name, &inverse);
6086 if (num < 0) {
6087 /* parametric option */
6088 *canon_parm = parm_name;
6089 *canon_val = val;
6090 } else {
6091 *canon_parm = parm_table[num].label;
6092 if (inverse) {
6093 if (!lp_invert_boolean(val, canon_val)) {
6094 *canon_val = NULL;
6095 return false;
6097 } else {
6098 *canon_val = val;
6102 return true;
6105 /***************************************************************************
6106 Map a parameter's string representation to something we can use.
6107 Returns false if the parameter string is not recognised, else TRUE.
6108 ***************************************************************************/
6110 static int map_parameter(const char *pszParmName)
6112 int iIndex;
6114 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6115 return (-1);
6117 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6118 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6119 return (iIndex);
6121 /* Warn only if it isn't parametric option */
6122 if (strchr(pszParmName, ':') == NULL)
6123 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6124 /* We do return 'fail' for parametric options as well because they are
6125 stored in different storage
6127 return (-1);
6130 /***************************************************************************
6131 Map a parameter's string representation to the index of the canonical
6132 form of the parameter (it might be a synonym).
6133 Returns -1 if the parameter string is not recognised.
6134 ***************************************************************************/
6136 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6138 int parm_num, canon_num;
6139 bool loc_inverse = false;
6141 parm_num = map_parameter(pszParmName);
6142 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6143 /* invalid, parametric or no canidate for synonyms ... */
6144 goto done;
6147 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6148 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6149 parm_num = canon_num;
6150 goto done;
6154 done:
6155 if (inverse != NULL) {
6156 *inverse = loc_inverse;
6158 return parm_num;
6161 /***************************************************************************
6162 return true if parameter number parm1 is a synonym of parameter
6163 number parm2 (parm2 being the principal name).
6164 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6165 false otherwise.
6166 ***************************************************************************/
6168 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6170 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
6171 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
6172 (parm_table[parm1].flags & FLAG_HIDE) &&
6173 !(parm_table[parm2].flags & FLAG_HIDE))
6175 if (inverse != NULL) {
6176 if ((parm_table[parm1].type == P_BOOLREV) &&
6177 (parm_table[parm2].type == P_BOOL))
6179 *inverse = true;
6180 } else {
6181 *inverse = false;
6184 return true;
6186 return false;
6189 /***************************************************************************
6190 Show one parameter's name, type, [values,] and flags.
6191 (helper functions for show_parameter_list)
6192 ***************************************************************************/
6194 static void show_parameter(int parmIndex)
6196 int enumIndex, flagIndex;
6197 int parmIndex2;
6198 bool hadFlag;
6199 bool hadSyn;
6200 bool inverse;
6201 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6202 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6203 "P_ENUM", "P_SEP"};
6204 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6205 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6206 FLAG_HIDE};
6207 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6208 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6209 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
6211 printf("%s=%s", parm_table[parmIndex].label,
6212 type[parm_table[parmIndex].type]);
6213 if (parm_table[parmIndex].type == P_ENUM) {
6214 printf(",");
6215 for (enumIndex=0;
6216 parm_table[parmIndex].enum_list[enumIndex].name;
6217 enumIndex++)
6219 printf("%s%s",
6220 enumIndex ? "|" : "",
6221 parm_table[parmIndex].enum_list[enumIndex].name);
6224 printf(",");
6225 hadFlag = false;
6226 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6227 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6228 printf("%s%s",
6229 hadFlag ? "|" : "",
6230 flag_names[flagIndex]);
6231 hadFlag = true;
6235 /* output synonyms */
6236 hadSyn = false;
6237 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6238 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6239 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6240 parm_table[parmIndex2].label);
6241 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6242 if (!hadSyn) {
6243 printf(" (synonyms: ");
6244 hadSyn = true;
6245 } else {
6246 printf(", ");
6248 printf("%s%s", parm_table[parmIndex2].label,
6249 inverse ? "[i]" : "");
6252 if (hadSyn) {
6253 printf(")");
6256 printf("\n");
6259 /***************************************************************************
6260 Show all parameter's name, type, [values,] and flags.
6261 ***************************************************************************/
6263 void show_parameter_list(void)
6265 int classIndex, parmIndex;
6266 const char *section_names[] = { "local", "global", NULL};
6268 for (classIndex=0; section_names[classIndex]; classIndex++) {
6269 printf("[%s]\n", section_names[classIndex]);
6270 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6271 if (parm_table[parmIndex].p_class == classIndex) {
6272 show_parameter(parmIndex);
6278 /***************************************************************************
6279 Check if a given string correctly represents a boolean value.
6280 ***************************************************************************/
6282 bool lp_string_is_valid_boolean(const char *parm_value)
6284 return set_boolean(parm_value, NULL);
6287 /***************************************************************************
6288 Get the standard string representation of a boolean value ("yes" or "no")
6289 ***************************************************************************/
6291 static const char *get_boolean(bool bool_value)
6293 static const char *yes_str = "yes";
6294 static const char *no_str = "no";
6296 return (bool_value ? yes_str : no_str);
6299 /***************************************************************************
6300 Provide the string of the negated boolean value associated to the boolean
6301 given as a string. Returns false if the passed string does not correctly
6302 represent a boolean.
6303 ***************************************************************************/
6305 bool lp_invert_boolean(const char *str, const char **inverse_str)
6307 bool val;
6309 if (!set_boolean(str, &val)) {
6310 return false;
6313 *inverse_str = get_boolean(!val);
6314 return true;
6317 /***************************************************************************
6318 Provide the canonical string representation of a boolean value given
6319 as a string. Return true on success, false if the string given does
6320 not correctly represent a boolean.
6321 ***************************************************************************/
6323 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6325 bool val;
6327 if (!set_boolean(str, &val)) {
6328 return false;
6331 *canon_str = get_boolean(val);
6332 return true;
6335 /***************************************************************************
6336 Find a service by name. Otherwise works like get_service.
6337 ***************************************************************************/
6339 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6341 int iService = -1;
6342 char *canon_name;
6343 TDB_DATA data;
6344 NTSTATUS status;
6346 if (ServiceHash == NULL) {
6347 return -1;
6350 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6352 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
6353 &data);
6355 if (NT_STATUS_IS_OK(status) &&
6356 (data.dptr != NULL) &&
6357 (data.dsize == sizeof(iService)))
6359 iService = *(int *)data.dptr;
6362 TALLOC_FREE(canon_name);
6364 if ((iService != -1) && (LP_SNUM_OK(iService))
6365 && (pserviceDest != NULL)) {
6366 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6369 return (iService);
6372 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6373 struct loadparm_service *lp_service(const char *pszServiceName)
6375 int iService = getservicebyname(pszServiceName, NULL);
6376 if (iService == -1 || !LP_SNUM_OK(iService)) {
6377 return NULL;
6379 return ServicePtrs[iService];
6382 struct loadparm_service *lp_servicebynum(int snum)
6384 if ((snum == -1) || !LP_SNUM_OK(snum)) {
6385 return NULL;
6387 return ServicePtrs[snum];
6390 struct loadparm_service *lp_default_loadparm_service()
6392 return &sDefault;
6396 /***************************************************************************
6397 Copy a service structure to another.
6398 If pcopymapDest is NULL then copy all fields
6399 ***************************************************************************/
6402 * Add a parametric option to a parmlist_entry,
6403 * replacing old value, if already present.
6405 static void set_param_opt(struct parmlist_entry **opt_list,
6406 const char *opt_name,
6407 const char *opt_value,
6408 unsigned priority)
6410 struct parmlist_entry *new_opt, *opt;
6411 bool not_added;
6413 if (opt_list == NULL) {
6414 return;
6417 opt = *opt_list;
6418 not_added = true;
6420 /* Traverse destination */
6421 while (opt) {
6422 /* If we already have same option, override it */
6423 if (strwicmp(opt->key, opt_name) == 0) {
6424 if ((opt->priority & FLAG_CMDLINE) &&
6425 !(priority & FLAG_CMDLINE)) {
6426 /* it's been marked as not to be
6427 overridden */
6428 return;
6430 string_free(&opt->value);
6431 TALLOC_FREE(opt->list);
6432 opt->value = SMB_STRDUP(opt_value);
6433 opt->priority = priority;
6434 not_added = false;
6435 break;
6437 opt = opt->next;
6439 if (not_added) {
6440 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
6441 new_opt->key = SMB_STRDUP(opt_name);
6442 new_opt->value = SMB_STRDUP(opt_value);
6443 new_opt->list = NULL;
6444 new_opt->priority = priority;
6445 DLIST_ADD(*opt_list, new_opt);
6449 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6450 struct bitmap *pcopymapDest)
6452 int i;
6453 bool bcopyall = (pcopymapDest == NULL);
6454 struct parmlist_entry *data;
6456 for (i = 0; parm_table[i].label; i++)
6457 if (parm_table[i].p_class == P_LOCAL &&
6458 (bcopyall || bitmap_query(pcopymapDest,i))) {
6459 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6460 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6462 switch (parm_table[i].type) {
6463 case P_BOOL:
6464 case P_BOOLREV:
6465 *(bool *)dest_ptr = *(bool *)src_ptr;
6466 break;
6468 case P_INTEGER:
6469 case P_ENUM:
6470 case P_OCTAL:
6471 case P_BYTES:
6472 *(int *)dest_ptr = *(int *)src_ptr;
6473 break;
6475 case P_CHAR:
6476 *(char *)dest_ptr = *(char *)src_ptr;
6477 break;
6479 case P_STRING:
6480 string_set((char **)dest_ptr,
6481 *(char **)src_ptr);
6482 break;
6484 case P_USTRING:
6486 char *upper_string = strupper_talloc(talloc_tos(),
6487 *(char **)src_ptr);
6488 string_set((char **)dest_ptr,
6489 upper_string);
6490 TALLOC_FREE(upper_string);
6491 break;
6493 case P_LIST:
6494 TALLOC_FREE(*((char ***)dest_ptr));
6495 *((char ***)dest_ptr) = str_list_copy(NULL,
6496 *(const char ***)src_ptr);
6497 break;
6498 default:
6499 break;
6503 if (bcopyall) {
6504 init_copymap(pserviceDest);
6505 if (pserviceSource->copymap)
6506 bitmap_copy(pserviceDest->copymap,
6507 pserviceSource->copymap);
6510 data = pserviceSource->param_opt;
6511 while (data) {
6512 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6513 data = data->next;
6517 /***************************************************************************
6518 Check a service for consistency. Return false if the service is in any way
6519 incomplete or faulty, else true.
6520 ***************************************************************************/
6522 bool service_ok(int iService)
6524 bool bRetval;
6526 bRetval = true;
6527 if (ServicePtrs[iService]->szService[0] == '\0') {
6528 DEBUG(0, ("The following message indicates an internal error:\n"));
6529 DEBUG(0, ("No service name in service entry.\n"));
6530 bRetval = false;
6533 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6534 /* I can't see why you'd want a non-printable printer service... */
6535 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6536 if (!ServicePtrs[iService]->bPrint_ok) {
6537 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6538 ServicePtrs[iService]->szService));
6539 ServicePtrs[iService]->bPrint_ok = true;
6541 /* [printers] service must also be non-browsable. */
6542 if (ServicePtrs[iService]->bBrowseable)
6543 ServicePtrs[iService]->bBrowseable = false;
6546 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6547 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6548 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6550 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6551 ServicePtrs[iService]->szService));
6552 ServicePtrs[iService]->bAvailable = false;
6555 /* If a service is flagged unavailable, log the fact at level 1. */
6556 if (!ServicePtrs[iService]->bAvailable)
6557 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6558 ServicePtrs[iService]->szService));
6560 return (bRetval);
6563 static struct smbconf_ctx *lp_smbconf_ctx(void)
6565 sbcErr err;
6566 static struct smbconf_ctx *conf_ctx = NULL;
6568 if (conf_ctx == NULL) {
6569 err = smbconf_init(NULL, &conf_ctx, "registry:");
6570 if (!SBC_ERROR_IS_OK(err)) {
6571 DEBUG(1, ("error initializing registry configuration: "
6572 "%s\n", sbcErrorString(err)));
6573 conf_ctx = NULL;
6577 return conf_ctx;
6580 static bool process_smbconf_service(struct smbconf_service *service)
6582 uint32_t count;
6583 bool ret;
6585 if (service == NULL) {
6586 return false;
6589 ret = do_section(service->name, NULL);
6590 if (ret != true) {
6591 return false;
6593 for (count = 0; count < service->num_params; count++) {
6594 ret = do_parameter(service->param_names[count],
6595 service->param_values[count],
6596 NULL);
6597 if (ret != true) {
6598 return false;
6601 if (iServiceIndex >= 0) {
6602 return service_ok(iServiceIndex);
6604 return true;
6608 * load a service from registry and activate it
6610 bool process_registry_service(const char *service_name)
6612 sbcErr err;
6613 struct smbconf_service *service = NULL;
6614 TALLOC_CTX *mem_ctx = talloc_stackframe();
6615 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6616 bool ret = false;
6618 if (conf_ctx == NULL) {
6619 goto done;
6622 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6624 if (!smbconf_share_exists(conf_ctx, service_name)) {
6626 * Registry does not contain data for this service (yet),
6627 * but make sure lp_load doesn't return false.
6629 ret = true;
6630 goto done;
6633 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6634 if (!SBC_ERROR_IS_OK(err)) {
6635 goto done;
6638 ret = process_smbconf_service(service);
6639 if (!ret) {
6640 goto done;
6643 /* store the csn */
6644 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6646 done:
6647 TALLOC_FREE(mem_ctx);
6648 return ret;
6652 * process_registry_globals
6654 static bool process_registry_globals(void)
6656 bool ret;
6658 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6660 ret = do_parameter("registry shares", "yes", NULL);
6661 if (!ret) {
6662 return ret;
6665 return process_registry_service(GLOBAL_NAME);
6668 bool process_registry_shares(void)
6670 sbcErr err;
6671 uint32_t count;
6672 struct smbconf_service **service = NULL;
6673 uint32_t num_shares = 0;
6674 TALLOC_CTX *mem_ctx = talloc_stackframe();
6675 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6676 bool ret = false;
6678 if (conf_ctx == NULL) {
6679 goto done;
6682 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6683 if (!SBC_ERROR_IS_OK(err)) {
6684 goto done;
6687 ret = true;
6689 for (count = 0; count < num_shares; count++) {
6690 if (strequal(service[count]->name, GLOBAL_NAME)) {
6691 continue;
6693 ret = process_smbconf_service(service[count]);
6694 if (!ret) {
6695 goto done;
6699 /* store the csn */
6700 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6702 done:
6703 TALLOC_FREE(mem_ctx);
6704 return ret;
6708 * reload those shares from registry that are already
6709 * activated in the services array.
6711 static bool reload_registry_shares(void)
6713 int i;
6714 bool ret = true;
6716 for (i = 0; i < iNumServices; i++) {
6717 if (!VALID(i)) {
6718 continue;
6721 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
6722 continue;
6725 ret = process_registry_service(ServicePtrs[i]->szService);
6726 if (!ret) {
6727 goto done;
6731 done:
6732 return ret;
6736 #define MAX_INCLUDE_DEPTH 100
6738 static uint8_t include_depth;
6740 static struct file_lists {
6741 struct file_lists *next;
6742 char *name;
6743 char *subfname;
6744 time_t modtime;
6745 } *file_lists = NULL;
6747 /*******************************************************************
6748 Keep a linked list of all config files so we know when one has changed
6749 it's date and needs to be reloaded.
6750 ********************************************************************/
6752 static void add_to_file_list(const char *fname, const char *subfname)
6754 struct file_lists *f = file_lists;
6756 while (f) {
6757 if (f->name && !strcmp(f->name, fname))
6758 break;
6759 f = f->next;
6762 if (!f) {
6763 f = SMB_MALLOC_P(struct file_lists);
6764 if (!f)
6765 return;
6766 f->next = file_lists;
6767 f->name = SMB_STRDUP(fname);
6768 if (!f->name) {
6769 SAFE_FREE(f);
6770 return;
6772 f->subfname = SMB_STRDUP(subfname);
6773 if (!f->subfname) {
6774 SAFE_FREE(f->name);
6775 SAFE_FREE(f);
6776 return;
6778 file_lists = f;
6779 f->modtime = file_modtime(subfname);
6780 } else {
6781 time_t t = file_modtime(subfname);
6782 if (t)
6783 f->modtime = t;
6785 return;
6789 * Free the file lists
6791 static void free_file_list(void)
6793 struct file_lists *f;
6794 struct file_lists *next;
6796 f = file_lists;
6797 while( f ) {
6798 next = f->next;
6799 SAFE_FREE( f->name );
6800 SAFE_FREE( f->subfname );
6801 SAFE_FREE( f );
6802 f = next;
6804 file_lists = NULL;
6809 * Utility function for outsiders to check if we're running on registry.
6811 bool lp_config_backend_is_registry(void)
6813 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6817 * Utility function to check if the config backend is FILE.
6819 bool lp_config_backend_is_file(void)
6821 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6824 /*******************************************************************
6825 Check if a config file has changed date.
6826 ********************************************************************/
6828 bool lp_file_list_changed(void)
6830 struct file_lists *f = file_lists;
6832 DEBUG(6, ("lp_file_list_changed()\n"));
6834 while (f) {
6835 time_t mod_time;
6837 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6838 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6840 if (conf_ctx == NULL) {
6841 return false;
6843 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6844 NULL))
6846 DEBUGADD(6, ("registry config changed\n"));
6847 return true;
6849 } else {
6850 char *n2 = NULL;
6851 n2 = talloc_sub_basic(talloc_tos(),
6852 get_current_username(),
6853 current_user_info.domain,
6854 f->name);
6855 if (!n2) {
6856 return false;
6858 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6859 f->name, n2, ctime(&f->modtime)));
6861 mod_time = file_modtime(n2);
6863 if (mod_time &&
6864 ((f->modtime != mod_time) ||
6865 (f->subfname == NULL) ||
6866 (strcmp(n2, f->subfname) != 0)))
6868 DEBUGADD(6,
6869 ("file %s modified: %s\n", n2,
6870 ctime(&mod_time)));
6871 f->modtime = mod_time;
6872 SAFE_FREE(f->subfname);
6873 f->subfname = SMB_STRDUP(n2);
6874 TALLOC_FREE(n2);
6875 return true;
6877 TALLOC_FREE(n2);
6879 f = f->next;
6881 return false;
6886 * Initialize iconv conversion descriptors.
6888 * This is called the first time it is needed, and also called again
6889 * every time the configuration is reloaded, because the charset or
6890 * codepage might have changed.
6892 static void init_iconv(void)
6894 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
6895 lp_unix_charset(),
6896 true, global_iconv_handle);
6899 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6901 if (strcmp(*ptr, pszParmValue) != 0) {
6902 string_set(ptr, pszParmValue);
6903 init_iconv();
6905 return true;
6908 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6910 bool is_utf8 = false;
6911 size_t len = strlen(pszParmValue);
6913 if (len == 4 || len == 5) {
6914 /* Don't use StrCaseCmp here as we don't want to
6915 initialize iconv. */
6916 if ((toupper_m(pszParmValue[0]) == 'U') &&
6917 (toupper_m(pszParmValue[1]) == 'T') &&
6918 (toupper_m(pszParmValue[2]) == 'F')) {
6919 if (len == 4) {
6920 if (pszParmValue[3] == '8') {
6921 is_utf8 = true;
6923 } else {
6924 if (pszParmValue[3] == '-' &&
6925 pszParmValue[4] == '8') {
6926 is_utf8 = true;
6932 if (strcmp(*ptr, pszParmValue) != 0) {
6933 if (is_utf8) {
6934 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6935 "be UTF8, using (default value) %s instead.\n",
6936 DEFAULT_DOS_CHARSET));
6937 pszParmValue = DEFAULT_DOS_CHARSET;
6939 string_set(ptr, pszParmValue);
6940 init_iconv();
6942 return true;
6945 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6947 bool ret = true;
6948 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
6949 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
6951 ret &= string_set(&Globals.szRealm, pszParmValue);
6952 ret &= string_set(&Globals.szRealmUpper, realm);
6953 ret &= string_set(&Globals.szDnsDomain, dnsdomain);
6954 TALLOC_FREE(realm);
6955 TALLOC_FREE(dnsdomain);
6957 return ret;
6960 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6962 TALLOC_FREE(Globals.szNetbiosAliases);
6963 Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
6964 return set_netbios_aliases(Globals.szNetbiosAliases);
6967 /***************************************************************************
6968 Handle the include operation.
6969 ***************************************************************************/
6970 static bool bAllowIncludeRegistry = true;
6972 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6974 char *fname;
6976 if (include_depth >= MAX_INCLUDE_DEPTH) {
6977 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6978 include_depth));
6979 return false;
6982 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6983 if (!bAllowIncludeRegistry) {
6984 return true;
6986 if (bInGlobalSection) {
6987 bool ret;
6988 include_depth++;
6989 ret = process_registry_globals();
6990 include_depth--;
6991 return ret;
6992 } else {
6993 DEBUG(1, ("\"include = registry\" only effective "
6994 "in %s section\n", GLOBAL_NAME));
6995 return false;
6999 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7000 current_user_info.domain,
7001 pszParmValue);
7003 add_to_file_list(pszParmValue, fname);
7005 string_set(ptr, fname);
7007 if (file_exist(fname)) {
7008 bool ret;
7009 include_depth++;
7010 ret = pm_process(fname, do_section, do_parameter, NULL);
7011 include_depth--;
7012 TALLOC_FREE(fname);
7013 return ret;
7016 DEBUG(2, ("Can't find include file %s\n", fname));
7017 TALLOC_FREE(fname);
7018 return true;
7021 /***************************************************************************
7022 Handle the interpretation of the copy parameter.
7023 ***************************************************************************/
7025 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7027 bool bRetval;
7028 int iTemp;
7029 struct loadparm_service serviceTemp;
7031 string_set(ptr, pszParmValue);
7033 init_service(&serviceTemp);
7035 bRetval = false;
7037 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7039 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7040 if (iTemp == iServiceIndex) {
7041 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7042 } else {
7043 copy_service(ServicePtrs[iServiceIndex],
7044 &serviceTemp,
7045 ServicePtrs[iServiceIndex]->copymap);
7046 bRetval = true;
7048 } else {
7049 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7050 bRetval = false;
7053 free_service(&serviceTemp);
7054 return (bRetval);
7057 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7059 Globals.ldap_debug_level = lp_int(pszParmValue);
7060 init_ldap_debugging();
7061 return true;
7064 /***************************************************************************
7065 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7066 parameters is:
7068 [global]
7070 idmap uid = 1000-1999
7071 idmap gid = 700-899
7073 We only do simple parsing checks here. The strings are parsed into useful
7074 structures in the idmap daemon code.
7076 ***************************************************************************/
7078 /* Some lp_ routines to return idmap [ug]id information */
7080 static uid_t idmap_uid_low, idmap_uid_high;
7081 static gid_t idmap_gid_low, idmap_gid_high;
7083 bool lp_idmap_uid(uid_t *low, uid_t *high)
7085 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7086 return false;
7088 if (low)
7089 *low = idmap_uid_low;
7091 if (high)
7092 *high = idmap_uid_high;
7094 return true;
7097 bool lp_idmap_gid(gid_t *low, gid_t *high)
7099 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7100 return false;
7102 if (low)
7103 *low = idmap_gid_low;
7105 if (high)
7106 *high = idmap_gid_high;
7108 return true;
7111 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7113 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7115 return true;
7118 /* Do some simple checks on "idmap [ug]id" parameter values */
7120 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7122 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7124 return true;
7127 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7129 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7131 return true;
7134 /***************************************************************************
7135 Handle the DEBUG level list.
7136 ***************************************************************************/
7138 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
7140 string_set(ptr, pszParmValueIn);
7141 return debug_parse_levels(pszParmValueIn);
7144 /***************************************************************************
7145 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7146 ***************************************************************************/
7148 static const char *append_ldap_suffix( const char *str )
7150 const char *suffix_string;
7153 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7154 Globals.szLdapSuffix );
7155 if ( !suffix_string ) {
7156 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7157 return "";
7160 return suffix_string;
7163 const char *lp_ldap_machine_suffix(void)
7165 if (Globals.szLdapMachineSuffix[0])
7166 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7168 return lp_string(Globals.szLdapSuffix);
7171 const char *lp_ldap_user_suffix(void)
7173 if (Globals.szLdapUserSuffix[0])
7174 return append_ldap_suffix(Globals.szLdapUserSuffix);
7176 return lp_string(Globals.szLdapSuffix);
7179 const char *lp_ldap_group_suffix(void)
7181 if (Globals.szLdapGroupSuffix[0])
7182 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7184 return lp_string(Globals.szLdapSuffix);
7187 const char *lp_ldap_idmap_suffix(void)
7189 if (Globals.szLdapIdmapSuffix[0])
7190 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7192 return lp_string(Globals.szLdapSuffix);
7195 /****************************************************************************
7196 set the value for a P_ENUM
7197 ***************************************************************************/
7199 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7200 int *ptr )
7202 int i;
7204 for (i = 0; parm->enum_list[i].name; i++) {
7205 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7206 *ptr = parm->enum_list[i].value;
7207 return;
7210 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7211 pszParmValue, parm->label));
7214 /***************************************************************************
7215 ***************************************************************************/
7217 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7219 static int parm_num = -1;
7220 struct loadparm_service *s;
7222 if ( parm_num == -1 )
7223 parm_num = map_parameter( "printing" );
7225 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7227 if ( snum < 0 )
7228 s = &sDefault;
7229 else
7230 s = ServicePtrs[snum];
7232 init_printer_values( s );
7234 return true;
7238 /***************************************************************************
7239 Initialise a copymap.
7240 ***************************************************************************/
7242 static void init_copymap(struct loadparm_service *pservice)
7244 int i;
7246 TALLOC_FREE(pservice->copymap);
7248 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7249 if (!pservice->copymap)
7250 DEBUG(0,
7251 ("Couldn't allocate copymap!! (size %d)\n",
7252 (int)NUMPARAMETERS));
7253 else
7254 for (i = 0; i < NUMPARAMETERS; i++)
7255 bitmap_set(pservice->copymap, i);
7259 return the parameter pointer for a parameter
7261 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7263 if (service == NULL) {
7264 if (parm->p_class == P_LOCAL)
7265 return (void *)(((char *)&sDefault)+parm->offset);
7266 else if (parm->p_class == P_GLOBAL)
7267 return (void *)(((char *)&Globals)+parm->offset);
7268 else return NULL;
7269 } else {
7270 return (void *)(((char *)service) + parm->offset);
7274 /***************************************************************************
7275 Return the local pointer to a parameter given the service number and parameter
7276 ***************************************************************************/
7278 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7280 return lp_parm_ptr(ServicePtrs[snum], parm);
7283 /***************************************************************************
7284 Process a parameter for a particular service number. If snum < 0
7285 then assume we are in the globals.
7286 ***************************************************************************/
7288 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7290 int parmnum, i;
7291 void *parm_ptr = NULL; /* where we are going to store the result */
7292 struct parmlist_entry **opt_list;
7294 parmnum = map_parameter(pszParmName);
7296 if (parmnum < 0) {
7297 if (strchr(pszParmName, ':') == NULL) {
7298 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7299 pszParmName));
7300 return true;
7304 * We've got a parametric option
7307 opt_list = (snum < 0)
7308 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7309 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7311 return true;
7314 /* if it's already been set by the command line, then we don't
7315 override here */
7316 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7317 return true;
7320 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7321 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7322 pszParmName));
7325 /* we might point at a service, the default service or a global */
7326 if (snum < 0) {
7327 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7328 } else {
7329 if (parm_table[parmnum].p_class == P_GLOBAL) {
7330 DEBUG(0,
7331 ("Global parameter %s found in service section!\n",
7332 pszParmName));
7333 return true;
7335 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7338 if (snum >= 0) {
7339 if (!ServicePtrs[snum]->copymap)
7340 init_copymap(ServicePtrs[snum]);
7342 /* this handles the aliases - set the copymap for other entries with
7343 the same data pointer */
7344 for (i = 0; parm_table[i].label; i++) {
7345 if ((parm_table[i].offset == parm_table[parmnum].offset)
7346 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
7347 bitmap_clear(ServicePtrs[snum]->copymap, i);
7352 /* if it is a special case then go ahead */
7353 if (parm_table[parmnum].special) {
7354 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7355 (char **)parm_ptr);
7358 /* now switch on the type of variable it is */
7359 switch (parm_table[parmnum].type)
7361 case P_BOOL:
7362 *(bool *)parm_ptr = lp_bool(pszParmValue);
7363 break;
7365 case P_BOOLREV:
7366 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7367 break;
7369 case P_INTEGER:
7370 *(int *)parm_ptr = lp_int(pszParmValue);
7371 break;
7373 case P_CHAR:
7374 *(char *)parm_ptr = *pszParmValue;
7375 break;
7377 case P_OCTAL:
7378 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7379 if ( i != 1 ) {
7380 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7382 break;
7384 case P_BYTES:
7386 uint64_t val;
7387 if (conv_str_size_error(pszParmValue, &val)) {
7388 if (val <= INT_MAX) {
7389 *(int *)parm_ptr = (int)val;
7390 break;
7394 DEBUG(0,("lp_do_parameter(%s): value is not "
7395 "a valid size specifier!\n", pszParmValue));
7396 return false;
7399 case P_LIST:
7400 case P_CMDLIST:
7401 TALLOC_FREE(*((char ***)parm_ptr));
7402 *(char ***)parm_ptr = str_list_make_v3(
7403 NULL, pszParmValue, NULL);
7404 break;
7406 case P_STRING:
7407 string_set((char **)parm_ptr, pszParmValue);
7408 break;
7410 case P_USTRING:
7412 char *upper_string = strupper_talloc(talloc_tos(),
7413 pszParmValue);
7414 string_set((char **)parm_ptr, upper_string);
7415 TALLOC_FREE(upper_string);
7416 break;
7418 case P_ENUM:
7419 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7420 break;
7421 case P_SEP:
7422 break;
7425 return true;
7428 /***************************************************************************
7429 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7430 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7431 ***************************************************************************/
7433 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7435 int parmnum, i;
7436 parmnum = map_parameter(pszParmName);
7437 if (parmnum >= 0) {
7438 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7439 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7440 return false;
7442 parm_table[parmnum].flags |= FLAG_CMDLINE;
7444 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7445 * be grouped in the table, so we don't have to search the
7446 * whole table */
7447 for (i=parmnum-1;
7448 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7449 && parm_table[i].p_class == parm_table[parmnum].p_class;
7450 i--) {
7451 parm_table[i].flags |= FLAG_CMDLINE;
7453 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
7454 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
7455 parm_table[i].flags |= FLAG_CMDLINE;
7458 if (store_values) {
7459 store_lp_set_cmdline(pszParmName, pszParmValue);
7461 return true;
7464 /* it might be parametric */
7465 if (strchr(pszParmName, ':') != NULL) {
7466 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7467 if (store_values) {
7468 store_lp_set_cmdline(pszParmName, pszParmValue);
7470 return true;
7473 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7474 return true;
7477 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7479 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7482 /***************************************************************************
7483 Process a parameter.
7484 ***************************************************************************/
7486 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7487 void *userdata)
7489 if (!bInGlobalSection && bGlobalOnly)
7490 return true;
7492 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7494 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7495 pszParmName, pszParmValue));
7499 set a option from the commandline in 'a=b' format. Use to support --option
7501 bool lp_set_option(const char *option)
7503 char *p, *s;
7504 bool ret;
7506 s = talloc_strdup(NULL, option);
7507 if (!s) {
7508 return false;
7511 p = strchr(s, '=');
7512 if (!p) {
7513 talloc_free(s);
7514 return false;
7517 *p = 0;
7519 /* skip white spaces after the = sign */
7520 do {
7521 p++;
7522 } while (*p == ' ');
7524 ret = lp_set_cmdline(s, p);
7525 talloc_free(s);
7526 return ret;
7529 /**************************************************************************
7530 Print a parameter of the specified type.
7531 ***************************************************************************/
7533 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7535 /* For the seperation of lists values that we print below */
7536 const char *list_sep = ", ";
7537 int i;
7538 switch (p->type)
7540 case P_ENUM:
7541 for (i = 0; p->enum_list[i].name; i++) {
7542 if (*(int *)ptr == p->enum_list[i].value) {
7543 fprintf(f, "%s",
7544 p->enum_list[i].name);
7545 break;
7548 break;
7550 case P_BOOL:
7551 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7552 break;
7554 case P_BOOLREV:
7555 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7556 break;
7558 case P_INTEGER:
7559 case P_BYTES:
7560 fprintf(f, "%d", *(int *)ptr);
7561 break;
7563 case P_CHAR:
7564 fprintf(f, "%c", *(char *)ptr);
7565 break;
7567 case P_OCTAL: {
7568 int val = *(int *)ptr;
7569 if (val == -1) {
7570 fprintf(f, "-1");
7571 } else {
7572 fprintf(f, "0%o", val);
7574 break;
7577 case P_CMDLIST:
7578 list_sep = " ";
7579 /* fall through */
7580 case P_LIST:
7581 if ((char ***)ptr && *(char ***)ptr) {
7582 char **list = *(char ***)ptr;
7583 for (; *list; list++) {
7584 /* surround strings with whitespace in double quotes */
7585 if (*(list+1) == NULL) {
7586 /* last item, no extra separator */
7587 list_sep = "";
7589 if ( strchr_m( *list, ' ' ) ) {
7590 fprintf(f, "\"%s\"%s", *list, list_sep);
7591 } else {
7592 fprintf(f, "%s%s", *list, list_sep);
7596 break;
7598 case P_STRING:
7599 case P_USTRING:
7600 if (*(char **)ptr) {
7601 fprintf(f, "%s", *(char **)ptr);
7603 break;
7604 case P_SEP:
7605 break;
7609 /***************************************************************************
7610 Check if two parameters are equal.
7611 ***************************************************************************/
7613 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7615 switch (type) {
7616 case P_BOOL:
7617 case P_BOOLREV:
7618 return (*((bool *)ptr1) == *((bool *)ptr2));
7620 case P_INTEGER:
7621 case P_ENUM:
7622 case P_OCTAL:
7623 case P_BYTES:
7624 return (*((int *)ptr1) == *((int *)ptr2));
7626 case P_CHAR:
7627 return (*((char *)ptr1) == *((char *)ptr2));
7629 case P_LIST:
7630 case P_CMDLIST:
7631 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7633 case P_STRING:
7634 case P_USTRING:
7636 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7637 if (p1 && !*p1)
7638 p1 = NULL;
7639 if (p2 && !*p2)
7640 p2 = NULL;
7641 return (p1 == p2 || strequal(p1, p2));
7643 case P_SEP:
7644 break;
7646 return false;
7649 /***************************************************************************
7650 Initialize any local varients in the sDefault table.
7651 ***************************************************************************/
7653 void init_locals(void)
7655 /* None as yet. */
7658 /***************************************************************************
7659 Process a new section (service). At this stage all sections are services.
7660 Later we'll have special sections that permit server parameters to be set.
7661 Returns true on success, false on failure.
7662 ***************************************************************************/
7664 static bool do_section(const char *pszSectionName, void *userdata)
7666 bool bRetval;
7667 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7668 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7669 bRetval = false;
7671 /* if we were in a global section then do the local inits */
7672 if (bInGlobalSection && !isglobal)
7673 init_locals();
7675 /* if we've just struck a global section, note the fact. */
7676 bInGlobalSection = isglobal;
7678 /* check for multiple global sections */
7679 if (bInGlobalSection) {
7680 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7681 return true;
7684 if (!bInGlobalSection && bGlobalOnly)
7685 return true;
7687 /* if we have a current service, tidy it up before moving on */
7688 bRetval = true;
7690 if (iServiceIndex >= 0)
7691 bRetval = service_ok(iServiceIndex);
7693 /* if all is still well, move to the next record in the services array */
7694 if (bRetval) {
7695 /* We put this here to avoid an odd message order if messages are */
7696 /* issued by the post-processing of a previous section. */
7697 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7699 iServiceIndex = add_a_service(&sDefault, pszSectionName);
7700 if (iServiceIndex < 0) {
7701 DEBUG(0, ("Failed to add a new service\n"));
7702 return false;
7704 /* Clean all parametric options for service */
7705 /* They will be added during parsing again */
7706 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7709 return bRetval;
7713 /***************************************************************************
7714 Determine if a partcular base parameter is currentl set to the default value.
7715 ***************************************************************************/
7717 static bool is_default(int i)
7719 if (!defaults_saved)
7720 return false;
7721 switch (parm_table[i].type) {
7722 case P_LIST:
7723 case P_CMDLIST:
7724 return str_list_equal((const char **)parm_table[i].def.lvalue,
7725 *(const char ***)lp_parm_ptr(NULL,
7726 &parm_table[i]));
7727 case P_STRING:
7728 case P_USTRING:
7729 return strequal(parm_table[i].def.svalue,
7730 *(char **)lp_parm_ptr(NULL,
7731 &parm_table[i]));
7732 case P_BOOL:
7733 case P_BOOLREV:
7734 return parm_table[i].def.bvalue ==
7735 *(bool *)lp_parm_ptr(NULL,
7736 &parm_table[i]);
7737 case P_CHAR:
7738 return parm_table[i].def.cvalue ==
7739 *(char *)lp_parm_ptr(NULL,
7740 &parm_table[i]);
7741 case P_INTEGER:
7742 case P_OCTAL:
7743 case P_ENUM:
7744 case P_BYTES:
7745 return parm_table[i].def.ivalue ==
7746 *(int *)lp_parm_ptr(NULL,
7747 &parm_table[i]);
7748 case P_SEP:
7749 break;
7751 return false;
7754 /***************************************************************************
7755 Display the contents of the global structure.
7756 ***************************************************************************/
7758 static void dump_globals(FILE *f)
7760 int i;
7761 struct parmlist_entry *data;
7763 fprintf(f, "[global]\n");
7765 for (i = 0; parm_table[i].label; i++)
7766 if (parm_table[i].p_class == P_GLOBAL &&
7767 !(parm_table[i].flags & FLAG_META) &&
7768 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
7769 if (defaults_saved && is_default(i))
7770 continue;
7771 fprintf(f, "\t%s = ", parm_table[i].label);
7772 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7773 &parm_table[i]),
7775 fprintf(f, "\n");
7777 if (Globals.param_opt != NULL) {
7778 data = Globals.param_opt;
7779 while(data) {
7780 fprintf(f, "\t%s = %s\n", data->key, data->value);
7781 data = data->next;
7787 /***************************************************************************
7788 Return true if a local parameter is currently set to the global default.
7789 ***************************************************************************/
7791 bool lp_is_default(int snum, struct parm_struct *parm)
7793 return equal_parameter(parm->type,
7794 lp_parm_ptr(ServicePtrs[snum], parm),
7795 lp_parm_ptr(NULL, parm));
7798 /***************************************************************************
7799 Display the contents of a single services record.
7800 ***************************************************************************/
7802 static void dump_a_service(struct loadparm_service *pService, FILE * f)
7804 int i;
7805 struct parmlist_entry *data;
7807 if (pService != &sDefault)
7808 fprintf(f, "[%s]\n", pService->szService);
7810 for (i = 0; parm_table[i].label; i++) {
7812 if (parm_table[i].p_class == P_LOCAL &&
7813 !(parm_table[i].flags & FLAG_META) &&
7814 (*parm_table[i].label != '-') &&
7815 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7817 if (pService == &sDefault) {
7818 if (defaults_saved && is_default(i))
7819 continue;
7820 } else {
7821 if (equal_parameter(parm_table[i].type,
7822 lp_parm_ptr(pService, &parm_table[i]),
7823 lp_parm_ptr(NULL, &parm_table[i])))
7824 continue;
7827 fprintf(f, "\t%s = ", parm_table[i].label);
7828 print_parameter(&parm_table[i],
7829 lp_parm_ptr(pService, &parm_table[i]),
7831 fprintf(f, "\n");
7835 if (pService->param_opt != NULL) {
7836 data = pService->param_opt;
7837 while(data) {
7838 fprintf(f, "\t%s = %s\n", data->key, data->value);
7839 data = data->next;
7844 /***************************************************************************
7845 Display the contents of a parameter of a single services record.
7846 ***************************************************************************/
7848 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7850 int i;
7851 bool result = false;
7852 parm_class p_class;
7853 unsigned flag = 0;
7854 fstring local_parm_name;
7855 char *parm_opt;
7856 const char *parm_opt_value;
7858 /* check for parametrical option */
7859 fstrcpy( local_parm_name, parm_name);
7860 parm_opt = strchr( local_parm_name, ':');
7862 if (parm_opt) {
7863 *parm_opt = '\0';
7864 parm_opt++;
7865 if (strlen(parm_opt)) {
7866 parm_opt_value = lp_parm_const_string( snum,
7867 local_parm_name, parm_opt, NULL);
7868 if (parm_opt_value) {
7869 printf( "%s\n", parm_opt_value);
7870 result = true;
7873 return result;
7876 /* check for a key and print the value */
7877 if (isGlobal) {
7878 p_class = P_GLOBAL;
7879 flag = FLAG_GLOBAL;
7880 } else
7881 p_class = P_LOCAL;
7883 for (i = 0; parm_table[i].label; i++) {
7884 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7885 !(parm_table[i].flags & FLAG_META) &&
7886 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7887 (*parm_table[i].label != '-') &&
7888 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7890 void *ptr;
7892 if (isGlobal) {
7893 ptr = lp_parm_ptr(NULL,
7894 &parm_table[i]);
7895 } else {
7896 ptr = lp_parm_ptr(ServicePtrs[snum],
7897 &parm_table[i]);
7900 print_parameter(&parm_table[i],
7901 ptr, f);
7902 fprintf(f, "\n");
7903 result = true;
7904 break;
7908 return result;
7911 /***************************************************************************
7912 Return info about the requested parameter (given as a string).
7913 Return NULL when the string is not a valid parameter name.
7914 ***************************************************************************/
7916 struct parm_struct *lp_get_parameter(const char *param_name)
7918 int num = map_parameter(param_name);
7920 if (num < 0) {
7921 return NULL;
7924 return &parm_table[num];
7927 /***************************************************************************
7928 Return info about the next parameter in a service.
7929 snum==GLOBAL_SECTION_SNUM gives the globals.
7930 Return NULL when out of parameters.
7931 ***************************************************************************/
7933 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7935 if (snum < 0) {
7936 /* do the globals */
7937 for (; parm_table[*i].label; (*i)++) {
7938 if (parm_table[*i].p_class == P_SEPARATOR)
7939 return &parm_table[(*i)++];
7941 if ((*parm_table[*i].label == '-'))
7942 continue;
7944 if ((*i) > 0
7945 && (parm_table[*i].offset ==
7946 parm_table[(*i) - 1].offset)
7947 && (parm_table[*i].p_class ==
7948 parm_table[(*i) - 1].p_class))
7949 continue;
7951 if (is_default(*i) && !allparameters)
7952 continue;
7954 return &parm_table[(*i)++];
7956 } else {
7957 struct loadparm_service *pService = ServicePtrs[snum];
7959 for (; parm_table[*i].label; (*i)++) {
7960 if (parm_table[*i].p_class == P_SEPARATOR)
7961 return &parm_table[(*i)++];
7963 if (parm_table[*i].p_class == P_LOCAL &&
7964 (*parm_table[*i].label != '-') &&
7965 ((*i) == 0 ||
7966 (parm_table[*i].offset !=
7967 parm_table[(*i) - 1].offset)))
7969 if (allparameters ||
7970 !equal_parameter(parm_table[*i].type,
7971 lp_parm_ptr(pService,
7972 &parm_table[*i]),
7973 lp_parm_ptr(NULL,
7974 &parm_table[*i])))
7976 return &parm_table[(*i)++];
7982 return NULL;
7986 #if 0
7987 /***************************************************************************
7988 Display the contents of a single copy structure.
7989 ***************************************************************************/
7990 static void dump_copy_map(bool *pcopymap)
7992 int i;
7993 if (!pcopymap)
7994 return;
7996 printf("\n\tNon-Copied parameters:\n");
7998 for (i = 0; parm_table[i].label; i++)
7999 if (parm_table[i].p_class == P_LOCAL &&
8000 parm_table[i].ptr && !pcopymap[i] &&
8001 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8003 printf("\t\t%s\n", parm_table[i].label);
8006 #endif
8008 /***************************************************************************
8009 Return TRUE if the passed service number is within range.
8010 ***************************************************************************/
8012 bool lp_snum_ok(int iService)
8014 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8017 /***************************************************************************
8018 Auto-load some home services.
8019 ***************************************************************************/
8021 static void lp_add_auto_services(char *str)
8023 char *s;
8024 char *p;
8025 int homes;
8026 char *saveptr;
8028 if (!str)
8029 return;
8031 s = SMB_STRDUP(str);
8032 if (!s)
8033 return;
8035 homes = lp_servicenumber(HOMES_NAME);
8037 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8038 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8039 char *home;
8041 if (lp_servicenumber(p) >= 0)
8042 continue;
8044 home = get_user_home_dir(talloc_tos(), p);
8046 if (home && home[0] && homes >= 0)
8047 lp_add_home(p, homes, p, home);
8049 TALLOC_FREE(home);
8051 SAFE_FREE(s);
8054 /***************************************************************************
8055 Auto-load one printer.
8056 ***************************************************************************/
8058 void lp_add_one_printer(const char *name, const char *comment,
8059 const char *location, void *pdata)
8061 int printers = lp_servicenumber(PRINTERS_NAME);
8062 int i;
8064 if (lp_servicenumber(name) < 0) {
8065 lp_add_printer(name, printers);
8066 if ((i = lp_servicenumber(name)) >= 0) {
8067 string_set(&ServicePtrs[i]->comment, comment);
8068 ServicePtrs[i]->autoloaded = true;
8073 /***************************************************************************
8074 Have we loaded a services file yet?
8075 ***************************************************************************/
8077 bool lp_loaded(void)
8079 return (bLoaded);
8082 /***************************************************************************
8083 Unload unused services.
8084 ***************************************************************************/
8086 void lp_killunused(struct smbd_server_connection *sconn,
8087 bool (*snumused) (struct smbd_server_connection *, int))
8089 int i;
8090 for (i = 0; i < iNumServices; i++) {
8091 if (!VALID(i))
8092 continue;
8094 /* don't kill autoloaded or usershare services */
8095 if ( ServicePtrs[i]->autoloaded ||
8096 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8097 continue;
8100 if (!snumused || !snumused(sconn, i)) {
8101 free_service_byindex(i);
8107 * Kill all except autoloaded and usershare services - convenience wrapper
8109 void lp_kill_all_services(void)
8111 lp_killunused(NULL, NULL);
8114 /***************************************************************************
8115 Unload a service.
8116 ***************************************************************************/
8118 void lp_killservice(int iServiceIn)
8120 if (VALID(iServiceIn)) {
8121 free_service_byindex(iServiceIn);
8125 /***************************************************************************
8126 Save the curent values of all global and sDefault parameters into the
8127 defaults union. This allows swat and testparm to show only the
8128 changed (ie. non-default) parameters.
8129 ***************************************************************************/
8131 static void lp_save_defaults(void)
8133 int i;
8134 for (i = 0; parm_table[i].label; i++) {
8135 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
8136 && parm_table[i].p_class == parm_table[i - 1].p_class)
8137 continue;
8138 switch (parm_table[i].type) {
8139 case P_LIST:
8140 case P_CMDLIST:
8141 parm_table[i].def.lvalue = str_list_copy(
8142 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8143 break;
8144 case P_STRING:
8145 case P_USTRING:
8146 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8147 break;
8148 case P_BOOL:
8149 case P_BOOLREV:
8150 parm_table[i].def.bvalue =
8151 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8152 break;
8153 case P_CHAR:
8154 parm_table[i].def.cvalue =
8155 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8156 break;
8157 case P_INTEGER:
8158 case P_OCTAL:
8159 case P_ENUM:
8160 case P_BYTES:
8161 parm_table[i].def.ivalue =
8162 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8163 break;
8164 case P_SEP:
8165 break;
8168 defaults_saved = true;
8171 /***********************************************************
8172 If we should send plaintext/LANMAN passwords in the clinet
8173 ************************************************************/
8175 static void set_allowed_client_auth(void)
8177 if (Globals.bClientNTLMv2Auth) {
8178 Globals.bClientLanManAuth = false;
8180 if (!Globals.bClientLanManAuth) {
8181 Globals.bClientPlaintextAuth = false;
8185 /***************************************************************************
8186 JRA.
8187 The following code allows smbd to read a user defined share file.
8188 Yes, this is my intent. Yes, I'm comfortable with that...
8190 THE FOLLOWING IS SECURITY CRITICAL CODE.
8192 It washes your clothes, it cleans your house, it guards you while you sleep...
8193 Do not f%^k with it....
8194 ***************************************************************************/
8196 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8198 /***************************************************************************
8199 Check allowed stat state of a usershare file.
8200 Ensure we print out who is dicking with us so the admin can
8201 get their sorry ass fired.
8202 ***************************************************************************/
8204 static bool check_usershare_stat(const char *fname,
8205 const SMB_STRUCT_STAT *psbuf)
8207 if (!S_ISREG(psbuf->st_ex_mode)) {
8208 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8209 "not a regular file\n",
8210 fname, (unsigned int)psbuf->st_ex_uid ));
8211 return false;
8214 /* Ensure this doesn't have the other write bit set. */
8215 if (psbuf->st_ex_mode & S_IWOTH) {
8216 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8217 "public write. Refusing to allow as a usershare file.\n",
8218 fname, (unsigned int)psbuf->st_ex_uid ));
8219 return false;
8222 /* Should be 10k or less. */
8223 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8224 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8225 "too large (%u) to be a user share file.\n",
8226 fname, (unsigned int)psbuf->st_ex_uid,
8227 (unsigned int)psbuf->st_ex_size ));
8228 return false;
8231 return true;
8234 /***************************************************************************
8235 Parse the contents of a usershare file.
8236 ***************************************************************************/
8238 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8239 SMB_STRUCT_STAT *psbuf,
8240 const char *servicename,
8241 int snum,
8242 char **lines,
8243 int numlines,
8244 char **pp_sharepath,
8245 char **pp_comment,
8246 char **pp_cp_servicename,
8247 struct security_descriptor **ppsd,
8248 bool *pallow_guest)
8250 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8251 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8252 int us_vers;
8253 DIR *dp;
8254 SMB_STRUCT_STAT sbuf;
8255 char *sharepath = NULL;
8256 char *comment = NULL;
8258 *pp_sharepath = NULL;
8259 *pp_comment = NULL;
8261 *pallow_guest = false;
8263 if (numlines < 4) {
8264 return USERSHARE_MALFORMED_FILE;
8267 if (strcmp(lines[0], "#VERSION 1") == 0) {
8268 us_vers = 1;
8269 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8270 us_vers = 2;
8271 if (numlines < 5) {
8272 return USERSHARE_MALFORMED_FILE;
8274 } else {
8275 return USERSHARE_BAD_VERSION;
8278 if (strncmp(lines[1], "path=", 5) != 0) {
8279 return USERSHARE_MALFORMED_PATH;
8282 sharepath = talloc_strdup(ctx, &lines[1][5]);
8283 if (!sharepath) {
8284 return USERSHARE_POSIX_ERR;
8286 trim_string(sharepath, " ", " ");
8288 if (strncmp(lines[2], "comment=", 8) != 0) {
8289 return USERSHARE_MALFORMED_COMMENT_DEF;
8292 comment = talloc_strdup(ctx, &lines[2][8]);
8293 if (!comment) {
8294 return USERSHARE_POSIX_ERR;
8296 trim_string(comment, " ", " ");
8297 trim_char(comment, '"', '"');
8299 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8300 return USERSHARE_MALFORMED_ACL_DEF;
8303 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8304 return USERSHARE_ACL_ERR;
8307 if (us_vers == 2) {
8308 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8309 return USERSHARE_MALFORMED_ACL_DEF;
8311 if (lines[4][9] == 'y') {
8312 *pallow_guest = true;
8315 /* Backwards compatible extension to file version #2. */
8316 if (numlines > 5) {
8317 if (strncmp(lines[5], "sharename=", 10) != 0) {
8318 return USERSHARE_MALFORMED_SHARENAME_DEF;
8320 if (!strequal(&lines[5][10], servicename)) {
8321 return USERSHARE_BAD_SHARENAME;
8323 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8324 if (!*pp_cp_servicename) {
8325 return USERSHARE_POSIX_ERR;
8330 if (*pp_cp_servicename == NULL) {
8331 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8332 if (!*pp_cp_servicename) {
8333 return USERSHARE_POSIX_ERR;
8337 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8338 /* Path didn't change, no checks needed. */
8339 *pp_sharepath = sharepath;
8340 *pp_comment = comment;
8341 return USERSHARE_OK;
8344 /* The path *must* be absolute. */
8345 if (sharepath[0] != '/') {
8346 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8347 servicename, sharepath));
8348 return USERSHARE_PATH_NOT_ABSOLUTE;
8351 /* If there is a usershare prefix deny list ensure one of these paths
8352 doesn't match the start of the user given path. */
8353 if (prefixdenylist) {
8354 int i;
8355 for ( i=0; prefixdenylist[i]; i++ ) {
8356 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8357 servicename, i, prefixdenylist[i], sharepath ));
8358 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8359 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8360 "usershare prefix deny list entries.\n",
8361 servicename, sharepath));
8362 return USERSHARE_PATH_IS_DENIED;
8367 /* If there is a usershare prefix allow list ensure one of these paths
8368 does match the start of the user given path. */
8370 if (prefixallowlist) {
8371 int i;
8372 for ( i=0; prefixallowlist[i]; i++ ) {
8373 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8374 servicename, i, prefixallowlist[i], sharepath ));
8375 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8376 break;
8379 if (prefixallowlist[i] == NULL) {
8380 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8381 "usershare prefix allow list entries.\n",
8382 servicename, sharepath));
8383 return USERSHARE_PATH_NOT_ALLOWED;
8387 /* Ensure this is pointing to a directory. */
8388 dp = opendir(sharepath);
8390 if (!dp) {
8391 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8392 servicename, sharepath));
8393 return USERSHARE_PATH_NOT_DIRECTORY;
8396 /* Ensure the owner of the usershare file has permission to share
8397 this directory. */
8399 if (sys_stat(sharepath, &sbuf, false) == -1) {
8400 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8401 servicename, sharepath, strerror(errno) ));
8402 closedir(dp);
8403 return USERSHARE_POSIX_ERR;
8406 closedir(dp);
8408 if (!S_ISDIR(sbuf.st_ex_mode)) {
8409 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8410 servicename, sharepath ));
8411 return USERSHARE_PATH_NOT_DIRECTORY;
8414 /* Check if sharing is restricted to owner-only. */
8415 /* psbuf is the stat of the usershare definition file,
8416 sbuf is the stat of the target directory to be shared. */
8418 if (lp_usershare_owner_only()) {
8419 /* root can share anything. */
8420 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8421 return USERSHARE_PATH_NOT_ALLOWED;
8425 *pp_sharepath = sharepath;
8426 *pp_comment = comment;
8427 return USERSHARE_OK;
8430 /***************************************************************************
8431 Deal with a usershare file.
8432 Returns:
8433 >= 0 - snum
8434 -1 - Bad name, invalid contents.
8435 - service name already existed and not a usershare, problem
8436 with permissions to share directory etc.
8437 ***************************************************************************/
8439 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8441 SMB_STRUCT_STAT sbuf;
8442 SMB_STRUCT_STAT lsbuf;
8443 char *fname = NULL;
8444 char *sharepath = NULL;
8445 char *comment = NULL;
8446 char *cp_service_name = NULL;
8447 char **lines = NULL;
8448 int numlines = 0;
8449 int fd = -1;
8450 int iService = -1;
8451 TALLOC_CTX *ctx = talloc_stackframe();
8452 struct security_descriptor *psd = NULL;
8453 bool guest_ok = false;
8454 char *canon_name = NULL;
8455 bool added_service = false;
8456 int ret = -1;
8458 /* Ensure share name doesn't contain invalid characters. */
8459 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8460 DEBUG(0,("process_usershare_file: share name %s contains "
8461 "invalid characters (any of %s)\n",
8462 file_name, INVALID_SHARENAME_CHARS ));
8463 goto out;
8466 canon_name = canonicalize_servicename(ctx, file_name);
8467 if (!canon_name) {
8468 goto out;
8471 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8472 if (!fname) {
8473 goto out;
8476 /* Minimize the race condition by doing an lstat before we
8477 open and fstat. Ensure this isn't a symlink link. */
8479 if (sys_lstat(fname, &lsbuf, false) != 0) {
8480 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8481 fname, strerror(errno) ));
8482 goto out;
8485 /* This must be a regular file, not a symlink, directory or
8486 other strange filetype. */
8487 if (!check_usershare_stat(fname, &lsbuf)) {
8488 goto out;
8492 TDB_DATA data;
8493 NTSTATUS status;
8495 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
8496 canon_name, &data);
8498 iService = -1;
8500 if (NT_STATUS_IS_OK(status) &&
8501 (data.dptr != NULL) &&
8502 (data.dsize == sizeof(iService))) {
8503 memcpy(&iService, data.dptr, sizeof(iService));
8507 if (iService != -1 &&
8508 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8509 &lsbuf.st_ex_mtime) == 0) {
8510 /* Nothing changed - Mark valid and return. */
8511 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8512 canon_name ));
8513 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8514 ret = iService;
8515 goto out;
8518 /* Try and open the file read only - no symlinks allowed. */
8519 #ifdef O_NOFOLLOW
8520 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
8521 #else
8522 fd = open(fname, O_RDONLY, 0);
8523 #endif
8525 if (fd == -1) {
8526 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8527 fname, strerror(errno) ));
8528 goto out;
8531 /* Now fstat to be *SURE* it's a regular file. */
8532 if (sys_fstat(fd, &sbuf, false) != 0) {
8533 close(fd);
8534 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8535 fname, strerror(errno) ));
8536 goto out;
8539 /* Is it the same dev/inode as was lstated ? */
8540 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8541 close(fd);
8542 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8543 "Symlink spoofing going on ?\n", fname ));
8544 goto out;
8547 /* This must be a regular file, not a symlink, directory or
8548 other strange filetype. */
8549 if (!check_usershare_stat(fname, &sbuf)) {
8550 goto out;
8553 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8555 close(fd);
8556 if (lines == NULL) {
8557 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8558 fname, (unsigned int)sbuf.st_ex_uid ));
8559 goto out;
8562 if (parse_usershare_file(ctx, &sbuf, file_name,
8563 iService, lines, numlines, &sharepath,
8564 &comment, &cp_service_name,
8565 &psd, &guest_ok) != USERSHARE_OK) {
8566 goto out;
8569 /* Everything ok - add the service possibly using a template. */
8570 if (iService < 0) {
8571 const struct loadparm_service *sp = &sDefault;
8572 if (snum_template != -1) {
8573 sp = ServicePtrs[snum_template];
8576 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8577 DEBUG(0, ("process_usershare_file: Failed to add "
8578 "new service %s\n", cp_service_name));
8579 goto out;
8582 added_service = true;
8584 /* Read only is controlled by usershare ACL below. */
8585 ServicePtrs[iService]->bRead_only = false;
8588 /* Write the ACL of the new/modified share. */
8589 if (!set_share_security(canon_name, psd)) {
8590 DEBUG(0, ("process_usershare_file: Failed to set share "
8591 "security for user share %s\n",
8592 canon_name ));
8593 goto out;
8596 /* If from a template it may be marked invalid. */
8597 ServicePtrs[iService]->valid = true;
8599 /* Set the service as a valid usershare. */
8600 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8602 /* Set guest access. */
8603 if (lp_usershare_allow_guests()) {
8604 ServicePtrs[iService]->bGuest_ok = guest_ok;
8607 /* And note when it was loaded. */
8608 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8609 string_set(&ServicePtrs[iService]->szPath, sharepath);
8610 string_set(&ServicePtrs[iService]->comment, comment);
8612 ret = iService;
8614 out:
8616 if (ret == -1 && iService != -1 && added_service) {
8617 lp_remove_service(iService);
8620 TALLOC_FREE(lines);
8621 TALLOC_FREE(ctx);
8622 return ret;
8625 /***************************************************************************
8626 Checks if a usershare entry has been modified since last load.
8627 ***************************************************************************/
8629 static bool usershare_exists(int iService, struct timespec *last_mod)
8631 SMB_STRUCT_STAT lsbuf;
8632 const char *usersharepath = Globals.szUsersharePath;
8633 char *fname;
8635 if (asprintf(&fname, "%s/%s",
8636 usersharepath,
8637 ServicePtrs[iService]->szService) < 0) {
8638 return false;
8641 if (sys_lstat(fname, &lsbuf, false) != 0) {
8642 SAFE_FREE(fname);
8643 return false;
8646 if (!S_ISREG(lsbuf.st_ex_mode)) {
8647 SAFE_FREE(fname);
8648 return false;
8651 SAFE_FREE(fname);
8652 *last_mod = lsbuf.st_ex_mtime;
8653 return true;
8656 /***************************************************************************
8657 Load a usershare service by name. Returns a valid servicenumber or -1.
8658 ***************************************************************************/
8660 int load_usershare_service(const char *servicename)
8662 SMB_STRUCT_STAT sbuf;
8663 const char *usersharepath = Globals.szUsersharePath;
8664 int max_user_shares = Globals.iUsershareMaxShares;
8665 int snum_template = -1;
8667 if (*usersharepath == 0 || max_user_shares == 0) {
8668 return -1;
8671 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8672 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8673 usersharepath, strerror(errno) ));
8674 return -1;
8677 if (!S_ISDIR(sbuf.st_ex_mode)) {
8678 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8679 usersharepath ));
8680 return -1;
8684 * This directory must be owned by root, and have the 't' bit set.
8685 * It also must not be writable by "other".
8688 #ifdef S_ISVTX
8689 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8690 #else
8691 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8692 #endif
8693 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8694 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8695 usersharepath ));
8696 return -1;
8699 /* Ensure the template share exists if it's set. */
8700 if (Globals.szUsershareTemplateShare[0]) {
8701 /* We can't use lp_servicenumber here as we are recommending that
8702 template shares have -valid=false set. */
8703 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8704 if (ServicePtrs[snum_template]->szService &&
8705 strequal(ServicePtrs[snum_template]->szService,
8706 Globals.szUsershareTemplateShare)) {
8707 break;
8711 if (snum_template == -1) {
8712 DEBUG(0,("load_usershare_service: usershare template share %s "
8713 "does not exist.\n",
8714 Globals.szUsershareTemplateShare ));
8715 return -1;
8719 return process_usershare_file(usersharepath, servicename, snum_template);
8722 /***************************************************************************
8723 Load all user defined shares from the user share directory.
8724 We only do this if we're enumerating the share list.
8725 This is the function that can delete usershares that have
8726 been removed.
8727 ***************************************************************************/
8729 int load_usershare_shares(struct smbd_server_connection *sconn,
8730 bool (*snumused) (struct smbd_server_connection *, int))
8732 DIR *dp;
8733 SMB_STRUCT_STAT sbuf;
8734 struct dirent *de;
8735 int num_usershares = 0;
8736 int max_user_shares = Globals.iUsershareMaxShares;
8737 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8738 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8739 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8740 int iService;
8741 int snum_template = -1;
8742 const char *usersharepath = Globals.szUsersharePath;
8743 int ret = lp_numservices();
8745 if (max_user_shares == 0 || *usersharepath == '\0') {
8746 return lp_numservices();
8749 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8750 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8751 usersharepath, strerror(errno) ));
8752 return ret;
8756 * This directory must be owned by root, and have the 't' bit set.
8757 * It also must not be writable by "other".
8760 #ifdef S_ISVTX
8761 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8762 #else
8763 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8764 #endif
8765 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8766 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8767 usersharepath ));
8768 return ret;
8771 /* Ensure the template share exists if it's set. */
8772 if (Globals.szUsershareTemplateShare[0]) {
8773 /* We can't use lp_servicenumber here as we are recommending that
8774 template shares have -valid=false set. */
8775 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8776 if (ServicePtrs[snum_template]->szService &&
8777 strequal(ServicePtrs[snum_template]->szService,
8778 Globals.szUsershareTemplateShare)) {
8779 break;
8783 if (snum_template == -1) {
8784 DEBUG(0,("load_usershare_shares: usershare template share %s "
8785 "does not exist.\n",
8786 Globals.szUsershareTemplateShare ));
8787 return ret;
8791 /* Mark all existing usershares as pending delete. */
8792 for (iService = iNumServices - 1; iService >= 0; iService--) {
8793 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8794 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8798 dp = opendir(usersharepath);
8799 if (!dp) {
8800 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8801 usersharepath, strerror(errno) ));
8802 return ret;
8805 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8806 (de = readdir(dp));
8807 num_dir_entries++ ) {
8808 int r;
8809 const char *n = de->d_name;
8811 /* Ignore . and .. */
8812 if (*n == '.') {
8813 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8814 continue;
8818 if (n[0] == ':') {
8819 /* Temporary file used when creating a share. */
8820 num_tmp_dir_entries++;
8823 /* Allow 20% tmp entries. */
8824 if (num_tmp_dir_entries > allowed_tmp_entries) {
8825 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8826 "in directory %s\n",
8827 num_tmp_dir_entries, usersharepath));
8828 break;
8831 r = process_usershare_file(usersharepath, n, snum_template);
8832 if (r == 0) {
8833 /* Update the services count. */
8834 num_usershares++;
8835 if (num_usershares >= max_user_shares) {
8836 DEBUG(0,("load_usershare_shares: max user shares reached "
8837 "on file %s in directory %s\n",
8838 n, usersharepath ));
8839 break;
8841 } else if (r == -1) {
8842 num_bad_dir_entries++;
8845 /* Allow 20% bad entries. */
8846 if (num_bad_dir_entries > allowed_bad_entries) {
8847 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8848 "in directory %s\n",
8849 num_bad_dir_entries, usersharepath));
8850 break;
8853 /* Allow 20% bad entries. */
8854 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8855 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8856 "in directory %s\n",
8857 num_dir_entries, usersharepath));
8858 break;
8862 closedir(dp);
8864 /* Sweep through and delete any non-refreshed usershares that are
8865 not currently in use. */
8866 for (iService = iNumServices - 1; iService >= 0; iService--) {
8867 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8868 if (snumused && snumused(sconn, iService)) {
8869 continue;
8871 /* Remove from the share ACL db. */
8872 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8873 lp_servicename(iService) ));
8874 delete_share_security(lp_servicename(iService));
8875 free_service_byindex(iService);
8879 return lp_numservices();
8882 /********************************************************
8883 Destroy global resources allocated in this file
8884 ********************************************************/
8886 void gfree_loadparm(void)
8888 int i;
8890 free_file_list();
8892 /* Free resources allocated to services */
8894 for ( i = 0; i < iNumServices; i++ ) {
8895 if ( VALID(i) ) {
8896 free_service_byindex(i);
8900 SAFE_FREE( ServicePtrs );
8901 iNumServices = 0;
8903 /* Now release all resources allocated to global
8904 parameters and the default service */
8906 free_global_parameters();
8910 /***************************************************************************
8911 Allow client apps to specify that they are a client
8912 ***************************************************************************/
8913 static void lp_set_in_client(bool b)
8915 in_client = b;
8919 /***************************************************************************
8920 Determine if we're running in a client app
8921 ***************************************************************************/
8922 static bool lp_is_in_client(void)
8924 return in_client;
8927 /***************************************************************************
8928 Load the services array from the services file. Return true on success,
8929 false on failure.
8930 ***************************************************************************/
8932 static bool lp_load_ex(const char *pszFname,
8933 bool global_only,
8934 bool save_defaults,
8935 bool add_ipc,
8936 bool initialize_globals,
8937 bool allow_include_registry,
8938 bool load_all_shares)
8940 char *n2 = NULL;
8941 bool bRetval;
8943 bRetval = false;
8945 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8947 bInGlobalSection = true;
8948 bGlobalOnly = global_only;
8949 bAllowIncludeRegistry = allow_include_registry;
8951 init_globals(initialize_globals);
8953 free_file_list();
8955 if (save_defaults) {
8956 init_locals();
8957 lp_save_defaults();
8960 if (!initialize_globals) {
8961 free_param_opts(&Globals.param_opt);
8962 apply_lp_set_cmdline();
8965 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
8967 /* We get sections first, so have to start 'behind' to make up */
8968 iServiceIndex = -1;
8970 if (lp_config_backend_is_file()) {
8971 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
8972 current_user_info.domain,
8973 pszFname);
8974 if (!n2) {
8975 smb_panic("lp_load_ex: out of memory");
8978 add_to_file_list(pszFname, n2);
8980 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8981 TALLOC_FREE(n2);
8983 /* finish up the last section */
8984 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8985 if (bRetval) {
8986 if (iServiceIndex >= 0) {
8987 bRetval = service_ok(iServiceIndex);
8991 if (lp_config_backend_is_registry()) {
8992 /* config backend changed to registry in config file */
8994 * We need to use this extra global variable here to
8995 * survive restart: init_globals uses this as a default
8996 * for ConfigBackend. Otherwise, init_globals would
8997 * send us into an endless loop here.
8999 config_backend = CONFIG_BACKEND_REGISTRY;
9000 /* start over */
9001 DEBUG(1, ("lp_load_ex: changing to config backend "
9002 "registry\n"));
9003 init_globals(true);
9004 lp_kill_all_services();
9005 return lp_load_ex(pszFname, global_only, save_defaults,
9006 add_ipc, initialize_globals,
9007 allow_include_registry,
9008 load_all_shares);
9010 } else if (lp_config_backend_is_registry()) {
9011 bRetval = process_registry_globals();
9012 } else {
9013 DEBUG(0, ("Illegal config backend given: %d\n",
9014 lp_config_backend()));
9015 bRetval = false;
9018 if (bRetval && lp_registry_shares()) {
9019 if (load_all_shares) {
9020 bRetval = process_registry_shares();
9021 } else {
9022 bRetval = reload_registry_shares();
9026 lp_add_auto_services(lp_auto_services());
9028 if (add_ipc) {
9029 /* When 'restrict anonymous = 2' guest connections to ipc$
9030 are denied */
9031 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9032 if ( lp_enable_asu_support() ) {
9033 lp_add_ipc("ADMIN$", false);
9037 set_allowed_client_auth();
9039 if (lp_security() == SEC_SERVER) {
9040 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9043 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9044 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9045 lp_passwordserver()));
9048 bLoaded = true;
9050 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9051 /* if bWINSsupport is true and we are in the client */
9052 if (lp_is_in_client() && Globals.bWINSsupport) {
9053 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9056 init_iconv();
9058 fault_configure(smb_panic_s3);
9060 bAllowIncludeRegistry = true;
9062 return (bRetval);
9065 bool lp_load(const char *pszFname,
9066 bool global_only,
9067 bool save_defaults,
9068 bool add_ipc,
9069 bool initialize_globals)
9071 return lp_load_ex(pszFname,
9072 global_only,
9073 save_defaults,
9074 add_ipc,
9075 initialize_globals,
9076 true, /* allow_include_registry */
9077 false); /* load_all_shares*/
9080 bool lp_load_initial_only(const char *pszFname)
9082 return lp_load_ex(pszFname,
9083 true, /* global only */
9084 false, /* save_defaults */
9085 false, /* add_ipc */
9086 true, /* initialize_globals */
9087 false, /* allow_include_registry */
9088 false); /* load_all_shares*/
9092 * most common lp_load wrapper, loading only the globals
9094 bool lp_load_global(const char *file_name)
9096 return lp_load_ex(file_name,
9097 true, /* global_only */
9098 false, /* save_defaults */
9099 false, /* add_ipc */
9100 true, /* initialize_globals */
9101 true, /* allow_include_registry */
9102 false); /* load_all_shares*/
9106 * lp_load wrapper, especially for clients
9108 bool lp_load_client(const char *file_name)
9110 lp_set_in_client(true);
9112 return lp_load_global(file_name);
9116 * lp_load wrapper, loading only globals, but intended
9117 * for subsequent calls, not reinitializing the globals
9118 * to default values
9120 bool lp_load_global_no_reinit(const char *file_name)
9122 return lp_load_ex(file_name,
9123 true, /* global_only */
9124 false, /* save_defaults */
9125 false, /* add_ipc */
9126 false, /* initialize_globals */
9127 true, /* allow_include_registry */
9128 false); /* load_all_shares*/
9132 * lp_load wrapper, especially for clients, no reinitialization
9134 bool lp_load_client_no_reinit(const char *file_name)
9136 lp_set_in_client(true);
9138 return lp_load_global_no_reinit(file_name);
9141 bool lp_load_with_registry_shares(const char *pszFname,
9142 bool global_only,
9143 bool save_defaults,
9144 bool add_ipc,
9145 bool initialize_globals)
9147 return lp_load_ex(pszFname,
9148 global_only,
9149 save_defaults,
9150 add_ipc,
9151 initialize_globals,
9152 true, /* allow_include_registry */
9153 true); /* load_all_shares*/
9156 /***************************************************************************
9157 Return the max number of services.
9158 ***************************************************************************/
9160 int lp_numservices(void)
9162 return (iNumServices);
9165 /***************************************************************************
9166 Display the contents of the services array in human-readable form.
9167 ***************************************************************************/
9169 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9171 int iService;
9173 if (show_defaults)
9174 defaults_saved = false;
9176 dump_globals(f);
9178 dump_a_service(&sDefault, f);
9180 for (iService = 0; iService < maxtoprint; iService++) {
9181 fprintf(f,"\n");
9182 lp_dump_one(f, show_defaults, iService);
9186 /***************************************************************************
9187 Display the contents of one service in human-readable form.
9188 ***************************************************************************/
9190 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9192 if (VALID(snum)) {
9193 if (ServicePtrs[snum]->szService[0] == '\0')
9194 return;
9195 dump_a_service(ServicePtrs[snum], f);
9199 /***************************************************************************
9200 Return the number of the service with the given name, or -1 if it doesn't
9201 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9202 getservicebyname()! This works ONLY if all services have been loaded, and
9203 does not copy the found service.
9204 ***************************************************************************/
9206 int lp_servicenumber(const char *pszServiceName)
9208 int iService;
9209 fstring serviceName;
9211 if (!pszServiceName) {
9212 return GLOBAL_SECTION_SNUM;
9215 for (iService = iNumServices - 1; iService >= 0; iService--) {
9216 if (VALID(iService) && ServicePtrs[iService]->szService) {
9218 * The substitution here is used to support %U is
9219 * service names
9221 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9222 standard_sub_basic(get_current_username(),
9223 current_user_info.domain,
9224 serviceName,sizeof(serviceName));
9225 if (strequal(serviceName, pszServiceName)) {
9226 break;
9231 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9232 struct timespec last_mod;
9234 if (!usershare_exists(iService, &last_mod)) {
9235 /* Remove the share security tdb entry for it. */
9236 delete_share_security(lp_servicename(iService));
9237 /* Remove it from the array. */
9238 free_service_byindex(iService);
9239 /* Doesn't exist anymore. */
9240 return GLOBAL_SECTION_SNUM;
9243 /* Has it been modified ? If so delete and reload. */
9244 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9245 &last_mod) < 0) {
9246 /* Remove it from the array. */
9247 free_service_byindex(iService);
9248 /* and now reload it. */
9249 iService = load_usershare_service(pszServiceName);
9253 if (iService < 0) {
9254 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9255 return GLOBAL_SECTION_SNUM;
9258 return (iService);
9261 /*******************************************************************
9262 A useful volume label function.
9263 ********************************************************************/
9265 const char *volume_label(int snum)
9267 char *ret;
9268 const char *label = lp_volume(snum);
9269 if (!*label) {
9270 label = lp_servicename(snum);
9273 /* This returns a 33 byte guarenteed null terminated string. */
9274 ret = talloc_strndup(talloc_tos(), label, 32);
9275 if (!ret) {
9276 return "";
9278 return ret;
9281 /*******************************************************************
9282 Get the default server type we will announce as via nmbd.
9283 ********************************************************************/
9285 int lp_default_server_announce(void)
9287 int default_server_announce = 0;
9288 default_server_announce |= SV_TYPE_WORKSTATION;
9289 default_server_announce |= SV_TYPE_SERVER;
9290 default_server_announce |= SV_TYPE_SERVER_UNIX;
9292 /* note that the flag should be set only if we have a
9293 printer service but nmbd doesn't actually load the
9294 services so we can't tell --jerry */
9296 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9298 default_server_announce |= SV_TYPE_SERVER_NT;
9299 default_server_announce |= SV_TYPE_NT;
9301 switch (lp_server_role()) {
9302 case ROLE_DOMAIN_MEMBER:
9303 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9304 break;
9305 case ROLE_DOMAIN_PDC:
9306 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9307 break;
9308 case ROLE_DOMAIN_BDC:
9309 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9310 break;
9311 case ROLE_STANDALONE:
9312 default:
9313 break;
9315 if (lp_time_server())
9316 default_server_announce |= SV_TYPE_TIME_SOURCE;
9318 if (lp_host_msdfs())
9319 default_server_announce |= SV_TYPE_DFS_SERVER;
9321 return default_server_announce;
9324 /***********************************************************
9325 If we are PDC then prefer us as DMB
9326 ************************************************************/
9328 bool lp_domain_master(void)
9330 if (Globals.iDomainMaster == Auto)
9331 return (lp_server_role() == ROLE_DOMAIN_PDC);
9333 return (bool)Globals.iDomainMaster;
9336 /***********************************************************
9337 If we are PDC then prefer us as DMB
9338 ************************************************************/
9340 static bool lp_domain_master_true_or_auto(void)
9342 if (Globals.iDomainMaster) /* auto or yes */
9343 return true;
9345 return false;
9348 /***********************************************************
9349 If we are DMB then prefer us as LMB
9350 ************************************************************/
9352 bool lp_preferred_master(void)
9354 if (Globals.iPreferredMaster == Auto)
9355 return (lp_local_master() && lp_domain_master());
9357 return (bool)Globals.iPreferredMaster;
9360 /*******************************************************************
9361 Remove a service.
9362 ********************************************************************/
9364 void lp_remove_service(int snum)
9366 ServicePtrs[snum]->valid = false;
9367 invalid_services[num_invalid_services++] = snum;
9370 /*******************************************************************
9371 Copy a service.
9372 ********************************************************************/
9374 void lp_copy_service(int snum, const char *new_name)
9376 do_section(new_name, NULL);
9377 if (snum >= 0) {
9378 snum = lp_servicenumber(new_name);
9379 if (snum >= 0)
9380 lp_do_parameter(snum, "copy", lp_servicename(snum));
9385 /***********************************************************
9386 Set the global name resolution order (used in smbclient).
9387 ************************************************************/
9389 void lp_set_name_resolve_order(const char *new_order)
9391 string_set(&Globals.szNameResolveOrder, new_order);
9394 const char *lp_printername(int snum)
9396 const char *ret = lp__printername(snum);
9397 if (ret == NULL || (ret != NULL && *ret == '\0'))
9398 ret = lp_const_servicename(snum);
9400 return ret;
9404 /***********************************************************
9405 Allow daemons such as winbindd to fix their logfile name.
9406 ************************************************************/
9408 void lp_set_logfile(const char *name)
9410 string_set(&Globals.szLogFile, name);
9411 debug_set_logfile(name);
9414 /*******************************************************************
9415 Return the max print jobs per queue.
9416 ********************************************************************/
9418 int lp_maxprintjobs(int snum)
9420 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9421 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9422 maxjobs = PRINT_MAX_JOBID - 1;
9424 return maxjobs;
9427 const char *lp_printcapname(void)
9429 if ((Globals.szPrintcapname != NULL) &&
9430 (Globals.szPrintcapname[0] != '\0'))
9431 return Globals.szPrintcapname;
9433 if (sDefault.iPrinting == PRINT_CUPS) {
9434 #ifdef HAVE_CUPS
9435 return "cups";
9436 #else
9437 return "lpstat";
9438 #endif
9441 if (sDefault.iPrinting == PRINT_BSD)
9442 return "/etc/printcap";
9444 return PRINTCAP_NAME;
9447 static uint32 spoolss_state;
9449 bool lp_disable_spoolss( void )
9451 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9452 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9454 return spoolss_state == SVCCTL_STOPPED ? true : false;
9457 void lp_set_spoolss_state( uint32 state )
9459 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9461 spoolss_state = state;
9464 uint32 lp_get_spoolss_state( void )
9466 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9469 /*******************************************************************
9470 Ensure we don't use sendfile if server smb signing is active.
9471 ********************************************************************/
9473 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9475 bool sign_active = false;
9477 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9478 if (get_Protocol() < PROTOCOL_NT1) {
9479 return false;
9481 if (signing_state) {
9482 sign_active = smb_signing_is_active(signing_state);
9484 return (lp__use_sendfile(snum) &&
9485 (get_remote_arch() != RA_WIN95) &&
9486 !sign_active);
9489 /*******************************************************************
9490 Turn off sendfile if we find the underlying OS doesn't support it.
9491 ********************************************************************/
9493 void set_use_sendfile(int snum, bool val)
9495 if (LP_SNUM_OK(snum))
9496 ServicePtrs[snum]->bUseSendfile = val;
9497 else
9498 sDefault.bUseSendfile = val;
9501 /*******************************************************************
9502 Turn off storing DOS attributes if this share doesn't support it.
9503 ********************************************************************/
9505 void set_store_dos_attributes(int snum, bool val)
9507 if (!LP_SNUM_OK(snum))
9508 return;
9509 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9512 void lp_set_mangling_method(const char *new_method)
9514 string_set(&Globals.szManglingMethod, new_method);
9517 /*******************************************************************
9518 Global state for POSIX pathname processing.
9519 ********************************************************************/
9521 static bool posix_pathnames;
9523 bool lp_posix_pathnames(void)
9525 return posix_pathnames;
9528 /*******************************************************************
9529 Change everything needed to ensure POSIX pathname processing (currently
9530 not much).
9531 ********************************************************************/
9533 void lp_set_posix_pathnames(void)
9535 posix_pathnames = true;
9538 /*******************************************************************
9539 Global state for POSIX lock processing - CIFS unix extensions.
9540 ********************************************************************/
9542 bool posix_default_lock_was_set;
9543 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9545 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9547 if (posix_default_lock_was_set) {
9548 return posix_cifsx_locktype;
9549 } else {
9550 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9554 /*******************************************************************
9555 ********************************************************************/
9557 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9559 posix_default_lock_was_set = true;
9560 posix_cifsx_locktype = val;
9563 int lp_min_receive_file_size(void)
9565 if (Globals.iminreceivefile < 0) {
9566 return 0;
9568 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9571 /*******************************************************************
9572 If socket address is an empty character string, it is necessary to
9573 define it as "0.0.0.0".
9574 ********************************************************************/
9576 const char *lp_socket_address(void)
9578 char *sock_addr = Globals.szSocketAddress;
9580 if (sock_addr[0] == '\0'){
9581 string_set(&Globals.szSocketAddress, "0.0.0.0");
9583 return Globals.szSocketAddress;
9586 /*******************************************************************
9587 Safe wide links checks.
9588 This helper function always verify the validity of wide links,
9589 even after a configuration file reload.
9590 ********************************************************************/
9592 static bool lp_widelinks_internal(int snum)
9594 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9595 sDefault.bWidelinks);
9598 void widelinks_warning(int snum)
9600 if (lp_allow_insecure_widelinks()) {
9601 return;
9604 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9605 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9606 "These parameters are incompatible. "
9607 "Wide links will be disabled for this share.\n",
9608 lp_servicename(snum) ));
9612 bool lp_widelinks(int snum)
9614 /* wide links is always incompatible with unix extensions */
9615 if (lp_unix_extensions()) {
9617 * Unless we have "allow insecure widelinks"
9618 * turned on.
9620 if (!lp_allow_insecure_widelinks()) {
9621 return false;
9625 return lp_widelinks_internal(snum);
9628 bool lp_writeraw(void)
9630 if (lp_async_smb_echo_handler()) {
9631 return false;
9633 return _lp_writeraw();
9636 bool lp_readraw(void)
9638 if (lp_async_smb_echo_handler()) {
9639 return false;
9641 return _lp_readraw();
9644 int lp_server_role(void)
9646 return lp_find_server_role(lp__server_role(),
9647 lp_security(),
9648 lp_domain_logons(),
9649 lp_domain_master_true_or_auto());