s4-torture: Add a lsarpc test_LookupNames4_fail function.
[Samba/gbeck.git] / source3 / param / loadparm.c
blob12ba2f1d3b9a487a5b14ab82aa5109163af86c2d
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14 Copyright (C) Andrew Bartlett 2011
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 3 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 * Load parameters.
33 * This module provides suitable callback functions for the params
34 * module. It builds the internal table of service details which is
35 * then used by the rest of the server.
37 * To add a parameter:
39 * 1) add it to the global or service structure definition
40 * 2) add it to the parm_table
41 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42 * 4) If it's a global then initialise it in init_globals. If a local
43 * (ie. service) parameter then initialise it in the sDefault structure
46 * Notes:
47 * The configuration file is processed sequentially for speed. It is NOT
48 * accessed randomly as happens in 'real' Windows. For this reason, there
49 * is a fair bit of sequence-dependent code here - ie., code which assumes
50 * that certain things happen before others. In particular, the code which
51 * happens at the boundary between sections is delicately poised, so be
52 * careful!
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "printing.h"
60 #include "lib/smbconf/smbconf.h"
61 #include "lib/smbconf/smbconf_init.h"
62 #include "lib/param/loadparm.h"
64 #include "ads.h"
65 #include "../librpc/gen_ndr/svcctl.h"
66 #include "intl.h"
67 #include "../libcli/smb/smb_signing.h"
68 #include "dbwrap/dbwrap.h"
69 #include "dbwrap/dbwrap_rbt.h"
70 #include "../lib/util/bitmap.h"
71 #include "../source4/dns_server/dns_update.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
75 #endif
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
81 #ifdef CLUSTER_SUPPORT
82 #include "ctdb_private.h"
83 #endif
85 bool bLoaded = false;
87 extern userdom_struct current_user_info;
89 /* the special value for the include parameter
90 * to be interpreted not as a file name but to
91 * trigger loading of the global smb.conf options
92 * from registry. */
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
95 #endif
97 static bool in_client = false; /* Not in the client by default */
98 static struct smbconf_csn conf_last_csn;
100 #define CONFIG_BACKEND_FILE 0
101 #define CONFIG_BACKEND_REGISTRY 1
103 static int config_backend = CONFIG_BACKEND_FILE;
105 /* some helpful bits */
106 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
107 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
109 #define USERSHARE_VALID 1
110 #define USERSHARE_PENDING_DELETE 2
112 static bool defaults_saved = false;
114 #define LOADPARM_EXTRA_GLOBALS \
115 struct parmlist_entry *param_opt; \
116 char *szRealm; \
117 char *szLogLevel; \
118 int iminreceivefile; \
119 char *szPrintcapname; \
120 int CupsEncrypt; \
121 int iPreferredMaster; \
122 int iDomainMaster; \
123 char *szLdapMachineSuffix; \
124 char *szLdapUserSuffix; \
125 char *szLdapIdmapSuffix; \
126 char *szLdapGroupSuffix; \
127 char *szStateDir; \
128 char *szCacheDir; \
129 char *szSocketAddress; \
130 char *szUsershareTemplateShare; \
131 char *szIdmapUID; \
132 char *szIdmapGID; \
133 int winbindMaxDomainConnections; \
134 int ismb2_max_credits;
136 #include "param/param_global.h"
138 static struct loadparm_global Globals;
140 /* This is a default service used to prime a services structure */
141 static struct loadparm_service sDefault =
143 .valid = true,
144 .autoloaded = false,
145 .usershare = 0,
146 .usershare_last_mod = {0, 0},
147 .szService = NULL,
148 .szPath = NULL,
149 .szUsername = NULL,
150 .szInvalidUsers = NULL,
151 .szValidUsers = NULL,
152 .szAdminUsers = NULL,
153 .szCopy = NULL,
154 .szInclude = NULL,
155 .szPreExec = NULL,
156 .szPostExec = NULL,
157 .szRootPreExec = NULL,
158 .szRootPostExec = NULL,
159 .szCupsOptions = NULL,
160 .szPrintcommand = NULL,
161 .szLpqcommand = NULL,
162 .szLprmcommand = NULL,
163 .szLppausecommand = NULL,
164 .szLpresumecommand = NULL,
165 .szQueuepausecommand = NULL,
166 .szQueueresumecommand = NULL,
167 .szPrintername = NULL,
168 .szPrintjobUsername = NULL,
169 .szDontdescend = NULL,
170 .szHostsallow = NULL,
171 .szHostsdeny = NULL,
172 .szMagicScript = NULL,
173 .szMagicOutput = NULL,
174 .szVetoFiles = NULL,
175 .szHideFiles = NULL,
176 .szVetoOplockFiles = NULL,
177 .comment = NULL,
178 .force_user = NULL,
179 .force_group = NULL,
180 .readlist = NULL,
181 .writelist = NULL,
182 .volume = NULL,
183 .fstype = NULL,
184 .szVfsObjects = NULL,
185 .szMSDfsProxy = NULL,
186 .szAioWriteBehind = NULL,
187 .szDfree = NULL,
188 .iMinPrintSpace = 0,
189 .iMaxPrintJobs = 1000,
190 .iMaxReportedPrintJobs = 0,
191 .iWriteCacheSize = 0,
192 .iCreate_mask = 0744,
193 .iCreate_force_mode = 0,
194 .iSecurity_mask = 0777,
195 .iSecurity_force_mode = 0,
196 .iDir_mask = 0755,
197 .iDir_force_mode = 0,
198 .iDir_Security_mask = 0777,
199 .iDir_Security_force_mode = 0,
200 .iMaxConnections = 0,
201 .iDefaultCase = CASE_LOWER,
202 .iPrinting = DEFAULT_PRINTING,
203 .iOplockContentionLimit = 2,
204 .iCSCPolicy = 0,
205 .iBlock_size = 1024,
206 .iDfreeCacheTime = 0,
207 .bPreexecClose = false,
208 .bRootpreexecClose = false,
209 .iCaseSensitive = Auto,
210 .bCasePreserve = true,
211 .bShortCasePreserve = true,
212 .bHideDotFiles = true,
213 .bHideSpecialFiles = false,
214 .bHideUnReadable = false,
215 .bHideUnWriteableFiles = false,
216 .bBrowseable = true,
217 .bAccessBasedShareEnum = false,
218 .bAvailable = true,
219 .bRead_only = true,
220 .bNo_set_dir = true,
221 .bGuest_only = false,
222 .bAdministrative_share = false,
223 .bGuest_ok = false,
224 .bPrint_ok = false,
225 .bPrintNotifyBackchannel = true,
226 .bMap_system = false,
227 .bMap_hidden = false,
228 .bMap_archive = true,
229 .bStoreDosAttributes = false,
230 .bDmapiSupport = false,
231 .bLocking = true,
232 .iStrictLocking = Auto,
233 .bPosixLocking = true,
234 .bShareModes = true,
235 .bOpLocks = true,
236 .bKernelOplocks = false,
237 .bLevel2OpLocks = true,
238 .bOnlyUser = false,
239 .bMangledNames = true,
240 .bWidelinks = false,
241 .bSymlinks = true,
242 .bSyncAlways = false,
243 .bStrictAllocate = false,
244 .bStrictSync = false,
245 .magic_char = '~',
246 .copymap = NULL,
247 .bDeleteReadonly = false,
248 .bFakeOplocks = false,
249 .bDeleteVetoFiles = false,
250 .bDosFilemode = false,
251 .bDosFiletimes = true,
252 .bDosFiletimeResolution = false,
253 .bFakeDirCreateTimes = false,
254 .bBlockingLocks = true,
255 .bInheritPerms = false,
256 .bInheritACLS = false,
257 .bInheritOwner = false,
258 .bMSDfsRoot = false,
259 .bUseClientDriver = false,
260 .bDefaultDevmode = true,
261 .bForcePrintername = false,
262 .bNTAclSupport = true,
263 .bForceUnknownAclUser = false,
264 .bUseSendfile = false,
265 .bProfileAcls = false,
266 .bMap_acl_inherit = false,
267 .bAfs_Share = false,
268 .bEASupport = false,
269 .bAclCheckPermissions = true,
270 .bAclMapFullControl = true,
271 .bAclGroupControl = false,
272 .bChangeNotify = true,
273 .bKernelChangeNotify = true,
274 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
275 .iAioReadSize = 0,
276 .iAioWriteSize = 0,
277 .iMap_readonly = MAP_READONLY_YES,
278 #ifdef BROKEN_DIRECTORY_HANDLING
279 .iDirectoryNameCacheSize = 0,
280 #else
281 .iDirectoryNameCacheSize = 100,
282 #endif
283 .ismb_encrypt = Auto,
284 .param_opt = NULL,
285 .dummy = ""
288 /* local variables */
289 static struct loadparm_service **ServicePtrs = NULL;
290 static int iNumServices = 0;
291 static int iServiceIndex = 0;
292 static struct db_context *ServiceHash;
293 static int *invalid_services = NULL;
294 static int num_invalid_services = 0;
295 static bool bInGlobalSection = true;
296 static bool bGlobalOnly = false;
298 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
300 /* prototypes for the special type handlers */
301 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
302 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
303 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
304 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
305 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
306 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
307 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
308 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
309 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
310 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
311 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
312 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
314 static void set_allowed_client_auth(void);
316 static void add_to_file_list(const char *fname, const char *subfname);
317 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
318 static void free_param_opts(struct parmlist_entry **popts);
320 #include "lib/param/param_enums.c"
322 static const struct enum_list enum_printing[] = {
323 {PRINT_SYSV, "sysv"},
324 {PRINT_AIX, "aix"},
325 {PRINT_HPUX, "hpux"},
326 {PRINT_BSD, "bsd"},
327 {PRINT_QNX, "qnx"},
328 {PRINT_PLP, "plp"},
329 {PRINT_LPRNG, "lprng"},
330 {PRINT_CUPS, "cups"},
331 {PRINT_IPRINT, "iprint"},
332 {PRINT_LPRNT, "nt"},
333 {PRINT_LPROS2, "os2"},
334 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
335 {PRINT_TEST, "test"},
336 {PRINT_VLP, "vlp"},
337 #endif /* DEVELOPER */
338 {-1, NULL}
341 static const struct enum_list enum_ldap_sasl_wrapping[] = {
342 {0, "plain"},
343 {ADS_AUTH_SASL_SIGN, "sign"},
344 {ADS_AUTH_SASL_SEAL, "seal"},
345 {-1, NULL}
348 static const struct enum_list enum_ldap_ssl[] = {
349 {LDAP_SSL_OFF, "no"},
350 {LDAP_SSL_OFF, "off"},
351 {LDAP_SSL_START_TLS, "start tls"},
352 {LDAP_SSL_START_TLS, "start_tls"},
353 {-1, NULL}
356 /* LDAP Dereferencing Alias types */
357 #define SAMBA_LDAP_DEREF_NEVER 0
358 #define SAMBA_LDAP_DEREF_SEARCHING 1
359 #define SAMBA_LDAP_DEREF_FINDING 2
360 #define SAMBA_LDAP_DEREF_ALWAYS 3
362 static const struct enum_list enum_ldap_deref[] = {
363 {SAMBA_LDAP_DEREF_NEVER, "never"},
364 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
365 {SAMBA_LDAP_DEREF_FINDING, "finding"},
366 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
367 {-1, "auto"}
370 static const struct enum_list enum_ldap_passwd_sync[] = {
371 {LDAP_PASSWD_SYNC_OFF, "no"},
372 {LDAP_PASSWD_SYNC_OFF, "off"},
373 {LDAP_PASSWD_SYNC_ON, "yes"},
374 {LDAP_PASSWD_SYNC_ON, "on"},
375 {LDAP_PASSWD_SYNC_ONLY, "only"},
376 {-1, NULL}
379 static const struct enum_list enum_map_readonly[] = {
380 {MAP_READONLY_NO, "no"},
381 {MAP_READONLY_NO, "false"},
382 {MAP_READONLY_NO, "0"},
383 {MAP_READONLY_YES, "yes"},
384 {MAP_READONLY_YES, "true"},
385 {MAP_READONLY_YES, "1"},
386 {MAP_READONLY_PERMISSIONS, "permissions"},
387 {MAP_READONLY_PERMISSIONS, "perms"},
388 {-1, NULL}
391 static const struct enum_list enum_case[] = {
392 {CASE_LOWER, "lower"},
393 {CASE_UPPER, "upper"},
394 {-1, NULL}
398 /* ACL compatibility options. */
399 static const struct enum_list enum_acl_compat_vals[] = {
400 { ACL_COMPAT_AUTO, "auto" },
401 { ACL_COMPAT_WINNT, "winnt" },
402 { ACL_COMPAT_WIN2K, "win2k" },
403 { -1, NULL}
407 Do you want session setups at user level security with a invalid
408 password to be rejected or allowed in as guest? WinNT rejects them
409 but it can be a pain as it means "net view" needs to use a password
411 You have 3 choices in the setting of map_to_guest:
413 "Never" means session setups with an invalid password
414 are rejected. This is the default.
416 "Bad User" means session setups with an invalid password
417 are rejected, unless the username does not exist, in which case it
418 is treated as a guest login
420 "Bad Password" means session setups with an invalid password
421 are treated as a guest login
423 Note that map_to_guest only has an effect in user or server
424 level security.
427 static const struct enum_list enum_map_to_guest[] = {
428 {NEVER_MAP_TO_GUEST, "Never"},
429 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
430 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
431 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
432 {-1, NULL}
435 /* Config backend options */
437 static const struct enum_list enum_config_backend[] = {
438 {CONFIG_BACKEND_FILE, "file"},
439 {CONFIG_BACKEND_REGISTRY, "registry"},
440 {-1, NULL}
443 /* ADS kerberos ticket verification options */
445 static const struct enum_list enum_kerberos_method[] = {
446 {KERBEROS_VERIFY_SECRETS, "default"},
447 {KERBEROS_VERIFY_SECRETS, "secrets only"},
448 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
449 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
450 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
451 {-1, NULL}
454 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
456 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
457 * screen in SWAT. This is used to exclude parameters as well as to squash all
458 * parameters that have been duplicated by pseudonyms.
460 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
461 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
462 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
463 * respective views.
465 * NOTE2: Handling of duplicated (synonym) parameters:
466 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
467 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
468 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
469 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
472 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
473 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
475 static struct parm_struct parm_table[] = {
476 {N_("Base Options"), P_SEP, P_SEPARATOR},
479 .label = "dos charset",
480 .type = P_STRING,
481 .p_class = P_GLOBAL,
482 .offset = GLOBAL_VAR(dos_charset),
483 .special = handle_dos_charset,
484 .enum_list = NULL,
485 .flags = FLAG_ADVANCED
488 .label = "unix charset",
489 .type = P_STRING,
490 .p_class = P_GLOBAL,
491 .offset = GLOBAL_VAR(unix_charset),
492 .special = handle_charset,
493 .enum_list = NULL,
494 .flags = FLAG_ADVANCED
497 .label = "comment",
498 .type = P_STRING,
499 .p_class = P_LOCAL,
500 .offset = LOCAL_VAR(comment),
501 .special = NULL,
502 .enum_list = NULL,
503 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
506 .label = "path",
507 .type = P_STRING,
508 .p_class = P_LOCAL,
509 .offset = LOCAL_VAR(szPath),
510 .special = NULL,
511 .enum_list = NULL,
512 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
515 .label = "directory",
516 .type = P_STRING,
517 .p_class = P_LOCAL,
518 .offset = LOCAL_VAR(szPath),
519 .special = NULL,
520 .enum_list = NULL,
521 .flags = FLAG_HIDE,
524 .label = "workgroup",
525 .type = P_USTRING,
526 .p_class = P_GLOBAL,
527 .offset = GLOBAL_VAR(szWorkgroup),
528 .special = NULL,
529 .enum_list = NULL,
530 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
533 .label = "realm",
534 .type = P_STRING,
535 .p_class = P_GLOBAL,
536 .offset = GLOBAL_VAR(szRealm),
537 .special = handle_realm,
538 .enum_list = NULL,
539 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
542 .label = "netbios name",
543 .type = P_USTRING,
544 .p_class = P_GLOBAL,
545 .offset = GLOBAL_VAR(szNetbiosName),
546 .special = NULL,
547 .enum_list = NULL,
548 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
551 .label = "netbios aliases",
552 .type = P_LIST,
553 .p_class = P_GLOBAL,
554 .offset = GLOBAL_VAR(szNetbiosAliases),
555 .special = handle_netbios_aliases,
556 .enum_list = NULL,
557 .flags = FLAG_ADVANCED,
560 .label = "netbios scope",
561 .type = P_USTRING,
562 .p_class = P_GLOBAL,
563 .offset = GLOBAL_VAR(szNetbiosScope),
564 .special = NULL,
565 .enum_list = NULL,
566 .flags = FLAG_ADVANCED,
569 .label = "server string",
570 .type = P_STRING,
571 .p_class = P_GLOBAL,
572 .offset = GLOBAL_VAR(szServerString),
573 .special = NULL,
574 .enum_list = NULL,
575 .flags = FLAG_BASIC | FLAG_ADVANCED,
578 .label = "interfaces",
579 .type = P_LIST,
580 .p_class = P_GLOBAL,
581 .offset = GLOBAL_VAR(szInterfaces),
582 .special = NULL,
583 .enum_list = NULL,
584 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
587 .label = "bind interfaces only",
588 .type = P_BOOL,
589 .p_class = P_GLOBAL,
590 .offset = GLOBAL_VAR(bBindInterfacesOnly),
591 .special = NULL,
592 .enum_list = NULL,
593 .flags = FLAG_ADVANCED | FLAG_WIZARD,
596 .label = "config backend",
597 .type = P_ENUM,
598 .p_class = P_GLOBAL,
599 .offset = GLOBAL_VAR(ConfigBackend),
600 .special = NULL,
601 .enum_list = enum_config_backend,
602 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
605 .label = "server role",
606 .type = P_ENUM,
607 .p_class = P_GLOBAL,
608 .offset = GLOBAL_VAR(ServerRole),
609 .special = NULL,
610 .enum_list = enum_server_role,
611 .flags = FLAG_BASIC | FLAG_ADVANCED,
614 {N_("Security Options"), P_SEP, P_SEPARATOR},
617 .label = "security",
618 .type = P_ENUM,
619 .p_class = P_GLOBAL,
620 .offset = GLOBAL_VAR(security),
621 .special = NULL,
622 .enum_list = enum_security,
623 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
626 .label = "auth methods",
627 .type = P_LIST,
628 .p_class = P_GLOBAL,
629 .offset = GLOBAL_VAR(AuthMethods),
630 .special = NULL,
631 .enum_list = NULL,
632 .flags = FLAG_ADVANCED,
635 .label = "encrypt passwords",
636 .type = P_BOOL,
637 .p_class = P_GLOBAL,
638 .offset = GLOBAL_VAR(bEncryptPasswords),
639 .special = NULL,
640 .enum_list = NULL,
641 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
644 .label = "client schannel",
645 .type = P_ENUM,
646 .p_class = P_GLOBAL,
647 .offset = GLOBAL_VAR(clientSchannel),
648 .special = NULL,
649 .enum_list = enum_bool_auto,
650 .flags = FLAG_BASIC | FLAG_ADVANCED,
653 .label = "server schannel",
654 .type = P_ENUM,
655 .p_class = P_GLOBAL,
656 .offset = GLOBAL_VAR(serverSchannel),
657 .special = NULL,
658 .enum_list = enum_bool_auto,
659 .flags = FLAG_BASIC | FLAG_ADVANCED,
662 .label = "allow trusted domains",
663 .type = P_BOOL,
664 .p_class = P_GLOBAL,
665 .offset = GLOBAL_VAR(bAllowTrustedDomains),
666 .special = NULL,
667 .enum_list = NULL,
668 .flags = FLAG_ADVANCED,
671 .label = "map to guest",
672 .type = P_ENUM,
673 .p_class = P_GLOBAL,
674 .offset = GLOBAL_VAR(map_to_guest),
675 .special = NULL,
676 .enum_list = enum_map_to_guest,
677 .flags = FLAG_ADVANCED,
680 .label = "null passwords",
681 .type = P_BOOL,
682 .p_class = P_GLOBAL,
683 .offset = GLOBAL_VAR(bNullPasswords),
684 .special = NULL,
685 .enum_list = NULL,
686 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
689 .label = "obey pam restrictions",
690 .type = P_BOOL,
691 .p_class = P_GLOBAL,
692 .offset = GLOBAL_VAR(bObeyPamRestrictions),
693 .special = NULL,
694 .enum_list = NULL,
695 .flags = FLAG_ADVANCED,
698 .label = "password server",
699 .type = P_STRING,
700 .p_class = P_GLOBAL,
701 .offset = GLOBAL_VAR(szPasswordServer),
702 .special = NULL,
703 .enum_list = NULL,
704 .flags = FLAG_ADVANCED | FLAG_WIZARD,
707 .label = "smb passwd file",
708 .type = P_STRING,
709 .p_class = P_GLOBAL,
710 .offset = GLOBAL_VAR(szSMBPasswdFile),
711 .special = NULL,
712 .enum_list = NULL,
713 .flags = FLAG_ADVANCED,
716 .label = "private dir",
717 .type = P_STRING,
718 .p_class = P_GLOBAL,
719 .offset = GLOBAL_VAR(szPrivateDir),
720 .special = NULL,
721 .enum_list = NULL,
722 .flags = FLAG_ADVANCED,
725 .label = "private directory",
726 .type = P_STRING,
727 .p_class = P_GLOBAL,
728 .offset = GLOBAL_VAR(szPrivateDir),
729 .special = NULL,
730 .enum_list = NULL,
731 .flags = FLAG_HIDE,
734 .label = "passdb backend",
735 .type = P_STRING,
736 .p_class = P_GLOBAL,
737 .offset = GLOBAL_VAR(passdb_backend),
738 .special = NULL,
739 .enum_list = NULL,
740 .flags = FLAG_ADVANCED | FLAG_WIZARD,
743 .label = "algorithmic rid base",
744 .type = P_INTEGER,
745 .p_class = P_GLOBAL,
746 .offset = GLOBAL_VAR(AlgorithmicRidBase),
747 .special = NULL,
748 .enum_list = NULL,
749 .flags = FLAG_ADVANCED,
752 .label = "root directory",
753 .type = P_STRING,
754 .p_class = P_GLOBAL,
755 .offset = GLOBAL_VAR(szRootdir),
756 .special = NULL,
757 .enum_list = NULL,
758 .flags = FLAG_ADVANCED,
761 .label = "root dir",
762 .type = P_STRING,
763 .p_class = P_GLOBAL,
764 .offset = GLOBAL_VAR(szRootdir),
765 .special = NULL,
766 .enum_list = NULL,
767 .flags = FLAG_HIDE,
770 .label = "root",
771 .type = P_STRING,
772 .p_class = P_GLOBAL,
773 .offset = GLOBAL_VAR(szRootdir),
774 .special = NULL,
775 .enum_list = NULL,
776 .flags = FLAG_HIDE,
779 .label = "guest account",
780 .type = P_STRING,
781 .p_class = P_GLOBAL,
782 .offset = GLOBAL_VAR(szGuestaccount),
783 .special = NULL,
784 .enum_list = NULL,
785 .flags = FLAG_BASIC | FLAG_ADVANCED,
788 .label = "enable privileges",
789 .type = P_BOOL,
790 .p_class = P_GLOBAL,
791 .offset = GLOBAL_VAR(bEnablePrivileges),
792 .special = NULL,
793 .enum_list = NULL,
794 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
798 .label = "pam password change",
799 .type = P_BOOL,
800 .p_class = P_GLOBAL,
801 .offset = GLOBAL_VAR(bPamPasswordChange),
802 .special = NULL,
803 .enum_list = NULL,
804 .flags = FLAG_ADVANCED,
807 .label = "passwd program",
808 .type = P_STRING,
809 .p_class = P_GLOBAL,
810 .offset = GLOBAL_VAR(szPasswdProgram),
811 .special = NULL,
812 .enum_list = NULL,
813 .flags = FLAG_ADVANCED,
816 .label = "passwd chat",
817 .type = P_STRING,
818 .p_class = P_GLOBAL,
819 .offset = GLOBAL_VAR(szPasswdChat),
820 .special = NULL,
821 .enum_list = NULL,
822 .flags = FLAG_ADVANCED,
825 .label = "passwd chat debug",
826 .type = P_BOOL,
827 .p_class = P_GLOBAL,
828 .offset = GLOBAL_VAR(bPasswdChatDebug),
829 .special = NULL,
830 .enum_list = NULL,
831 .flags = FLAG_ADVANCED,
834 .label = "passwd chat timeout",
835 .type = P_INTEGER,
836 .p_class = P_GLOBAL,
837 .offset = GLOBAL_VAR(iPasswdChatTimeout),
838 .special = NULL,
839 .enum_list = NULL,
840 .flags = FLAG_ADVANCED,
843 .label = "check password script",
844 .type = P_STRING,
845 .p_class = P_GLOBAL,
846 .offset = GLOBAL_VAR(szCheckPasswordScript),
847 .special = NULL,
848 .enum_list = NULL,
849 .flags = FLAG_ADVANCED,
852 .label = "username map",
853 .type = P_STRING,
854 .p_class = P_GLOBAL,
855 .offset = GLOBAL_VAR(szUsernameMap),
856 .special = NULL,
857 .enum_list = NULL,
858 .flags = FLAG_ADVANCED,
861 .label = "password level",
862 .type = P_INTEGER,
863 .p_class = P_GLOBAL,
864 .offset = GLOBAL_VAR(pwordlevel),
865 .special = NULL,
866 .enum_list = NULL,
867 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
870 .label = "username level",
871 .type = P_INTEGER,
872 .p_class = P_GLOBAL,
873 .offset = GLOBAL_VAR(unamelevel),
874 .special = NULL,
875 .enum_list = NULL,
876 .flags = FLAG_ADVANCED,
879 .label = "unix password sync",
880 .type = P_BOOL,
881 .p_class = P_GLOBAL,
882 .offset = GLOBAL_VAR(bUnixPasswdSync),
883 .special = NULL,
884 .enum_list = NULL,
885 .flags = FLAG_ADVANCED,
888 .label = "restrict anonymous",
889 .type = P_INTEGER,
890 .p_class = P_GLOBAL,
891 .offset = GLOBAL_VAR(restrict_anonymous),
892 .special = NULL,
893 .enum_list = NULL,
894 .flags = FLAG_ADVANCED,
897 .label = "lanman auth",
898 .type = P_BOOL,
899 .p_class = P_GLOBAL,
900 .offset = GLOBAL_VAR(bLanmanAuth),
901 .special = NULL,
902 .enum_list = NULL,
903 .flags = FLAG_ADVANCED,
906 .label = "ntlm auth",
907 .type = P_BOOL,
908 .p_class = P_GLOBAL,
909 .offset = GLOBAL_VAR(bNTLMAuth),
910 .special = NULL,
911 .enum_list = NULL,
912 .flags = FLAG_ADVANCED,
915 .label = "client NTLMv2 auth",
916 .type = P_BOOL,
917 .p_class = P_GLOBAL,
918 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
919 .special = NULL,
920 .enum_list = NULL,
921 .flags = FLAG_ADVANCED,
924 .label = "client lanman auth",
925 .type = P_BOOL,
926 .p_class = P_GLOBAL,
927 .offset = GLOBAL_VAR(bClientLanManAuth),
928 .special = NULL,
929 .enum_list = NULL,
930 .flags = FLAG_ADVANCED,
933 .label = "client plaintext auth",
934 .type = P_BOOL,
935 .p_class = P_GLOBAL,
936 .offset = GLOBAL_VAR(bClientPlaintextAuth),
937 .special = NULL,
938 .enum_list = NULL,
939 .flags = FLAG_ADVANCED,
942 .label = "client use spnego principal",
943 .type = P_BOOL,
944 .p_class = P_GLOBAL,
945 .offset = GLOBAL_VAR(client_use_spnego_principal),
946 .special = NULL,
947 .enum_list = NULL,
948 .flags = FLAG_ADVANCED,
951 .label = "username",
952 .type = P_STRING,
953 .p_class = P_LOCAL,
954 .offset = LOCAL_VAR(szUsername),
955 .special = NULL,
956 .enum_list = NULL,
957 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
960 .label = "user",
961 .type = P_STRING,
962 .p_class = P_LOCAL,
963 .offset = LOCAL_VAR(szUsername),
964 .special = NULL,
965 .enum_list = NULL,
966 .flags = FLAG_HIDE,
969 .label = "users",
970 .type = P_STRING,
971 .p_class = P_LOCAL,
972 .offset = LOCAL_VAR(szUsername),
973 .special = NULL,
974 .enum_list = NULL,
975 .flags = FLAG_HIDE,
978 .label = "invalid users",
979 .type = P_LIST,
980 .p_class = P_LOCAL,
981 .offset = LOCAL_VAR(szInvalidUsers),
982 .special = NULL,
983 .enum_list = NULL,
984 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
987 .label = "valid users",
988 .type = P_LIST,
989 .p_class = P_LOCAL,
990 .offset = LOCAL_VAR(szValidUsers),
991 .special = NULL,
992 .enum_list = NULL,
993 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
996 .label = "admin users",
997 .type = P_LIST,
998 .p_class = P_LOCAL,
999 .offset = LOCAL_VAR(szAdminUsers),
1000 .special = NULL,
1001 .enum_list = NULL,
1002 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1005 .label = "read list",
1006 .type = P_LIST,
1007 .p_class = P_LOCAL,
1008 .offset = LOCAL_VAR(readlist),
1009 .special = NULL,
1010 .enum_list = NULL,
1011 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1014 .label = "write list",
1015 .type = P_LIST,
1016 .p_class = P_LOCAL,
1017 .offset = LOCAL_VAR(writelist),
1018 .special = NULL,
1019 .enum_list = NULL,
1020 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1023 .label = "force user",
1024 .type = P_STRING,
1025 .p_class = P_LOCAL,
1026 .offset = LOCAL_VAR(force_user),
1027 .special = NULL,
1028 .enum_list = NULL,
1029 .flags = FLAG_ADVANCED | FLAG_SHARE,
1032 .label = "force group",
1033 .type = P_STRING,
1034 .p_class = P_LOCAL,
1035 .offset = LOCAL_VAR(force_group),
1036 .special = NULL,
1037 .enum_list = NULL,
1038 .flags = FLAG_ADVANCED | FLAG_SHARE,
1041 .label = "group",
1042 .type = P_STRING,
1043 .p_class = P_LOCAL,
1044 .offset = LOCAL_VAR(force_group),
1045 .special = NULL,
1046 .enum_list = NULL,
1047 .flags = FLAG_ADVANCED,
1050 .label = "read only",
1051 .type = P_BOOL,
1052 .p_class = P_LOCAL,
1053 .offset = LOCAL_VAR(bRead_only),
1054 .special = NULL,
1055 .enum_list = NULL,
1056 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1059 .label = "write ok",
1060 .type = P_BOOLREV,
1061 .p_class = P_LOCAL,
1062 .offset = LOCAL_VAR(bRead_only),
1063 .special = NULL,
1064 .enum_list = NULL,
1065 .flags = FLAG_HIDE,
1068 .label = "writeable",
1069 .type = P_BOOLREV,
1070 .p_class = P_LOCAL,
1071 .offset = LOCAL_VAR(bRead_only),
1072 .special = NULL,
1073 .enum_list = NULL,
1074 .flags = FLAG_HIDE,
1077 .label = "writable",
1078 .type = P_BOOLREV,
1079 .p_class = P_LOCAL,
1080 .offset = LOCAL_VAR(bRead_only),
1081 .special = NULL,
1082 .enum_list = NULL,
1083 .flags = FLAG_HIDE,
1086 .label = "acl check permissions",
1087 .type = P_BOOL,
1088 .p_class = P_LOCAL,
1089 .offset = LOCAL_VAR(bAclCheckPermissions),
1090 .special = NULL,
1091 .enum_list = NULL,
1092 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1095 .label = "acl group control",
1096 .type = P_BOOL,
1097 .p_class = P_LOCAL,
1098 .offset = LOCAL_VAR(bAclGroupControl),
1099 .special = NULL,
1100 .enum_list = NULL,
1101 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1104 .label = "acl map full control",
1105 .type = P_BOOL,
1106 .p_class = P_LOCAL,
1107 .offset = LOCAL_VAR(bAclMapFullControl),
1108 .special = NULL,
1109 .enum_list = NULL,
1110 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1113 .label = "create mask",
1114 .type = P_OCTAL,
1115 .p_class = P_LOCAL,
1116 .offset = LOCAL_VAR(iCreate_mask),
1117 .special = NULL,
1118 .enum_list = NULL,
1119 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1122 .label = "create mode",
1123 .type = P_OCTAL,
1124 .p_class = P_LOCAL,
1125 .offset = LOCAL_VAR(iCreate_mask),
1126 .special = NULL,
1127 .enum_list = NULL,
1128 .flags = FLAG_HIDE,
1131 .label = "force create mode",
1132 .type = P_OCTAL,
1133 .p_class = P_LOCAL,
1134 .offset = LOCAL_VAR(iCreate_force_mode),
1135 .special = NULL,
1136 .enum_list = NULL,
1137 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1140 .label = "security mask",
1141 .type = P_OCTAL,
1142 .p_class = P_LOCAL,
1143 .offset = LOCAL_VAR(iSecurity_mask),
1144 .special = NULL,
1145 .enum_list = NULL,
1146 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1149 .label = "force security mode",
1150 .type = P_OCTAL,
1151 .p_class = P_LOCAL,
1152 .offset = LOCAL_VAR(iSecurity_force_mode),
1153 .special = NULL,
1154 .enum_list = NULL,
1155 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1158 .label = "directory mask",
1159 .type = P_OCTAL,
1160 .p_class = P_LOCAL,
1161 .offset = LOCAL_VAR(iDir_mask),
1162 .special = NULL,
1163 .enum_list = NULL,
1164 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1167 .label = "directory mode",
1168 .type = P_OCTAL,
1169 .p_class = P_LOCAL,
1170 .offset = LOCAL_VAR(iDir_mask),
1171 .special = NULL,
1172 .enum_list = NULL,
1173 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1176 .label = "force directory mode",
1177 .type = P_OCTAL,
1178 .p_class = P_LOCAL,
1179 .offset = LOCAL_VAR(iDir_force_mode),
1180 .special = NULL,
1181 .enum_list = NULL,
1182 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1185 .label = "directory security mask",
1186 .type = P_OCTAL,
1187 .p_class = P_LOCAL,
1188 .offset = LOCAL_VAR(iDir_Security_mask),
1189 .special = NULL,
1190 .enum_list = NULL,
1191 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1194 .label = "force directory security mode",
1195 .type = P_OCTAL,
1196 .p_class = P_LOCAL,
1197 .offset = LOCAL_VAR(iDir_Security_force_mode),
1198 .special = NULL,
1199 .enum_list = NULL,
1200 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1203 .label = "force unknown acl user",
1204 .type = P_BOOL,
1205 .p_class = P_LOCAL,
1206 .offset = LOCAL_VAR(bForceUnknownAclUser),
1207 .special = NULL,
1208 .enum_list = NULL,
1209 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1212 .label = "inherit permissions",
1213 .type = P_BOOL,
1214 .p_class = P_LOCAL,
1215 .offset = LOCAL_VAR(bInheritPerms),
1216 .special = NULL,
1217 .enum_list = NULL,
1218 .flags = FLAG_ADVANCED | FLAG_SHARE,
1221 .label = "inherit acls",
1222 .type = P_BOOL,
1223 .p_class = P_LOCAL,
1224 .offset = LOCAL_VAR(bInheritACLS),
1225 .special = NULL,
1226 .enum_list = NULL,
1227 .flags = FLAG_ADVANCED | FLAG_SHARE,
1230 .label = "inherit owner",
1231 .type = P_BOOL,
1232 .p_class = P_LOCAL,
1233 .offset = LOCAL_VAR(bInheritOwner),
1234 .special = NULL,
1235 .enum_list = NULL,
1236 .flags = FLAG_ADVANCED | FLAG_SHARE,
1239 .label = "guest only",
1240 .type = P_BOOL,
1241 .p_class = P_LOCAL,
1242 .offset = LOCAL_VAR(bGuest_only),
1243 .special = NULL,
1244 .enum_list = NULL,
1245 .flags = FLAG_ADVANCED | FLAG_SHARE,
1248 .label = "only guest",
1249 .type = P_BOOL,
1250 .p_class = P_LOCAL,
1251 .offset = LOCAL_VAR(bGuest_only),
1252 .special = NULL,
1253 .enum_list = NULL,
1254 .flags = FLAG_HIDE,
1257 .label = "administrative share",
1258 .type = P_BOOL,
1259 .p_class = P_LOCAL,
1260 .offset = LOCAL_VAR(bAdministrative_share),
1261 .special = NULL,
1262 .enum_list = NULL,
1263 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1267 .label = "guest ok",
1268 .type = P_BOOL,
1269 .p_class = P_LOCAL,
1270 .offset = LOCAL_VAR(bGuest_ok),
1271 .special = NULL,
1272 .enum_list = NULL,
1273 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1276 .label = "public",
1277 .type = P_BOOL,
1278 .p_class = P_LOCAL,
1279 .offset = LOCAL_VAR(bGuest_ok),
1280 .special = NULL,
1281 .enum_list = NULL,
1282 .flags = FLAG_HIDE,
1285 .label = "only user",
1286 .type = P_BOOL,
1287 .p_class = P_LOCAL,
1288 .offset = LOCAL_VAR(bOnlyUser),
1289 .special = NULL,
1290 .enum_list = NULL,
1291 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1294 .label = "hosts allow",
1295 .type = P_LIST,
1296 .p_class = P_LOCAL,
1297 .offset = LOCAL_VAR(szHostsallow),
1298 .special = NULL,
1299 .enum_list = NULL,
1300 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1303 .label = "allow hosts",
1304 .type = P_LIST,
1305 .p_class = P_LOCAL,
1306 .offset = LOCAL_VAR(szHostsallow),
1307 .special = NULL,
1308 .enum_list = NULL,
1309 .flags = FLAG_HIDE,
1312 .label = "hosts deny",
1313 .type = P_LIST,
1314 .p_class = P_LOCAL,
1315 .offset = LOCAL_VAR(szHostsdeny),
1316 .special = NULL,
1317 .enum_list = NULL,
1318 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1321 .label = "deny hosts",
1322 .type = P_LIST,
1323 .p_class = P_LOCAL,
1324 .offset = LOCAL_VAR(szHostsdeny),
1325 .special = NULL,
1326 .enum_list = NULL,
1327 .flags = FLAG_HIDE,
1330 .label = "preload modules",
1331 .type = P_LIST,
1332 .p_class = P_GLOBAL,
1333 .offset = GLOBAL_VAR(szPreloadModules),
1334 .special = NULL,
1335 .enum_list = NULL,
1336 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1339 .label = "dedicated keytab file",
1340 .type = P_STRING,
1341 .p_class = P_GLOBAL,
1342 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1343 .special = NULL,
1344 .enum_list = NULL,
1345 .flags = FLAG_ADVANCED,
1348 .label = "kerberos method",
1349 .type = P_ENUM,
1350 .p_class = P_GLOBAL,
1351 .offset = GLOBAL_VAR(iKerberosMethod),
1352 .special = NULL,
1353 .enum_list = enum_kerberos_method,
1354 .flags = FLAG_ADVANCED,
1357 .label = "map untrusted to domain",
1358 .type = P_BOOL,
1359 .p_class = P_GLOBAL,
1360 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1361 .special = NULL,
1362 .enum_list = NULL,
1363 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1367 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1370 .label = "log level",
1371 .type = P_STRING,
1372 .p_class = P_GLOBAL,
1373 .offset = GLOBAL_VAR(szLogLevel),
1374 .special = handle_debug_list,
1375 .enum_list = NULL,
1376 .flags = FLAG_ADVANCED,
1379 .label = "debuglevel",
1380 .type = P_STRING,
1381 .p_class = P_GLOBAL,
1382 .offset = GLOBAL_VAR(szLogLevel),
1383 .special = handle_debug_list,
1384 .enum_list = NULL,
1385 .flags = FLAG_HIDE,
1388 .label = "syslog",
1389 .type = P_INTEGER,
1390 .p_class = P_GLOBAL,
1391 .offset = GLOBAL_VAR(syslog),
1392 .special = NULL,
1393 .enum_list = NULL,
1394 .flags = FLAG_ADVANCED,
1397 .label = "syslog only",
1398 .type = P_BOOL,
1399 .p_class = P_GLOBAL,
1400 .offset = GLOBAL_VAR(bSyslogOnly),
1401 .special = NULL,
1402 .enum_list = NULL,
1403 .flags = FLAG_ADVANCED,
1406 .label = "log file",
1407 .type = P_STRING,
1408 .p_class = P_GLOBAL,
1409 .offset = GLOBAL_VAR(logfile),
1410 .special = NULL,
1411 .enum_list = NULL,
1412 .flags = FLAG_ADVANCED,
1415 .label = "max log size",
1416 .type = P_BYTES,
1417 .p_class = P_GLOBAL,
1418 .offset = GLOBAL_VAR(max_log_size),
1419 .special = NULL,
1420 .enum_list = NULL,
1421 .flags = FLAG_ADVANCED,
1424 .label = "debug timestamp",
1425 .type = P_BOOL,
1426 .p_class = P_GLOBAL,
1427 .offset = GLOBAL_VAR(bTimestampLogs),
1428 .special = NULL,
1429 .enum_list = NULL,
1430 .flags = FLAG_ADVANCED,
1433 .label = "timestamp logs",
1434 .type = P_BOOL,
1435 .p_class = P_GLOBAL,
1436 .offset = GLOBAL_VAR(bTimestampLogs),
1437 .special = NULL,
1438 .enum_list = NULL,
1439 .flags = FLAG_ADVANCED,
1442 .label = "debug prefix timestamp",
1443 .type = P_BOOL,
1444 .p_class = P_GLOBAL,
1445 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1446 .special = NULL,
1447 .enum_list = NULL,
1448 .flags = FLAG_ADVANCED,
1451 .label = "debug hires timestamp",
1452 .type = P_BOOL,
1453 .p_class = P_GLOBAL,
1454 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1455 .special = NULL,
1456 .enum_list = NULL,
1457 .flags = FLAG_ADVANCED,
1460 .label = "debug pid",
1461 .type = P_BOOL,
1462 .p_class = P_GLOBAL,
1463 .offset = GLOBAL_VAR(bDebugPid),
1464 .special = NULL,
1465 .enum_list = NULL,
1466 .flags = FLAG_ADVANCED,
1469 .label = "debug uid",
1470 .type = P_BOOL,
1471 .p_class = P_GLOBAL,
1472 .offset = GLOBAL_VAR(bDebugUid),
1473 .special = NULL,
1474 .enum_list = NULL,
1475 .flags = FLAG_ADVANCED,
1478 .label = "debug class",
1479 .type = P_BOOL,
1480 .p_class = P_GLOBAL,
1481 .offset = GLOBAL_VAR(bDebugClass),
1482 .special = NULL,
1483 .enum_list = NULL,
1484 .flags = FLAG_ADVANCED,
1487 .label = "enable core files",
1488 .type = P_BOOL,
1489 .p_class = P_GLOBAL,
1490 .offset = GLOBAL_VAR(bEnableCoreFiles),
1491 .special = NULL,
1492 .enum_list = NULL,
1493 .flags = FLAG_ADVANCED,
1496 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1499 .label = "allocation roundup size",
1500 .type = P_BYTES,
1501 .p_class = P_LOCAL,
1502 .offset = LOCAL_VAR(iallocation_roundup_size),
1503 .special = NULL,
1504 .enum_list = NULL,
1505 .flags = FLAG_ADVANCED,
1508 .label = "aio read size",
1509 .type = P_BYTES,
1510 .p_class = P_LOCAL,
1511 .offset = LOCAL_VAR(iAioReadSize),
1512 .special = NULL,
1513 .enum_list = NULL,
1514 .flags = FLAG_ADVANCED,
1517 .label = "aio write size",
1518 .type = P_BYTES,
1519 .p_class = P_LOCAL,
1520 .offset = LOCAL_VAR(iAioWriteSize),
1521 .special = NULL,
1522 .enum_list = NULL,
1523 .flags = FLAG_ADVANCED,
1526 .label = "aio write behind",
1527 .type = P_STRING,
1528 .p_class = P_LOCAL,
1529 .offset = LOCAL_VAR(szAioWriteBehind),
1530 .special = NULL,
1531 .enum_list = NULL,
1532 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1535 .label = "smb ports",
1536 .type = P_STRING,
1537 .p_class = P_GLOBAL,
1538 .offset = GLOBAL_VAR(smb_ports),
1539 .special = NULL,
1540 .enum_list = NULL,
1541 .flags = FLAG_ADVANCED,
1544 .label = "large readwrite",
1545 .type = P_BOOL,
1546 .p_class = P_GLOBAL,
1547 .offset = GLOBAL_VAR(bLargeReadwrite),
1548 .special = NULL,
1549 .enum_list = NULL,
1550 .flags = FLAG_ADVANCED,
1553 .label = "server max protocol",
1554 .type = P_ENUM,
1555 .p_class = P_GLOBAL,
1556 .offset = GLOBAL_VAR(srv_maxprotocol),
1557 .special = NULL,
1558 .enum_list = enum_protocol,
1559 .flags = FLAG_ADVANCED,
1562 .label = "max protocol",
1563 .type = P_ENUM,
1564 .p_class = P_GLOBAL,
1565 .offset = GLOBAL_VAR(srv_maxprotocol),
1566 .special = NULL,
1567 .enum_list = enum_protocol,
1568 .flags = FLAG_ADVANCED,
1571 .label = "protocol",
1572 .type = P_ENUM,
1573 .p_class = P_GLOBAL,
1574 .offset = GLOBAL_VAR(srv_maxprotocol),
1575 .special = NULL,
1576 .enum_list = enum_protocol,
1577 .flags = FLAG_ADVANCED,
1580 .label = "server min protocol",
1581 .type = P_ENUM,
1582 .p_class = P_GLOBAL,
1583 .offset = GLOBAL_VAR(srv_minprotocol),
1584 .special = NULL,
1585 .enum_list = enum_protocol,
1586 .flags = FLAG_ADVANCED,
1589 .label = "min protocol",
1590 .type = P_ENUM,
1591 .p_class = P_GLOBAL,
1592 .offset = GLOBAL_VAR(srv_minprotocol),
1593 .special = NULL,
1594 .enum_list = enum_protocol,
1595 .flags = FLAG_ADVANCED,
1598 .label = "min receivefile size",
1599 .type = P_BYTES,
1600 .p_class = P_GLOBAL,
1601 .offset = GLOBAL_VAR(iminreceivefile),
1602 .special = NULL,
1603 .enum_list = NULL,
1604 .flags = FLAG_ADVANCED,
1607 .label = "read raw",
1608 .type = P_BOOL,
1609 .p_class = P_GLOBAL,
1610 .offset = GLOBAL_VAR(bReadRaw),
1611 .special = NULL,
1612 .enum_list = NULL,
1613 .flags = FLAG_ADVANCED,
1616 .label = "write raw",
1617 .type = P_BOOL,
1618 .p_class = P_GLOBAL,
1619 .offset = GLOBAL_VAR(bWriteRaw),
1620 .special = NULL,
1621 .enum_list = NULL,
1622 .flags = FLAG_ADVANCED,
1625 .label = "disable netbios",
1626 .type = P_BOOL,
1627 .p_class = P_GLOBAL,
1628 .offset = GLOBAL_VAR(bDisableNetbios),
1629 .special = NULL,
1630 .enum_list = NULL,
1631 .flags = FLAG_ADVANCED,
1634 .label = "reset on zero vc",
1635 .type = P_BOOL,
1636 .p_class = P_GLOBAL,
1637 .offset = GLOBAL_VAR(bResetOnZeroVC),
1638 .special = NULL,
1639 .enum_list = NULL,
1640 .flags = FLAG_ADVANCED,
1643 .label = "log writeable files on exit",
1644 .type = P_BOOL,
1645 .p_class = P_GLOBAL,
1646 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1647 .special = NULL,
1648 .enum_list = NULL,
1649 .flags = FLAG_ADVANCED,
1652 .label = "acl compatibility",
1653 .type = P_ENUM,
1654 .p_class = P_GLOBAL,
1655 .offset = GLOBAL_VAR(iAclCompat),
1656 .special = NULL,
1657 .enum_list = enum_acl_compat_vals,
1658 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1661 .label = "defer sharing violations",
1662 .type = P_BOOL,
1663 .p_class = P_GLOBAL,
1664 .offset = GLOBAL_VAR(bDeferSharingViolations),
1665 .special = NULL,
1666 .enum_list = NULL,
1667 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1670 .label = "ea support",
1671 .type = P_BOOL,
1672 .p_class = P_LOCAL,
1673 .offset = LOCAL_VAR(bEASupport),
1674 .special = NULL,
1675 .enum_list = NULL,
1676 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1679 .label = "nt acl support",
1680 .type = P_BOOL,
1681 .p_class = P_LOCAL,
1682 .offset = LOCAL_VAR(bNTAclSupport),
1683 .special = NULL,
1684 .enum_list = NULL,
1685 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1688 .label = "nt pipe support",
1689 .type = P_BOOL,
1690 .p_class = P_GLOBAL,
1691 .offset = GLOBAL_VAR(bNTPipeSupport),
1692 .special = NULL,
1693 .enum_list = NULL,
1694 .flags = FLAG_ADVANCED,
1697 .label = "nt status support",
1698 .type = P_BOOL,
1699 .p_class = P_GLOBAL,
1700 .offset = GLOBAL_VAR(bNTStatusSupport),
1701 .special = NULL,
1702 .enum_list = NULL,
1703 .flags = FLAG_ADVANCED,
1706 .label = "profile acls",
1707 .type = P_BOOL,
1708 .p_class = P_LOCAL,
1709 .offset = LOCAL_VAR(bProfileAcls),
1710 .special = NULL,
1711 .enum_list = NULL,
1712 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1715 .label = "map acl inherit",
1716 .type = P_BOOL,
1717 .p_class = P_LOCAL,
1718 .offset = LOCAL_VAR(bMap_acl_inherit),
1719 .special = NULL,
1720 .enum_list = NULL,
1721 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1724 .label = "afs share",
1725 .type = P_BOOL,
1726 .p_class = P_LOCAL,
1727 .offset = LOCAL_VAR(bAfs_Share),
1728 .special = NULL,
1729 .enum_list = NULL,
1730 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1733 .label = "max mux",
1734 .type = P_INTEGER,
1735 .p_class = P_GLOBAL,
1736 .offset = GLOBAL_VAR(max_mux),
1737 .special = NULL,
1738 .enum_list = NULL,
1739 .flags = FLAG_ADVANCED,
1742 .label = "max xmit",
1743 .type = P_BYTES,
1744 .p_class = P_GLOBAL,
1745 .offset = GLOBAL_VAR(max_xmit),
1746 .special = NULL,
1747 .enum_list = NULL,
1748 .flags = FLAG_ADVANCED,
1751 .label = "name resolve order",
1752 .type = P_STRING,
1753 .p_class = P_GLOBAL,
1754 .offset = GLOBAL_VAR(szNameResolveOrder),
1755 .special = NULL,
1756 .enum_list = NULL,
1757 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1760 .label = "max ttl",
1761 .type = P_INTEGER,
1762 .p_class = P_GLOBAL,
1763 .offset = GLOBAL_VAR(max_ttl),
1764 .special = NULL,
1765 .enum_list = NULL,
1766 .flags = FLAG_ADVANCED,
1769 .label = "max wins ttl",
1770 .type = P_INTEGER,
1771 .p_class = P_GLOBAL,
1772 .offset = GLOBAL_VAR(max_wins_ttl),
1773 .special = NULL,
1774 .enum_list = NULL,
1775 .flags = FLAG_ADVANCED,
1778 .label = "min wins ttl",
1779 .type = P_INTEGER,
1780 .p_class = P_GLOBAL,
1781 .offset = GLOBAL_VAR(min_wins_ttl),
1782 .special = NULL,
1783 .enum_list = NULL,
1784 .flags = FLAG_ADVANCED,
1787 .label = "time server",
1788 .type = P_BOOL,
1789 .p_class = P_GLOBAL,
1790 .offset = GLOBAL_VAR(bTimeServer),
1791 .special = NULL,
1792 .enum_list = NULL,
1793 .flags = FLAG_ADVANCED,
1796 .label = "unix extensions",
1797 .type = P_BOOL,
1798 .p_class = P_GLOBAL,
1799 .offset = GLOBAL_VAR(bUnixExtensions),
1800 .special = NULL,
1801 .enum_list = NULL,
1802 .flags = FLAG_ADVANCED,
1805 .label = "use spnego",
1806 .type = P_BOOL,
1807 .p_class = P_GLOBAL,
1808 .offset = GLOBAL_VAR(bUseSpnego),
1809 .special = NULL,
1810 .enum_list = NULL,
1811 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1814 .label = "client signing",
1815 .type = P_ENUM,
1816 .p_class = P_GLOBAL,
1817 .offset = GLOBAL_VAR(client_signing),
1818 .special = NULL,
1819 .enum_list = enum_smb_signing_vals,
1820 .flags = FLAG_ADVANCED,
1823 .label = "server signing",
1824 .type = P_ENUM,
1825 .p_class = P_GLOBAL,
1826 .offset = GLOBAL_VAR(server_signing),
1827 .special = NULL,
1828 .enum_list = enum_smb_signing_vals,
1829 .flags = FLAG_ADVANCED,
1832 .label = "smb encrypt",
1833 .type = P_ENUM,
1834 .p_class = P_LOCAL,
1835 .offset = LOCAL_VAR(ismb_encrypt),
1836 .special = NULL,
1837 .enum_list = enum_smb_signing_vals,
1838 .flags = FLAG_ADVANCED,
1841 .label = "client use spnego",
1842 .type = P_BOOL,
1843 .p_class = P_GLOBAL,
1844 .offset = GLOBAL_VAR(bClientUseSpnego),
1845 .special = NULL,
1846 .enum_list = NULL,
1847 .flags = FLAG_ADVANCED,
1850 .label = "client ldap sasl wrapping",
1851 .type = P_ENUM,
1852 .p_class = P_GLOBAL,
1853 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1854 .special = NULL,
1855 .enum_list = enum_ldap_sasl_wrapping,
1856 .flags = FLAG_ADVANCED,
1859 .label = "enable asu support",
1860 .type = P_BOOL,
1861 .p_class = P_GLOBAL,
1862 .offset = GLOBAL_VAR(bASUSupport),
1863 .special = NULL,
1864 .enum_list = NULL,
1865 .flags = FLAG_ADVANCED,
1868 .label = "svcctl list",
1869 .type = P_LIST,
1870 .p_class = P_GLOBAL,
1871 .offset = GLOBAL_VAR(szServicesList),
1872 .special = NULL,
1873 .enum_list = NULL,
1874 .flags = FLAG_ADVANCED,
1877 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1880 .label = "block size",
1881 .type = P_BYTES,
1882 .p_class = P_LOCAL,
1883 .offset = LOCAL_VAR(iBlock_size),
1884 .special = NULL,
1885 .enum_list = NULL,
1886 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1889 .label = "deadtime",
1890 .type = P_INTEGER,
1891 .p_class = P_GLOBAL,
1892 .offset = GLOBAL_VAR(deadtime),
1893 .special = NULL,
1894 .enum_list = NULL,
1895 .flags = FLAG_ADVANCED,
1898 .label = "getwd cache",
1899 .type = P_BOOL,
1900 .p_class = P_GLOBAL,
1901 .offset = GLOBAL_VAR(getwd_cache),
1902 .special = NULL,
1903 .enum_list = NULL,
1904 .flags = FLAG_ADVANCED,
1907 .label = "keepalive",
1908 .type = P_INTEGER,
1909 .p_class = P_GLOBAL,
1910 .offset = GLOBAL_VAR(iKeepalive),
1911 .special = NULL,
1912 .enum_list = NULL,
1913 .flags = FLAG_ADVANCED,
1916 .label = "change notify",
1917 .type = P_BOOL,
1918 .p_class = P_LOCAL,
1919 .offset = LOCAL_VAR(bChangeNotify),
1920 .special = NULL,
1921 .enum_list = NULL,
1922 .flags = FLAG_ADVANCED | FLAG_SHARE,
1925 .label = "directory name cache size",
1926 .type = P_INTEGER,
1927 .p_class = P_LOCAL,
1928 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
1929 .special = NULL,
1930 .enum_list = NULL,
1931 .flags = FLAG_ADVANCED | FLAG_SHARE,
1934 .label = "kernel change notify",
1935 .type = P_BOOL,
1936 .p_class = P_LOCAL,
1937 .offset = LOCAL_VAR(bKernelChangeNotify),
1938 .special = NULL,
1939 .enum_list = NULL,
1940 .flags = FLAG_ADVANCED | FLAG_SHARE,
1943 .label = "lpq cache time",
1944 .type = P_INTEGER,
1945 .p_class = P_GLOBAL,
1946 .offset = GLOBAL_VAR(lpqcachetime),
1947 .special = NULL,
1948 .enum_list = NULL,
1949 .flags = FLAG_ADVANCED,
1952 .label = "max smbd processes",
1953 .type = P_INTEGER,
1954 .p_class = P_GLOBAL,
1955 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
1956 .special = NULL,
1957 .enum_list = NULL,
1958 .flags = FLAG_ADVANCED,
1961 .label = "max connections",
1962 .type = P_INTEGER,
1963 .p_class = P_LOCAL,
1964 .offset = LOCAL_VAR(iMaxConnections),
1965 .special = NULL,
1966 .enum_list = NULL,
1967 .flags = FLAG_ADVANCED | FLAG_SHARE,
1970 .label = "paranoid server security",
1971 .type = P_BOOL,
1972 .p_class = P_GLOBAL,
1973 .offset = GLOBAL_VAR(paranoid_server_security),
1974 .special = NULL,
1975 .enum_list = NULL,
1976 .flags = FLAG_ADVANCED,
1979 .label = "max disk size",
1980 .type = P_BYTES,
1981 .p_class = P_GLOBAL,
1982 .offset = GLOBAL_VAR(maxdisksize),
1983 .special = NULL,
1984 .enum_list = NULL,
1985 .flags = FLAG_ADVANCED,
1988 .label = "max open files",
1989 .type = P_INTEGER,
1990 .p_class = P_GLOBAL,
1991 .offset = GLOBAL_VAR(max_open_files),
1992 .special = NULL,
1993 .enum_list = NULL,
1994 .flags = FLAG_ADVANCED,
1997 .label = "min print space",
1998 .type = P_INTEGER,
1999 .p_class = P_LOCAL,
2000 .offset = LOCAL_VAR(iMinPrintSpace),
2001 .special = NULL,
2002 .enum_list = NULL,
2003 .flags = FLAG_ADVANCED | FLAG_PRINT,
2006 .label = "socket options",
2007 .type = P_STRING,
2008 .p_class = P_GLOBAL,
2009 .offset = GLOBAL_VAR(socket_options),
2010 .special = NULL,
2011 .enum_list = NULL,
2012 .flags = FLAG_ADVANCED,
2015 .label = "strict allocate",
2016 .type = P_BOOL,
2017 .p_class = P_LOCAL,
2018 .offset = LOCAL_VAR(bStrictAllocate),
2019 .special = NULL,
2020 .enum_list = NULL,
2021 .flags = FLAG_ADVANCED | FLAG_SHARE,
2024 .label = "strict sync",
2025 .type = P_BOOL,
2026 .p_class = P_LOCAL,
2027 .offset = LOCAL_VAR(bStrictSync),
2028 .special = NULL,
2029 .enum_list = NULL,
2030 .flags = FLAG_ADVANCED | FLAG_SHARE,
2033 .label = "sync always",
2034 .type = P_BOOL,
2035 .p_class = P_LOCAL,
2036 .offset = LOCAL_VAR(bSyncAlways),
2037 .special = NULL,
2038 .enum_list = NULL,
2039 .flags = FLAG_ADVANCED | FLAG_SHARE,
2042 .label = "use mmap",
2043 .type = P_BOOL,
2044 .p_class = P_GLOBAL,
2045 .offset = GLOBAL_VAR(bUseMmap),
2046 .special = NULL,
2047 .enum_list = NULL,
2048 .flags = FLAG_ADVANCED,
2051 .label = "use sendfile",
2052 .type = P_BOOL,
2053 .p_class = P_LOCAL,
2054 .offset = LOCAL_VAR(bUseSendfile),
2055 .special = NULL,
2056 .enum_list = NULL,
2057 .flags = FLAG_ADVANCED | FLAG_SHARE,
2060 .label = "hostname lookups",
2061 .type = P_BOOL,
2062 .p_class = P_GLOBAL,
2063 .offset = GLOBAL_VAR(bHostnameLookups),
2064 .special = NULL,
2065 .enum_list = NULL,
2066 .flags = FLAG_ADVANCED,
2069 .label = "write cache size",
2070 .type = P_BYTES,
2071 .p_class = P_LOCAL,
2072 .offset = LOCAL_VAR(iWriteCacheSize),
2073 .special = NULL,
2074 .enum_list = NULL,
2075 .flags = FLAG_ADVANCED | FLAG_SHARE,
2078 .label = "name cache timeout",
2079 .type = P_INTEGER,
2080 .p_class = P_GLOBAL,
2081 .offset = GLOBAL_VAR(name_cache_timeout),
2082 .special = NULL,
2083 .enum_list = NULL,
2084 .flags = FLAG_ADVANCED,
2087 .label = "ctdbd socket",
2088 .type = P_STRING,
2089 .p_class = P_GLOBAL,
2090 .offset = GLOBAL_VAR(ctdbdSocket),
2091 .special = NULL,
2092 .enum_list = NULL,
2093 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2096 .label = "cluster addresses",
2097 .type = P_LIST,
2098 .p_class = P_GLOBAL,
2099 .offset = GLOBAL_VAR(szClusterAddresses),
2100 .special = NULL,
2101 .enum_list = NULL,
2102 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2105 .label = "clustering",
2106 .type = P_BOOL,
2107 .p_class = P_GLOBAL,
2108 .offset = GLOBAL_VAR(clustering),
2109 .special = NULL,
2110 .enum_list = NULL,
2111 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2114 .label = "ctdb timeout",
2115 .type = P_INTEGER,
2116 .p_class = P_GLOBAL,
2117 .offset = GLOBAL_VAR(ctdb_timeout),
2118 .special = NULL,
2119 .enum_list = NULL,
2120 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2123 .label = "ctdb locktime warn threshold",
2124 .type = P_INTEGER,
2125 .p_class = P_GLOBAL,
2126 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2127 .special = NULL,
2128 .enum_list = NULL,
2129 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2132 .label = "smb2 max read",
2133 .type = P_BYTES,
2134 .p_class = P_GLOBAL,
2135 .offset = GLOBAL_VAR(ismb2_max_read),
2136 .special = NULL,
2137 .enum_list = NULL,
2138 .flags = FLAG_ADVANCED,
2141 .label = "smb2 max write",
2142 .type = P_BYTES,
2143 .p_class = P_GLOBAL,
2144 .offset = GLOBAL_VAR(ismb2_max_write),
2145 .special = NULL,
2146 .enum_list = NULL,
2147 .flags = FLAG_ADVANCED,
2150 .label = "smb2 max trans",
2151 .type = P_BYTES,
2152 .p_class = P_GLOBAL,
2153 .offset = GLOBAL_VAR(ismb2_max_trans),
2154 .special = NULL,
2155 .enum_list = NULL,
2156 .flags = FLAG_ADVANCED,
2159 .label = "smb2 max credits",
2160 .type = P_INTEGER,
2161 .p_class = P_GLOBAL,
2162 .offset = GLOBAL_VAR(ismb2_max_credits),
2163 .special = NULL,
2164 .enum_list = NULL,
2165 .flags = FLAG_ADVANCED,
2168 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2171 .label = "max reported print jobs",
2172 .type = P_INTEGER,
2173 .p_class = P_LOCAL,
2174 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2175 .special = NULL,
2176 .enum_list = NULL,
2177 .flags = FLAG_ADVANCED | FLAG_PRINT,
2180 .label = "max print jobs",
2181 .type = P_INTEGER,
2182 .p_class = P_LOCAL,
2183 .offset = LOCAL_VAR(iMaxPrintJobs),
2184 .special = NULL,
2185 .enum_list = NULL,
2186 .flags = FLAG_ADVANCED | FLAG_PRINT,
2189 .label = "load printers",
2190 .type = P_BOOL,
2191 .p_class = P_GLOBAL,
2192 .offset = GLOBAL_VAR(bLoadPrinters),
2193 .special = NULL,
2194 .enum_list = NULL,
2195 .flags = FLAG_ADVANCED | FLAG_PRINT,
2198 .label = "printcap cache time",
2199 .type = P_INTEGER,
2200 .p_class = P_GLOBAL,
2201 .offset = GLOBAL_VAR(PrintcapCacheTime),
2202 .special = NULL,
2203 .enum_list = NULL,
2204 .flags = FLAG_ADVANCED | FLAG_PRINT,
2207 .label = "printcap name",
2208 .type = P_STRING,
2209 .p_class = P_GLOBAL,
2210 .offset = GLOBAL_VAR(szPrintcapname),
2211 .special = NULL,
2212 .enum_list = NULL,
2213 .flags = FLAG_ADVANCED | FLAG_PRINT,
2216 .label = "printcap",
2217 .type = P_STRING,
2218 .p_class = P_GLOBAL,
2219 .offset = GLOBAL_VAR(szPrintcapname),
2220 .special = NULL,
2221 .enum_list = NULL,
2222 .flags = FLAG_HIDE,
2225 .label = "printable",
2226 .type = P_BOOL,
2227 .p_class = P_LOCAL,
2228 .offset = LOCAL_VAR(bPrint_ok),
2229 .special = NULL,
2230 .enum_list = NULL,
2231 .flags = FLAG_ADVANCED | FLAG_PRINT,
2234 .label = "print notify backchannel",
2235 .type = P_BOOL,
2236 .p_class = P_LOCAL,
2237 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2238 .special = NULL,
2239 .enum_list = NULL,
2240 .flags = FLAG_ADVANCED,
2243 .label = "print ok",
2244 .type = P_BOOL,
2245 .p_class = P_LOCAL,
2246 .offset = LOCAL_VAR(bPrint_ok),
2247 .special = NULL,
2248 .enum_list = NULL,
2249 .flags = FLAG_HIDE,
2252 .label = "printing",
2253 .type = P_ENUM,
2254 .p_class = P_LOCAL,
2255 .offset = LOCAL_VAR(iPrinting),
2256 .special = handle_printing,
2257 .enum_list = enum_printing,
2258 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2261 .label = "cups options",
2262 .type = P_STRING,
2263 .p_class = P_LOCAL,
2264 .offset = LOCAL_VAR(szCupsOptions),
2265 .special = NULL,
2266 .enum_list = NULL,
2267 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2270 .label = "cups server",
2271 .type = P_STRING,
2272 .p_class = P_GLOBAL,
2273 .offset = GLOBAL_VAR(szCupsServer),
2274 .special = NULL,
2275 .enum_list = NULL,
2276 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2279 .label = "cups encrypt",
2280 .type = P_ENUM,
2281 .p_class = P_GLOBAL,
2282 .offset = GLOBAL_VAR(CupsEncrypt),
2283 .special = NULL,
2284 .enum_list = enum_bool_auto,
2285 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2289 .label = "cups connection timeout",
2290 .type = P_INTEGER,
2291 .p_class = P_GLOBAL,
2292 .offset = GLOBAL_VAR(cups_connection_timeout),
2293 .special = NULL,
2294 .enum_list = NULL,
2295 .flags = FLAG_ADVANCED,
2298 .label = "iprint server",
2299 .type = P_STRING,
2300 .p_class = P_GLOBAL,
2301 .offset = GLOBAL_VAR(szIPrintServer),
2302 .special = NULL,
2303 .enum_list = NULL,
2304 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2307 .label = "print command",
2308 .type = P_STRING,
2309 .p_class = P_LOCAL,
2310 .offset = LOCAL_VAR(szPrintcommand),
2311 .special = NULL,
2312 .enum_list = NULL,
2313 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2316 .label = "disable spoolss",
2317 .type = P_BOOL,
2318 .p_class = P_GLOBAL,
2319 .offset = GLOBAL_VAR(bDisableSpoolss),
2320 .special = NULL,
2321 .enum_list = NULL,
2322 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2325 .label = "enable spoolss",
2326 .type = P_BOOLREV,
2327 .p_class = P_GLOBAL,
2328 .offset = GLOBAL_VAR(bDisableSpoolss),
2329 .special = NULL,
2330 .enum_list = NULL,
2331 .flags = FLAG_HIDE,
2334 .label = "lpq command",
2335 .type = P_STRING,
2336 .p_class = P_LOCAL,
2337 .offset = LOCAL_VAR(szLpqcommand),
2338 .special = NULL,
2339 .enum_list = NULL,
2340 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2343 .label = "lprm command",
2344 .type = P_STRING,
2345 .p_class = P_LOCAL,
2346 .offset = LOCAL_VAR(szLprmcommand),
2347 .special = NULL,
2348 .enum_list = NULL,
2349 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2352 .label = "lppause command",
2353 .type = P_STRING,
2354 .p_class = P_LOCAL,
2355 .offset = LOCAL_VAR(szLppausecommand),
2356 .special = NULL,
2357 .enum_list = NULL,
2358 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2361 .label = "lpresume command",
2362 .type = P_STRING,
2363 .p_class = P_LOCAL,
2364 .offset = LOCAL_VAR(szLpresumecommand),
2365 .special = NULL,
2366 .enum_list = NULL,
2367 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2370 .label = "queuepause command",
2371 .type = P_STRING,
2372 .p_class = P_LOCAL,
2373 .offset = LOCAL_VAR(szQueuepausecommand),
2374 .special = NULL,
2375 .enum_list = NULL,
2376 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2379 .label = "queueresume command",
2380 .type = P_STRING,
2381 .p_class = P_LOCAL,
2382 .offset = LOCAL_VAR(szQueueresumecommand),
2383 .special = NULL,
2384 .enum_list = NULL,
2385 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2388 .label = "addport command",
2389 .type = P_STRING,
2390 .p_class = P_GLOBAL,
2391 .offset = GLOBAL_VAR(szAddPortCommand),
2392 .special = NULL,
2393 .enum_list = NULL,
2394 .flags = FLAG_ADVANCED,
2397 .label = "enumports command",
2398 .type = P_STRING,
2399 .p_class = P_GLOBAL,
2400 .offset = GLOBAL_VAR(szEnumPortsCommand),
2401 .special = NULL,
2402 .enum_list = NULL,
2403 .flags = FLAG_ADVANCED,
2406 .label = "addprinter command",
2407 .type = P_STRING,
2408 .p_class = P_GLOBAL,
2409 .offset = GLOBAL_VAR(szAddPrinterCommand),
2410 .special = NULL,
2411 .enum_list = NULL,
2412 .flags = FLAG_ADVANCED,
2415 .label = "deleteprinter command",
2416 .type = P_STRING,
2417 .p_class = P_GLOBAL,
2418 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2419 .special = NULL,
2420 .enum_list = NULL,
2421 .flags = FLAG_ADVANCED,
2424 .label = "show add printer wizard",
2425 .type = P_BOOL,
2426 .p_class = P_GLOBAL,
2427 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2428 .special = NULL,
2429 .enum_list = NULL,
2430 .flags = FLAG_ADVANCED,
2433 .label = "os2 driver map",
2434 .type = P_STRING,
2435 .p_class = P_GLOBAL,
2436 .offset = GLOBAL_VAR(szOs2DriverMap),
2437 .special = NULL,
2438 .enum_list = NULL,
2439 .flags = FLAG_ADVANCED,
2443 .label = "printer name",
2444 .type = P_STRING,
2445 .p_class = P_LOCAL,
2446 .offset = LOCAL_VAR(szPrintername),
2447 .special = NULL,
2448 .enum_list = NULL,
2449 .flags = FLAG_ADVANCED | FLAG_PRINT,
2452 .label = "printer",
2453 .type = P_STRING,
2454 .p_class = P_LOCAL,
2455 .offset = LOCAL_VAR(szPrintername),
2456 .special = NULL,
2457 .enum_list = NULL,
2458 .flags = FLAG_HIDE,
2461 .label = "use client driver",
2462 .type = P_BOOL,
2463 .p_class = P_LOCAL,
2464 .offset = LOCAL_VAR(bUseClientDriver),
2465 .special = NULL,
2466 .enum_list = NULL,
2467 .flags = FLAG_ADVANCED | FLAG_PRINT,
2470 .label = "default devmode",
2471 .type = P_BOOL,
2472 .p_class = P_LOCAL,
2473 .offset = LOCAL_VAR(bDefaultDevmode),
2474 .special = NULL,
2475 .enum_list = NULL,
2476 .flags = FLAG_ADVANCED | FLAG_PRINT,
2479 .label = "force printername",
2480 .type = P_BOOL,
2481 .p_class = P_LOCAL,
2482 .offset = LOCAL_VAR(bForcePrintername),
2483 .special = NULL,
2484 .enum_list = NULL,
2485 .flags = FLAG_ADVANCED | FLAG_PRINT,
2488 .label = "printjob username",
2489 .type = P_STRING,
2490 .p_class = P_LOCAL,
2491 .offset = LOCAL_VAR(szPrintjobUsername),
2492 .special = NULL,
2493 .enum_list = NULL,
2494 .flags = FLAG_ADVANCED | FLAG_PRINT,
2497 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2500 .label = "mangling method",
2501 .type = P_STRING,
2502 .p_class = P_GLOBAL,
2503 .offset = GLOBAL_VAR(szManglingMethod),
2504 .special = NULL,
2505 .enum_list = NULL,
2506 .flags = FLAG_ADVANCED,
2509 .label = "mangle prefix",
2510 .type = P_INTEGER,
2511 .p_class = P_GLOBAL,
2512 .offset = GLOBAL_VAR(mangle_prefix),
2513 .special = NULL,
2514 .enum_list = NULL,
2515 .flags = FLAG_ADVANCED,
2519 .label = "default case",
2520 .type = P_ENUM,
2521 .p_class = P_LOCAL,
2522 .offset = LOCAL_VAR(iDefaultCase),
2523 .special = NULL,
2524 .enum_list = enum_case,
2525 .flags = FLAG_ADVANCED | FLAG_SHARE,
2528 .label = "case sensitive",
2529 .type = P_ENUM,
2530 .p_class = P_LOCAL,
2531 .offset = LOCAL_VAR(iCaseSensitive),
2532 .special = NULL,
2533 .enum_list = enum_bool_auto,
2534 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2537 .label = "casesignames",
2538 .type = P_ENUM,
2539 .p_class = P_LOCAL,
2540 .offset = LOCAL_VAR(iCaseSensitive),
2541 .special = NULL,
2542 .enum_list = enum_bool_auto,
2543 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2546 .label = "preserve case",
2547 .type = P_BOOL,
2548 .p_class = P_LOCAL,
2549 .offset = LOCAL_VAR(bCasePreserve),
2550 .special = NULL,
2551 .enum_list = NULL,
2552 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2555 .label = "short preserve case",
2556 .type = P_BOOL,
2557 .p_class = P_LOCAL,
2558 .offset = LOCAL_VAR(bShortCasePreserve),
2559 .special = NULL,
2560 .enum_list = NULL,
2561 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2564 .label = "mangling char",
2565 .type = P_CHAR,
2566 .p_class = P_LOCAL,
2567 .offset = LOCAL_VAR(magic_char),
2568 .special = NULL,
2569 .enum_list = NULL,
2570 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2573 .label = "hide dot files",
2574 .type = P_BOOL,
2575 .p_class = P_LOCAL,
2576 .offset = LOCAL_VAR(bHideDotFiles),
2577 .special = NULL,
2578 .enum_list = NULL,
2579 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2582 .label = "hide special files",
2583 .type = P_BOOL,
2584 .p_class = P_LOCAL,
2585 .offset = LOCAL_VAR(bHideSpecialFiles),
2586 .special = NULL,
2587 .enum_list = NULL,
2588 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2591 .label = "hide unreadable",
2592 .type = P_BOOL,
2593 .p_class = P_LOCAL,
2594 .offset = LOCAL_VAR(bHideUnReadable),
2595 .special = NULL,
2596 .enum_list = NULL,
2597 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2600 .label = "hide unwriteable files",
2601 .type = P_BOOL,
2602 .p_class = P_LOCAL,
2603 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2604 .special = NULL,
2605 .enum_list = NULL,
2606 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2609 .label = "delete veto files",
2610 .type = P_BOOL,
2611 .p_class = P_LOCAL,
2612 .offset = LOCAL_VAR(bDeleteVetoFiles),
2613 .special = NULL,
2614 .enum_list = NULL,
2615 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2618 .label = "veto files",
2619 .type = P_STRING,
2620 .p_class = P_LOCAL,
2621 .offset = LOCAL_VAR(szVetoFiles),
2622 .special = NULL,
2623 .enum_list = NULL,
2624 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2627 .label = "hide files",
2628 .type = P_STRING,
2629 .p_class = P_LOCAL,
2630 .offset = LOCAL_VAR(szHideFiles),
2631 .special = NULL,
2632 .enum_list = NULL,
2633 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2636 .label = "veto oplock files",
2637 .type = P_STRING,
2638 .p_class = P_LOCAL,
2639 .offset = LOCAL_VAR(szVetoOplockFiles),
2640 .special = NULL,
2641 .enum_list = NULL,
2642 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2645 .label = "map archive",
2646 .type = P_BOOL,
2647 .p_class = P_LOCAL,
2648 .offset = LOCAL_VAR(bMap_archive),
2649 .special = NULL,
2650 .enum_list = NULL,
2651 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2654 .label = "map hidden",
2655 .type = P_BOOL,
2656 .p_class = P_LOCAL,
2657 .offset = LOCAL_VAR(bMap_hidden),
2658 .special = NULL,
2659 .enum_list = NULL,
2660 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2663 .label = "map system",
2664 .type = P_BOOL,
2665 .p_class = P_LOCAL,
2666 .offset = LOCAL_VAR(bMap_system),
2667 .special = NULL,
2668 .enum_list = NULL,
2669 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2672 .label = "map readonly",
2673 .type = P_ENUM,
2674 .p_class = P_LOCAL,
2675 .offset = LOCAL_VAR(iMap_readonly),
2676 .special = NULL,
2677 .enum_list = enum_map_readonly,
2678 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2681 .label = "mangled names",
2682 .type = P_BOOL,
2683 .p_class = P_LOCAL,
2684 .offset = LOCAL_VAR(bMangledNames),
2685 .special = NULL,
2686 .enum_list = NULL,
2687 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2690 .label = "max stat cache size",
2691 .type = P_INTEGER,
2692 .p_class = P_GLOBAL,
2693 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2694 .special = NULL,
2695 .enum_list = NULL,
2696 .flags = FLAG_ADVANCED,
2699 .label = "stat cache",
2700 .type = P_BOOL,
2701 .p_class = P_GLOBAL,
2702 .offset = GLOBAL_VAR(bStatCache),
2703 .special = NULL,
2704 .enum_list = NULL,
2705 .flags = FLAG_ADVANCED,
2708 .label = "store dos attributes",
2709 .type = P_BOOL,
2710 .p_class = P_LOCAL,
2711 .offset = LOCAL_VAR(bStoreDosAttributes),
2712 .special = NULL,
2713 .enum_list = NULL,
2714 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2717 .label = "dmapi support",
2718 .type = P_BOOL,
2719 .p_class = P_LOCAL,
2720 .offset = LOCAL_VAR(bDmapiSupport),
2721 .special = NULL,
2722 .enum_list = NULL,
2723 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2727 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2730 .label = "machine password timeout",
2731 .type = P_INTEGER,
2732 .p_class = P_GLOBAL,
2733 .offset = GLOBAL_VAR(machine_password_timeout),
2734 .special = NULL,
2735 .enum_list = NULL,
2736 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2739 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2742 .label = "add user script",
2743 .type = P_STRING,
2744 .p_class = P_GLOBAL,
2745 .offset = GLOBAL_VAR(szAddUserScript),
2746 .special = NULL,
2747 .enum_list = NULL,
2748 .flags = FLAG_ADVANCED,
2751 .label = "rename user script",
2752 .type = P_STRING,
2753 .p_class = P_GLOBAL,
2754 .offset = GLOBAL_VAR(szRenameUserScript),
2755 .special = NULL,
2756 .enum_list = NULL,
2757 .flags = FLAG_ADVANCED,
2760 .label = "delete user script",
2761 .type = P_STRING,
2762 .p_class = P_GLOBAL,
2763 .offset = GLOBAL_VAR(szDelUserScript),
2764 .special = NULL,
2765 .enum_list = NULL,
2766 .flags = FLAG_ADVANCED,
2769 .label = "add group script",
2770 .type = P_STRING,
2771 .p_class = P_GLOBAL,
2772 .offset = GLOBAL_VAR(szAddGroupScript),
2773 .special = NULL,
2774 .enum_list = NULL,
2775 .flags = FLAG_ADVANCED,
2778 .label = "delete group script",
2779 .type = P_STRING,
2780 .p_class = P_GLOBAL,
2781 .offset = GLOBAL_VAR(szDelGroupScript),
2782 .special = NULL,
2783 .enum_list = NULL,
2784 .flags = FLAG_ADVANCED,
2787 .label = "add user to group script",
2788 .type = P_STRING,
2789 .p_class = P_GLOBAL,
2790 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2791 .special = NULL,
2792 .enum_list = NULL,
2793 .flags = FLAG_ADVANCED,
2796 .label = "delete user from group script",
2797 .type = P_STRING,
2798 .p_class = P_GLOBAL,
2799 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2800 .special = NULL,
2801 .enum_list = NULL,
2802 .flags = FLAG_ADVANCED,
2805 .label = "set primary group script",
2806 .type = P_STRING,
2807 .p_class = P_GLOBAL,
2808 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2809 .special = NULL,
2810 .enum_list = NULL,
2811 .flags = FLAG_ADVANCED,
2814 .label = "add machine script",
2815 .type = P_STRING,
2816 .p_class = P_GLOBAL,
2817 .offset = GLOBAL_VAR(szAddMachineScript),
2818 .special = NULL,
2819 .enum_list = NULL,
2820 .flags = FLAG_ADVANCED,
2823 .label = "shutdown script",
2824 .type = P_STRING,
2825 .p_class = P_GLOBAL,
2826 .offset = GLOBAL_VAR(szShutdownScript),
2827 .special = NULL,
2828 .enum_list = NULL,
2829 .flags = FLAG_ADVANCED,
2832 .label = "abort shutdown script",
2833 .type = P_STRING,
2834 .p_class = P_GLOBAL,
2835 .offset = GLOBAL_VAR(szAbortShutdownScript),
2836 .special = NULL,
2837 .enum_list = NULL,
2838 .flags = FLAG_ADVANCED,
2841 .label = "username map script",
2842 .type = P_STRING,
2843 .p_class = P_GLOBAL,
2844 .offset = GLOBAL_VAR(szUsernameMapScript),
2845 .special = NULL,
2846 .enum_list = NULL,
2847 .flags = FLAG_ADVANCED,
2850 .label = "username map cache time",
2851 .type = P_INTEGER,
2852 .p_class = P_GLOBAL,
2853 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2854 .special = NULL,
2855 .enum_list = NULL,
2856 .flags = FLAG_ADVANCED,
2859 .label = "logon script",
2860 .type = P_STRING,
2861 .p_class = P_GLOBAL,
2862 .offset = GLOBAL_VAR(szLogonScript),
2863 .special = NULL,
2864 .enum_list = NULL,
2865 .flags = FLAG_ADVANCED,
2868 .label = "logon path",
2869 .type = P_STRING,
2870 .p_class = P_GLOBAL,
2871 .offset = GLOBAL_VAR(szLogonPath),
2872 .special = NULL,
2873 .enum_list = NULL,
2874 .flags = FLAG_ADVANCED,
2877 .label = "logon drive",
2878 .type = P_STRING,
2879 .p_class = P_GLOBAL,
2880 .offset = GLOBAL_VAR(szLogonDrive),
2881 .special = NULL,
2882 .enum_list = NULL,
2883 .flags = FLAG_ADVANCED,
2886 .label = "logon home",
2887 .type = P_STRING,
2888 .p_class = P_GLOBAL,
2889 .offset = GLOBAL_VAR(szLogonHome),
2890 .special = NULL,
2891 .enum_list = NULL,
2892 .flags = FLAG_ADVANCED,
2895 .label = "domain logons",
2896 .type = P_BOOL,
2897 .p_class = P_GLOBAL,
2898 .offset = GLOBAL_VAR(bDomainLogons),
2899 .special = NULL,
2900 .enum_list = NULL,
2901 .flags = FLAG_ADVANCED,
2905 .label = "init logon delayed hosts",
2906 .type = P_LIST,
2907 .p_class = P_GLOBAL,
2908 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2909 .special = NULL,
2910 .enum_list = NULL,
2911 .flags = FLAG_ADVANCED,
2915 .label = "init logon delay",
2916 .type = P_INTEGER,
2917 .p_class = P_GLOBAL,
2918 .offset = GLOBAL_VAR(InitLogonDelay),
2919 .special = NULL,
2920 .enum_list = NULL,
2921 .flags = FLAG_ADVANCED,
2925 {N_("Browse Options"), P_SEP, P_SEPARATOR},
2928 .label = "os level",
2929 .type = P_INTEGER,
2930 .p_class = P_GLOBAL,
2931 .offset = GLOBAL_VAR(os_level),
2932 .special = NULL,
2933 .enum_list = NULL,
2934 .flags = FLAG_BASIC | FLAG_ADVANCED,
2937 .label = "lm announce",
2938 .type = P_ENUM,
2939 .p_class = P_GLOBAL,
2940 .offset = GLOBAL_VAR(lm_announce),
2941 .special = NULL,
2942 .enum_list = enum_bool_auto,
2943 .flags = FLAG_ADVANCED,
2946 .label = "lm interval",
2947 .type = P_INTEGER,
2948 .p_class = P_GLOBAL,
2949 .offset = GLOBAL_VAR(lm_interval),
2950 .special = NULL,
2951 .enum_list = NULL,
2952 .flags = FLAG_ADVANCED,
2955 .label = "preferred master",
2956 .type = P_ENUM,
2957 .p_class = P_GLOBAL,
2958 .offset = GLOBAL_VAR(iPreferredMaster),
2959 .special = NULL,
2960 .enum_list = enum_bool_auto,
2961 .flags = FLAG_BASIC | FLAG_ADVANCED,
2964 .label = "prefered master",
2965 .type = P_ENUM,
2966 .p_class = P_GLOBAL,
2967 .offset = GLOBAL_VAR(iPreferredMaster),
2968 .special = NULL,
2969 .enum_list = enum_bool_auto,
2970 .flags = FLAG_HIDE,
2973 .label = "local master",
2974 .type = P_BOOL,
2975 .p_class = P_GLOBAL,
2976 .offset = GLOBAL_VAR(bLocalMaster),
2977 .special = NULL,
2978 .enum_list = NULL,
2979 .flags = FLAG_BASIC | FLAG_ADVANCED,
2982 .label = "domain master",
2983 .type = P_ENUM,
2984 .p_class = P_GLOBAL,
2985 .offset = GLOBAL_VAR(iDomainMaster),
2986 .special = NULL,
2987 .enum_list = enum_bool_auto,
2988 .flags = FLAG_BASIC | FLAG_ADVANCED,
2991 .label = "browse list",
2992 .type = P_BOOL,
2993 .p_class = P_GLOBAL,
2994 .offset = GLOBAL_VAR(bBrowseList),
2995 .special = NULL,
2996 .enum_list = NULL,
2997 .flags = FLAG_ADVANCED,
3000 .label = "browseable",
3001 .type = P_BOOL,
3002 .p_class = P_LOCAL,
3003 .offset = LOCAL_VAR(bBrowseable),
3004 .special = NULL,
3005 .enum_list = NULL,
3006 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3009 .label = "browsable",
3010 .type = P_BOOL,
3011 .p_class = P_LOCAL,
3012 .offset = LOCAL_VAR(bBrowseable),
3013 .special = NULL,
3014 .enum_list = NULL,
3015 .flags = FLAG_HIDE,
3018 .label = "access based share enum",
3019 .type = P_BOOL,
3020 .p_class = P_LOCAL,
3021 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3022 .special = NULL,
3023 .enum_list = NULL,
3024 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3027 .label = "enhanced browsing",
3028 .type = P_BOOL,
3029 .p_class = P_GLOBAL,
3030 .offset = GLOBAL_VAR(enhanced_browsing),
3031 .special = NULL,
3032 .enum_list = NULL,
3033 .flags = FLAG_ADVANCED,
3036 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3039 .label = "dns proxy",
3040 .type = P_BOOL,
3041 .p_class = P_GLOBAL,
3042 .offset = GLOBAL_VAR(bWINSdnsProxy),
3043 .special = NULL,
3044 .enum_list = NULL,
3045 .flags = FLAG_ADVANCED,
3048 .label = "wins proxy",
3049 .type = P_BOOL,
3050 .p_class = P_GLOBAL,
3051 .offset = GLOBAL_VAR(bWINSproxy),
3052 .special = NULL,
3053 .enum_list = NULL,
3054 .flags = FLAG_ADVANCED,
3057 .label = "wins server",
3058 .type = P_LIST,
3059 .p_class = P_GLOBAL,
3060 .offset = GLOBAL_VAR(szWINSservers),
3061 .special = NULL,
3062 .enum_list = NULL,
3063 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3066 .label = "wins support",
3067 .type = P_BOOL,
3068 .p_class = P_GLOBAL,
3069 .offset = GLOBAL_VAR(bWINSsupport),
3070 .special = NULL,
3071 .enum_list = NULL,
3072 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3075 .label = "wins hook",
3076 .type = P_STRING,
3077 .p_class = P_GLOBAL,
3078 .offset = GLOBAL_VAR(szWINSHook),
3079 .special = NULL,
3080 .enum_list = NULL,
3081 .flags = FLAG_ADVANCED,
3084 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3087 .label = "blocking locks",
3088 .type = P_BOOL,
3089 .p_class = P_LOCAL,
3090 .offset = LOCAL_VAR(bBlockingLocks),
3091 .special = NULL,
3092 .enum_list = NULL,
3093 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3096 .label = "csc policy",
3097 .type = P_ENUM,
3098 .p_class = P_LOCAL,
3099 .offset = LOCAL_VAR(iCSCPolicy),
3100 .special = NULL,
3101 .enum_list = enum_csc_policy,
3102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3105 .label = "fake oplocks",
3106 .type = P_BOOL,
3107 .p_class = P_LOCAL,
3108 .offset = LOCAL_VAR(bFakeOplocks),
3109 .special = NULL,
3110 .enum_list = NULL,
3111 .flags = FLAG_ADVANCED | FLAG_SHARE,
3114 .label = "kernel oplocks",
3115 .type = P_BOOL,
3116 .p_class = P_LOCAL,
3117 .offset = LOCAL_VAR(bKernelOplocks),
3118 .special = NULL,
3119 .enum_list = NULL,
3120 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3123 .label = "locking",
3124 .type = P_BOOL,
3125 .p_class = P_LOCAL,
3126 .offset = LOCAL_VAR(bLocking),
3127 .special = NULL,
3128 .enum_list = NULL,
3129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3132 .label = "lock spin time",
3133 .type = P_INTEGER,
3134 .p_class = P_GLOBAL,
3135 .offset = GLOBAL_VAR(iLockSpinTime),
3136 .special = NULL,
3137 .enum_list = NULL,
3138 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3141 .label = "oplocks",
3142 .type = P_BOOL,
3143 .p_class = P_LOCAL,
3144 .offset = LOCAL_VAR(bOpLocks),
3145 .special = NULL,
3146 .enum_list = NULL,
3147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3150 .label = "level2 oplocks",
3151 .type = P_BOOL,
3152 .p_class = P_LOCAL,
3153 .offset = LOCAL_VAR(bLevel2OpLocks),
3154 .special = NULL,
3155 .enum_list = NULL,
3156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3159 .label = "oplock break wait time",
3160 .type = P_INTEGER,
3161 .p_class = P_GLOBAL,
3162 .offset = GLOBAL_VAR(oplock_break_wait_time),
3163 .special = NULL,
3164 .enum_list = NULL,
3165 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3168 .label = "oplock contention limit",
3169 .type = P_INTEGER,
3170 .p_class = P_LOCAL,
3171 .offset = LOCAL_VAR(iOplockContentionLimit),
3172 .special = NULL,
3173 .enum_list = NULL,
3174 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3177 .label = "posix locking",
3178 .type = P_BOOL,
3179 .p_class = P_LOCAL,
3180 .offset = LOCAL_VAR(bPosixLocking),
3181 .special = NULL,
3182 .enum_list = NULL,
3183 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3186 .label = "strict locking",
3187 .type = P_ENUM,
3188 .p_class = P_LOCAL,
3189 .offset = LOCAL_VAR(iStrictLocking),
3190 .special = NULL,
3191 .enum_list = enum_bool_auto,
3192 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3195 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3198 .label = "ldap admin dn",
3199 .type = P_STRING,
3200 .p_class = P_GLOBAL,
3201 .offset = GLOBAL_VAR(szLdapAdminDn),
3202 .special = NULL,
3203 .enum_list = NULL,
3204 .flags = FLAG_ADVANCED,
3207 .label = "ldap delete dn",
3208 .type = P_BOOL,
3209 .p_class = P_GLOBAL,
3210 .offset = GLOBAL_VAR(ldap_delete_dn),
3211 .special = NULL,
3212 .enum_list = NULL,
3213 .flags = FLAG_ADVANCED,
3216 .label = "ldap group suffix",
3217 .type = P_STRING,
3218 .p_class = P_GLOBAL,
3219 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3220 .special = NULL,
3221 .enum_list = NULL,
3222 .flags = FLAG_ADVANCED,
3225 .label = "ldap idmap suffix",
3226 .type = P_STRING,
3227 .p_class = P_GLOBAL,
3228 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3229 .special = NULL,
3230 .enum_list = NULL,
3231 .flags = FLAG_ADVANCED,
3234 .label = "ldap machine suffix",
3235 .type = P_STRING,
3236 .p_class = P_GLOBAL,
3237 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3238 .special = NULL,
3239 .enum_list = NULL,
3240 .flags = FLAG_ADVANCED,
3243 .label = "ldap passwd sync",
3244 .type = P_ENUM,
3245 .p_class = P_GLOBAL,
3246 .offset = GLOBAL_VAR(ldap_passwd_sync),
3247 .special = NULL,
3248 .enum_list = enum_ldap_passwd_sync,
3249 .flags = FLAG_ADVANCED,
3252 .label = "ldap password sync",
3253 .type = P_ENUM,
3254 .p_class = P_GLOBAL,
3255 .offset = GLOBAL_VAR(ldap_passwd_sync),
3256 .special = NULL,
3257 .enum_list = enum_ldap_passwd_sync,
3258 .flags = FLAG_HIDE,
3261 .label = "ldap replication sleep",
3262 .type = P_INTEGER,
3263 .p_class = P_GLOBAL,
3264 .offset = GLOBAL_VAR(ldap_replication_sleep),
3265 .special = NULL,
3266 .enum_list = NULL,
3267 .flags = FLAG_ADVANCED,
3270 .label = "ldap suffix",
3271 .type = P_STRING,
3272 .p_class = P_GLOBAL,
3273 .offset = GLOBAL_VAR(szLdapSuffix),
3274 .special = NULL,
3275 .enum_list = NULL,
3276 .flags = FLAG_ADVANCED,
3279 .label = "ldap ssl",
3280 .type = P_ENUM,
3281 .p_class = P_GLOBAL,
3282 .offset = GLOBAL_VAR(ldap_ssl),
3283 .special = NULL,
3284 .enum_list = enum_ldap_ssl,
3285 .flags = FLAG_ADVANCED,
3288 .label = "ldap ssl ads",
3289 .type = P_BOOL,
3290 .p_class = P_GLOBAL,
3291 .offset = GLOBAL_VAR(ldap_ssl_ads),
3292 .special = NULL,
3293 .enum_list = NULL,
3294 .flags = FLAG_ADVANCED,
3297 .label = "ldap deref",
3298 .type = P_ENUM,
3299 .p_class = P_GLOBAL,
3300 .offset = GLOBAL_VAR(ldap_deref),
3301 .special = NULL,
3302 .enum_list = enum_ldap_deref,
3303 .flags = FLAG_ADVANCED,
3306 .label = "ldap follow referral",
3307 .type = P_ENUM,
3308 .p_class = P_GLOBAL,
3309 .offset = GLOBAL_VAR(ldap_follow_referral),
3310 .special = NULL,
3311 .enum_list = enum_bool_auto,
3312 .flags = FLAG_ADVANCED,
3315 .label = "ldap timeout",
3316 .type = P_INTEGER,
3317 .p_class = P_GLOBAL,
3318 .offset = GLOBAL_VAR(ldap_timeout),
3319 .special = NULL,
3320 .enum_list = NULL,
3321 .flags = FLAG_ADVANCED,
3324 .label = "ldap connection timeout",
3325 .type = P_INTEGER,
3326 .p_class = P_GLOBAL,
3327 .offset = GLOBAL_VAR(ldap_connection_timeout),
3328 .special = NULL,
3329 .enum_list = NULL,
3330 .flags = FLAG_ADVANCED,
3333 .label = "ldap page size",
3334 .type = P_INTEGER,
3335 .p_class = P_GLOBAL,
3336 .offset = GLOBAL_VAR(ldap_page_size),
3337 .special = NULL,
3338 .enum_list = NULL,
3339 .flags = FLAG_ADVANCED,
3342 .label = "ldap user suffix",
3343 .type = P_STRING,
3344 .p_class = P_GLOBAL,
3345 .offset = GLOBAL_VAR(szLdapUserSuffix),
3346 .special = NULL,
3347 .enum_list = NULL,
3348 .flags = FLAG_ADVANCED,
3351 .label = "ldap debug level",
3352 .type = P_INTEGER,
3353 .p_class = P_GLOBAL,
3354 .offset = GLOBAL_VAR(ldap_debug_level),
3355 .special = handle_ldap_debug_level,
3356 .enum_list = NULL,
3357 .flags = FLAG_ADVANCED,
3360 .label = "ldap debug threshold",
3361 .type = P_INTEGER,
3362 .p_class = P_GLOBAL,
3363 .offset = GLOBAL_VAR(ldap_debug_threshold),
3364 .special = NULL,
3365 .enum_list = NULL,
3366 .flags = FLAG_ADVANCED,
3369 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3372 .label = "eventlog list",
3373 .type = P_LIST,
3374 .p_class = P_GLOBAL,
3375 .offset = GLOBAL_VAR(szEventLogs),
3376 .special = NULL,
3377 .enum_list = NULL,
3378 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3381 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3384 .label = "add share command",
3385 .type = P_STRING,
3386 .p_class = P_GLOBAL,
3387 .offset = GLOBAL_VAR(szAddShareCommand),
3388 .special = NULL,
3389 .enum_list = NULL,
3390 .flags = FLAG_ADVANCED,
3393 .label = "change share command",
3394 .type = P_STRING,
3395 .p_class = P_GLOBAL,
3396 .offset = GLOBAL_VAR(szChangeShareCommand),
3397 .special = NULL,
3398 .enum_list = NULL,
3399 .flags = FLAG_ADVANCED,
3402 .label = "delete share command",
3403 .type = P_STRING,
3404 .p_class = P_GLOBAL,
3405 .offset = GLOBAL_VAR(szDeleteShareCommand),
3406 .special = NULL,
3407 .enum_list = NULL,
3408 .flags = FLAG_ADVANCED,
3411 .label = "config file",
3412 .type = P_STRING,
3413 .p_class = P_GLOBAL,
3414 .offset = GLOBAL_VAR(szConfigFile),
3415 .special = NULL,
3416 .enum_list = NULL,
3417 .flags = FLAG_HIDE|FLAG_META,
3420 .label = "preload",
3421 .type = P_STRING,
3422 .p_class = P_GLOBAL,
3423 .offset = GLOBAL_VAR(szAutoServices),
3424 .special = NULL,
3425 .enum_list = NULL,
3426 .flags = FLAG_ADVANCED,
3429 .label = "auto services",
3430 .type = P_STRING,
3431 .p_class = P_GLOBAL,
3432 .offset = GLOBAL_VAR(szAutoServices),
3433 .special = NULL,
3434 .enum_list = NULL,
3435 .flags = FLAG_ADVANCED,
3438 .label = "lock directory",
3439 .type = P_STRING,
3440 .p_class = P_GLOBAL,
3441 .offset = GLOBAL_VAR(szLockDir),
3442 .special = NULL,
3443 .enum_list = NULL,
3444 .flags = FLAG_ADVANCED,
3447 .label = "lock dir",
3448 .type = P_STRING,
3449 .p_class = P_GLOBAL,
3450 .offset = GLOBAL_VAR(szLockDir),
3451 .special = NULL,
3452 .enum_list = NULL,
3453 .flags = FLAG_HIDE,
3456 .label = "state directory",
3457 .type = P_STRING,
3458 .p_class = P_GLOBAL,
3459 .offset = GLOBAL_VAR(szStateDir),
3460 .special = NULL,
3461 .enum_list = NULL,
3462 .flags = FLAG_ADVANCED,
3465 .label = "cache directory",
3466 .type = P_STRING,
3467 .p_class = P_GLOBAL,
3468 .offset = GLOBAL_VAR(szCacheDir),
3469 .special = NULL,
3470 .enum_list = NULL,
3471 .flags = FLAG_ADVANCED,
3474 .label = "pid directory",
3475 .type = P_STRING,
3476 .p_class = P_GLOBAL,
3477 .offset = GLOBAL_VAR(szPidDir),
3478 .special = NULL,
3479 .enum_list = NULL,
3480 .flags = FLAG_ADVANCED,
3482 #ifdef WITH_UTMP
3484 .label = "utmp directory",
3485 .type = P_STRING,
3486 .p_class = P_GLOBAL,
3487 .offset = GLOBAL_VAR(szUtmpDir),
3488 .special = NULL,
3489 .enum_list = NULL,
3490 .flags = FLAG_ADVANCED,
3493 .label = "wtmp directory",
3494 .type = P_STRING,
3495 .p_class = P_GLOBAL,
3496 .offset = GLOBAL_VAR(szWtmpDir),
3497 .special = NULL,
3498 .enum_list = NULL,
3499 .flags = FLAG_ADVANCED,
3502 .label = "utmp",
3503 .type = P_BOOL,
3504 .p_class = P_GLOBAL,
3505 .offset = GLOBAL_VAR(bUtmp),
3506 .special = NULL,
3507 .enum_list = NULL,
3508 .flags = FLAG_ADVANCED,
3510 #endif
3512 .label = "default service",
3513 .type = P_STRING,
3514 .p_class = P_GLOBAL,
3515 .offset = GLOBAL_VAR(szDefaultService),
3516 .special = NULL,
3517 .enum_list = NULL,
3518 .flags = FLAG_ADVANCED,
3521 .label = "default",
3522 .type = P_STRING,
3523 .p_class = P_GLOBAL,
3524 .offset = GLOBAL_VAR(szDefaultService),
3525 .special = NULL,
3526 .enum_list = NULL,
3527 .flags = FLAG_ADVANCED,
3530 .label = "message command",
3531 .type = P_STRING,
3532 .p_class = P_GLOBAL,
3533 .offset = GLOBAL_VAR(szMsgCommand),
3534 .special = NULL,
3535 .enum_list = NULL,
3536 .flags = FLAG_ADVANCED,
3539 .label = "dfree cache time",
3540 .type = P_INTEGER,
3541 .p_class = P_LOCAL,
3542 .offset = LOCAL_VAR(iDfreeCacheTime),
3543 .special = NULL,
3544 .enum_list = NULL,
3545 .flags = FLAG_ADVANCED,
3548 .label = "dfree command",
3549 .type = P_STRING,
3550 .p_class = P_LOCAL,
3551 .offset = LOCAL_VAR(szDfree),
3552 .special = NULL,
3553 .enum_list = NULL,
3554 .flags = FLAG_ADVANCED,
3557 .label = "get quota command",
3558 .type = P_STRING,
3559 .p_class = P_GLOBAL,
3560 .offset = GLOBAL_VAR(szGetQuota),
3561 .special = NULL,
3562 .enum_list = NULL,
3563 .flags = FLAG_ADVANCED,
3566 .label = "set quota command",
3567 .type = P_STRING,
3568 .p_class = P_GLOBAL,
3569 .offset = GLOBAL_VAR(szSetQuota),
3570 .special = NULL,
3571 .enum_list = NULL,
3572 .flags = FLAG_ADVANCED,
3575 .label = "remote announce",
3576 .type = P_STRING,
3577 .p_class = P_GLOBAL,
3578 .offset = GLOBAL_VAR(szRemoteAnnounce),
3579 .special = NULL,
3580 .enum_list = NULL,
3581 .flags = FLAG_ADVANCED,
3584 .label = "remote browse sync",
3585 .type = P_STRING,
3586 .p_class = P_GLOBAL,
3587 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3588 .special = NULL,
3589 .enum_list = NULL,
3590 .flags = FLAG_ADVANCED,
3593 .label = "socket address",
3594 .type = P_STRING,
3595 .p_class = P_GLOBAL,
3596 .offset = GLOBAL_VAR(szSocketAddress),
3597 .special = NULL,
3598 .enum_list = NULL,
3599 .flags = FLAG_ADVANCED,
3602 .label = "nmbd bind explicit broadcast",
3603 .type = P_BOOL,
3604 .p_class = P_GLOBAL,
3605 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3606 .special = NULL,
3607 .enum_list = NULL,
3608 .flags = FLAG_ADVANCED,
3611 .label = "homedir map",
3612 .type = P_STRING,
3613 .p_class = P_GLOBAL,
3614 .offset = GLOBAL_VAR(szNISHomeMapName),
3615 .special = NULL,
3616 .enum_list = NULL,
3617 .flags = FLAG_ADVANCED,
3620 .label = "afs username map",
3621 .type = P_STRING,
3622 .p_class = P_GLOBAL,
3623 .offset = GLOBAL_VAR(szAfsUsernameMap),
3624 .special = NULL,
3625 .enum_list = NULL,
3626 .flags = FLAG_ADVANCED,
3629 .label = "afs token lifetime",
3630 .type = P_INTEGER,
3631 .p_class = P_GLOBAL,
3632 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3633 .special = NULL,
3634 .enum_list = NULL,
3635 .flags = FLAG_ADVANCED,
3638 .label = "log nt token command",
3639 .type = P_STRING,
3640 .p_class = P_GLOBAL,
3641 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3642 .special = NULL,
3643 .enum_list = NULL,
3644 .flags = FLAG_ADVANCED,
3647 .label = "NIS homedir",
3648 .type = P_BOOL,
3649 .p_class = P_GLOBAL,
3650 .offset = GLOBAL_VAR(bNISHomeMap),
3651 .special = NULL,
3652 .enum_list = NULL,
3653 .flags = FLAG_ADVANCED,
3656 .label = "-valid",
3657 .type = P_BOOL,
3658 .p_class = P_LOCAL,
3659 .offset = LOCAL_VAR(valid),
3660 .special = NULL,
3661 .enum_list = NULL,
3662 .flags = FLAG_HIDE,
3665 .label = "copy",
3666 .type = P_STRING,
3667 .p_class = P_LOCAL,
3668 .offset = LOCAL_VAR(szCopy),
3669 .special = handle_copy,
3670 .enum_list = NULL,
3671 .flags = FLAG_HIDE,
3674 .label = "include",
3675 .type = P_STRING,
3676 .p_class = P_LOCAL,
3677 .offset = LOCAL_VAR(szInclude),
3678 .special = handle_include,
3679 .enum_list = NULL,
3680 .flags = FLAG_HIDE|FLAG_META,
3683 .label = "preexec",
3684 .type = P_STRING,
3685 .p_class = P_LOCAL,
3686 .offset = LOCAL_VAR(szPreExec),
3687 .special = NULL,
3688 .enum_list = NULL,
3689 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3692 .label = "exec",
3693 .type = P_STRING,
3694 .p_class = P_LOCAL,
3695 .offset = LOCAL_VAR(szPreExec),
3696 .special = NULL,
3697 .enum_list = NULL,
3698 .flags = FLAG_ADVANCED,
3701 .label = "preexec close",
3702 .type = P_BOOL,
3703 .p_class = P_LOCAL,
3704 .offset = LOCAL_VAR(bPreexecClose),
3705 .special = NULL,
3706 .enum_list = NULL,
3707 .flags = FLAG_ADVANCED | FLAG_SHARE,
3710 .label = "postexec",
3711 .type = P_STRING,
3712 .p_class = P_LOCAL,
3713 .offset = LOCAL_VAR(szPostExec),
3714 .special = NULL,
3715 .enum_list = NULL,
3716 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3719 .label = "root preexec",
3720 .type = P_STRING,
3721 .p_class = P_LOCAL,
3722 .offset = LOCAL_VAR(szRootPreExec),
3723 .special = NULL,
3724 .enum_list = NULL,
3725 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3728 .label = "root preexec close",
3729 .type = P_BOOL,
3730 .p_class = P_LOCAL,
3731 .offset = LOCAL_VAR(bRootpreexecClose),
3732 .special = NULL,
3733 .enum_list = NULL,
3734 .flags = FLAG_ADVANCED | FLAG_SHARE,
3737 .label = "root postexec",
3738 .type = P_STRING,
3739 .p_class = P_LOCAL,
3740 .offset = LOCAL_VAR(szRootPostExec),
3741 .special = NULL,
3742 .enum_list = NULL,
3743 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3746 .label = "available",
3747 .type = P_BOOL,
3748 .p_class = P_LOCAL,
3749 .offset = LOCAL_VAR(bAvailable),
3750 .special = NULL,
3751 .enum_list = NULL,
3752 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3755 .label = "registry shares",
3756 .type = P_BOOL,
3757 .p_class = P_GLOBAL,
3758 .offset = GLOBAL_VAR(bRegistryShares),
3759 .special = NULL,
3760 .enum_list = NULL,
3761 .flags = FLAG_ADVANCED,
3764 .label = "usershare allow guests",
3765 .type = P_BOOL,
3766 .p_class = P_GLOBAL,
3767 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3768 .special = NULL,
3769 .enum_list = NULL,
3770 .flags = FLAG_ADVANCED,
3773 .label = "usershare max shares",
3774 .type = P_INTEGER,
3775 .p_class = P_GLOBAL,
3776 .offset = GLOBAL_VAR(iUsershareMaxShares),
3777 .special = NULL,
3778 .enum_list = NULL,
3779 .flags = FLAG_ADVANCED,
3782 .label = "usershare owner only",
3783 .type = P_BOOL,
3784 .p_class = P_GLOBAL,
3785 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3786 .special = NULL,
3787 .enum_list = NULL,
3788 .flags = FLAG_ADVANCED,
3791 .label = "usershare path",
3792 .type = P_STRING,
3793 .p_class = P_GLOBAL,
3794 .offset = GLOBAL_VAR(szUsersharePath),
3795 .special = NULL,
3796 .enum_list = NULL,
3797 .flags = FLAG_ADVANCED,
3800 .label = "usershare prefix allow list",
3801 .type = P_LIST,
3802 .p_class = P_GLOBAL,
3803 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3804 .special = NULL,
3805 .enum_list = NULL,
3806 .flags = FLAG_ADVANCED,
3809 .label = "usershare prefix deny list",
3810 .type = P_LIST,
3811 .p_class = P_GLOBAL,
3812 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3813 .special = NULL,
3814 .enum_list = NULL,
3815 .flags = FLAG_ADVANCED,
3818 .label = "usershare template share",
3819 .type = P_STRING,
3820 .p_class = P_GLOBAL,
3821 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3822 .special = NULL,
3823 .enum_list = NULL,
3824 .flags = FLAG_ADVANCED,
3827 .label = "volume",
3828 .type = P_STRING,
3829 .p_class = P_LOCAL,
3830 .offset = LOCAL_VAR(volume),
3831 .special = NULL,
3832 .enum_list = NULL,
3833 .flags = FLAG_ADVANCED | FLAG_SHARE,
3836 .label = "fstype",
3837 .type = P_STRING,
3838 .p_class = P_LOCAL,
3839 .offset = LOCAL_VAR(fstype),
3840 .special = NULL,
3841 .enum_list = NULL,
3842 .flags = FLAG_ADVANCED | FLAG_SHARE,
3845 .label = "set directory",
3846 .type = P_BOOLREV,
3847 .p_class = P_LOCAL,
3848 .offset = LOCAL_VAR(bNo_set_dir),
3849 .special = NULL,
3850 .enum_list = NULL,
3851 .flags = FLAG_ADVANCED | FLAG_SHARE,
3854 .label = "allow insecure wide links",
3855 .type = P_BOOL,
3856 .p_class = P_GLOBAL,
3857 .offset = GLOBAL_VAR(bAllowInsecureWidelinks),
3858 .special = NULL,
3859 .enum_list = NULL,
3860 .flags = FLAG_ADVANCED,
3863 .label = "wide links",
3864 .type = P_BOOL,
3865 .p_class = P_LOCAL,
3866 .offset = LOCAL_VAR(bWidelinks),
3867 .special = NULL,
3868 .enum_list = NULL,
3869 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3872 .label = "follow symlinks",
3873 .type = P_BOOL,
3874 .p_class = P_LOCAL,
3875 .offset = LOCAL_VAR(bSymlinks),
3876 .special = NULL,
3877 .enum_list = NULL,
3878 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3881 .label = "dont descend",
3882 .type = P_STRING,
3883 .p_class = P_LOCAL,
3884 .offset = LOCAL_VAR(szDontdescend),
3885 .special = NULL,
3886 .enum_list = NULL,
3887 .flags = FLAG_ADVANCED | FLAG_SHARE,
3890 .label = "magic script",
3891 .type = P_STRING,
3892 .p_class = P_LOCAL,
3893 .offset = LOCAL_VAR(szMagicScript),
3894 .special = NULL,
3895 .enum_list = NULL,
3896 .flags = FLAG_ADVANCED | FLAG_SHARE,
3899 .label = "magic output",
3900 .type = P_STRING,
3901 .p_class = P_LOCAL,
3902 .offset = LOCAL_VAR(szMagicOutput),
3903 .special = NULL,
3904 .enum_list = NULL,
3905 .flags = FLAG_ADVANCED | FLAG_SHARE,
3908 .label = "delete readonly",
3909 .type = P_BOOL,
3910 .p_class = P_LOCAL,
3911 .offset = LOCAL_VAR(bDeleteReadonly),
3912 .special = NULL,
3913 .enum_list = NULL,
3914 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3917 .label = "dos filemode",
3918 .type = P_BOOL,
3919 .p_class = P_LOCAL,
3920 .offset = LOCAL_VAR(bDosFilemode),
3921 .special = NULL,
3922 .enum_list = NULL,
3923 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3926 .label = "dos filetimes",
3927 .type = P_BOOL,
3928 .p_class = P_LOCAL,
3929 .offset = LOCAL_VAR(bDosFiletimes),
3930 .special = NULL,
3931 .enum_list = NULL,
3932 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3935 .label = "dos filetime resolution",
3936 .type = P_BOOL,
3937 .p_class = P_LOCAL,
3938 .offset = LOCAL_VAR(bDosFiletimeResolution),
3939 .special = NULL,
3940 .enum_list = NULL,
3941 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3944 .label = "fake directory create times",
3945 .type = P_BOOL,
3946 .p_class = P_LOCAL,
3947 .offset = LOCAL_VAR(bFakeDirCreateTimes),
3948 .special = NULL,
3949 .enum_list = NULL,
3950 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3953 .label = "async smb echo handler",
3954 .type = P_BOOL,
3955 .p_class = P_GLOBAL,
3956 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
3957 .special = NULL,
3958 .enum_list = NULL,
3959 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3962 .label = "multicast dns register",
3963 .type = P_BOOL,
3964 .p_class = P_GLOBAL,
3965 .offset = GLOBAL_VAR(bMulticastDnsRegister),
3966 .special = NULL,
3967 .enum_list = NULL,
3968 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3971 .label = "panic action",
3972 .type = P_STRING,
3973 .p_class = P_GLOBAL,
3974 .offset = GLOBAL_VAR(szPanicAction),
3975 .special = NULL,
3976 .enum_list = NULL,
3977 .flags = FLAG_ADVANCED,
3980 .label = "perfcount module",
3981 .type = P_STRING,
3982 .p_class = P_GLOBAL,
3983 .offset = GLOBAL_VAR(szSMBPerfcountModule),
3984 .special = NULL,
3985 .enum_list = NULL,
3986 .flags = FLAG_ADVANCED,
3989 {N_("VFS module options"), P_SEP, P_SEPARATOR},
3992 .label = "vfs objects",
3993 .type = P_LIST,
3994 .p_class = P_LOCAL,
3995 .offset = LOCAL_VAR(szVfsObjects),
3996 .special = NULL,
3997 .enum_list = NULL,
3998 .flags = FLAG_ADVANCED | FLAG_SHARE,
4001 .label = "vfs object",
4002 .type = P_LIST,
4003 .p_class = P_LOCAL,
4004 .offset = LOCAL_VAR(szVfsObjects),
4005 .special = NULL,
4006 .enum_list = NULL,
4007 .flags = FLAG_HIDE,
4011 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4014 .label = "msdfs root",
4015 .type = P_BOOL,
4016 .p_class = P_LOCAL,
4017 .offset = LOCAL_VAR(bMSDfsRoot),
4018 .special = NULL,
4019 .enum_list = NULL,
4020 .flags = FLAG_ADVANCED | FLAG_SHARE,
4023 .label = "msdfs proxy",
4024 .type = P_STRING,
4025 .p_class = P_LOCAL,
4026 .offset = LOCAL_VAR(szMSDfsProxy),
4027 .special = NULL,
4028 .enum_list = NULL,
4029 .flags = FLAG_ADVANCED | FLAG_SHARE,
4032 .label = "host msdfs",
4033 .type = P_BOOL,
4034 .p_class = P_GLOBAL,
4035 .offset = GLOBAL_VAR(bHostMSDfs),
4036 .special = NULL,
4037 .enum_list = NULL,
4038 .flags = FLAG_ADVANCED,
4041 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4044 .label = "passdb expand explicit",
4045 .type = P_BOOL,
4046 .p_class = P_GLOBAL,
4047 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4048 .special = NULL,
4049 .enum_list = NULL,
4050 .flags = FLAG_ADVANCED,
4053 .label = "idmap backend",
4054 .type = P_STRING,
4055 .p_class = P_GLOBAL,
4056 .offset = GLOBAL_VAR(szIdmapBackend),
4057 .special = handle_idmap_backend,
4058 .enum_list = NULL,
4059 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4062 .label = "idmap cache time",
4063 .type = P_INTEGER,
4064 .p_class = P_GLOBAL,
4065 .offset = GLOBAL_VAR(iIdmapCacheTime),
4066 .special = NULL,
4067 .enum_list = NULL,
4068 .flags = FLAG_ADVANCED,
4071 .label = "idmap negative cache time",
4072 .type = P_INTEGER,
4073 .p_class = P_GLOBAL,
4074 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4075 .special = NULL,
4076 .enum_list = NULL,
4077 .flags = FLAG_ADVANCED,
4080 .label = "idmap uid",
4081 .type = P_STRING,
4082 .p_class = P_GLOBAL,
4083 .offset = GLOBAL_VAR(szIdmapUID),
4084 .special = handle_idmap_uid,
4085 .enum_list = NULL,
4086 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4089 .label = "winbind uid",
4090 .type = P_STRING,
4091 .p_class = P_GLOBAL,
4092 .offset = GLOBAL_VAR(szIdmapUID),
4093 .special = handle_idmap_uid,
4094 .enum_list = NULL,
4095 .flags = FLAG_HIDE,
4098 .label = "idmap gid",
4099 .type = P_STRING,
4100 .p_class = P_GLOBAL,
4101 .offset = GLOBAL_VAR(szIdmapGID),
4102 .special = handle_idmap_gid,
4103 .enum_list = NULL,
4104 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4107 .label = "winbind gid",
4108 .type = P_STRING,
4109 .p_class = P_GLOBAL,
4110 .offset = GLOBAL_VAR(szIdmapGID),
4111 .special = handle_idmap_gid,
4112 .enum_list = NULL,
4113 .flags = FLAG_HIDE,
4116 .label = "template homedir",
4117 .type = P_STRING,
4118 .p_class = P_GLOBAL,
4119 .offset = GLOBAL_VAR(szTemplateHomedir),
4120 .special = NULL,
4121 .enum_list = NULL,
4122 .flags = FLAG_ADVANCED,
4125 .label = "template shell",
4126 .type = P_STRING,
4127 .p_class = P_GLOBAL,
4128 .offset = GLOBAL_VAR(szTemplateShell),
4129 .special = NULL,
4130 .enum_list = NULL,
4131 .flags = FLAG_ADVANCED,
4134 .label = "winbind separator",
4135 .type = P_STRING,
4136 .p_class = P_GLOBAL,
4137 .offset = GLOBAL_VAR(szWinbindSeparator),
4138 .special = NULL,
4139 .enum_list = NULL,
4140 .flags = FLAG_ADVANCED,
4143 .label = "winbind cache time",
4144 .type = P_INTEGER,
4145 .p_class = P_GLOBAL,
4146 .offset = GLOBAL_VAR(winbind_cache_time),
4147 .special = NULL,
4148 .enum_list = NULL,
4149 .flags = FLAG_ADVANCED,
4152 .label = "winbind reconnect delay",
4153 .type = P_INTEGER,
4154 .p_class = P_GLOBAL,
4155 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4156 .special = NULL,
4157 .enum_list = NULL,
4158 .flags = FLAG_ADVANCED,
4161 .label = "winbind max clients",
4162 .type = P_INTEGER,
4163 .p_class = P_GLOBAL,
4164 .offset = GLOBAL_VAR(winbind_max_clients),
4165 .special = NULL,
4166 .enum_list = NULL,
4167 .flags = FLAG_ADVANCED,
4170 .label = "winbind enum users",
4171 .type = P_BOOL,
4172 .p_class = P_GLOBAL,
4173 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4174 .special = NULL,
4175 .enum_list = NULL,
4176 .flags = FLAG_ADVANCED,
4179 .label = "winbind enum groups",
4180 .type = P_BOOL,
4181 .p_class = P_GLOBAL,
4182 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4183 .special = NULL,
4184 .enum_list = NULL,
4185 .flags = FLAG_ADVANCED,
4188 .label = "winbind use default domain",
4189 .type = P_BOOL,
4190 .p_class = P_GLOBAL,
4191 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4192 .special = NULL,
4193 .enum_list = NULL,
4194 .flags = FLAG_ADVANCED,
4197 .label = "winbind trusted domains only",
4198 .type = P_BOOL,
4199 .p_class = P_GLOBAL,
4200 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4201 .special = NULL,
4202 .enum_list = NULL,
4203 .flags = FLAG_ADVANCED,
4206 .label = "winbind nested groups",
4207 .type = P_BOOL,
4208 .p_class = P_GLOBAL,
4209 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4210 .special = NULL,
4211 .enum_list = NULL,
4212 .flags = FLAG_ADVANCED,
4215 .label = "winbind expand groups",
4216 .type = P_INTEGER,
4217 .p_class = P_GLOBAL,
4218 .offset = GLOBAL_VAR(winbind_expand_groups),
4219 .special = NULL,
4220 .enum_list = NULL,
4221 .flags = FLAG_ADVANCED,
4224 .label = "winbind nss info",
4225 .type = P_LIST,
4226 .p_class = P_GLOBAL,
4227 .offset = GLOBAL_VAR(szWinbindNssInfo),
4228 .special = NULL,
4229 .enum_list = NULL,
4230 .flags = FLAG_ADVANCED,
4233 .label = "winbind refresh tickets",
4234 .type = P_BOOL,
4235 .p_class = P_GLOBAL,
4236 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4237 .special = NULL,
4238 .enum_list = NULL,
4239 .flags = FLAG_ADVANCED,
4242 .label = "winbind offline logon",
4243 .type = P_BOOL,
4244 .p_class = P_GLOBAL,
4245 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4246 .special = NULL,
4247 .enum_list = NULL,
4248 .flags = FLAG_ADVANCED,
4251 .label = "winbind normalize names",
4252 .type = P_BOOL,
4253 .p_class = P_GLOBAL,
4254 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4255 .special = NULL,
4256 .enum_list = NULL,
4257 .flags = FLAG_ADVANCED,
4260 .label = "winbind rpc only",
4261 .type = P_BOOL,
4262 .p_class = P_GLOBAL,
4263 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4264 .special = NULL,
4265 .enum_list = NULL,
4266 .flags = FLAG_ADVANCED,
4269 .label = "create krb5 conf",
4270 .type = P_BOOL,
4271 .p_class = P_GLOBAL,
4272 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4273 .special = NULL,
4274 .enum_list = NULL,
4275 .flags = FLAG_ADVANCED,
4278 .label = "ncalrpc dir",
4279 .type = P_STRING,
4280 .p_class = P_GLOBAL,
4281 .offset = GLOBAL_VAR(ncalrpc_dir),
4282 .special = NULL,
4283 .enum_list = NULL,
4284 .flags = FLAG_ADVANCED,
4287 .label = "winbind max domain connections",
4288 .type = P_INTEGER,
4289 .p_class = P_GLOBAL,
4290 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4291 .special = NULL,
4292 .enum_list = NULL,
4293 .flags = FLAG_ADVANCED,
4296 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4299 /***************************************************************************
4300 Initialise the sDefault parameter structure for the printer values.
4301 ***************************************************************************/
4303 static void init_printer_values(struct loadparm_service *pService)
4305 /* choose defaults depending on the type of printing */
4306 switch (pService->iPrinting) {
4307 case PRINT_BSD:
4308 case PRINT_AIX:
4309 case PRINT_LPRNT:
4310 case PRINT_LPROS2:
4311 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4312 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4313 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4314 break;
4316 case PRINT_LPRNG:
4317 case PRINT_PLP:
4318 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4319 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4320 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4321 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4322 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4323 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4324 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4325 break;
4327 case PRINT_CUPS:
4328 case PRINT_IPRINT:
4329 #ifdef HAVE_CUPS
4330 /* set the lpq command to contain the destination printer
4331 name only. This is used by cups_queue_get() */
4332 string_set(&pService->szLpqcommand, "%p");
4333 string_set(&pService->szLprmcommand, "");
4334 string_set(&pService->szPrintcommand, "");
4335 string_set(&pService->szLppausecommand, "");
4336 string_set(&pService->szLpresumecommand, "");
4337 string_set(&pService->szQueuepausecommand, "");
4338 string_set(&pService->szQueueresumecommand, "");
4339 #else
4340 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4341 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4342 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4343 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4344 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4345 string_set(&pService->szQueuepausecommand, "disable '%p'");
4346 string_set(&pService->szQueueresumecommand, "enable '%p'");
4347 #endif /* HAVE_CUPS */
4348 break;
4350 case PRINT_SYSV:
4351 case PRINT_HPUX:
4352 string_set(&pService->szLpqcommand, "lpstat -o%p");
4353 string_set(&pService->szLprmcommand, "cancel %p-%j");
4354 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4355 string_set(&pService->szQueuepausecommand, "disable %p");
4356 string_set(&pService->szQueueresumecommand, "enable %p");
4357 #ifndef HPUX
4358 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4359 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4360 #endif /* HPUX */
4361 break;
4363 case PRINT_QNX:
4364 string_set(&pService->szLpqcommand, "lpq -P%p");
4365 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4366 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4367 break;
4369 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4371 case PRINT_TEST:
4372 case PRINT_VLP: {
4373 const char *tdbfile;
4374 char *tmp;
4376 tdbfile = talloc_asprintf(
4377 talloc_tos(), "tdbfile=%s",
4378 lp_parm_const_string(-1, "vlp", "tdbfile",
4379 "/tmp/vlp.tdb"));
4380 if (tdbfile == NULL) {
4381 tdbfile="tdbfile=/tmp/vlp.tdb";
4384 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4385 tdbfile);
4386 string_set(&pService->szPrintcommand,
4387 tmp ? tmp : "vlp print %p %s");
4388 TALLOC_FREE(tmp);
4390 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4391 tdbfile);
4392 string_set(&pService->szLpqcommand,
4393 tmp ? tmp : "vlp lpq %p");
4394 TALLOC_FREE(tmp);
4396 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4397 tdbfile);
4398 string_set(&pService->szLprmcommand,
4399 tmp ? tmp : "vlp lprm %p %j");
4400 TALLOC_FREE(tmp);
4402 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4403 tdbfile);
4404 string_set(&pService->szLppausecommand,
4405 tmp ? tmp : "vlp lppause %p %j");
4406 TALLOC_FREE(tmp);
4408 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4409 tdbfile);
4410 string_set(&pService->szLpresumecommand,
4411 tmp ? tmp : "vlp lpresume %p %j");
4412 TALLOC_FREE(tmp);
4414 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4415 tdbfile);
4416 string_set(&pService->szQueuepausecommand,
4417 tmp ? tmp : "vlp queuepause %p");
4418 TALLOC_FREE(tmp);
4420 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4421 tdbfile);
4422 string_set(&pService->szQueueresumecommand,
4423 tmp ? tmp : "vlp queueresume %p");
4424 TALLOC_FREE(tmp);
4426 break;
4428 #endif /* DEVELOPER */
4433 * Function to return the default value for the maximum number of open
4434 * file descriptors permitted. This function tries to consult the
4435 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4436 * the smaller of those.
4438 static int max_open_files(void)
4440 int sysctl_max = MAX_OPEN_FILES;
4441 int rlimit_max = MAX_OPEN_FILES;
4443 #ifdef HAVE_SYSCTLBYNAME
4445 size_t size = sizeof(sysctl_max);
4446 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4449 #endif
4451 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4453 struct rlimit rl;
4455 ZERO_STRUCT(rl);
4457 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4458 rlimit_max = rl.rlim_cur;
4460 #if defined(RLIM_INFINITY)
4461 if(rl.rlim_cur == RLIM_INFINITY)
4462 rlimit_max = MAX_OPEN_FILES;
4463 #endif
4465 #endif
4467 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4468 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4469 "minimum Windows limit (%d)\n",
4470 sysctl_max,
4471 MIN_OPEN_FILES_WINDOWS));
4472 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4475 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4476 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4477 "minimum Windows limit (%d)\n",
4478 rlimit_max,
4479 MIN_OPEN_FILES_WINDOWS));
4480 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4483 return MIN(sysctl_max, rlimit_max);
4487 * Common part of freeing allocated data for one parameter.
4489 static void free_one_parameter_common(void *parm_ptr,
4490 struct parm_struct parm)
4492 if ((parm.type == P_STRING) ||
4493 (parm.type == P_USTRING))
4495 string_free((char**)parm_ptr);
4496 } else if (parm.type == P_LIST) {
4497 TALLOC_FREE(*((char***)parm_ptr));
4502 * Free the allocated data for one parameter for a share
4503 * given as a service struct.
4505 static void free_one_parameter(struct loadparm_service *service,
4506 struct parm_struct parm)
4508 void *parm_ptr;
4510 if (parm.p_class != P_LOCAL) {
4511 return;
4514 parm_ptr = lp_parm_ptr(service, &parm);
4516 free_one_parameter_common(parm_ptr, parm);
4520 * Free the allocated parameter data of a share given
4521 * as a service struct.
4523 static void free_parameters(struct loadparm_service *service)
4525 uint32_t i;
4527 for (i=0; parm_table[i].label; i++) {
4528 free_one_parameter(service, parm_table[i]);
4533 * Free the allocated data for one parameter for a given share
4534 * specified by an snum.
4536 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4538 void *parm_ptr;
4540 if (snum < 0) {
4541 parm_ptr = lp_parm_ptr(NULL, &parm);
4542 } else if (parm.p_class != P_LOCAL) {
4543 return;
4544 } else {
4545 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4548 free_one_parameter_common(parm_ptr, parm);
4552 * Free the allocated parameter data for a share specified
4553 * by an snum.
4555 static void free_parameters_by_snum(int snum)
4557 uint32_t i;
4559 for (i=0; parm_table[i].label; i++) {
4560 free_one_parameter_by_snum(snum, parm_table[i]);
4565 * Free the allocated global parameters.
4567 static void free_global_parameters(void)
4569 free_param_opts(&Globals.param_opt);
4570 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4573 static int map_parameter(const char *pszParmName);
4575 struct lp_stored_option {
4576 struct lp_stored_option *prev, *next;
4577 const char *label;
4578 const char *value;
4581 static struct lp_stored_option *stored_options;
4584 save options set by lp_set_cmdline() into a list. This list is
4585 re-applied when we do a globals reset, so that cmdline set options
4586 are sticky across reloads of smb.conf
4588 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4590 struct lp_stored_option *entry, *entry_next;
4591 for (entry = stored_options; entry != NULL; entry = entry_next) {
4592 entry_next = entry->next;
4593 if (strcmp(pszParmName, entry->label) == 0) {
4594 DLIST_REMOVE(stored_options, entry);
4595 talloc_free(entry);
4596 break;
4600 entry = talloc(NULL, struct lp_stored_option);
4601 if (!entry) {
4602 return false;
4605 entry->label = talloc_strdup(entry, pszParmName);
4606 if (!entry->label) {
4607 talloc_free(entry);
4608 return false;
4611 entry->value = talloc_strdup(entry, pszParmValue);
4612 if (!entry->value) {
4613 talloc_free(entry);
4614 return false;
4617 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4619 return true;
4622 static bool apply_lp_set_cmdline(void)
4624 struct lp_stored_option *entry = NULL;
4625 for (entry = stored_options; entry != NULL; entry = entry->next) {
4626 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
4627 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4628 entry->label, entry->value));
4629 return false;
4632 return true;
4635 /***************************************************************************
4636 Initialise the global parameter structure.
4637 ***************************************************************************/
4639 static void init_globals(bool reinit_globals)
4641 static bool done_init = false;
4642 char *s = NULL;
4643 int i;
4645 /* If requested to initialize only once and we've already done it... */
4646 if (!reinit_globals && done_init) {
4647 /* ... then we have nothing more to do */
4648 return;
4651 if (!done_init) {
4652 /* The logfile can be set before this is invoked. Free it if so. */
4653 if (Globals.logfile != NULL) {
4654 string_free(&Globals.logfile);
4655 Globals.logfile = NULL;
4657 done_init = true;
4658 } else {
4659 free_global_parameters();
4662 /* This memset and the free_global_parameters() above will
4663 * wipe out smb.conf options set with lp_set_cmdline(). The
4664 * apply_lp_set_cmdline() call puts these values back in the
4665 * table once the defaults are set */
4666 ZERO_STRUCT(Globals);
4668 for (i = 0; parm_table[i].label; i++) {
4669 if ((parm_table[i].type == P_STRING ||
4670 parm_table[i].type == P_USTRING))
4672 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
4677 string_set(&sDefault.fstype, FSTYPE_STRING);
4678 string_set(&sDefault.szPrintjobUsername, "%U");
4680 init_printer_values(&sDefault);
4683 DEBUG(3, ("Initialising global parameters\n"));
4685 /* Must manually force to upper case here, as this does not go via the handler */
4686 string_set(&Globals.szNetbiosName, myhostname_upper());
4688 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4689 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4691 /* use the new 'hash2' method by default, with a prefix of 1 */
4692 string_set(&Globals.szManglingMethod, "hash2");
4693 Globals.mangle_prefix = 1;
4695 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4697 /* using UTF8 by default allows us to support all chars */
4698 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4700 /* Use codepage 850 as a default for the dos character set */
4701 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4704 * Allow the default PASSWD_CHAT to be overridden in local.h.
4706 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4708 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
4710 string_set(&Globals.szPasswdProgram, "");
4711 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4712 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4713 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4714 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4715 string_set(&Globals.szSocketAddress, "0.0.0.0");
4717 * By default support explicit binding to broadcast
4718 * addresses.
4720 Globals.bNmbdBindExplicitBroadcast = true;
4722 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4723 smb_panic("init_globals: ENOMEM");
4725 string_set(&Globals.szServerString, s);
4726 SAFE_FREE(s);
4727 #ifdef DEVELOPER
4728 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4729 #endif
4731 string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
4733 string_set(&Globals.szLogonDrive, "");
4734 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4735 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4736 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4738 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4739 string_set(&Globals.szPasswordServer, "*");
4741 Globals.AlgorithmicRidBase = BASE_RID;
4743 Globals.bLoadPrinters = true;
4744 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4746 Globals.ConfigBackend = config_backend;
4747 Globals.ServerRole = ROLE_AUTO;
4749 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4750 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4751 Globals.max_xmit = 0x4104;
4752 Globals.max_mux = 50; /* This is *needed* for profile support. */
4753 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4754 Globals.bDisableSpoolss = false;
4755 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4756 Globals.pwordlevel = 0;
4757 Globals.unamelevel = 0;
4758 Globals.deadtime = 0;
4759 Globals.getwd_cache = true;
4760 Globals.bLargeReadwrite = true;
4761 Globals.max_log_size = 5000;
4762 Globals.max_open_files = max_open_files();
4763 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4764 Globals.srv_maxprotocol = PROTOCOL_SMB2_10;
4765 Globals.srv_minprotocol = PROTOCOL_LANMAN1;
4766 Globals.security = SEC_USER;
4767 Globals.paranoid_server_security = true;
4768 Globals.bEncryptPasswords = true;
4769 Globals.clientSchannel = Auto;
4770 Globals.serverSchannel = Auto;
4771 Globals.bReadRaw = true;
4772 Globals.bWriteRaw = true;
4773 Globals.bNullPasswords = false;
4774 Globals.bObeyPamRestrictions = false;
4775 Globals.syslog = 1;
4776 Globals.bSyslogOnly = false;
4777 Globals.bTimestampLogs = true;
4778 string_set(&Globals.szLogLevel, "0");
4779 Globals.bDebugPrefixTimestamp = false;
4780 Globals.bDebugHiresTimestamp = true;
4781 Globals.bDebugPid = false;
4782 Globals.bDebugUid = false;
4783 Globals.bDebugClass = false;
4784 Globals.bEnableCoreFiles = true;
4785 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4786 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4787 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4788 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4789 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
4790 Globals.lm_interval = 60;
4791 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4792 Globals.bNISHomeMap = false;
4793 #ifdef WITH_NISPLUS_HOME
4794 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4795 #else
4796 string_set(&Globals.szNISHomeMapName, "auto.home");
4797 #endif
4798 #endif
4799 Globals.bTimeServer = false;
4800 Globals.bBindInterfacesOnly = false;
4801 Globals.bUnixPasswdSync = false;
4802 Globals.bPamPasswordChange = false;
4803 Globals.bPasswdChatDebug = false;
4804 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4805 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
4806 Globals.bNTStatusSupport = true; /* Use NT status by default. */
4807 Globals.bStatCache = true; /* use stat cache by default */
4808 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4809 Globals.restrict_anonymous = 0;
4810 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
4811 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
4812 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
4813 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4814 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4815 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4817 Globals.map_to_guest = 0; /* By Default, "Never" */
4818 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4819 Globals.enhanced_browsing = true;
4820 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4821 #ifdef MMAP_BLACKLIST
4822 Globals.bUseMmap = false;
4823 #else
4824 Globals.bUseMmap = true;
4825 #endif
4826 Globals.bUnixExtensions = true;
4827 Globals.bResetOnZeroVC = false;
4828 Globals.bLogWriteableFilesOnExit = false;
4829 Globals.bCreateKrb5Conf = true;
4830 Globals.winbindMaxDomainConnections = 1;
4832 /* hostname lookups can be very expensive and are broken on
4833 a large number of sites (tridge) */
4834 Globals.bHostnameLookups = false;
4836 string_set(&Globals.passdb_backend, "tdbsam");
4837 string_set(&Globals.szLdapSuffix, "");
4838 string_set(&Globals.szLdapMachineSuffix, "");
4839 string_set(&Globals.szLdapUserSuffix, "");
4840 string_set(&Globals.szLdapGroupSuffix, "");
4841 string_set(&Globals.szLdapIdmapSuffix, "");
4843 string_set(&Globals.szLdapAdminDn, "");
4844 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4845 Globals.ldap_ssl_ads = false;
4846 Globals.ldap_deref = -1;
4847 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4848 Globals.ldap_delete_dn = false;
4849 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4850 Globals.ldap_follow_referral = Auto;
4851 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4852 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4853 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4855 Globals.ldap_debug_level = 0;
4856 Globals.ldap_debug_threshold = 10;
4858 /* This is what we tell the afs client. in reality we set the token
4859 * to never expire, though, when this runs out the afs client will
4860 * forget the token. Set to 0 to get NEVERDATE.*/
4861 Globals.iAfsTokenLifetime = 604800;
4862 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4864 /* these parameters are set to defaults that are more appropriate
4865 for the increasing samba install base:
4867 as a member of the workgroup, that will possibly become a
4868 _local_ master browser (lm = true). this is opposed to a forced
4869 local master browser startup (pm = true).
4871 doesn't provide WINS server service by default (wsupp = false),
4872 and doesn't provide domain master browser services by default, either.
4876 Globals.bMsAddPrinterWizard = true;
4877 Globals.os_level = 20;
4878 Globals.bLocalMaster = true;
4879 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4880 Globals.bDomainLogons = false;
4881 Globals.bBrowseList = true;
4882 Globals.bWINSsupport = false;
4883 Globals.bWINSproxy = false;
4885 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4886 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4888 Globals.bWINSdnsProxy = true;
4890 Globals.bAllowTrustedDomains = true;
4891 string_set(&Globals.szIdmapBackend, "tdb");
4893 string_set(&Globals.szTemplateShell, "/bin/false");
4894 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4895 string_set(&Globals.szWinbindSeparator, "\\");
4897 string_set(&Globals.szCupsServer, "");
4898 string_set(&Globals.szIPrintServer, "");
4900 string_set(&Globals.ctdbdSocket, "");
4901 Globals.szClusterAddresses = NULL;
4902 Globals.clustering = false;
4903 Globals.ctdb_timeout = 0;
4904 Globals.ctdb_locktime_warn_threshold = 0;
4906 Globals.winbind_cache_time = 300; /* 5 minutes */
4907 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4908 Globals.winbind_max_clients = 200;
4909 Globals.bWinbindEnumUsers = false;
4910 Globals.bWinbindEnumGroups = false;
4911 Globals.bWinbindUseDefaultDomain = false;
4912 Globals.bWinbindTrustedDomainsOnly = false;
4913 Globals.bWinbindNestedGroups = true;
4914 Globals.winbind_expand_groups = 1;
4915 Globals.szWinbindNssInfo = (const char **)str_list_make_v3(NULL, "template", NULL);
4916 Globals.bWinbindRefreshTickets = false;
4917 Globals.bWinbindOfflineLogon = false;
4919 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4920 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4922 Globals.bPassdbExpandExplicit = false;
4924 Globals.name_cache_timeout = 660; /* In seconds */
4926 Globals.bUseSpnego = true;
4927 Globals.bClientUseSpnego = true;
4929 Globals.client_signing = SMB_SIGNING_DEFAULT;
4930 Globals.server_signing = SMB_SIGNING_DEFAULT;
4932 Globals.bDeferSharingViolations = true;
4933 string_set(&Globals.smb_ports, SMB_PORTS);
4935 Globals.bEnablePrivileges = true;
4936 Globals.bHostMSDfs = true;
4937 Globals.bASUSupport = false;
4939 /* User defined shares. */
4940 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4941 smb_panic("init_globals: ENOMEM");
4943 string_set(&Globals.szUsersharePath, s);
4944 SAFE_FREE(s);
4945 string_set(&Globals.szUsershareTemplateShare, "");
4946 Globals.iUsershareMaxShares = 0;
4947 /* By default disallow sharing of directories not owned by the sharer. */
4948 Globals.bUsershareOwnerOnly = true;
4949 /* By default disallow guest access to usershares. */
4950 Globals.bUsershareAllowGuests = false;
4952 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4954 /* By default no shares out of the registry */
4955 Globals.bRegistryShares = false;
4957 Globals.iminreceivefile = 0;
4959 Globals.bMapUntrustedToDomain = false;
4960 Globals.bMulticastDnsRegister = true;
4962 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
4963 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
4964 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
4965 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
4967 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
4969 /* Now put back the settings that were set with lp_set_cmdline() */
4970 apply_lp_set_cmdline();
4973 /*******************************************************************
4974 Convenience routine to grab string parameters into temporary memory
4975 and run standard_sub_basic on them. The buffers can be written to by
4976 callers without affecting the source string.
4977 ********************************************************************/
4979 static char *lp_string(const char *s)
4981 char *ret;
4982 TALLOC_CTX *ctx = talloc_tos();
4984 /* The follow debug is useful for tracking down memory problems
4985 especially if you have an inner loop that is calling a lp_*()
4986 function that returns a string. Perhaps this debug should be
4987 present all the time? */
4989 #if 0
4990 DEBUG(10, ("lp_string(%s)\n", s));
4991 #endif
4992 if (!s) {
4993 return NULL;
4996 ret = talloc_sub_basic(ctx,
4997 get_current_username(),
4998 current_user_info.domain,
5000 if (trim_char(ret, '\"', '\"')) {
5001 if (strchr(ret,'\"') != NULL) {
5002 TALLOC_FREE(ret);
5003 ret = talloc_sub_basic(ctx,
5004 get_current_username(),
5005 current_user_info.domain,
5009 return ret;
5013 In this section all the functions that are used to access the
5014 parameters from the rest of the program are defined
5017 #define FN_GLOBAL_STRING(fn_name,ptr) \
5018 char *lp_ ## fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5019 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5020 const char *lp_ ## fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5021 #define FN_GLOBAL_LIST(fn_name,ptr) \
5022 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5023 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5024 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
5025 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5026 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
5027 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5028 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
5030 #define FN_LOCAL_STRING(fn_name,val) \
5031 char *lp_ ## fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5032 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5033 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5034 #define FN_LOCAL_LIST(fn_name,val) \
5035 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5036 #define FN_LOCAL_BOOL(fn_name,val) \
5037 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5038 #define FN_LOCAL_INTEGER(fn_name,val) \
5039 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5041 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5042 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5043 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5044 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5045 #define FN_LOCAL_CHAR(fn_name,val) \
5046 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5049 static FN_GLOBAL_BOOL(domain_logons, bDomainLogons)
5050 static FN_GLOBAL_BOOL(_readraw, bReadRaw)
5051 static FN_GLOBAL_BOOL(time_server, bTimeServer)
5052 static FN_GLOBAL_BOOL(_writeraw, bWriteRaw)
5053 static FN_GLOBAL_CONST_STRING(_ctdbd_socket, ctdbdSocket)
5054 static FN_GLOBAL_INTEGER(_server_role, ServerRole)
5056 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5057 * build process or in smb.conf, we use that value. Otherwise they
5058 * default to the value of lp_lockdir(). */
5059 const char *lp_statedir(void) {
5060 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5061 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5062 return(*(char **)(&Globals.szStateDir) ?
5063 *(char **)(&Globals.szStateDir) : "");
5064 else
5065 return(*(char **)(&Globals.szLockDir) ?
5066 *(char **)(&Globals.szLockDir) : "");
5068 const char *lp_cachedir(void) {
5069 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5070 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5071 return(*(char **)(&Globals.szCacheDir) ?
5072 *(char **)(&Globals.szCacheDir) : "");
5073 else
5074 return(*(char **)(&Globals.szLockDir) ?
5075 *(char **)(&Globals.szLockDir) : "");
5077 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
5078 winbindMaxDomainConnections)
5080 int lp_winbind_max_domain_connections(void)
5082 if (lp_winbind_offline_logon() &&
5083 lp_winbind_max_domain_connections_int() > 1) {
5084 DEBUG(1, ("offline logons active, restricting max domain "
5085 "connections to 1\n"));
5086 return 1;
5088 return MAX(1, lp_winbind_max_domain_connections_int());
5091 int lp_smb2_max_credits(void)
5093 if (Globals.ismb2_max_credits == 0) {
5094 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5096 return Globals.ismb2_max_credits;
5098 int lp_cups_encrypt(void)
5100 int result = 0;
5101 #ifdef HAVE_HTTPCONNECTENCRYPT
5102 switch (Globals.CupsEncrypt) {
5103 case Auto:
5104 result = HTTP_ENCRYPT_REQUIRED;
5105 break;
5106 case true:
5107 result = HTTP_ENCRYPT_ALWAYS;
5108 break;
5109 case false:
5110 result = HTTP_ENCRYPT_NEVER;
5111 break;
5113 #endif
5114 return result;
5117 /* These functions remain in source3/param for now */
5119 FN_GLOBAL_CONST_STRING(name_resolve_order, szNameResolveOrder)
5120 FN_GLOBAL_CONST_STRING(smb_ports, smb_ports)
5121 FN_GLOBAL_INTEGER(security, security)
5122 FN_GLOBAL_INTEGER(usershare_max_shares, iUsershareMaxShares)
5123 FN_GLOBAL_STRING(configfile, szConfigFile)
5125 #include "lib/param/param_functions.c"
5127 FN_LOCAL_STRING(servicename, szService)
5128 FN_LOCAL_CONST_STRING(const_servicename, szService)
5130 /* local prototypes */
5132 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5133 static const char *get_boolean(bool bool_value);
5134 static int getservicebyname(const char *pszServiceName,
5135 struct loadparm_service *pserviceDest);
5136 static void copy_service(struct loadparm_service *pserviceDest,
5137 struct loadparm_service *pserviceSource,
5138 struct bitmap *pcopymapDest);
5139 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5140 void *userdata);
5141 static bool do_section(const char *pszSectionName, void *userdata);
5142 static void init_copymap(struct loadparm_service *pservice);
5143 static bool hash_a_service(const char *name, int number);
5144 static void free_service_byindex(int iService);
5145 static void show_parameter(int parmIndex);
5146 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5149 * This is a helper function for parametrical options support. It returns a
5150 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5151 * parametrical functions are quite simple
5153 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
5154 const char *option)
5156 bool global_section = false;
5157 char* param_key;
5158 struct parmlist_entry *data;
5160 if (service == NULL) {
5161 data = Globals.param_opt;
5162 global_section = true;
5163 } else {
5164 data = service->param_opt;
5167 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5168 DEBUG(0,("asprintf failed!\n"));
5169 return NULL;
5172 while (data) {
5173 if (strwicmp(data->key, param_key) == 0) {
5174 string_free(&param_key);
5175 return data;
5177 data = data->next;
5180 if (!global_section) {
5181 /* Try to fetch the same option but from globals */
5182 /* but only if we are not already working with Globals */
5183 data = Globals.param_opt;
5184 while (data) {
5185 if (strwicmp(data->key, param_key) == 0) {
5186 string_free(&param_key);
5187 return data;
5189 data = data->next;
5193 string_free(&param_key);
5195 return NULL;
5199 * This is a helper function for parametrical options support. It returns a
5200 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5201 * parametrical functions are quite simple
5203 static struct parmlist_entry *get_parametrics(int snum, const char *type,
5204 const char *option)
5206 if (snum >= iNumServices) return NULL;
5208 if (snum < 0) {
5209 return get_parametrics_by_service(NULL, type, option);
5210 } else {
5211 return get_parametrics_by_service(ServicePtrs[snum], type, option);
5216 #define MISSING_PARAMETER(name) \
5217 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5219 /*******************************************************************
5220 convenience routine to return int parameters.
5221 ********************************************************************/
5222 static int lp_int(const char *s)
5225 if (!s || !*s) {
5226 MISSING_PARAMETER(lp_int);
5227 return (-1);
5230 return (int)strtol(s, NULL, 0);
5233 /*******************************************************************
5234 convenience routine to return unsigned long parameters.
5235 ********************************************************************/
5236 static unsigned long lp_ulong(const char *s)
5239 if (!s || !*s) {
5240 MISSING_PARAMETER(lp_ulong);
5241 return (0);
5244 return strtoul(s, NULL, 0);
5247 /*******************************************************************
5248 convenience routine to return boolean parameters.
5249 ********************************************************************/
5250 static bool lp_bool(const char *s)
5252 bool ret = false;
5254 if (!s || !*s) {
5255 MISSING_PARAMETER(lp_bool);
5256 return false;
5259 if (!set_boolean(s, &ret)) {
5260 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5261 return false;
5264 return ret;
5267 /*******************************************************************
5268 convenience routine to return enum parameters.
5269 ********************************************************************/
5270 static int lp_enum(const char *s,const struct enum_list *_enum)
5272 int i;
5274 if (!s || !*s || !_enum) {
5275 MISSING_PARAMETER(lp_enum);
5276 return (-1);
5279 for (i=0; _enum[i].name; i++) {
5280 if (strequal(_enum[i].name,s))
5281 return _enum[i].value;
5284 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5285 return (-1);
5288 #undef MISSING_PARAMETER
5290 /* Return parametric option from a given service. Type is a part of option before ':' */
5291 /* Parametric option has following syntax: 'Type: option = value' */
5292 /* the returned value is talloced on the talloc_tos() */
5293 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5295 struct parmlist_entry *data = get_parametrics(snum, type, option);
5297 if (data == NULL||data->value==NULL) {
5298 if (def) {
5299 return lp_string(def);
5300 } else {
5301 return NULL;
5305 return lp_string(data->value);
5308 /* Return parametric option from a given service. Type is a part of option before ':' */
5309 /* Parametric option has following syntax: 'Type: option = value' */
5310 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5312 struct parmlist_entry *data = get_parametrics(snum, type, option);
5314 if (data == NULL||data->value==NULL)
5315 return def;
5317 return data->value;
5320 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
5322 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
5324 if (data == NULL||data->value==NULL)
5325 return NULL;
5327 return data->value;
5331 /* Return parametric option from a given service. Type is a part of option before ':' */
5332 /* Parametric option has following syntax: 'Type: option = value' */
5334 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5336 struct parmlist_entry *data = get_parametrics(snum, type, option);
5338 if (data == NULL||data->value==NULL)
5339 return (const char **)def;
5341 if (data->list==NULL) {
5342 data->list = str_list_make_v3(NULL, data->value, NULL);
5345 return (const char **)data->list;
5348 /* Return parametric option from a given service. Type is a part of option before ':' */
5349 /* Parametric option has following syntax: 'Type: option = value' */
5351 int lp_parm_int(int snum, const char *type, const char *option, int def)
5353 struct parmlist_entry *data = get_parametrics(snum, type, option);
5355 if (data && data->value && *data->value)
5356 return lp_int(data->value);
5358 return def;
5361 /* Return parametric option from a given service. Type is a part of option before ':' */
5362 /* Parametric option has following syntax: 'Type: option = value' */
5364 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5366 struct parmlist_entry *data = get_parametrics(snum, type, option);
5368 if (data && data->value && *data->value)
5369 return lp_ulong(data->value);
5371 return def;
5374 /* Return parametric option from a given service. Type is a part of option before ':' */
5375 /* Parametric option has following syntax: 'Type: option = value' */
5377 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5379 struct parmlist_entry *data = get_parametrics(snum, type, option);
5381 if (data && data->value && *data->value)
5382 return lp_bool(data->value);
5384 return def;
5387 /* Return parametric option from a given service. Type is a part of option before ':' */
5388 /* Parametric option has following syntax: 'Type: option = value' */
5390 int lp_parm_enum(int snum, const char *type, const char *option,
5391 const struct enum_list *_enum, int def)
5393 struct parmlist_entry *data = get_parametrics(snum, type, option);
5395 if (data && data->value && *data->value && _enum)
5396 return lp_enum(data->value, _enum);
5398 return def;
5402 /***************************************************************************
5403 Initialise a service to the defaults.
5404 ***************************************************************************/
5406 static void init_service(struct loadparm_service *pservice)
5408 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
5409 copy_service(pservice, &sDefault, NULL);
5414 * free a param_opts structure.
5415 * param_opts handling should be moved to talloc;
5416 * then this whole functions reduces to a TALLOC_FREE().
5419 static void free_param_opts(struct parmlist_entry **popts)
5421 struct parmlist_entry *opt, *next_opt;
5423 if (popts == NULL) {
5424 return;
5427 if (*popts != NULL) {
5428 DEBUG(5, ("Freeing parametrics:\n"));
5430 opt = *popts;
5431 while (opt != NULL) {
5432 string_free(&opt->key);
5433 string_free(&opt->value);
5434 TALLOC_FREE(opt->list);
5435 next_opt = opt->next;
5436 SAFE_FREE(opt);
5437 opt = next_opt;
5439 *popts = NULL;
5442 /***************************************************************************
5443 Free the dynamically allocated parts of a service struct.
5444 ***************************************************************************/
5446 static void free_service(struct loadparm_service *pservice)
5448 if (!pservice)
5449 return;
5451 if (pservice->szService)
5452 DEBUG(5, ("free_service: Freeing service %s\n",
5453 pservice->szService));
5455 free_parameters(pservice);
5457 string_free(&pservice->szService);
5458 TALLOC_FREE(pservice->copymap);
5460 free_param_opts(&pservice->param_opt);
5462 ZERO_STRUCTP(pservice);
5466 /***************************************************************************
5467 remove a service indexed in the ServicePtrs array from the ServiceHash
5468 and free the dynamically allocated parts
5469 ***************************************************************************/
5471 static void free_service_byindex(int idx)
5473 if ( !LP_SNUM_OK(idx) )
5474 return;
5476 ServicePtrs[idx]->valid = false;
5477 invalid_services[num_invalid_services++] = idx;
5479 /* we have to cleanup the hash record */
5481 if (ServicePtrs[idx]->szService) {
5482 char *canon_name = canonicalize_servicename(
5483 talloc_tos(),
5484 ServicePtrs[idx]->szService );
5486 dbwrap_delete_bystring(ServiceHash, canon_name );
5487 TALLOC_FREE(canon_name);
5490 free_service(ServicePtrs[idx]);
5493 /***************************************************************************
5494 Add a new service to the services array initialising it with the given
5495 service.
5496 ***************************************************************************/
5498 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5500 int i;
5501 struct loadparm_service tservice;
5502 int num_to_alloc = iNumServices + 1;
5504 tservice = *pservice;
5506 /* it might already exist */
5507 if (name) {
5508 i = getservicebyname(name, NULL);
5509 if (i >= 0) {
5510 return (i);
5514 /* find an invalid one */
5515 i = iNumServices;
5516 if (num_invalid_services > 0) {
5517 i = invalid_services[--num_invalid_services];
5520 /* if not, then create one */
5521 if (i == iNumServices) {
5522 struct loadparm_service **tsp;
5523 int *tinvalid;
5525 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5526 if (tsp == NULL) {
5527 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5528 return (-1);
5530 ServicePtrs = tsp;
5531 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5532 if (!ServicePtrs[iNumServices]) {
5533 DEBUG(0,("add_a_service: out of memory!\n"));
5534 return (-1);
5536 iNumServices++;
5538 /* enlarge invalid_services here for now... */
5539 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5540 num_to_alloc);
5541 if (tinvalid == NULL) {
5542 DEBUG(0,("add_a_service: failed to enlarge "
5543 "invalid_services!\n"));
5544 return (-1);
5546 invalid_services = tinvalid;
5547 } else {
5548 free_service_byindex(i);
5551 ServicePtrs[i]->valid = true;
5553 init_service(ServicePtrs[i]);
5554 copy_service(ServicePtrs[i], &tservice, NULL);
5555 if (name)
5556 string_set(&ServicePtrs[i]->szService, name);
5558 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5559 i, ServicePtrs[i]->szService));
5561 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5562 return (-1);
5565 return (i);
5568 /***************************************************************************
5569 Convert a string to uppercase and remove whitespaces.
5570 ***************************************************************************/
5572 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5574 char *result;
5576 if ( !src ) {
5577 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5578 return NULL;
5581 result = talloc_strdup(ctx, src);
5582 SMB_ASSERT(result != NULL);
5584 strlower_m(result);
5585 return result;
5588 /***************************************************************************
5589 Add a name/index pair for the services array to the hash table.
5590 ***************************************************************************/
5592 static bool hash_a_service(const char *name, int idx)
5594 char *canon_name;
5596 if ( !ServiceHash ) {
5597 DEBUG(10,("hash_a_service: creating servicehash\n"));
5598 ServiceHash = db_open_rbt(NULL);
5599 if ( !ServiceHash ) {
5600 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5601 return false;
5605 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5606 idx, name));
5608 canon_name = canonicalize_servicename(talloc_tos(), name );
5610 dbwrap_store_bystring(ServiceHash, canon_name,
5611 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5612 TDB_REPLACE);
5614 TALLOC_FREE(canon_name);
5616 return true;
5619 /***************************************************************************
5620 Add a new home service, with the specified home directory, defaults coming
5621 from service ifrom.
5622 ***************************************************************************/
5624 bool lp_add_home(const char *pszHomename, int iDefaultService,
5625 const char *user, const char *pszHomedir)
5627 int i;
5629 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5630 pszHomedir[0] == '\0') {
5631 return false;
5634 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5636 if (i < 0)
5637 return false;
5639 if (!(*(ServicePtrs[iDefaultService]->szPath))
5640 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5641 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5644 if (!(*(ServicePtrs[i]->comment))) {
5645 char *comment = NULL;
5646 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5647 return false;
5649 string_set(&ServicePtrs[i]->comment, comment);
5650 SAFE_FREE(comment);
5653 /* set the browseable flag from the global default */
5655 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5656 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
5658 ServicePtrs[i]->autoloaded = true;
5660 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5661 user, ServicePtrs[i]->szPath ));
5663 return true;
5666 /***************************************************************************
5667 Add a new service, based on an old one.
5668 ***************************************************************************/
5670 int lp_add_service(const char *pszService, int iDefaultService)
5672 if (iDefaultService < 0) {
5673 return add_a_service(&sDefault, pszService);
5676 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5679 /***************************************************************************
5680 Add the IPC service.
5681 ***************************************************************************/
5683 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5685 char *comment = NULL;
5686 int i = add_a_service(&sDefault, ipc_name);
5688 if (i < 0)
5689 return false;
5691 if (asprintf(&comment, "IPC Service (%s)",
5692 Globals.szServerString) < 0) {
5693 return false;
5696 string_set(&ServicePtrs[i]->szPath, tmpdir());
5697 string_set(&ServicePtrs[i]->szUsername, "");
5698 string_set(&ServicePtrs[i]->comment, comment);
5699 string_set(&ServicePtrs[i]->fstype, "IPC");
5700 ServicePtrs[i]->iMaxConnections = 0;
5701 ServicePtrs[i]->bAvailable = true;
5702 ServicePtrs[i]->bRead_only = true;
5703 ServicePtrs[i]->bGuest_only = false;
5704 ServicePtrs[i]->bAdministrative_share = true;
5705 ServicePtrs[i]->bGuest_ok = guest_ok;
5706 ServicePtrs[i]->bPrint_ok = false;
5707 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5709 DEBUG(3, ("adding IPC service\n"));
5711 SAFE_FREE(comment);
5712 return true;
5715 /***************************************************************************
5716 Add a new printer service, with defaults coming from service iFrom.
5717 ***************************************************************************/
5719 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5721 const char *comment = "From Printcap";
5722 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5724 if (i < 0)
5725 return false;
5727 /* note that we do NOT default the availability flag to true - */
5728 /* we take it from the default service passed. This allows all */
5729 /* dynamic printers to be disabled by disabling the [printers] */
5730 /* entry (if/when the 'available' keyword is implemented!). */
5732 /* the printer name is set to the service name. */
5733 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5734 string_set(&ServicePtrs[i]->comment, comment);
5736 /* set the browseable flag from the gloabl default */
5737 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5739 /* Printers cannot be read_only. */
5740 ServicePtrs[i]->bRead_only = false;
5741 /* No share modes on printer services. */
5742 ServicePtrs[i]->bShareModes = false;
5743 /* No oplocks on printer services. */
5744 ServicePtrs[i]->bOpLocks = false;
5745 /* Printer services must be printable. */
5746 ServicePtrs[i]->bPrint_ok = true;
5748 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5750 return true;
5754 /***************************************************************************
5755 Check whether the given parameter name is valid.
5756 Parametric options (names containing a colon) are considered valid.
5757 ***************************************************************************/
5759 bool lp_parameter_is_valid(const char *pszParmName)
5761 return ((map_parameter(pszParmName) != -1) ||
5762 (strchr(pszParmName, ':') != NULL));
5765 /***************************************************************************
5766 Check whether the given name is the name of a global parameter.
5767 Returns true for strings belonging to parameters of class
5768 P_GLOBAL, false for all other strings, also for parametric options
5769 and strings not belonging to any option.
5770 ***************************************************************************/
5772 bool lp_parameter_is_global(const char *pszParmName)
5774 int num = map_parameter(pszParmName);
5776 if (num >= 0) {
5777 return (parm_table[num].p_class == P_GLOBAL);
5780 return false;
5783 /**************************************************************************
5784 Check whether the given name is the canonical name of a parameter.
5785 Returns false if it is not a valid parameter Name.
5786 For parametric options, true is returned.
5787 **************************************************************************/
5789 bool lp_parameter_is_canonical(const char *parm_name)
5791 if (!lp_parameter_is_valid(parm_name)) {
5792 return false;
5795 return (map_parameter(parm_name) ==
5796 map_parameter_canonical(parm_name, NULL));
5799 /**************************************************************************
5800 Determine the canonical name for a parameter.
5801 Indicate when it is an inverse (boolean) synonym instead of a
5802 "usual" synonym.
5803 **************************************************************************/
5805 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5806 bool *inverse)
5808 int num;
5810 if (!lp_parameter_is_valid(parm_name)) {
5811 *canon_parm = NULL;
5812 return false;
5815 num = map_parameter_canonical(parm_name, inverse);
5816 if (num < 0) {
5817 /* parametric option */
5818 *canon_parm = parm_name;
5819 } else {
5820 *canon_parm = parm_table[num].label;
5823 return true;
5827 /**************************************************************************
5828 Determine the canonical name for a parameter.
5829 Turn the value given into the inverse boolean expression when
5830 the synonym is an invers boolean synonym.
5832 Return true if parm_name is a valid parameter name and
5833 in case it is an invers boolean synonym, if the val string could
5834 successfully be converted to the reverse bool.
5835 Return false in all other cases.
5836 **************************************************************************/
5838 bool lp_canonicalize_parameter_with_value(const char *parm_name,
5839 const char *val,
5840 const char **canon_parm,
5841 const char **canon_val)
5843 int num;
5844 bool inverse;
5846 if (!lp_parameter_is_valid(parm_name)) {
5847 *canon_parm = NULL;
5848 *canon_val = NULL;
5849 return false;
5852 num = map_parameter_canonical(parm_name, &inverse);
5853 if (num < 0) {
5854 /* parametric option */
5855 *canon_parm = parm_name;
5856 *canon_val = val;
5857 } else {
5858 *canon_parm = parm_table[num].label;
5859 if (inverse) {
5860 if (!lp_invert_boolean(val, canon_val)) {
5861 *canon_val = NULL;
5862 return false;
5864 } else {
5865 *canon_val = val;
5869 return true;
5872 /***************************************************************************
5873 Map a parameter's string representation to something we can use.
5874 Returns false if the parameter string is not recognised, else TRUE.
5875 ***************************************************************************/
5877 static int map_parameter(const char *pszParmName)
5879 int iIndex;
5881 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
5882 return (-1);
5884 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
5885 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
5886 return (iIndex);
5888 /* Warn only if it isn't parametric option */
5889 if (strchr(pszParmName, ':') == NULL)
5890 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
5891 /* We do return 'fail' for parametric options as well because they are
5892 stored in different storage
5894 return (-1);
5897 /***************************************************************************
5898 Map a parameter's string representation to the index of the canonical
5899 form of the parameter (it might be a synonym).
5900 Returns -1 if the parameter string is not recognised.
5901 ***************************************************************************/
5903 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
5905 int parm_num, canon_num;
5906 bool loc_inverse = false;
5908 parm_num = map_parameter(pszParmName);
5909 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
5910 /* invalid, parametric or no canidate for synonyms ... */
5911 goto done;
5914 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
5915 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
5916 parm_num = canon_num;
5917 goto done;
5921 done:
5922 if (inverse != NULL) {
5923 *inverse = loc_inverse;
5925 return parm_num;
5928 /***************************************************************************
5929 return true if parameter number parm1 is a synonym of parameter
5930 number parm2 (parm2 being the principal name).
5931 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
5932 false otherwise.
5933 ***************************************************************************/
5935 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
5937 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
5938 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
5939 (parm_table[parm1].flags & FLAG_HIDE) &&
5940 !(parm_table[parm2].flags & FLAG_HIDE))
5942 if (inverse != NULL) {
5943 if ((parm_table[parm1].type == P_BOOLREV) &&
5944 (parm_table[parm2].type == P_BOOL))
5946 *inverse = true;
5947 } else {
5948 *inverse = false;
5951 return true;
5953 return false;
5956 /***************************************************************************
5957 Show one parameter's name, type, [values,] and flags.
5958 (helper functions for show_parameter_list)
5959 ***************************************************************************/
5961 static void show_parameter(int parmIndex)
5963 int enumIndex, flagIndex;
5964 int parmIndex2;
5965 bool hadFlag;
5966 bool hadSyn;
5967 bool inverse;
5968 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
5969 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
5970 "P_ENUM", "P_SEP"};
5971 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
5972 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
5973 FLAG_HIDE};
5974 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
5975 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
5976 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
5978 printf("%s=%s", parm_table[parmIndex].label,
5979 type[parm_table[parmIndex].type]);
5980 if (parm_table[parmIndex].type == P_ENUM) {
5981 printf(",");
5982 for (enumIndex=0;
5983 parm_table[parmIndex].enum_list[enumIndex].name;
5984 enumIndex++)
5986 printf("%s%s",
5987 enumIndex ? "|" : "",
5988 parm_table[parmIndex].enum_list[enumIndex].name);
5991 printf(",");
5992 hadFlag = false;
5993 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
5994 if (parm_table[parmIndex].flags & flags[flagIndex]) {
5995 printf("%s%s",
5996 hadFlag ? "|" : "",
5997 flag_names[flagIndex]);
5998 hadFlag = true;
6002 /* output synonyms */
6003 hadSyn = false;
6004 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6005 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6006 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6007 parm_table[parmIndex2].label);
6008 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6009 if (!hadSyn) {
6010 printf(" (synonyms: ");
6011 hadSyn = true;
6012 } else {
6013 printf(", ");
6015 printf("%s%s", parm_table[parmIndex2].label,
6016 inverse ? "[i]" : "");
6019 if (hadSyn) {
6020 printf(")");
6023 printf("\n");
6026 /***************************************************************************
6027 Show all parameter's name, type, [values,] and flags.
6028 ***************************************************************************/
6030 void show_parameter_list(void)
6032 int classIndex, parmIndex;
6033 const char *section_names[] = { "local", "global", NULL};
6035 for (classIndex=0; section_names[classIndex]; classIndex++) {
6036 printf("[%s]\n", section_names[classIndex]);
6037 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6038 if (parm_table[parmIndex].p_class == classIndex) {
6039 show_parameter(parmIndex);
6045 /***************************************************************************
6046 Check if a given string correctly represents a boolean value.
6047 ***************************************************************************/
6049 bool lp_string_is_valid_boolean(const char *parm_value)
6051 return set_boolean(parm_value, NULL);
6054 /***************************************************************************
6055 Get the standard string representation of a boolean value ("yes" or "no")
6056 ***************************************************************************/
6058 static const char *get_boolean(bool bool_value)
6060 static const char *yes_str = "yes";
6061 static const char *no_str = "no";
6063 return (bool_value ? yes_str : no_str);
6066 /***************************************************************************
6067 Provide the string of the negated boolean value associated to the boolean
6068 given as a string. Returns false if the passed string does not correctly
6069 represent a boolean.
6070 ***************************************************************************/
6072 bool lp_invert_boolean(const char *str, const char **inverse_str)
6074 bool val;
6076 if (!set_boolean(str, &val)) {
6077 return false;
6080 *inverse_str = get_boolean(!val);
6081 return true;
6084 /***************************************************************************
6085 Provide the canonical string representation of a boolean value given
6086 as a string. Return true on success, false if the string given does
6087 not correctly represent a boolean.
6088 ***************************************************************************/
6090 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6092 bool val;
6094 if (!set_boolean(str, &val)) {
6095 return false;
6098 *canon_str = get_boolean(val);
6099 return true;
6102 /***************************************************************************
6103 Find a service by name. Otherwise works like get_service.
6104 ***************************************************************************/
6106 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6108 int iService = -1;
6109 char *canon_name;
6110 TDB_DATA data;
6111 NTSTATUS status;
6113 if (ServiceHash == NULL) {
6114 return -1;
6117 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6119 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
6120 &data);
6122 if (NT_STATUS_IS_OK(status) &&
6123 (data.dptr != NULL) &&
6124 (data.dsize == sizeof(iService)))
6126 iService = *(int *)data.dptr;
6129 TALLOC_FREE(canon_name);
6131 if ((iService != -1) && (LP_SNUM_OK(iService))
6132 && (pserviceDest != NULL)) {
6133 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6136 return (iService);
6139 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6140 struct loadparm_service *lp_service(const char *pszServiceName)
6142 int iService = getservicebyname(pszServiceName, NULL);
6143 if (iService == -1 || !LP_SNUM_OK(iService)) {
6144 return NULL;
6146 return ServicePtrs[iService];
6149 struct loadparm_service *lp_servicebynum(int snum)
6151 if ((snum == -1) || !LP_SNUM_OK(snum)) {
6152 return NULL;
6154 return ServicePtrs[snum];
6157 struct loadparm_service *lp_default_loadparm_service()
6159 return &sDefault;
6163 /***************************************************************************
6164 Copy a service structure to another.
6165 If pcopymapDest is NULL then copy all fields
6166 ***************************************************************************/
6169 * Add a parametric option to a parmlist_entry,
6170 * replacing old value, if already present.
6172 static void set_param_opt(struct parmlist_entry **opt_list,
6173 const char *opt_name,
6174 const char *opt_value,
6175 unsigned priority)
6177 struct parmlist_entry *new_opt, *opt;
6178 bool not_added;
6180 if (opt_list == NULL) {
6181 return;
6184 opt = *opt_list;
6185 not_added = true;
6187 /* Traverse destination */
6188 while (opt) {
6189 /* If we already have same option, override it */
6190 if (strwicmp(opt->key, opt_name) == 0) {
6191 if ((opt->priority & FLAG_CMDLINE) &&
6192 !(priority & FLAG_CMDLINE)) {
6193 /* it's been marked as not to be
6194 overridden */
6195 return;
6197 string_free(&opt->value);
6198 TALLOC_FREE(opt->list);
6199 opt->value = SMB_STRDUP(opt_value);
6200 opt->priority = priority;
6201 not_added = false;
6202 break;
6204 opt = opt->next;
6206 if (not_added) {
6207 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
6208 new_opt->key = SMB_STRDUP(opt_name);
6209 new_opt->value = SMB_STRDUP(opt_value);
6210 new_opt->list = NULL;
6211 new_opt->priority = priority;
6212 DLIST_ADD(*opt_list, new_opt);
6216 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6217 struct bitmap *pcopymapDest)
6219 int i;
6220 bool bcopyall = (pcopymapDest == NULL);
6221 struct parmlist_entry *data;
6223 for (i = 0; parm_table[i].label; i++)
6224 if (parm_table[i].p_class == P_LOCAL &&
6225 (bcopyall || bitmap_query(pcopymapDest,i))) {
6226 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6227 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6229 switch (parm_table[i].type) {
6230 case P_BOOL:
6231 case P_BOOLREV:
6232 *(bool *)dest_ptr = *(bool *)src_ptr;
6233 break;
6235 case P_INTEGER:
6236 case P_ENUM:
6237 case P_OCTAL:
6238 case P_BYTES:
6239 *(int *)dest_ptr = *(int *)src_ptr;
6240 break;
6242 case P_CHAR:
6243 *(char *)dest_ptr = *(char *)src_ptr;
6244 break;
6246 case P_STRING:
6247 string_set((char **)dest_ptr,
6248 *(char **)src_ptr);
6249 break;
6251 case P_USTRING:
6253 char *upper_string = strupper_talloc(talloc_tos(),
6254 *(char **)src_ptr);
6255 string_set((char **)dest_ptr,
6256 upper_string);
6257 TALLOC_FREE(upper_string);
6258 break;
6260 case P_LIST:
6261 TALLOC_FREE(*((char ***)dest_ptr));
6262 *((char ***)dest_ptr) = str_list_copy(NULL,
6263 *(const char ***)src_ptr);
6264 break;
6265 default:
6266 break;
6270 if (bcopyall) {
6271 init_copymap(pserviceDest);
6272 if (pserviceSource->copymap)
6273 bitmap_copy(pserviceDest->copymap,
6274 pserviceSource->copymap);
6277 data = pserviceSource->param_opt;
6278 while (data) {
6279 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6280 data = data->next;
6284 /***************************************************************************
6285 Check a service for consistency. Return false if the service is in any way
6286 incomplete or faulty, else true.
6287 ***************************************************************************/
6289 bool service_ok(int iService)
6291 bool bRetval;
6293 bRetval = true;
6294 if (ServicePtrs[iService]->szService[0] == '\0') {
6295 DEBUG(0, ("The following message indicates an internal error:\n"));
6296 DEBUG(0, ("No service name in service entry.\n"));
6297 bRetval = false;
6300 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6301 /* I can't see why you'd want a non-printable printer service... */
6302 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6303 if (!ServicePtrs[iService]->bPrint_ok) {
6304 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6305 ServicePtrs[iService]->szService));
6306 ServicePtrs[iService]->bPrint_ok = true;
6308 /* [printers] service must also be non-browsable. */
6309 if (ServicePtrs[iService]->bBrowseable)
6310 ServicePtrs[iService]->bBrowseable = false;
6313 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6314 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6315 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6317 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6318 ServicePtrs[iService]->szService));
6319 ServicePtrs[iService]->bAvailable = false;
6322 /* If a service is flagged unavailable, log the fact at level 1. */
6323 if (!ServicePtrs[iService]->bAvailable)
6324 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6325 ServicePtrs[iService]->szService));
6327 return (bRetval);
6330 static struct smbconf_ctx *lp_smbconf_ctx(void)
6332 sbcErr err;
6333 static struct smbconf_ctx *conf_ctx = NULL;
6335 if (conf_ctx == NULL) {
6336 err = smbconf_init(NULL, &conf_ctx, "registry:");
6337 if (!SBC_ERROR_IS_OK(err)) {
6338 DEBUG(1, ("error initializing registry configuration: "
6339 "%s\n", sbcErrorString(err)));
6340 conf_ctx = NULL;
6344 return conf_ctx;
6347 static bool process_smbconf_service(struct smbconf_service *service)
6349 uint32_t count;
6350 bool ret;
6352 if (service == NULL) {
6353 return false;
6356 ret = do_section(service->name, NULL);
6357 if (ret != true) {
6358 return false;
6360 for (count = 0; count < service->num_params; count++) {
6361 ret = do_parameter(service->param_names[count],
6362 service->param_values[count],
6363 NULL);
6364 if (ret != true) {
6365 return false;
6368 if (iServiceIndex >= 0) {
6369 return service_ok(iServiceIndex);
6371 return true;
6375 * load a service from registry and activate it
6377 bool process_registry_service(const char *service_name)
6379 sbcErr err;
6380 struct smbconf_service *service = NULL;
6381 TALLOC_CTX *mem_ctx = talloc_stackframe();
6382 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6383 bool ret = false;
6385 if (conf_ctx == NULL) {
6386 goto done;
6389 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6391 if (!smbconf_share_exists(conf_ctx, service_name)) {
6393 * Registry does not contain data for this service (yet),
6394 * but make sure lp_load doesn't return false.
6396 ret = true;
6397 goto done;
6400 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6401 if (!SBC_ERROR_IS_OK(err)) {
6402 goto done;
6405 ret = process_smbconf_service(service);
6406 if (!ret) {
6407 goto done;
6410 /* store the csn */
6411 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6413 done:
6414 TALLOC_FREE(mem_ctx);
6415 return ret;
6419 * process_registry_globals
6421 static bool process_registry_globals(void)
6423 bool ret;
6425 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6427 ret = do_parameter("registry shares", "yes", NULL);
6428 if (!ret) {
6429 return ret;
6432 return process_registry_service(GLOBAL_NAME);
6435 bool process_registry_shares(void)
6437 sbcErr err;
6438 uint32_t count;
6439 struct smbconf_service **service = NULL;
6440 uint32_t num_shares = 0;
6441 TALLOC_CTX *mem_ctx = talloc_stackframe();
6442 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6443 bool ret = false;
6445 if (conf_ctx == NULL) {
6446 goto done;
6449 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6450 if (!SBC_ERROR_IS_OK(err)) {
6451 goto done;
6454 ret = true;
6456 for (count = 0; count < num_shares; count++) {
6457 if (strequal(service[count]->name, GLOBAL_NAME)) {
6458 continue;
6460 ret = process_smbconf_service(service[count]);
6461 if (!ret) {
6462 goto done;
6466 /* store the csn */
6467 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6469 done:
6470 TALLOC_FREE(mem_ctx);
6471 return ret;
6475 * reload those shares from registry that are already
6476 * activated in the services array.
6478 static bool reload_registry_shares(void)
6480 int i;
6481 bool ret = true;
6483 for (i = 0; i < iNumServices; i++) {
6484 if (!VALID(i)) {
6485 continue;
6488 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
6489 continue;
6492 ret = process_registry_service(ServicePtrs[i]->szService);
6493 if (!ret) {
6494 goto done;
6498 done:
6499 return ret;
6503 #define MAX_INCLUDE_DEPTH 100
6505 static uint8_t include_depth;
6507 static struct file_lists {
6508 struct file_lists *next;
6509 char *name;
6510 char *subfname;
6511 time_t modtime;
6512 } *file_lists = NULL;
6514 /*******************************************************************
6515 Keep a linked list of all config files so we know when one has changed
6516 it's date and needs to be reloaded.
6517 ********************************************************************/
6519 static void add_to_file_list(const char *fname, const char *subfname)
6521 struct file_lists *f = file_lists;
6523 while (f) {
6524 if (f->name && !strcmp(f->name, fname))
6525 break;
6526 f = f->next;
6529 if (!f) {
6530 f = SMB_MALLOC_P(struct file_lists);
6531 if (!f)
6532 return;
6533 f->next = file_lists;
6534 f->name = SMB_STRDUP(fname);
6535 if (!f->name) {
6536 SAFE_FREE(f);
6537 return;
6539 f->subfname = SMB_STRDUP(subfname);
6540 if (!f->subfname) {
6541 SAFE_FREE(f->name);
6542 SAFE_FREE(f);
6543 return;
6545 file_lists = f;
6546 f->modtime = file_modtime(subfname);
6547 } else {
6548 time_t t = file_modtime(subfname);
6549 if (t)
6550 f->modtime = t;
6552 return;
6556 * Free the file lists
6558 static void free_file_list(void)
6560 struct file_lists *f;
6561 struct file_lists *next;
6563 f = file_lists;
6564 while( f ) {
6565 next = f->next;
6566 SAFE_FREE( f->name );
6567 SAFE_FREE( f->subfname );
6568 SAFE_FREE( f );
6569 f = next;
6571 file_lists = NULL;
6576 * Utility function for outsiders to check if we're running on registry.
6578 bool lp_config_backend_is_registry(void)
6580 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6584 * Utility function to check if the config backend is FILE.
6586 bool lp_config_backend_is_file(void)
6588 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6591 /*******************************************************************
6592 Check if a config file has changed date.
6593 ********************************************************************/
6595 bool lp_file_list_changed(void)
6597 struct file_lists *f = file_lists;
6599 DEBUG(6, ("lp_file_list_changed()\n"));
6601 while (f) {
6602 time_t mod_time;
6604 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6605 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6607 if (conf_ctx == NULL) {
6608 return false;
6610 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6611 NULL))
6613 DEBUGADD(6, ("registry config changed\n"));
6614 return true;
6616 } else {
6617 char *n2 = NULL;
6618 n2 = talloc_sub_basic(talloc_tos(),
6619 get_current_username(),
6620 current_user_info.domain,
6621 f->name);
6622 if (!n2) {
6623 return false;
6625 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6626 f->name, n2, ctime(&f->modtime)));
6628 mod_time = file_modtime(n2);
6630 if (mod_time &&
6631 ((f->modtime != mod_time) ||
6632 (f->subfname == NULL) ||
6633 (strcmp(n2, f->subfname) != 0)))
6635 DEBUGADD(6,
6636 ("file %s modified: %s\n", n2,
6637 ctime(&mod_time)));
6638 f->modtime = mod_time;
6639 SAFE_FREE(f->subfname);
6640 f->subfname = SMB_STRDUP(n2);
6641 TALLOC_FREE(n2);
6642 return true;
6644 TALLOC_FREE(n2);
6646 f = f->next;
6648 return false;
6653 * Initialize iconv conversion descriptors.
6655 * This is called the first time it is needed, and also called again
6656 * every time the configuration is reloaded, because the charset or
6657 * codepage might have changed.
6659 static void init_iconv(void)
6661 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
6662 lp_unix_charset(),
6663 true, global_iconv_handle);
6666 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6668 if (strcmp(*ptr, pszParmValue) != 0) {
6669 string_set(ptr, pszParmValue);
6670 init_iconv();
6672 return true;
6675 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6677 bool is_utf8 = false;
6678 size_t len = strlen(pszParmValue);
6680 if (len == 4 || len == 5) {
6681 /* Don't use StrCaseCmp here as we don't want to
6682 initialize iconv. */
6683 if ((toupper_m(pszParmValue[0]) == 'U') &&
6684 (toupper_m(pszParmValue[1]) == 'T') &&
6685 (toupper_m(pszParmValue[2]) == 'F')) {
6686 if (len == 4) {
6687 if (pszParmValue[3] == '8') {
6688 is_utf8 = true;
6690 } else {
6691 if (pszParmValue[3] == '-' &&
6692 pszParmValue[4] == '8') {
6693 is_utf8 = true;
6699 if (strcmp(*ptr, pszParmValue) != 0) {
6700 if (is_utf8) {
6701 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6702 "be UTF8, using (default value) %s instead.\n",
6703 DEFAULT_DOS_CHARSET));
6704 pszParmValue = DEFAULT_DOS_CHARSET;
6706 string_set(ptr, pszParmValue);
6707 init_iconv();
6709 return true;
6712 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6714 bool ret = true;
6715 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
6716 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
6718 ret &= string_set(&Globals.szRealm, pszParmValue);
6719 ret &= string_set(&Globals.szRealm_upper, realm);
6720 ret &= string_set(&Globals.szRealm_lower, dnsdomain);
6721 TALLOC_FREE(realm);
6722 TALLOC_FREE(dnsdomain);
6724 return ret;
6727 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6729 TALLOC_FREE(Globals.szNetbiosAliases);
6730 Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
6731 return set_netbios_aliases(Globals.szNetbiosAliases);
6734 /***************************************************************************
6735 Handle the include operation.
6736 ***************************************************************************/
6737 static bool bAllowIncludeRegistry = true;
6739 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6741 char *fname;
6743 if (include_depth >= MAX_INCLUDE_DEPTH) {
6744 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6745 include_depth));
6746 return false;
6749 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6750 if (!bAllowIncludeRegistry) {
6751 return true;
6753 if (bInGlobalSection) {
6754 bool ret;
6755 include_depth++;
6756 ret = process_registry_globals();
6757 include_depth--;
6758 return ret;
6759 } else {
6760 DEBUG(1, ("\"include = registry\" only effective "
6761 "in %s section\n", GLOBAL_NAME));
6762 return false;
6766 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
6767 current_user_info.domain,
6768 pszParmValue);
6770 add_to_file_list(pszParmValue, fname);
6772 string_set(ptr, fname);
6774 if (file_exist(fname)) {
6775 bool ret;
6776 include_depth++;
6777 ret = pm_process(fname, do_section, do_parameter, NULL);
6778 include_depth--;
6779 TALLOC_FREE(fname);
6780 return ret;
6783 DEBUG(2, ("Can't find include file %s\n", fname));
6784 TALLOC_FREE(fname);
6785 return true;
6788 /***************************************************************************
6789 Handle the interpretation of the copy parameter.
6790 ***************************************************************************/
6792 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6794 bool bRetval;
6795 int iTemp;
6796 struct loadparm_service serviceTemp;
6798 string_set(ptr, pszParmValue);
6800 init_service(&serviceTemp);
6802 bRetval = false;
6804 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6806 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6807 if (iTemp == iServiceIndex) {
6808 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6809 } else {
6810 copy_service(ServicePtrs[iServiceIndex],
6811 &serviceTemp,
6812 ServicePtrs[iServiceIndex]->copymap);
6813 bRetval = true;
6815 } else {
6816 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6817 bRetval = false;
6820 free_service(&serviceTemp);
6821 return (bRetval);
6824 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6826 Globals.ldap_debug_level = lp_int(pszParmValue);
6827 init_ldap_debugging();
6828 return true;
6831 /***************************************************************************
6832 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6833 parameters is:
6835 [global]
6837 idmap uid = 1000-1999
6838 idmap gid = 700-899
6840 We only do simple parsing checks here. The strings are parsed into useful
6841 structures in the idmap daemon code.
6843 ***************************************************************************/
6845 /* Some lp_ routines to return idmap [ug]id information */
6847 static uid_t idmap_uid_low, idmap_uid_high;
6848 static gid_t idmap_gid_low, idmap_gid_high;
6850 bool lp_idmap_uid(uid_t *low, uid_t *high)
6852 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6853 return false;
6855 if (low)
6856 *low = idmap_uid_low;
6858 if (high)
6859 *high = idmap_uid_high;
6861 return true;
6864 bool lp_idmap_gid(gid_t *low, gid_t *high)
6866 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6867 return false;
6869 if (low)
6870 *low = idmap_gid_low;
6872 if (high)
6873 *high = idmap_gid_high;
6875 return true;
6878 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6880 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
6882 return true;
6885 /* Do some simple checks on "idmap [ug]id" parameter values */
6887 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6889 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
6891 return true;
6894 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6896 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
6898 return true;
6901 /***************************************************************************
6902 Handle the DEBUG level list.
6903 ***************************************************************************/
6905 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
6907 string_set(ptr, pszParmValueIn);
6908 return debug_parse_levels(pszParmValueIn);
6911 /***************************************************************************
6912 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6913 ***************************************************************************/
6915 static const char *append_ldap_suffix( const char *str )
6917 const char *suffix_string;
6920 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6921 Globals.szLdapSuffix );
6922 if ( !suffix_string ) {
6923 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6924 return "";
6927 return suffix_string;
6930 const char *lp_ldap_machine_suffix(void)
6932 if (Globals.szLdapMachineSuffix[0])
6933 return append_ldap_suffix(Globals.szLdapMachineSuffix);
6935 return lp_string(Globals.szLdapSuffix);
6938 const char *lp_ldap_user_suffix(void)
6940 if (Globals.szLdapUserSuffix[0])
6941 return append_ldap_suffix(Globals.szLdapUserSuffix);
6943 return lp_string(Globals.szLdapSuffix);
6946 const char *lp_ldap_group_suffix(void)
6948 if (Globals.szLdapGroupSuffix[0])
6949 return append_ldap_suffix(Globals.szLdapGroupSuffix);
6951 return lp_string(Globals.szLdapSuffix);
6954 const char *lp_ldap_idmap_suffix(void)
6956 if (Globals.szLdapIdmapSuffix[0])
6957 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
6959 return lp_string(Globals.szLdapSuffix);
6962 /****************************************************************************
6963 set the value for a P_ENUM
6964 ***************************************************************************/
6966 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
6967 int *ptr )
6969 int i;
6971 for (i = 0; parm->enum_list[i].name; i++) {
6972 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
6973 *ptr = parm->enum_list[i].value;
6974 return;
6977 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
6978 pszParmValue, parm->label));
6981 /***************************************************************************
6982 ***************************************************************************/
6984 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6986 static int parm_num = -1;
6987 struct loadparm_service *s;
6989 if ( parm_num == -1 )
6990 parm_num = map_parameter( "printing" );
6992 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
6994 if ( snum < 0 )
6995 s = &sDefault;
6996 else
6997 s = ServicePtrs[snum];
6999 init_printer_values( s );
7001 return true;
7005 /***************************************************************************
7006 Initialise a copymap.
7007 ***************************************************************************/
7009 static void init_copymap(struct loadparm_service *pservice)
7011 int i;
7013 TALLOC_FREE(pservice->copymap);
7015 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7016 if (!pservice->copymap)
7017 DEBUG(0,
7018 ("Couldn't allocate copymap!! (size %d)\n",
7019 (int)NUMPARAMETERS));
7020 else
7021 for (i = 0; i < NUMPARAMETERS; i++)
7022 bitmap_set(pservice->copymap, i);
7026 return the parameter pointer for a parameter
7028 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7030 if (service == NULL) {
7031 if (parm->p_class == P_LOCAL)
7032 return (void *)(((char *)&sDefault)+parm->offset);
7033 else if (parm->p_class == P_GLOBAL)
7034 return (void *)(((char *)&Globals)+parm->offset);
7035 else return NULL;
7036 } else {
7037 return (void *)(((char *)service) + parm->offset);
7041 /***************************************************************************
7042 Return the local pointer to a parameter given the service number and parameter
7043 ***************************************************************************/
7045 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7047 return lp_parm_ptr(ServicePtrs[snum], parm);
7050 /***************************************************************************
7051 Process a parameter for a particular service number. If snum < 0
7052 then assume we are in the globals.
7053 ***************************************************************************/
7055 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7057 int parmnum, i;
7058 void *parm_ptr = NULL; /* where we are going to store the result */
7059 struct parmlist_entry **opt_list;
7061 parmnum = map_parameter(pszParmName);
7063 if (parmnum < 0) {
7064 if (strchr(pszParmName, ':') == NULL) {
7065 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7066 pszParmName));
7067 return true;
7071 * We've got a parametric option
7074 opt_list = (snum < 0)
7075 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7076 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7078 return true;
7081 /* if it's already been set by the command line, then we don't
7082 override here */
7083 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7084 return true;
7087 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7088 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7089 pszParmName));
7092 /* we might point at a service, the default service or a global */
7093 if (snum < 0) {
7094 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7095 } else {
7096 if (parm_table[parmnum].p_class == P_GLOBAL) {
7097 DEBUG(0,
7098 ("Global parameter %s found in service section!\n",
7099 pszParmName));
7100 return true;
7102 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7105 if (snum >= 0) {
7106 if (!ServicePtrs[snum]->copymap)
7107 init_copymap(ServicePtrs[snum]);
7109 /* this handles the aliases - set the copymap for other entries with
7110 the same data pointer */
7111 for (i = 0; parm_table[i].label; i++) {
7112 if ((parm_table[i].offset == parm_table[parmnum].offset)
7113 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
7114 bitmap_clear(ServicePtrs[snum]->copymap, i);
7119 /* if it is a special case then go ahead */
7120 if (parm_table[parmnum].special) {
7121 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7122 (char **)parm_ptr);
7125 /* now switch on the type of variable it is */
7126 switch (parm_table[parmnum].type)
7128 case P_BOOL:
7129 *(bool *)parm_ptr = lp_bool(pszParmValue);
7130 break;
7132 case P_BOOLREV:
7133 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7134 break;
7136 case P_INTEGER:
7137 *(int *)parm_ptr = lp_int(pszParmValue);
7138 break;
7140 case P_CHAR:
7141 *(char *)parm_ptr = *pszParmValue;
7142 break;
7144 case P_OCTAL:
7145 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7146 if ( i != 1 ) {
7147 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7149 break;
7151 case P_BYTES:
7153 uint64_t val;
7154 if (conv_str_size_error(pszParmValue, &val)) {
7155 if (val <= INT_MAX) {
7156 *(int *)parm_ptr = (int)val;
7157 break;
7161 DEBUG(0,("lp_do_parameter(%s): value is not "
7162 "a valid size specifier!\n", pszParmValue));
7163 return false;
7166 case P_LIST:
7167 case P_CMDLIST:
7168 TALLOC_FREE(*((char ***)parm_ptr));
7169 *(char ***)parm_ptr = str_list_make_v3(
7170 NULL, pszParmValue, NULL);
7171 break;
7173 case P_STRING:
7174 string_set((char **)parm_ptr, pszParmValue);
7175 break;
7177 case P_USTRING:
7179 char *upper_string = strupper_talloc(talloc_tos(),
7180 pszParmValue);
7181 string_set((char **)parm_ptr, upper_string);
7182 TALLOC_FREE(upper_string);
7183 break;
7185 case P_ENUM:
7186 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7187 break;
7188 case P_SEP:
7189 break;
7192 return true;
7195 /***************************************************************************
7196 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7197 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7198 ***************************************************************************/
7200 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7202 int parmnum, i;
7203 parmnum = map_parameter(pszParmName);
7204 if (parmnum >= 0) {
7205 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7206 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7207 return false;
7209 parm_table[parmnum].flags |= FLAG_CMDLINE;
7211 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7212 * be grouped in the table, so we don't have to search the
7213 * whole table */
7214 for (i=parmnum-1;
7215 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7216 && parm_table[i].p_class == parm_table[parmnum].p_class;
7217 i--) {
7218 parm_table[i].flags |= FLAG_CMDLINE;
7220 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
7221 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
7222 parm_table[i].flags |= FLAG_CMDLINE;
7225 if (store_values) {
7226 store_lp_set_cmdline(pszParmName, pszParmValue);
7228 return true;
7231 /* it might be parametric */
7232 if (strchr(pszParmName, ':') != NULL) {
7233 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7234 if (store_values) {
7235 store_lp_set_cmdline(pszParmName, pszParmValue);
7237 return true;
7240 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7241 return true;
7244 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7246 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7249 /***************************************************************************
7250 Process a parameter.
7251 ***************************************************************************/
7253 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7254 void *userdata)
7256 if (!bInGlobalSection && bGlobalOnly)
7257 return true;
7259 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7261 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7262 pszParmName, pszParmValue));
7266 set a option from the commandline in 'a=b' format. Use to support --option
7268 bool lp_set_option(const char *option)
7270 char *p, *s;
7271 bool ret;
7273 s = talloc_strdup(NULL, option);
7274 if (!s) {
7275 return false;
7278 p = strchr(s, '=');
7279 if (!p) {
7280 talloc_free(s);
7281 return false;
7284 *p = 0;
7286 /* skip white spaces after the = sign */
7287 do {
7288 p++;
7289 } while (*p == ' ');
7291 ret = lp_set_cmdline(s, p);
7292 talloc_free(s);
7293 return ret;
7296 /**************************************************************************
7297 Print a parameter of the specified type.
7298 ***************************************************************************/
7300 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7302 /* For the seperation of lists values that we print below */
7303 const char *list_sep = ", ";
7304 int i;
7305 switch (p->type)
7307 case P_ENUM:
7308 for (i = 0; p->enum_list[i].name; i++) {
7309 if (*(int *)ptr == p->enum_list[i].value) {
7310 fprintf(f, "%s",
7311 p->enum_list[i].name);
7312 break;
7315 break;
7317 case P_BOOL:
7318 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7319 break;
7321 case P_BOOLREV:
7322 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7323 break;
7325 case P_INTEGER:
7326 case P_BYTES:
7327 fprintf(f, "%d", *(int *)ptr);
7328 break;
7330 case P_CHAR:
7331 fprintf(f, "%c", *(char *)ptr);
7332 break;
7334 case P_OCTAL: {
7335 int val = *(int *)ptr;
7336 if (val == -1) {
7337 fprintf(f, "-1");
7338 } else {
7339 fprintf(f, "0%o", val);
7341 break;
7344 case P_CMDLIST:
7345 list_sep = " ";
7346 /* fall through */
7347 case P_LIST:
7348 if ((char ***)ptr && *(char ***)ptr) {
7349 char **list = *(char ***)ptr;
7350 for (; *list; list++) {
7351 /* surround strings with whitespace in double quotes */
7352 if (*(list+1) == NULL) {
7353 /* last item, no extra separator */
7354 list_sep = "";
7356 if ( strchr_m( *list, ' ' ) ) {
7357 fprintf(f, "\"%s\"%s", *list, list_sep);
7358 } else {
7359 fprintf(f, "%s%s", *list, list_sep);
7363 break;
7365 case P_STRING:
7366 case P_USTRING:
7367 if (*(char **)ptr) {
7368 fprintf(f, "%s", *(char **)ptr);
7370 break;
7371 case P_SEP:
7372 break;
7376 /***************************************************************************
7377 Check if two parameters are equal.
7378 ***************************************************************************/
7380 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7382 switch (type) {
7383 case P_BOOL:
7384 case P_BOOLREV:
7385 return (*((bool *)ptr1) == *((bool *)ptr2));
7387 case P_INTEGER:
7388 case P_ENUM:
7389 case P_OCTAL:
7390 case P_BYTES:
7391 return (*((int *)ptr1) == *((int *)ptr2));
7393 case P_CHAR:
7394 return (*((char *)ptr1) == *((char *)ptr2));
7396 case P_LIST:
7397 case P_CMDLIST:
7398 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7400 case P_STRING:
7401 case P_USTRING:
7403 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7404 if (p1 && !*p1)
7405 p1 = NULL;
7406 if (p2 && !*p2)
7407 p2 = NULL;
7408 return (p1 == p2 || strequal(p1, p2));
7410 case P_SEP:
7411 break;
7413 return false;
7416 /***************************************************************************
7417 Initialize any local varients in the sDefault table.
7418 ***************************************************************************/
7420 void init_locals(void)
7422 /* None as yet. */
7425 /***************************************************************************
7426 Process a new section (service). At this stage all sections are services.
7427 Later we'll have special sections that permit server parameters to be set.
7428 Returns true on success, false on failure.
7429 ***************************************************************************/
7431 static bool do_section(const char *pszSectionName, void *userdata)
7433 bool bRetval;
7434 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7435 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7436 bRetval = false;
7438 /* if we were in a global section then do the local inits */
7439 if (bInGlobalSection && !isglobal)
7440 init_locals();
7442 /* if we've just struck a global section, note the fact. */
7443 bInGlobalSection = isglobal;
7445 /* check for multiple global sections */
7446 if (bInGlobalSection) {
7447 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7448 return true;
7451 if (!bInGlobalSection && bGlobalOnly)
7452 return true;
7454 /* if we have a current service, tidy it up before moving on */
7455 bRetval = true;
7457 if (iServiceIndex >= 0)
7458 bRetval = service_ok(iServiceIndex);
7460 /* if all is still well, move to the next record in the services array */
7461 if (bRetval) {
7462 /* We put this here to avoid an odd message order if messages are */
7463 /* issued by the post-processing of a previous section. */
7464 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7466 iServiceIndex = add_a_service(&sDefault, pszSectionName);
7467 if (iServiceIndex < 0) {
7468 DEBUG(0, ("Failed to add a new service\n"));
7469 return false;
7471 /* Clean all parametric options for service */
7472 /* They will be added during parsing again */
7473 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7476 return bRetval;
7480 /***************************************************************************
7481 Determine if a partcular base parameter is currentl set to the default value.
7482 ***************************************************************************/
7484 static bool is_default(int i)
7486 if (!defaults_saved)
7487 return false;
7488 switch (parm_table[i].type) {
7489 case P_LIST:
7490 case P_CMDLIST:
7491 return str_list_equal((const char **)parm_table[i].def.lvalue,
7492 *(const char ***)lp_parm_ptr(NULL,
7493 &parm_table[i]));
7494 case P_STRING:
7495 case P_USTRING:
7496 return strequal(parm_table[i].def.svalue,
7497 *(char **)lp_parm_ptr(NULL,
7498 &parm_table[i]));
7499 case P_BOOL:
7500 case P_BOOLREV:
7501 return parm_table[i].def.bvalue ==
7502 *(bool *)lp_parm_ptr(NULL,
7503 &parm_table[i]);
7504 case P_CHAR:
7505 return parm_table[i].def.cvalue ==
7506 *(char *)lp_parm_ptr(NULL,
7507 &parm_table[i]);
7508 case P_INTEGER:
7509 case P_OCTAL:
7510 case P_ENUM:
7511 case P_BYTES:
7512 return parm_table[i].def.ivalue ==
7513 *(int *)lp_parm_ptr(NULL,
7514 &parm_table[i]);
7515 case P_SEP:
7516 break;
7518 return false;
7521 /***************************************************************************
7522 Display the contents of the global structure.
7523 ***************************************************************************/
7525 static void dump_globals(FILE *f)
7527 int i;
7528 struct parmlist_entry *data;
7530 fprintf(f, "[global]\n");
7532 for (i = 0; parm_table[i].label; i++)
7533 if (parm_table[i].p_class == P_GLOBAL &&
7534 !(parm_table[i].flags & FLAG_META) &&
7535 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
7536 if (defaults_saved && is_default(i))
7537 continue;
7538 fprintf(f, "\t%s = ", parm_table[i].label);
7539 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7540 &parm_table[i]),
7542 fprintf(f, "\n");
7544 if (Globals.param_opt != NULL) {
7545 data = Globals.param_opt;
7546 while(data) {
7547 fprintf(f, "\t%s = %s\n", data->key, data->value);
7548 data = data->next;
7554 /***************************************************************************
7555 Return true if a local parameter is currently set to the global default.
7556 ***************************************************************************/
7558 bool lp_is_default(int snum, struct parm_struct *parm)
7560 return equal_parameter(parm->type,
7561 lp_parm_ptr(ServicePtrs[snum], parm),
7562 lp_parm_ptr(NULL, parm));
7565 /***************************************************************************
7566 Display the contents of a single services record.
7567 ***************************************************************************/
7569 static void dump_a_service(struct loadparm_service *pService, FILE * f)
7571 int i;
7572 struct parmlist_entry *data;
7574 if (pService != &sDefault)
7575 fprintf(f, "[%s]\n", pService->szService);
7577 for (i = 0; parm_table[i].label; i++) {
7579 if (parm_table[i].p_class == P_LOCAL &&
7580 !(parm_table[i].flags & FLAG_META) &&
7581 (*parm_table[i].label != '-') &&
7582 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7584 if (pService == &sDefault) {
7585 if (defaults_saved && is_default(i))
7586 continue;
7587 } else {
7588 if (equal_parameter(parm_table[i].type,
7589 lp_parm_ptr(pService, &parm_table[i]),
7590 lp_parm_ptr(NULL, &parm_table[i])))
7591 continue;
7594 fprintf(f, "\t%s = ", parm_table[i].label);
7595 print_parameter(&parm_table[i],
7596 lp_parm_ptr(pService, &parm_table[i]),
7598 fprintf(f, "\n");
7602 if (pService->param_opt != NULL) {
7603 data = pService->param_opt;
7604 while(data) {
7605 fprintf(f, "\t%s = %s\n", data->key, data->value);
7606 data = data->next;
7611 /***************************************************************************
7612 Display the contents of a parameter of a single services record.
7613 ***************************************************************************/
7615 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7617 int i;
7618 bool result = false;
7619 parm_class p_class;
7620 unsigned flag = 0;
7621 fstring local_parm_name;
7622 char *parm_opt;
7623 const char *parm_opt_value;
7625 /* check for parametrical option */
7626 fstrcpy( local_parm_name, parm_name);
7627 parm_opt = strchr( local_parm_name, ':');
7629 if (parm_opt) {
7630 *parm_opt = '\0';
7631 parm_opt++;
7632 if (strlen(parm_opt)) {
7633 parm_opt_value = lp_parm_const_string( snum,
7634 local_parm_name, parm_opt, NULL);
7635 if (parm_opt_value) {
7636 printf( "%s\n", parm_opt_value);
7637 result = true;
7640 return result;
7643 /* check for a key and print the value */
7644 if (isGlobal) {
7645 p_class = P_GLOBAL;
7646 flag = FLAG_GLOBAL;
7647 } else
7648 p_class = P_LOCAL;
7650 for (i = 0; parm_table[i].label; i++) {
7651 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7652 !(parm_table[i].flags & FLAG_META) &&
7653 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7654 (*parm_table[i].label != '-') &&
7655 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7657 void *ptr;
7659 if (isGlobal) {
7660 ptr = lp_parm_ptr(NULL,
7661 &parm_table[i]);
7662 } else {
7663 ptr = lp_parm_ptr(ServicePtrs[snum],
7664 &parm_table[i]);
7667 print_parameter(&parm_table[i],
7668 ptr, f);
7669 fprintf(f, "\n");
7670 result = true;
7671 break;
7675 return result;
7678 /***************************************************************************
7679 Return info about the requested parameter (given as a string).
7680 Return NULL when the string is not a valid parameter name.
7681 ***************************************************************************/
7683 struct parm_struct *lp_get_parameter(const char *param_name)
7685 int num = map_parameter(param_name);
7687 if (num < 0) {
7688 return NULL;
7691 return &parm_table[num];
7694 /***************************************************************************
7695 Return info about the next parameter in a service.
7696 snum==GLOBAL_SECTION_SNUM gives the globals.
7697 Return NULL when out of parameters.
7698 ***************************************************************************/
7700 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7702 if (snum < 0) {
7703 /* do the globals */
7704 for (; parm_table[*i].label; (*i)++) {
7705 if (parm_table[*i].p_class == P_SEPARATOR)
7706 return &parm_table[(*i)++];
7708 if ((*parm_table[*i].label == '-'))
7709 continue;
7711 if ((*i) > 0
7712 && (parm_table[*i].offset ==
7713 parm_table[(*i) - 1].offset)
7714 && (parm_table[*i].p_class ==
7715 parm_table[(*i) - 1].p_class))
7716 continue;
7718 if (is_default(*i) && !allparameters)
7719 continue;
7721 return &parm_table[(*i)++];
7723 } else {
7724 struct loadparm_service *pService = ServicePtrs[snum];
7726 for (; parm_table[*i].label; (*i)++) {
7727 if (parm_table[*i].p_class == P_SEPARATOR)
7728 return &parm_table[(*i)++];
7730 if (parm_table[*i].p_class == P_LOCAL &&
7731 (*parm_table[*i].label != '-') &&
7732 ((*i) == 0 ||
7733 (parm_table[*i].offset !=
7734 parm_table[(*i) - 1].offset)))
7736 if (allparameters ||
7737 !equal_parameter(parm_table[*i].type,
7738 lp_parm_ptr(pService,
7739 &parm_table[*i]),
7740 lp_parm_ptr(NULL,
7741 &parm_table[*i])))
7743 return &parm_table[(*i)++];
7749 return NULL;
7753 #if 0
7754 /***************************************************************************
7755 Display the contents of a single copy structure.
7756 ***************************************************************************/
7757 static void dump_copy_map(bool *pcopymap)
7759 int i;
7760 if (!pcopymap)
7761 return;
7763 printf("\n\tNon-Copied parameters:\n");
7765 for (i = 0; parm_table[i].label; i++)
7766 if (parm_table[i].p_class == P_LOCAL &&
7767 parm_table[i].ptr && !pcopymap[i] &&
7768 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7770 printf("\t\t%s\n", parm_table[i].label);
7773 #endif
7775 /***************************************************************************
7776 Return TRUE if the passed service number is within range.
7777 ***************************************************************************/
7779 bool lp_snum_ok(int iService)
7781 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7784 /***************************************************************************
7785 Auto-load some home services.
7786 ***************************************************************************/
7788 static void lp_add_auto_services(char *str)
7790 char *s;
7791 char *p;
7792 int homes;
7793 char *saveptr;
7795 if (!str)
7796 return;
7798 s = SMB_STRDUP(str);
7799 if (!s)
7800 return;
7802 homes = lp_servicenumber(HOMES_NAME);
7804 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7805 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7806 char *home;
7808 if (lp_servicenumber(p) >= 0)
7809 continue;
7811 home = get_user_home_dir(talloc_tos(), p);
7813 if (home && home[0] && homes >= 0)
7814 lp_add_home(p, homes, p, home);
7816 TALLOC_FREE(home);
7818 SAFE_FREE(s);
7821 /***************************************************************************
7822 Auto-load one printer.
7823 ***************************************************************************/
7825 void lp_add_one_printer(const char *name, const char *comment,
7826 const char *location, void *pdata)
7828 int printers = lp_servicenumber(PRINTERS_NAME);
7829 int i;
7831 if (lp_servicenumber(name) < 0) {
7832 lp_add_printer(name, printers);
7833 if ((i = lp_servicenumber(name)) >= 0) {
7834 string_set(&ServicePtrs[i]->comment, comment);
7835 ServicePtrs[i]->autoloaded = true;
7840 /***************************************************************************
7841 Have we loaded a services file yet?
7842 ***************************************************************************/
7844 bool lp_loaded(void)
7846 return (bLoaded);
7849 /***************************************************************************
7850 Unload unused services.
7851 ***************************************************************************/
7853 void lp_killunused(struct smbd_server_connection *sconn,
7854 bool (*snumused) (struct smbd_server_connection *, int))
7856 int i;
7857 for (i = 0; i < iNumServices; i++) {
7858 if (!VALID(i))
7859 continue;
7861 /* don't kill autoloaded or usershare services */
7862 if ( ServicePtrs[i]->autoloaded ||
7863 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7864 continue;
7867 if (!snumused || !snumused(sconn, i)) {
7868 free_service_byindex(i);
7874 * Kill all except autoloaded and usershare services - convenience wrapper
7876 void lp_kill_all_services(void)
7878 lp_killunused(NULL, NULL);
7881 /***************************************************************************
7882 Unload a service.
7883 ***************************************************************************/
7885 void lp_killservice(int iServiceIn)
7887 if (VALID(iServiceIn)) {
7888 free_service_byindex(iServiceIn);
7892 /***************************************************************************
7893 Save the curent values of all global and sDefault parameters into the
7894 defaults union. This allows swat and testparm to show only the
7895 changed (ie. non-default) parameters.
7896 ***************************************************************************/
7898 static void lp_save_defaults(void)
7900 int i;
7901 for (i = 0; parm_table[i].label; i++) {
7902 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
7903 && parm_table[i].p_class == parm_table[i - 1].p_class)
7904 continue;
7905 switch (parm_table[i].type) {
7906 case P_LIST:
7907 case P_CMDLIST:
7908 parm_table[i].def.lvalue = str_list_copy(
7909 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
7910 break;
7911 case P_STRING:
7912 case P_USTRING:
7913 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
7914 break;
7915 case P_BOOL:
7916 case P_BOOLREV:
7917 parm_table[i].def.bvalue =
7918 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
7919 break;
7920 case P_CHAR:
7921 parm_table[i].def.cvalue =
7922 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
7923 break;
7924 case P_INTEGER:
7925 case P_OCTAL:
7926 case P_ENUM:
7927 case P_BYTES:
7928 parm_table[i].def.ivalue =
7929 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
7930 break;
7931 case P_SEP:
7932 break;
7935 defaults_saved = true;
7938 /***********************************************************
7939 If we should send plaintext/LANMAN passwords in the clinet
7940 ************************************************************/
7942 static void set_allowed_client_auth(void)
7944 if (Globals.bClientNTLMv2Auth) {
7945 Globals.bClientLanManAuth = false;
7947 if (!Globals.bClientLanManAuth) {
7948 Globals.bClientPlaintextAuth = false;
7952 /***************************************************************************
7953 JRA.
7954 The following code allows smbd to read a user defined share file.
7955 Yes, this is my intent. Yes, I'm comfortable with that...
7957 THE FOLLOWING IS SECURITY CRITICAL CODE.
7959 It washes your clothes, it cleans your house, it guards you while you sleep...
7960 Do not f%^k with it....
7961 ***************************************************************************/
7963 #define MAX_USERSHARE_FILE_SIZE (10*1024)
7965 /***************************************************************************
7966 Check allowed stat state of a usershare file.
7967 Ensure we print out who is dicking with us so the admin can
7968 get their sorry ass fired.
7969 ***************************************************************************/
7971 static bool check_usershare_stat(const char *fname,
7972 const SMB_STRUCT_STAT *psbuf)
7974 if (!S_ISREG(psbuf->st_ex_mode)) {
7975 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7976 "not a regular file\n",
7977 fname, (unsigned int)psbuf->st_ex_uid ));
7978 return false;
7981 /* Ensure this doesn't have the other write bit set. */
7982 if (psbuf->st_ex_mode & S_IWOTH) {
7983 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
7984 "public write. Refusing to allow as a usershare file.\n",
7985 fname, (unsigned int)psbuf->st_ex_uid ));
7986 return false;
7989 /* Should be 10k or less. */
7990 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
7991 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7992 "too large (%u) to be a user share file.\n",
7993 fname, (unsigned int)psbuf->st_ex_uid,
7994 (unsigned int)psbuf->st_ex_size ));
7995 return false;
7998 return true;
8001 /***************************************************************************
8002 Parse the contents of a usershare file.
8003 ***************************************************************************/
8005 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8006 SMB_STRUCT_STAT *psbuf,
8007 const char *servicename,
8008 int snum,
8009 char **lines,
8010 int numlines,
8011 char **pp_sharepath,
8012 char **pp_comment,
8013 char **pp_cp_servicename,
8014 struct security_descriptor **ppsd,
8015 bool *pallow_guest)
8017 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8018 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8019 int us_vers;
8020 DIR *dp;
8021 SMB_STRUCT_STAT sbuf;
8022 char *sharepath = NULL;
8023 char *comment = NULL;
8025 *pp_sharepath = NULL;
8026 *pp_comment = NULL;
8028 *pallow_guest = false;
8030 if (numlines < 4) {
8031 return USERSHARE_MALFORMED_FILE;
8034 if (strcmp(lines[0], "#VERSION 1") == 0) {
8035 us_vers = 1;
8036 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8037 us_vers = 2;
8038 if (numlines < 5) {
8039 return USERSHARE_MALFORMED_FILE;
8041 } else {
8042 return USERSHARE_BAD_VERSION;
8045 if (strncmp(lines[1], "path=", 5) != 0) {
8046 return USERSHARE_MALFORMED_PATH;
8049 sharepath = talloc_strdup(ctx, &lines[1][5]);
8050 if (!sharepath) {
8051 return USERSHARE_POSIX_ERR;
8053 trim_string(sharepath, " ", " ");
8055 if (strncmp(lines[2], "comment=", 8) != 0) {
8056 return USERSHARE_MALFORMED_COMMENT_DEF;
8059 comment = talloc_strdup(ctx, &lines[2][8]);
8060 if (!comment) {
8061 return USERSHARE_POSIX_ERR;
8063 trim_string(comment, " ", " ");
8064 trim_char(comment, '"', '"');
8066 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8067 return USERSHARE_MALFORMED_ACL_DEF;
8070 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8071 return USERSHARE_ACL_ERR;
8074 if (us_vers == 2) {
8075 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8076 return USERSHARE_MALFORMED_ACL_DEF;
8078 if (lines[4][9] == 'y') {
8079 *pallow_guest = true;
8082 /* Backwards compatible extension to file version #2. */
8083 if (numlines > 5) {
8084 if (strncmp(lines[5], "sharename=", 10) != 0) {
8085 return USERSHARE_MALFORMED_SHARENAME_DEF;
8087 if (!strequal(&lines[5][10], servicename)) {
8088 return USERSHARE_BAD_SHARENAME;
8090 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8091 if (!*pp_cp_servicename) {
8092 return USERSHARE_POSIX_ERR;
8097 if (*pp_cp_servicename == NULL) {
8098 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8099 if (!*pp_cp_servicename) {
8100 return USERSHARE_POSIX_ERR;
8104 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8105 /* Path didn't change, no checks needed. */
8106 *pp_sharepath = sharepath;
8107 *pp_comment = comment;
8108 return USERSHARE_OK;
8111 /* The path *must* be absolute. */
8112 if (sharepath[0] != '/') {
8113 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8114 servicename, sharepath));
8115 return USERSHARE_PATH_NOT_ABSOLUTE;
8118 /* If there is a usershare prefix deny list ensure one of these paths
8119 doesn't match the start of the user given path. */
8120 if (prefixdenylist) {
8121 int i;
8122 for ( i=0; prefixdenylist[i]; i++ ) {
8123 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8124 servicename, i, prefixdenylist[i], sharepath ));
8125 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8126 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8127 "usershare prefix deny list entries.\n",
8128 servicename, sharepath));
8129 return USERSHARE_PATH_IS_DENIED;
8134 /* If there is a usershare prefix allow list ensure one of these paths
8135 does match the start of the user given path. */
8137 if (prefixallowlist) {
8138 int i;
8139 for ( i=0; prefixallowlist[i]; i++ ) {
8140 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8141 servicename, i, prefixallowlist[i], sharepath ));
8142 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8143 break;
8146 if (prefixallowlist[i] == NULL) {
8147 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8148 "usershare prefix allow list entries.\n",
8149 servicename, sharepath));
8150 return USERSHARE_PATH_NOT_ALLOWED;
8154 /* Ensure this is pointing to a directory. */
8155 dp = opendir(sharepath);
8157 if (!dp) {
8158 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8159 servicename, sharepath));
8160 return USERSHARE_PATH_NOT_DIRECTORY;
8163 /* Ensure the owner of the usershare file has permission to share
8164 this directory. */
8166 if (sys_stat(sharepath, &sbuf, false) == -1) {
8167 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8168 servicename, sharepath, strerror(errno) ));
8169 closedir(dp);
8170 return USERSHARE_POSIX_ERR;
8173 closedir(dp);
8175 if (!S_ISDIR(sbuf.st_ex_mode)) {
8176 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8177 servicename, sharepath ));
8178 return USERSHARE_PATH_NOT_DIRECTORY;
8181 /* Check if sharing is restricted to owner-only. */
8182 /* psbuf is the stat of the usershare definition file,
8183 sbuf is the stat of the target directory to be shared. */
8185 if (lp_usershare_owner_only()) {
8186 /* root can share anything. */
8187 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8188 return USERSHARE_PATH_NOT_ALLOWED;
8192 *pp_sharepath = sharepath;
8193 *pp_comment = comment;
8194 return USERSHARE_OK;
8197 /***************************************************************************
8198 Deal with a usershare file.
8199 Returns:
8200 >= 0 - snum
8201 -1 - Bad name, invalid contents.
8202 - service name already existed and not a usershare, problem
8203 with permissions to share directory etc.
8204 ***************************************************************************/
8206 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8208 SMB_STRUCT_STAT sbuf;
8209 SMB_STRUCT_STAT lsbuf;
8210 char *fname = NULL;
8211 char *sharepath = NULL;
8212 char *comment = NULL;
8213 char *cp_service_name = NULL;
8214 char **lines = NULL;
8215 int numlines = 0;
8216 int fd = -1;
8217 int iService = -1;
8218 TALLOC_CTX *ctx = talloc_stackframe();
8219 struct security_descriptor *psd = NULL;
8220 bool guest_ok = false;
8221 char *canon_name = NULL;
8222 bool added_service = false;
8223 int ret = -1;
8225 /* Ensure share name doesn't contain invalid characters. */
8226 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8227 DEBUG(0,("process_usershare_file: share name %s contains "
8228 "invalid characters (any of %s)\n",
8229 file_name, INVALID_SHARENAME_CHARS ));
8230 goto out;
8233 canon_name = canonicalize_servicename(ctx, file_name);
8234 if (!canon_name) {
8235 goto out;
8238 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8239 if (!fname) {
8240 goto out;
8243 /* Minimize the race condition by doing an lstat before we
8244 open and fstat. Ensure this isn't a symlink link. */
8246 if (sys_lstat(fname, &lsbuf, false) != 0) {
8247 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8248 fname, strerror(errno) ));
8249 goto out;
8252 /* This must be a regular file, not a symlink, directory or
8253 other strange filetype. */
8254 if (!check_usershare_stat(fname, &lsbuf)) {
8255 goto out;
8259 TDB_DATA data;
8260 NTSTATUS status;
8262 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
8263 canon_name, &data);
8265 iService = -1;
8267 if (NT_STATUS_IS_OK(status) &&
8268 (data.dptr != NULL) &&
8269 (data.dsize == sizeof(iService))) {
8270 memcpy(&iService, data.dptr, sizeof(iService));
8274 if (iService != -1 &&
8275 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8276 &lsbuf.st_ex_mtime) == 0) {
8277 /* Nothing changed - Mark valid and return. */
8278 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8279 canon_name ));
8280 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8281 ret = iService;
8282 goto out;
8285 /* Try and open the file read only - no symlinks allowed. */
8286 #ifdef O_NOFOLLOW
8287 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
8288 #else
8289 fd = open(fname, O_RDONLY, 0);
8290 #endif
8292 if (fd == -1) {
8293 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8294 fname, strerror(errno) ));
8295 goto out;
8298 /* Now fstat to be *SURE* it's a regular file. */
8299 if (sys_fstat(fd, &sbuf, false) != 0) {
8300 close(fd);
8301 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8302 fname, strerror(errno) ));
8303 goto out;
8306 /* Is it the same dev/inode as was lstated ? */
8307 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8308 close(fd);
8309 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8310 "Symlink spoofing going on ?\n", fname ));
8311 goto out;
8314 /* This must be a regular file, not a symlink, directory or
8315 other strange filetype. */
8316 if (!check_usershare_stat(fname, &sbuf)) {
8317 goto out;
8320 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8322 close(fd);
8323 if (lines == NULL) {
8324 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8325 fname, (unsigned int)sbuf.st_ex_uid ));
8326 goto out;
8329 if (parse_usershare_file(ctx, &sbuf, file_name,
8330 iService, lines, numlines, &sharepath,
8331 &comment, &cp_service_name,
8332 &psd, &guest_ok) != USERSHARE_OK) {
8333 goto out;
8336 /* Everything ok - add the service possibly using a template. */
8337 if (iService < 0) {
8338 const struct loadparm_service *sp = &sDefault;
8339 if (snum_template != -1) {
8340 sp = ServicePtrs[snum_template];
8343 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8344 DEBUG(0, ("process_usershare_file: Failed to add "
8345 "new service %s\n", cp_service_name));
8346 goto out;
8349 added_service = true;
8351 /* Read only is controlled by usershare ACL below. */
8352 ServicePtrs[iService]->bRead_only = false;
8355 /* Write the ACL of the new/modified share. */
8356 if (!set_share_security(canon_name, psd)) {
8357 DEBUG(0, ("process_usershare_file: Failed to set share "
8358 "security for user share %s\n",
8359 canon_name ));
8360 goto out;
8363 /* If from a template it may be marked invalid. */
8364 ServicePtrs[iService]->valid = true;
8366 /* Set the service as a valid usershare. */
8367 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8369 /* Set guest access. */
8370 if (lp_usershare_allow_guests()) {
8371 ServicePtrs[iService]->bGuest_ok = guest_ok;
8374 /* And note when it was loaded. */
8375 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8376 string_set(&ServicePtrs[iService]->szPath, sharepath);
8377 string_set(&ServicePtrs[iService]->comment, comment);
8379 ret = iService;
8381 out:
8383 if (ret == -1 && iService != -1 && added_service) {
8384 lp_remove_service(iService);
8387 TALLOC_FREE(lines);
8388 TALLOC_FREE(ctx);
8389 return ret;
8392 /***************************************************************************
8393 Checks if a usershare entry has been modified since last load.
8394 ***************************************************************************/
8396 static bool usershare_exists(int iService, struct timespec *last_mod)
8398 SMB_STRUCT_STAT lsbuf;
8399 const char *usersharepath = Globals.szUsersharePath;
8400 char *fname;
8402 if (asprintf(&fname, "%s/%s",
8403 usersharepath,
8404 ServicePtrs[iService]->szService) < 0) {
8405 return false;
8408 if (sys_lstat(fname, &lsbuf, false) != 0) {
8409 SAFE_FREE(fname);
8410 return false;
8413 if (!S_ISREG(lsbuf.st_ex_mode)) {
8414 SAFE_FREE(fname);
8415 return false;
8418 SAFE_FREE(fname);
8419 *last_mod = lsbuf.st_ex_mtime;
8420 return true;
8423 /***************************************************************************
8424 Load a usershare service by name. Returns a valid servicenumber or -1.
8425 ***************************************************************************/
8427 int load_usershare_service(const char *servicename)
8429 SMB_STRUCT_STAT sbuf;
8430 const char *usersharepath = Globals.szUsersharePath;
8431 int max_user_shares = Globals.iUsershareMaxShares;
8432 int snum_template = -1;
8434 if (*usersharepath == 0 || max_user_shares == 0) {
8435 return -1;
8438 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8439 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8440 usersharepath, strerror(errno) ));
8441 return -1;
8444 if (!S_ISDIR(sbuf.st_ex_mode)) {
8445 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8446 usersharepath ));
8447 return -1;
8451 * This directory must be owned by root, and have the 't' bit set.
8452 * It also must not be writable by "other".
8455 #ifdef S_ISVTX
8456 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8457 #else
8458 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8459 #endif
8460 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8461 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8462 usersharepath ));
8463 return -1;
8466 /* Ensure the template share exists if it's set. */
8467 if (Globals.szUsershareTemplateShare[0]) {
8468 /* We can't use lp_servicenumber here as we are recommending that
8469 template shares have -valid=false set. */
8470 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8471 if (ServicePtrs[snum_template]->szService &&
8472 strequal(ServicePtrs[snum_template]->szService,
8473 Globals.szUsershareTemplateShare)) {
8474 break;
8478 if (snum_template == -1) {
8479 DEBUG(0,("load_usershare_service: usershare template share %s "
8480 "does not exist.\n",
8481 Globals.szUsershareTemplateShare ));
8482 return -1;
8486 return process_usershare_file(usersharepath, servicename, snum_template);
8489 /***************************************************************************
8490 Load all user defined shares from the user share directory.
8491 We only do this if we're enumerating the share list.
8492 This is the function that can delete usershares that have
8493 been removed.
8494 ***************************************************************************/
8496 int load_usershare_shares(struct smbd_server_connection *sconn,
8497 bool (*snumused) (struct smbd_server_connection *, int))
8499 DIR *dp;
8500 SMB_STRUCT_STAT sbuf;
8501 struct dirent *de;
8502 int num_usershares = 0;
8503 int max_user_shares = Globals.iUsershareMaxShares;
8504 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8505 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8506 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8507 int iService;
8508 int snum_template = -1;
8509 const char *usersharepath = Globals.szUsersharePath;
8510 int ret = lp_numservices();
8512 if (max_user_shares == 0 || *usersharepath == '\0') {
8513 return lp_numservices();
8516 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8517 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8518 usersharepath, strerror(errno) ));
8519 return ret;
8523 * This directory must be owned by root, and have the 't' bit set.
8524 * It also must not be writable by "other".
8527 #ifdef S_ISVTX
8528 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8529 #else
8530 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8531 #endif
8532 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8533 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8534 usersharepath ));
8535 return ret;
8538 /* Ensure the template share exists if it's set. */
8539 if (Globals.szUsershareTemplateShare[0]) {
8540 /* We can't use lp_servicenumber here as we are recommending that
8541 template shares have -valid=false set. */
8542 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8543 if (ServicePtrs[snum_template]->szService &&
8544 strequal(ServicePtrs[snum_template]->szService,
8545 Globals.szUsershareTemplateShare)) {
8546 break;
8550 if (snum_template == -1) {
8551 DEBUG(0,("load_usershare_shares: usershare template share %s "
8552 "does not exist.\n",
8553 Globals.szUsershareTemplateShare ));
8554 return ret;
8558 /* Mark all existing usershares as pending delete. */
8559 for (iService = iNumServices - 1; iService >= 0; iService--) {
8560 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8561 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8565 dp = opendir(usersharepath);
8566 if (!dp) {
8567 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8568 usersharepath, strerror(errno) ));
8569 return ret;
8572 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8573 (de = readdir(dp));
8574 num_dir_entries++ ) {
8575 int r;
8576 const char *n = de->d_name;
8578 /* Ignore . and .. */
8579 if (*n == '.') {
8580 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8581 continue;
8585 if (n[0] == ':') {
8586 /* Temporary file used when creating a share. */
8587 num_tmp_dir_entries++;
8590 /* Allow 20% tmp entries. */
8591 if (num_tmp_dir_entries > allowed_tmp_entries) {
8592 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8593 "in directory %s\n",
8594 num_tmp_dir_entries, usersharepath));
8595 break;
8598 r = process_usershare_file(usersharepath, n, snum_template);
8599 if (r == 0) {
8600 /* Update the services count. */
8601 num_usershares++;
8602 if (num_usershares >= max_user_shares) {
8603 DEBUG(0,("load_usershare_shares: max user shares reached "
8604 "on file %s in directory %s\n",
8605 n, usersharepath ));
8606 break;
8608 } else if (r == -1) {
8609 num_bad_dir_entries++;
8612 /* Allow 20% bad entries. */
8613 if (num_bad_dir_entries > allowed_bad_entries) {
8614 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8615 "in directory %s\n",
8616 num_bad_dir_entries, usersharepath));
8617 break;
8620 /* Allow 20% bad entries. */
8621 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8622 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8623 "in directory %s\n",
8624 num_dir_entries, usersharepath));
8625 break;
8629 closedir(dp);
8631 /* Sweep through and delete any non-refreshed usershares that are
8632 not currently in use. */
8633 for (iService = iNumServices - 1; iService >= 0; iService--) {
8634 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8635 if (snumused && snumused(sconn, iService)) {
8636 continue;
8638 /* Remove from the share ACL db. */
8639 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8640 lp_servicename(iService) ));
8641 delete_share_security(lp_servicename(iService));
8642 free_service_byindex(iService);
8646 return lp_numservices();
8649 /********************************************************
8650 Destroy global resources allocated in this file
8651 ********************************************************/
8653 void gfree_loadparm(void)
8655 int i;
8657 free_file_list();
8659 /* Free resources allocated to services */
8661 for ( i = 0; i < iNumServices; i++ ) {
8662 if ( VALID(i) ) {
8663 free_service_byindex(i);
8667 SAFE_FREE( ServicePtrs );
8668 iNumServices = 0;
8670 /* Now release all resources allocated to global
8671 parameters and the default service */
8673 free_global_parameters();
8677 /***************************************************************************
8678 Allow client apps to specify that they are a client
8679 ***************************************************************************/
8680 static void lp_set_in_client(bool b)
8682 in_client = b;
8686 /***************************************************************************
8687 Determine if we're running in a client app
8688 ***************************************************************************/
8689 static bool lp_is_in_client(void)
8691 return in_client;
8694 /***************************************************************************
8695 Load the services array from the services file. Return true on success,
8696 false on failure.
8697 ***************************************************************************/
8699 static bool lp_load_ex(const char *pszFname,
8700 bool global_only,
8701 bool save_defaults,
8702 bool add_ipc,
8703 bool initialize_globals,
8704 bool allow_include_registry,
8705 bool load_all_shares)
8707 char *n2 = NULL;
8708 bool bRetval;
8710 bRetval = false;
8712 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8714 bInGlobalSection = true;
8715 bGlobalOnly = global_only;
8716 bAllowIncludeRegistry = allow_include_registry;
8718 init_globals(initialize_globals);
8720 free_file_list();
8722 if (save_defaults) {
8723 init_locals();
8724 lp_save_defaults();
8727 if (!initialize_globals) {
8728 free_param_opts(&Globals.param_opt);
8729 apply_lp_set_cmdline();
8732 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
8734 /* We get sections first, so have to start 'behind' to make up */
8735 iServiceIndex = -1;
8737 if (lp_config_backend_is_file()) {
8738 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
8739 current_user_info.domain,
8740 pszFname);
8741 if (!n2) {
8742 smb_panic("lp_load_ex: out of memory");
8745 add_to_file_list(pszFname, n2);
8747 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8748 TALLOC_FREE(n2);
8750 /* finish up the last section */
8751 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8752 if (bRetval) {
8753 if (iServiceIndex >= 0) {
8754 bRetval = service_ok(iServiceIndex);
8758 if (lp_config_backend_is_registry()) {
8759 /* config backend changed to registry in config file */
8761 * We need to use this extra global variable here to
8762 * survive restart: init_globals uses this as a default
8763 * for ConfigBackend. Otherwise, init_globals would
8764 * send us into an endless loop here.
8766 config_backend = CONFIG_BACKEND_REGISTRY;
8767 /* start over */
8768 DEBUG(1, ("lp_load_ex: changing to config backend "
8769 "registry\n"));
8770 init_globals(true);
8771 lp_kill_all_services();
8772 return lp_load_ex(pszFname, global_only, save_defaults,
8773 add_ipc, initialize_globals,
8774 allow_include_registry,
8775 load_all_shares);
8777 } else if (lp_config_backend_is_registry()) {
8778 bRetval = process_registry_globals();
8779 } else {
8780 DEBUG(0, ("Illegal config backend given: %d\n",
8781 lp_config_backend()));
8782 bRetval = false;
8785 if (bRetval && lp_registry_shares()) {
8786 if (load_all_shares) {
8787 bRetval = process_registry_shares();
8788 } else {
8789 bRetval = reload_registry_shares();
8794 char *serv = lp_auto_services();
8795 lp_add_auto_services(serv);
8796 TALLOC_FREE(serv);
8799 if (add_ipc) {
8800 /* When 'restrict anonymous = 2' guest connections to ipc$
8801 are denied */
8802 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8803 if ( lp_enable_asu_support() ) {
8804 lp_add_ipc("ADMIN$", false);
8808 set_allowed_client_auth();
8810 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
8811 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
8812 lp_passwordserver()));
8815 bLoaded = true;
8817 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8818 /* if bWINSsupport is true and we are in the client */
8819 if (lp_is_in_client() && Globals.bWINSsupport) {
8820 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8823 init_iconv();
8825 fault_configure(smb_panic_s3);
8827 bAllowIncludeRegistry = true;
8829 return (bRetval);
8832 bool lp_load(const char *pszFname,
8833 bool global_only,
8834 bool save_defaults,
8835 bool add_ipc,
8836 bool initialize_globals)
8838 return lp_load_ex(pszFname,
8839 global_only,
8840 save_defaults,
8841 add_ipc,
8842 initialize_globals,
8843 true, /* allow_include_registry */
8844 false); /* load_all_shares*/
8847 bool lp_load_initial_only(const char *pszFname)
8849 return lp_load_ex(pszFname,
8850 true, /* global only */
8851 false, /* save_defaults */
8852 false, /* add_ipc */
8853 true, /* initialize_globals */
8854 false, /* allow_include_registry */
8855 false); /* load_all_shares*/
8859 * most common lp_load wrapper, loading only the globals
8861 bool lp_load_global(const char *file_name)
8863 return lp_load_ex(file_name,
8864 true, /* global_only */
8865 false, /* save_defaults */
8866 false, /* add_ipc */
8867 true, /* initialize_globals */
8868 true, /* allow_include_registry */
8869 false); /* load_all_shares*/
8873 * lp_load wrapper, especially for clients
8875 bool lp_load_client(const char *file_name)
8877 lp_set_in_client(true);
8879 return lp_load_global(file_name);
8883 * lp_load wrapper, loading only globals, but intended
8884 * for subsequent calls, not reinitializing the globals
8885 * to default values
8887 bool lp_load_global_no_reinit(const char *file_name)
8889 return lp_load_ex(file_name,
8890 true, /* global_only */
8891 false, /* save_defaults */
8892 false, /* add_ipc */
8893 false, /* initialize_globals */
8894 true, /* allow_include_registry */
8895 false); /* load_all_shares*/
8899 * lp_load wrapper, especially for clients, no reinitialization
8901 bool lp_load_client_no_reinit(const char *file_name)
8903 lp_set_in_client(true);
8905 return lp_load_global_no_reinit(file_name);
8908 bool lp_load_with_registry_shares(const char *pszFname,
8909 bool global_only,
8910 bool save_defaults,
8911 bool add_ipc,
8912 bool initialize_globals)
8914 return lp_load_ex(pszFname,
8915 global_only,
8916 save_defaults,
8917 add_ipc,
8918 initialize_globals,
8919 true, /* allow_include_registry */
8920 true); /* load_all_shares*/
8923 /***************************************************************************
8924 Return the max number of services.
8925 ***************************************************************************/
8927 int lp_numservices(void)
8929 return (iNumServices);
8932 /***************************************************************************
8933 Display the contents of the services array in human-readable form.
8934 ***************************************************************************/
8936 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8938 int iService;
8940 if (show_defaults)
8941 defaults_saved = false;
8943 dump_globals(f);
8945 dump_a_service(&sDefault, f);
8947 for (iService = 0; iService < maxtoprint; iService++) {
8948 fprintf(f,"\n");
8949 lp_dump_one(f, show_defaults, iService);
8953 /***************************************************************************
8954 Display the contents of one service in human-readable form.
8955 ***************************************************************************/
8957 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8959 if (VALID(snum)) {
8960 if (ServicePtrs[snum]->szService[0] == '\0')
8961 return;
8962 dump_a_service(ServicePtrs[snum], f);
8966 /***************************************************************************
8967 Return the number of the service with the given name, or -1 if it doesn't
8968 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8969 getservicebyname()! This works ONLY if all services have been loaded, and
8970 does not copy the found service.
8971 ***************************************************************************/
8973 int lp_servicenumber(const char *pszServiceName)
8975 int iService;
8976 fstring serviceName;
8978 if (!pszServiceName) {
8979 return GLOBAL_SECTION_SNUM;
8982 for (iService = iNumServices - 1; iService >= 0; iService--) {
8983 if (VALID(iService) && ServicePtrs[iService]->szService) {
8985 * The substitution here is used to support %U is
8986 * service names
8988 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8989 standard_sub_basic(get_current_username(),
8990 current_user_info.domain,
8991 serviceName,sizeof(serviceName));
8992 if (strequal(serviceName, pszServiceName)) {
8993 break;
8998 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8999 struct timespec last_mod;
9001 if (!usershare_exists(iService, &last_mod)) {
9002 /* Remove the share security tdb entry for it. */
9003 delete_share_security(lp_servicename(iService));
9004 /* Remove it from the array. */
9005 free_service_byindex(iService);
9006 /* Doesn't exist anymore. */
9007 return GLOBAL_SECTION_SNUM;
9010 /* Has it been modified ? If so delete and reload. */
9011 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9012 &last_mod) < 0) {
9013 /* Remove it from the array. */
9014 free_service_byindex(iService);
9015 /* and now reload it. */
9016 iService = load_usershare_service(pszServiceName);
9020 if (iService < 0) {
9021 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9022 return GLOBAL_SECTION_SNUM;
9025 return (iService);
9028 /*******************************************************************
9029 A useful volume label function.
9030 ********************************************************************/
9032 const char *volume_label(int snum)
9034 char *ret;
9035 const char *label = lp_volume(snum);
9036 if (!*label) {
9037 label = lp_servicename(snum);
9040 /* This returns a 33 byte guarenteed null terminated string. */
9041 ret = talloc_strndup(talloc_tos(), label, 32);
9042 if (!ret) {
9043 return "";
9045 return ret;
9048 /*******************************************************************
9049 Get the default server type we will announce as via nmbd.
9050 ********************************************************************/
9052 int lp_default_server_announce(void)
9054 int default_server_announce = 0;
9055 default_server_announce |= SV_TYPE_WORKSTATION;
9056 default_server_announce |= SV_TYPE_SERVER;
9057 default_server_announce |= SV_TYPE_SERVER_UNIX;
9059 /* note that the flag should be set only if we have a
9060 printer service but nmbd doesn't actually load the
9061 services so we can't tell --jerry */
9063 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9065 default_server_announce |= SV_TYPE_SERVER_NT;
9066 default_server_announce |= SV_TYPE_NT;
9068 switch (lp_server_role()) {
9069 case ROLE_DOMAIN_MEMBER:
9070 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9071 break;
9072 case ROLE_DOMAIN_PDC:
9073 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9074 break;
9075 case ROLE_DOMAIN_BDC:
9076 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9077 break;
9078 case ROLE_STANDALONE:
9079 default:
9080 break;
9082 if (lp_time_server())
9083 default_server_announce |= SV_TYPE_TIME_SOURCE;
9085 if (lp_host_msdfs())
9086 default_server_announce |= SV_TYPE_DFS_SERVER;
9088 return default_server_announce;
9091 /***********************************************************
9092 If we are PDC then prefer us as DMB
9093 ************************************************************/
9095 bool lp_domain_master(void)
9097 if (Globals.iDomainMaster == Auto)
9098 return (lp_server_role() == ROLE_DOMAIN_PDC);
9100 return (bool)Globals.iDomainMaster;
9103 /***********************************************************
9104 If we are PDC then prefer us as DMB
9105 ************************************************************/
9107 static bool lp_domain_master_true_or_auto(void)
9109 if (Globals.iDomainMaster) /* auto or yes */
9110 return true;
9112 return false;
9115 /***********************************************************
9116 If we are DMB then prefer us as LMB
9117 ************************************************************/
9119 bool lp_preferred_master(void)
9121 if (Globals.iPreferredMaster == Auto)
9122 return (lp_local_master() && lp_domain_master());
9124 return (bool)Globals.iPreferredMaster;
9127 /*******************************************************************
9128 Remove a service.
9129 ********************************************************************/
9131 void lp_remove_service(int snum)
9133 ServicePtrs[snum]->valid = false;
9134 invalid_services[num_invalid_services++] = snum;
9137 /*******************************************************************
9138 Copy a service.
9139 ********************************************************************/
9141 void lp_copy_service(int snum, const char *new_name)
9143 do_section(new_name, NULL);
9144 if (snum >= 0) {
9145 snum = lp_servicenumber(new_name);
9146 if (snum >= 0)
9147 lp_do_parameter(snum, "copy", lp_servicename(snum));
9152 /***********************************************************
9153 Set the global name resolution order (used in smbclient).
9154 ************************************************************/
9156 void lp_set_name_resolve_order(const char *new_order)
9158 string_set(&Globals.szNameResolveOrder, new_order);
9161 const char *lp_printername(int snum)
9163 const char *ret = lp__printername(snum);
9164 if (ret == NULL || (ret != NULL && *ret == '\0'))
9165 ret = lp_const_servicename(snum);
9167 return ret;
9171 /***********************************************************
9172 Allow daemons such as winbindd to fix their logfile name.
9173 ************************************************************/
9175 void lp_set_logfile(const char *name)
9177 string_set(&Globals.logfile, name);
9178 debug_set_logfile(name);
9181 /*******************************************************************
9182 Return the max print jobs per queue.
9183 ********************************************************************/
9185 int lp_maxprintjobs(int snum)
9187 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9188 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9189 maxjobs = PRINT_MAX_JOBID - 1;
9191 return maxjobs;
9194 const char *lp_printcapname(void)
9196 if ((Globals.szPrintcapname != NULL) &&
9197 (Globals.szPrintcapname[0] != '\0'))
9198 return Globals.szPrintcapname;
9200 if (sDefault.iPrinting == PRINT_CUPS) {
9201 #ifdef HAVE_CUPS
9202 return "cups";
9203 #else
9204 return "lpstat";
9205 #endif
9208 if (sDefault.iPrinting == PRINT_BSD)
9209 return "/etc/printcap";
9211 return PRINTCAP_NAME;
9214 static uint32 spoolss_state;
9216 bool lp_disable_spoolss( void )
9218 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9219 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9221 return spoolss_state == SVCCTL_STOPPED ? true : false;
9224 void lp_set_spoolss_state( uint32 state )
9226 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9228 spoolss_state = state;
9231 uint32 lp_get_spoolss_state( void )
9233 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9236 /*******************************************************************
9237 Ensure we don't use sendfile if server smb signing is active.
9238 ********************************************************************/
9240 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9242 bool sign_active = false;
9244 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9245 if (get_Protocol() < PROTOCOL_NT1) {
9246 return false;
9248 if (signing_state) {
9249 sign_active = smb_signing_is_active(signing_state);
9251 return (lp__use_sendfile(snum) &&
9252 (get_remote_arch() != RA_WIN95) &&
9253 !sign_active);
9256 /*******************************************************************
9257 Turn off sendfile if we find the underlying OS doesn't support it.
9258 ********************************************************************/
9260 void set_use_sendfile(int snum, bool val)
9262 if (LP_SNUM_OK(snum))
9263 ServicePtrs[snum]->bUseSendfile = val;
9264 else
9265 sDefault.bUseSendfile = val;
9268 /*******************************************************************
9269 Turn off storing DOS attributes if this share doesn't support it.
9270 ********************************************************************/
9272 void set_store_dos_attributes(int snum, bool val)
9274 if (!LP_SNUM_OK(snum))
9275 return;
9276 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9279 void lp_set_mangling_method(const char *new_method)
9281 string_set(&Globals.szManglingMethod, new_method);
9284 /*******************************************************************
9285 Global state for POSIX pathname processing.
9286 ********************************************************************/
9288 static bool posix_pathnames;
9290 bool lp_posix_pathnames(void)
9292 return posix_pathnames;
9295 /*******************************************************************
9296 Change everything needed to ensure POSIX pathname processing (currently
9297 not much).
9298 ********************************************************************/
9300 void lp_set_posix_pathnames(void)
9302 posix_pathnames = true;
9305 /*******************************************************************
9306 Global state for POSIX lock processing - CIFS unix extensions.
9307 ********************************************************************/
9309 bool posix_default_lock_was_set;
9310 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9312 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9314 if (posix_default_lock_was_set) {
9315 return posix_cifsx_locktype;
9316 } else {
9317 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9321 /*******************************************************************
9322 ********************************************************************/
9324 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9326 posix_default_lock_was_set = true;
9327 posix_cifsx_locktype = val;
9330 int lp_min_receive_file_size(void)
9332 if (Globals.iminreceivefile < 0) {
9333 return 0;
9335 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9338 /*******************************************************************
9339 If socket address is an empty character string, it is necessary to
9340 define it as "0.0.0.0".
9341 ********************************************************************/
9343 const char *lp_socket_address(void)
9345 char *sock_addr = Globals.szSocketAddress;
9347 if (sock_addr[0] == '\0'){
9348 string_set(&Globals.szSocketAddress, "0.0.0.0");
9350 return Globals.szSocketAddress;
9353 /*******************************************************************
9354 Safe wide links checks.
9355 This helper function always verify the validity of wide links,
9356 even after a configuration file reload.
9357 ********************************************************************/
9359 static bool lp_widelinks_internal(int snum)
9361 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9362 sDefault.bWidelinks);
9365 void widelinks_warning(int snum)
9367 if (lp_allow_insecure_widelinks()) {
9368 return;
9371 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9372 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9373 "These parameters are incompatible. "
9374 "Wide links will be disabled for this share.\n",
9375 lp_servicename(snum) ));
9379 bool lp_widelinks(int snum)
9381 /* wide links is always incompatible with unix extensions */
9382 if (lp_unix_extensions()) {
9384 * Unless we have "allow insecure widelinks"
9385 * turned on.
9387 if (!lp_allow_insecure_widelinks()) {
9388 return false;
9392 return lp_widelinks_internal(snum);
9395 bool lp_writeraw(void)
9397 if (lp_async_smb_echo_handler()) {
9398 return false;
9400 return lp__writeraw();
9403 bool lp_readraw(void)
9405 if (lp_async_smb_echo_handler()) {
9406 return false;
9408 return lp__readraw();
9411 int lp_server_role(void)
9413 return lp_find_server_role(lp__server_role(),
9414 lp_security(),
9415 lp_domain_logons(),
9416 lp_domain_master_true_or_auto());
9419 const char *lp_ctdbd_socket(void)
9421 const char *result = lp__ctdbd_socket();
9423 #ifdef CLUSTER_SUPPORT
9424 if ((result == NULL) || (*result == '\0')) {
9425 return CTDB_PATH;
9427 #endif
9428 return result;