s3:param: make use of SMB_SIGNING_* constants
[Samba/vl.git] / source3 / param / loadparm.c
blob88c855cd8ca04d0989f56ca42adac559b6f98834
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 "smbldap.h"
71 #include "../lib/util/bitmap.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
75 #endif
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
81 bool bLoaded = false;
83 extern userdom_struct current_user_info;
85 /* the special value for the include parameter
86 * to be interpreted not as a file name but to
87 * trigger loading of the global smb.conf options
88 * from registry. */
89 #ifndef INCLUDE_REGISTRY_NAME
90 #define INCLUDE_REGISTRY_NAME "registry"
91 #endif
93 static bool in_client = false; /* Not in the client by default */
94 static struct smbconf_csn conf_last_csn;
96 #define CONFIG_BACKEND_FILE 0
97 #define CONFIG_BACKEND_REGISTRY 1
99 static int config_backend = CONFIG_BACKEND_FILE;
101 /* some helpful bits */
102 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
103 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
105 #define USERSHARE_VALID 1
106 #define USERSHARE_PENDING_DELETE 2
108 static bool defaults_saved = false;
110 #define LOADPARM_EXTRA_GLOBALS \
111 struct parmlist_entry *param_opt; \
112 char *szRealm; \
113 char *szLogLevel; \
114 int iminreceivefile; \
115 char *szPrintcapname; \
116 int CupsEncrypt; \
117 int iPreferredMaster; \
118 int iDomainMaster; \
119 char *szLdapMachineSuffix; \
120 char *szLdapUserSuffix; \
121 char *szLdapIdmapSuffix; \
122 char *szLdapGroupSuffix; \
123 char *szStateDir; \
124 char *szCacheDir; \
125 char *szSocketAddress; \
126 char *szUsershareTemplateShare; \
127 char *szIdmapUID; \
128 char *szIdmapGID; \
129 int winbindMaxDomainConnections; \
130 int ismb2_max_credits;
132 #include "param/param_global.h"
134 static struct loadparm_global Globals;
136 /* This is a default service used to prime a services structure */
137 static struct loadparm_service sDefault =
139 .valid = true,
140 .autoloaded = false,
141 .usershare = 0,
142 .usershare_last_mod = {0, 0},
143 .szService = NULL,
144 .szPath = NULL,
145 .szUsername = NULL,
146 .szInvalidUsers = NULL,
147 .szValidUsers = NULL,
148 .szAdminUsers = NULL,
149 .szCopy = NULL,
150 .szInclude = NULL,
151 .szPreExec = NULL,
152 .szPostExec = NULL,
153 .szRootPreExec = NULL,
154 .szRootPostExec = NULL,
155 .szCupsOptions = NULL,
156 .szPrintcommand = NULL,
157 .szLpqcommand = NULL,
158 .szLprmcommand = NULL,
159 .szLppausecommand = NULL,
160 .szLpresumecommand = NULL,
161 .szQueuepausecommand = NULL,
162 .szQueueresumecommand = NULL,
163 .szPrintername = NULL,
164 .szPrintjobUsername = NULL,
165 .szDontdescend = NULL,
166 .szHostsallow = NULL,
167 .szHostsdeny = NULL,
168 .szMagicScript = NULL,
169 .szMagicOutput = NULL,
170 .szVetoFiles = NULL,
171 .szHideFiles = NULL,
172 .szVetoOplockFiles = NULL,
173 .comment = NULL,
174 .force_user = NULL,
175 .force_group = NULL,
176 .readlist = NULL,
177 .writelist = NULL,
178 .printer_admin = NULL,
179 .volume = NULL,
180 .fstype = NULL,
181 .szVfsObjects = NULL,
182 .szMSDfsProxy = NULL,
183 .szAioWriteBehind = NULL,
184 .szDfree = NULL,
185 .iMinPrintSpace = 0,
186 .iMaxPrintJobs = 1000,
187 .iMaxReportedPrintJobs = 0,
188 .iWriteCacheSize = 0,
189 .iCreate_mask = 0744,
190 .iCreate_force_mode = 0,
191 .iSecurity_mask = 0777,
192 .iSecurity_force_mode = 0,
193 .iDir_mask = 0755,
194 .iDir_force_mode = 0,
195 .iDir_Security_mask = 0777,
196 .iDir_Security_force_mode = 0,
197 .iMaxConnections = 0,
198 .iDefaultCase = CASE_LOWER,
199 .iPrinting = DEFAULT_PRINTING,
200 .iOplockContentionLimit = 2,
201 .iCSCPolicy = 0,
202 .iBlock_size = 1024,
203 .iDfreeCacheTime = 0,
204 .bPreexecClose = false,
205 .bRootpreexecClose = false,
206 .iCaseSensitive = Auto,
207 .bCasePreserve = true,
208 .bShortCasePreserve = true,
209 .bHideDotFiles = true,
210 .bHideSpecialFiles = false,
211 .bHideUnReadable = false,
212 .bHideUnWriteableFiles = false,
213 .bBrowseable = true,
214 .bAccessBasedShareEnum = false,
215 .bAvailable = true,
216 .bRead_only = true,
217 .bNo_set_dir = true,
218 .bGuest_only = false,
219 .bAdministrative_share = false,
220 .bGuest_ok = false,
221 .bPrint_ok = false,
222 .bPrintNotifyBackchannel = true,
223 .bMap_system = false,
224 .bMap_hidden = false,
225 .bMap_archive = true,
226 .bStoreDosAttributes = false,
227 .bDmapiSupport = false,
228 .bLocking = true,
229 .iStrictLocking = Auto,
230 .bPosixLocking = true,
231 .bShareModes = true,
232 .bOpLocks = true,
233 .bLevel2OpLocks = true,
234 .bOnlyUser = false,
235 .bMangledNames = true,
236 .bWidelinks = false,
237 .bSymlinks = true,
238 .bSyncAlways = false,
239 .bStrictAllocate = false,
240 .bStrictSync = false,
241 .magic_char = '~',
242 .copymap = NULL,
243 .bDeleteReadonly = false,
244 .bFakeOplocks = false,
245 .bDeleteVetoFiles = false,
246 .bDosFilemode = false,
247 .bDosFiletimes = true,
248 .bDosFiletimeResolution = false,
249 .bFakeDirCreateTimes = false,
250 .bBlockingLocks = true,
251 .bInheritPerms = false,
252 .bInheritACLS = false,
253 .bInheritOwner = false,
254 .bMSDfsRoot = false,
255 .bUseClientDriver = false,
256 .bDefaultDevmode = true,
257 .bForcePrintername = false,
258 .bNTAclSupport = true,
259 .bForceUnknownAclUser = false,
260 .bUseSendfile = false,
261 .bProfileAcls = false,
262 .bMap_acl_inherit = false,
263 .bAfs_Share = false,
264 .bEASupport = false,
265 .bAclCheckPermissions = true,
266 .bAclMapFullControl = true,
267 .bAclGroupControl = false,
268 .bChangeNotify = true,
269 .bKernelChangeNotify = true,
270 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
271 .iAioReadSize = 0,
272 .iAioWriteSize = 0,
273 .iMap_readonly = MAP_READONLY_YES,
274 #ifdef BROKEN_DIRECTORY_HANDLING
275 .iDirectoryNameCacheSize = 0,
276 #else
277 .iDirectoryNameCacheSize = 100,
278 #endif
279 .ismb_encrypt = Auto,
280 .param_opt = NULL,
281 .dummy = ""
284 /* local variables */
285 static struct loadparm_service **ServicePtrs = NULL;
286 static int iNumServices = 0;
287 static int iServiceIndex = 0;
288 static struct db_context *ServiceHash;
289 static int *invalid_services = NULL;
290 static int num_invalid_services = 0;
291 static bool bInGlobalSection = true;
292 static bool bGlobalOnly = false;
294 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
296 /* prototypes for the special type handlers */
297 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
298 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
299 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
300 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
301 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
302 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
303 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
304 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
305 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
306 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
307 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
308 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
310 static void set_allowed_client_auth(void);
312 static void add_to_file_list(const char *fname, const char *subfname);
313 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
314 static void free_param_opts(struct parmlist_entry **popts);
316 static const struct enum_list enum_protocol[] = {
317 {PROTOCOL_SMB2_02, "SMB2"}, /* for now keep PROTOCOL_SMB2_02 */
318 {PROTOCOL_SMB2_10, "SMB2_10"},
319 {PROTOCOL_SMB2_02, "SMB2_02"},
320 {PROTOCOL_NT1, "NT1"},
321 {PROTOCOL_LANMAN2, "LANMAN2"},
322 {PROTOCOL_LANMAN1, "LANMAN1"},
323 {PROTOCOL_CORE, "CORE"},
324 {PROTOCOL_COREPLUS, "COREPLUS"},
325 {PROTOCOL_COREPLUS, "CORE+"},
326 {-1, NULL}
329 static const struct enum_list enum_security[] = {
330 {SEC_SHARE, "SHARE"},
331 {SEC_USER, "USER"},
332 {SEC_SERVER, "SERVER"},
333 {SEC_DOMAIN, "DOMAIN"},
334 #ifdef HAVE_ADS
335 {SEC_ADS, "ADS"},
336 #endif
337 {-1, NULL}
340 static const struct enum_list enum_printing[] = {
341 {PRINT_SYSV, "sysv"},
342 {PRINT_AIX, "aix"},
343 {PRINT_HPUX, "hpux"},
344 {PRINT_BSD, "bsd"},
345 {PRINT_QNX, "qnx"},
346 {PRINT_PLP, "plp"},
347 {PRINT_LPRNG, "lprng"},
348 {PRINT_CUPS, "cups"},
349 {PRINT_IPRINT, "iprint"},
350 {PRINT_LPRNT, "nt"},
351 {PRINT_LPROS2, "os2"},
352 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
353 {PRINT_TEST, "test"},
354 {PRINT_VLP, "vlp"},
355 #endif /* DEVELOPER */
356 {-1, NULL}
359 static const struct enum_list enum_ldap_sasl_wrapping[] = {
360 {0, "plain"},
361 {ADS_AUTH_SASL_SIGN, "sign"},
362 {ADS_AUTH_SASL_SEAL, "seal"},
363 {-1, NULL}
366 static const struct enum_list enum_ldap_ssl[] = {
367 {LDAP_SSL_OFF, "no"},
368 {LDAP_SSL_OFF, "off"},
369 {LDAP_SSL_START_TLS, "start tls"},
370 {LDAP_SSL_START_TLS, "start_tls"},
371 {-1, NULL}
374 /* LDAP Dereferencing Alias types */
375 #define SAMBA_LDAP_DEREF_NEVER 0
376 #define SAMBA_LDAP_DEREF_SEARCHING 1
377 #define SAMBA_LDAP_DEREF_FINDING 2
378 #define SAMBA_LDAP_DEREF_ALWAYS 3
380 static const struct enum_list enum_ldap_deref[] = {
381 {SAMBA_LDAP_DEREF_NEVER, "never"},
382 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
383 {SAMBA_LDAP_DEREF_FINDING, "finding"},
384 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
385 {-1, "auto"}
388 static const struct enum_list enum_ldap_passwd_sync[] = {
389 {LDAP_PASSWD_SYNC_OFF, "no"},
390 {LDAP_PASSWD_SYNC_OFF, "off"},
391 {LDAP_PASSWD_SYNC_ON, "yes"},
392 {LDAP_PASSWD_SYNC_ON, "on"},
393 {LDAP_PASSWD_SYNC_ONLY, "only"},
394 {-1, NULL}
397 static const struct enum_list enum_map_readonly[] = {
398 {MAP_READONLY_NO, "no"},
399 {MAP_READONLY_NO, "false"},
400 {MAP_READONLY_NO, "0"},
401 {MAP_READONLY_YES, "yes"},
402 {MAP_READONLY_YES, "true"},
403 {MAP_READONLY_YES, "1"},
404 {MAP_READONLY_PERMISSIONS, "permissions"},
405 {MAP_READONLY_PERMISSIONS, "perms"},
406 {-1, NULL}
409 static const struct enum_list enum_case[] = {
410 {CASE_LOWER, "lower"},
411 {CASE_UPPER, "upper"},
412 {-1, NULL}
417 static const struct enum_list enum_bool_auto[] = {
418 {false, "No"},
419 {false, "False"},
420 {false, "0"},
421 {true, "Yes"},
422 {true, "True"},
423 {true, "1"},
424 {Auto, "Auto"},
425 {-1, NULL}
428 static const struct enum_list enum_csc_policy[] = {
429 {CSC_POLICY_MANUAL, "manual"},
430 {CSC_POLICY_DOCUMENTS, "documents"},
431 {CSC_POLICY_PROGRAMS, "programs"},
432 {CSC_POLICY_DISABLE, "disable"},
433 {-1, NULL}
436 /* SMB signing types. */
437 static const struct enum_list enum_smb_signing_vals[] = {
438 {SMB_SIGNING_DEFAULT, "default"},
439 {SMB_SIGNING_OFF, "No"},
440 {SMB_SIGNING_OFF, "False"},
441 {SMB_SIGNING_OFF, "0"},
442 {SMB_SIGNING_OFF, "Off"},
443 {SMB_SIGNING_OFF, "disabled"},
444 {SMB_SIGNING_IF_REQUIRED, "if_required"},
445 {SMB_SIGNING_IF_REQUIRED, "Yes"},
446 {SMB_SIGNING_IF_REQUIRED, "True"},
447 {SMB_SIGNING_IF_REQUIRED, "1"},
448 {SMB_SIGNING_IF_REQUIRED, "On"},
449 {SMB_SIGNING_IF_REQUIRED, "enabled"},
450 {SMB_SIGNING_IF_REQUIRED, "auto"},
451 {SMB_SIGNING_REQUIRED, "required"},
452 {SMB_SIGNING_REQUIRED, "mandatory"},
453 {SMB_SIGNING_REQUIRED, "force"},
454 {SMB_SIGNING_REQUIRED, "forced"},
455 {SMB_SIGNING_REQUIRED, "enforced"},
456 {-1, NULL}
459 /* ACL compatibility options. */
460 static const struct enum_list enum_acl_compat_vals[] = {
461 { ACL_COMPAT_AUTO, "auto" },
462 { ACL_COMPAT_WINNT, "winnt" },
463 { ACL_COMPAT_WIN2K, "win2k" },
464 { -1, NULL}
468 Do you want session setups at user level security with a invalid
469 password to be rejected or allowed in as guest? WinNT rejects them
470 but it can be a pain as it means "net view" needs to use a password
472 You have 3 choices in the setting of map_to_guest:
474 "Never" means session setups with an invalid password
475 are rejected. This is the default.
477 "Bad User" means session setups with an invalid password
478 are rejected, unless the username does not exist, in which case it
479 is treated as a guest login
481 "Bad Password" means session setups with an invalid password
482 are treated as a guest login
484 Note that map_to_guest only has an effect in user or server
485 level security.
488 static const struct enum_list enum_map_to_guest[] = {
489 {NEVER_MAP_TO_GUEST, "Never"},
490 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
491 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
492 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
493 {-1, NULL}
496 /* Config backend options */
498 static const struct enum_list enum_config_backend[] = {
499 {CONFIG_BACKEND_FILE, "file"},
500 {CONFIG_BACKEND_REGISTRY, "registry"},
501 {-1, NULL}
504 /* ADS kerberos ticket verification options */
506 static const struct enum_list enum_kerberos_method[] = {
507 {KERBEROS_VERIFY_SECRETS, "default"},
508 {KERBEROS_VERIFY_SECRETS, "secrets only"},
509 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
510 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
511 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
512 {-1, NULL}
515 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
517 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
518 * screen in SWAT. This is used to exclude parameters as well as to squash all
519 * parameters that have been duplicated by pseudonyms.
521 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
522 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
523 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
524 * respective views.
526 * NOTE2: Handling of duplicated (synonym) parameters:
527 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
528 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
529 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
530 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
533 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
534 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
536 static struct parm_struct parm_table[] = {
537 {N_("Base Options"), P_SEP, P_SEPARATOR},
540 .label = "dos charset",
541 .type = P_STRING,
542 .p_class = P_GLOBAL,
543 .offset = GLOBAL_VAR(dos_charset),
544 .special = handle_dos_charset,
545 .enum_list = NULL,
546 .flags = FLAG_ADVANCED
549 .label = "unix charset",
550 .type = P_STRING,
551 .p_class = P_GLOBAL,
552 .offset = GLOBAL_VAR(unix_charset),
553 .special = handle_charset,
554 .enum_list = NULL,
555 .flags = FLAG_ADVANCED
558 .label = "comment",
559 .type = P_STRING,
560 .p_class = P_LOCAL,
561 .offset = LOCAL_VAR(comment),
562 .special = NULL,
563 .enum_list = NULL,
564 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
567 .label = "path",
568 .type = P_STRING,
569 .p_class = P_LOCAL,
570 .offset = LOCAL_VAR(szPath),
571 .special = NULL,
572 .enum_list = NULL,
573 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
576 .label = "directory",
577 .type = P_STRING,
578 .p_class = P_LOCAL,
579 .offset = LOCAL_VAR(szPath),
580 .special = NULL,
581 .enum_list = NULL,
582 .flags = FLAG_HIDE,
585 .label = "workgroup",
586 .type = P_USTRING,
587 .p_class = P_GLOBAL,
588 .offset = GLOBAL_VAR(szWorkgroup),
589 .special = NULL,
590 .enum_list = NULL,
591 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
594 .label = "realm",
595 .type = P_USTRING,
596 .p_class = P_GLOBAL,
597 .offset = GLOBAL_VAR(szRealm),
598 .special = handle_realm,
599 .enum_list = NULL,
600 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
603 .label = "netbios name",
604 .type = P_USTRING,
605 .p_class = P_GLOBAL,
606 .offset = GLOBAL_VAR(szNetbiosName),
607 .special = NULL,
608 .enum_list = NULL,
609 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
612 .label = "netbios aliases",
613 .type = P_LIST,
614 .p_class = P_GLOBAL,
615 .offset = GLOBAL_VAR(szNetbiosAliases),
616 .special = handle_netbios_aliases,
617 .enum_list = NULL,
618 .flags = FLAG_ADVANCED,
621 .label = "netbios scope",
622 .type = P_USTRING,
623 .p_class = P_GLOBAL,
624 .offset = GLOBAL_VAR(szNetbiosScope),
625 .special = NULL,
626 .enum_list = NULL,
627 .flags = FLAG_ADVANCED,
630 .label = "server string",
631 .type = P_STRING,
632 .p_class = P_GLOBAL,
633 .offset = GLOBAL_VAR(szServerString),
634 .special = NULL,
635 .enum_list = NULL,
636 .flags = FLAG_BASIC | FLAG_ADVANCED,
639 .label = "interfaces",
640 .type = P_LIST,
641 .p_class = P_GLOBAL,
642 .offset = GLOBAL_VAR(szInterfaces),
643 .special = NULL,
644 .enum_list = NULL,
645 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
648 .label = "bind interfaces only",
649 .type = P_BOOL,
650 .p_class = P_GLOBAL,
651 .offset = GLOBAL_VAR(bBindInterfacesOnly),
652 .special = NULL,
653 .enum_list = NULL,
654 .flags = FLAG_ADVANCED | FLAG_WIZARD,
657 .label = "config backend",
658 .type = P_ENUM,
659 .p_class = P_GLOBAL,
660 .offset = GLOBAL_VAR(ConfigBackend),
661 .special = NULL,
662 .enum_list = enum_config_backend,
663 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
666 {N_("Security Options"), P_SEP, P_SEPARATOR},
669 .label = "security",
670 .type = P_ENUM,
671 .p_class = P_GLOBAL,
672 .offset = GLOBAL_VAR(security),
673 .special = NULL,
674 .enum_list = enum_security,
675 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
678 .label = "auth methods",
679 .type = P_LIST,
680 .p_class = P_GLOBAL,
681 .offset = GLOBAL_VAR(AuthMethods),
682 .special = NULL,
683 .enum_list = NULL,
684 .flags = FLAG_ADVANCED,
687 .label = "encrypt passwords",
688 .type = P_BOOL,
689 .p_class = P_GLOBAL,
690 .offset = GLOBAL_VAR(bEncryptPasswords),
691 .special = NULL,
692 .enum_list = NULL,
693 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
696 .label = "client schannel",
697 .type = P_ENUM,
698 .p_class = P_GLOBAL,
699 .offset = GLOBAL_VAR(clientSchannel),
700 .special = NULL,
701 .enum_list = enum_bool_auto,
702 .flags = FLAG_BASIC | FLAG_ADVANCED,
705 .label = "server schannel",
706 .type = P_ENUM,
707 .p_class = P_GLOBAL,
708 .offset = GLOBAL_VAR(serverSchannel),
709 .special = NULL,
710 .enum_list = enum_bool_auto,
711 .flags = FLAG_BASIC | FLAG_ADVANCED,
714 .label = "allow trusted domains",
715 .type = P_BOOL,
716 .p_class = P_GLOBAL,
717 .offset = GLOBAL_VAR(bAllowTrustedDomains),
718 .special = NULL,
719 .enum_list = NULL,
720 .flags = FLAG_ADVANCED,
723 .label = "map to guest",
724 .type = P_ENUM,
725 .p_class = P_GLOBAL,
726 .offset = GLOBAL_VAR(map_to_guest),
727 .special = NULL,
728 .enum_list = enum_map_to_guest,
729 .flags = FLAG_ADVANCED,
732 .label = "null passwords",
733 .type = P_BOOL,
734 .p_class = P_GLOBAL,
735 .offset = GLOBAL_VAR(bNullPasswords),
736 .special = NULL,
737 .enum_list = NULL,
738 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
741 .label = "obey pam restrictions",
742 .type = P_BOOL,
743 .p_class = P_GLOBAL,
744 .offset = GLOBAL_VAR(bObeyPamRestrictions),
745 .special = NULL,
746 .enum_list = NULL,
747 .flags = FLAG_ADVANCED,
750 .label = "password server",
751 .type = P_STRING,
752 .p_class = P_GLOBAL,
753 .offset = GLOBAL_VAR(szPasswordServer),
754 .special = NULL,
755 .enum_list = NULL,
756 .flags = FLAG_ADVANCED | FLAG_WIZARD,
759 .label = "smb passwd file",
760 .type = P_STRING,
761 .p_class = P_GLOBAL,
762 .offset = GLOBAL_VAR(szSMBPasswdFile),
763 .special = NULL,
764 .enum_list = NULL,
765 .flags = FLAG_ADVANCED,
768 .label = "private dir",
769 .type = P_STRING,
770 .p_class = P_GLOBAL,
771 .offset = GLOBAL_VAR(szPrivateDir),
772 .special = NULL,
773 .enum_list = NULL,
774 .flags = FLAG_ADVANCED,
777 .label = "passdb backend",
778 .type = P_STRING,
779 .p_class = P_GLOBAL,
780 .offset = GLOBAL_VAR(szPassdbBackend),
781 .special = NULL,
782 .enum_list = NULL,
783 .flags = FLAG_ADVANCED | FLAG_WIZARD,
786 .label = "algorithmic rid base",
787 .type = P_INTEGER,
788 .p_class = P_GLOBAL,
789 .offset = GLOBAL_VAR(AlgorithmicRidBase),
790 .special = NULL,
791 .enum_list = NULL,
792 .flags = FLAG_ADVANCED,
795 .label = "root directory",
796 .type = P_STRING,
797 .p_class = P_GLOBAL,
798 .offset = GLOBAL_VAR(szRootdir),
799 .special = NULL,
800 .enum_list = NULL,
801 .flags = FLAG_ADVANCED,
804 .label = "root dir",
805 .type = P_STRING,
806 .p_class = P_GLOBAL,
807 .offset = GLOBAL_VAR(szRootdir),
808 .special = NULL,
809 .enum_list = NULL,
810 .flags = FLAG_HIDE,
813 .label = "root",
814 .type = P_STRING,
815 .p_class = P_GLOBAL,
816 .offset = GLOBAL_VAR(szRootdir),
817 .special = NULL,
818 .enum_list = NULL,
819 .flags = FLAG_HIDE,
822 .label = "guest account",
823 .type = P_STRING,
824 .p_class = P_GLOBAL,
825 .offset = GLOBAL_VAR(szGuestaccount),
826 .special = NULL,
827 .enum_list = NULL,
828 .flags = FLAG_BASIC | FLAG_ADVANCED,
831 .label = "enable privileges",
832 .type = P_BOOL,
833 .p_class = P_GLOBAL,
834 .offset = GLOBAL_VAR(bEnablePrivileges),
835 .special = NULL,
836 .enum_list = NULL,
837 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
841 .label = "pam password change",
842 .type = P_BOOL,
843 .p_class = P_GLOBAL,
844 .offset = GLOBAL_VAR(bPamPasswordChange),
845 .special = NULL,
846 .enum_list = NULL,
847 .flags = FLAG_ADVANCED,
850 .label = "passwd program",
851 .type = P_STRING,
852 .p_class = P_GLOBAL,
853 .offset = GLOBAL_VAR(szPasswdProgram),
854 .special = NULL,
855 .enum_list = NULL,
856 .flags = FLAG_ADVANCED,
859 .label = "passwd chat",
860 .type = P_STRING,
861 .p_class = P_GLOBAL,
862 .offset = GLOBAL_VAR(szPasswdChat),
863 .special = NULL,
864 .enum_list = NULL,
865 .flags = FLAG_ADVANCED,
868 .label = "passwd chat debug",
869 .type = P_BOOL,
870 .p_class = P_GLOBAL,
871 .offset = GLOBAL_VAR(bPasswdChatDebug),
872 .special = NULL,
873 .enum_list = NULL,
874 .flags = FLAG_ADVANCED,
877 .label = "passwd chat timeout",
878 .type = P_INTEGER,
879 .p_class = P_GLOBAL,
880 .offset = GLOBAL_VAR(iPasswdChatTimeout),
881 .special = NULL,
882 .enum_list = NULL,
883 .flags = FLAG_ADVANCED,
886 .label = "check password script",
887 .type = P_STRING,
888 .p_class = P_GLOBAL,
889 .offset = GLOBAL_VAR(szCheckPasswordScript),
890 .special = NULL,
891 .enum_list = NULL,
892 .flags = FLAG_ADVANCED,
895 .label = "username map",
896 .type = P_STRING,
897 .p_class = P_GLOBAL,
898 .offset = GLOBAL_VAR(szUsernameMap),
899 .special = NULL,
900 .enum_list = NULL,
901 .flags = FLAG_ADVANCED,
904 .label = "password level",
905 .type = P_INTEGER,
906 .p_class = P_GLOBAL,
907 .offset = GLOBAL_VAR(pwordlevel),
908 .special = NULL,
909 .enum_list = NULL,
910 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
913 .label = "username level",
914 .type = P_INTEGER,
915 .p_class = P_GLOBAL,
916 .offset = GLOBAL_VAR(unamelevel),
917 .special = NULL,
918 .enum_list = NULL,
919 .flags = FLAG_ADVANCED,
922 .label = "unix password sync",
923 .type = P_BOOL,
924 .p_class = P_GLOBAL,
925 .offset = GLOBAL_VAR(bUnixPasswdSync),
926 .special = NULL,
927 .enum_list = NULL,
928 .flags = FLAG_ADVANCED,
931 .label = "restrict anonymous",
932 .type = P_INTEGER,
933 .p_class = P_GLOBAL,
934 .offset = GLOBAL_VAR(restrict_anonymous),
935 .special = NULL,
936 .enum_list = NULL,
937 .flags = FLAG_ADVANCED,
940 .label = "lanman auth",
941 .type = P_BOOL,
942 .p_class = P_GLOBAL,
943 .offset = GLOBAL_VAR(bLanmanAuth),
944 .special = NULL,
945 .enum_list = NULL,
946 .flags = FLAG_ADVANCED,
949 .label = "ntlm auth",
950 .type = P_BOOL,
951 .p_class = P_GLOBAL,
952 .offset = GLOBAL_VAR(bNTLMAuth),
953 .special = NULL,
954 .enum_list = NULL,
955 .flags = FLAG_ADVANCED,
958 .label = "client NTLMv2 auth",
959 .type = P_BOOL,
960 .p_class = P_GLOBAL,
961 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
962 .special = NULL,
963 .enum_list = NULL,
964 .flags = FLAG_ADVANCED,
967 .label = "client lanman auth",
968 .type = P_BOOL,
969 .p_class = P_GLOBAL,
970 .offset = GLOBAL_VAR(bClientLanManAuth),
971 .special = NULL,
972 .enum_list = NULL,
973 .flags = FLAG_ADVANCED,
976 .label = "client plaintext auth",
977 .type = P_BOOL,
978 .p_class = P_GLOBAL,
979 .offset = GLOBAL_VAR(bClientPlaintextAuth),
980 .special = NULL,
981 .enum_list = NULL,
982 .flags = FLAG_ADVANCED,
985 .label = "client use spnego principal",
986 .type = P_BOOL,
987 .p_class = P_GLOBAL,
988 .offset = GLOBAL_VAR(client_use_spnego_principal),
989 .special = NULL,
990 .enum_list = NULL,
991 .flags = FLAG_ADVANCED,
994 .label = "send spnego principal",
995 .type = P_BOOL,
996 .p_class = P_GLOBAL,
997 .offset = GLOBAL_VAR(send_spnego_principal),
998 .special = NULL,
999 .enum_list = NULL,
1000 .flags = FLAG_ADVANCED,
1003 .label = "username",
1004 .type = P_STRING,
1005 .p_class = P_LOCAL,
1006 .offset = LOCAL_VAR(szUsername),
1007 .special = NULL,
1008 .enum_list = NULL,
1009 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1012 .label = "user",
1013 .type = P_STRING,
1014 .p_class = P_LOCAL,
1015 .offset = LOCAL_VAR(szUsername),
1016 .special = NULL,
1017 .enum_list = NULL,
1018 .flags = FLAG_HIDE,
1021 .label = "users",
1022 .type = P_STRING,
1023 .p_class = P_LOCAL,
1024 .offset = LOCAL_VAR(szUsername),
1025 .special = NULL,
1026 .enum_list = NULL,
1027 .flags = FLAG_HIDE,
1030 .label = "invalid users",
1031 .type = P_LIST,
1032 .p_class = P_LOCAL,
1033 .offset = LOCAL_VAR(szInvalidUsers),
1034 .special = NULL,
1035 .enum_list = NULL,
1036 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1039 .label = "valid users",
1040 .type = P_LIST,
1041 .p_class = P_LOCAL,
1042 .offset = LOCAL_VAR(szValidUsers),
1043 .special = NULL,
1044 .enum_list = NULL,
1045 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1048 .label = "admin users",
1049 .type = P_LIST,
1050 .p_class = P_LOCAL,
1051 .offset = LOCAL_VAR(szAdminUsers),
1052 .special = NULL,
1053 .enum_list = NULL,
1054 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1057 .label = "read list",
1058 .type = P_LIST,
1059 .p_class = P_LOCAL,
1060 .offset = LOCAL_VAR(readlist),
1061 .special = NULL,
1062 .enum_list = NULL,
1063 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1066 .label = "write list",
1067 .type = P_LIST,
1068 .p_class = P_LOCAL,
1069 .offset = LOCAL_VAR(writelist),
1070 .special = NULL,
1071 .enum_list = NULL,
1072 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1075 .label = "printer admin",
1076 .type = P_LIST,
1077 .p_class = P_LOCAL,
1078 .offset = LOCAL_VAR(printer_admin),
1079 .special = NULL,
1080 .enum_list = NULL,
1081 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1084 .label = "force user",
1085 .type = P_STRING,
1086 .p_class = P_LOCAL,
1087 .offset = LOCAL_VAR(force_user),
1088 .special = NULL,
1089 .enum_list = NULL,
1090 .flags = FLAG_ADVANCED | FLAG_SHARE,
1093 .label = "force group",
1094 .type = P_STRING,
1095 .p_class = P_LOCAL,
1096 .offset = LOCAL_VAR(force_group),
1097 .special = NULL,
1098 .enum_list = NULL,
1099 .flags = FLAG_ADVANCED | FLAG_SHARE,
1102 .label = "group",
1103 .type = P_STRING,
1104 .p_class = P_LOCAL,
1105 .offset = LOCAL_VAR(force_group),
1106 .special = NULL,
1107 .enum_list = NULL,
1108 .flags = FLAG_ADVANCED,
1111 .label = "read only",
1112 .type = P_BOOL,
1113 .p_class = P_LOCAL,
1114 .offset = LOCAL_VAR(bRead_only),
1115 .special = NULL,
1116 .enum_list = NULL,
1117 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1120 .label = "write ok",
1121 .type = P_BOOLREV,
1122 .p_class = P_LOCAL,
1123 .offset = LOCAL_VAR(bRead_only),
1124 .special = NULL,
1125 .enum_list = NULL,
1126 .flags = FLAG_HIDE,
1129 .label = "writeable",
1130 .type = P_BOOLREV,
1131 .p_class = P_LOCAL,
1132 .offset = LOCAL_VAR(bRead_only),
1133 .special = NULL,
1134 .enum_list = NULL,
1135 .flags = FLAG_HIDE,
1138 .label = "writable",
1139 .type = P_BOOLREV,
1140 .p_class = P_LOCAL,
1141 .offset = LOCAL_VAR(bRead_only),
1142 .special = NULL,
1143 .enum_list = NULL,
1144 .flags = FLAG_HIDE,
1147 .label = "acl check permissions",
1148 .type = P_BOOL,
1149 .p_class = P_LOCAL,
1150 .offset = LOCAL_VAR(bAclCheckPermissions),
1151 .special = NULL,
1152 .enum_list = NULL,
1153 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1156 .label = "acl group control",
1157 .type = P_BOOL,
1158 .p_class = P_LOCAL,
1159 .offset = LOCAL_VAR(bAclGroupControl),
1160 .special = NULL,
1161 .enum_list = NULL,
1162 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1165 .label = "acl map full control",
1166 .type = P_BOOL,
1167 .p_class = P_LOCAL,
1168 .offset = LOCAL_VAR(bAclMapFullControl),
1169 .special = NULL,
1170 .enum_list = NULL,
1171 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1174 .label = "create mask",
1175 .type = P_OCTAL,
1176 .p_class = P_LOCAL,
1177 .offset = LOCAL_VAR(iCreate_mask),
1178 .special = NULL,
1179 .enum_list = NULL,
1180 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1183 .label = "create mode",
1184 .type = P_OCTAL,
1185 .p_class = P_LOCAL,
1186 .offset = LOCAL_VAR(iCreate_mask),
1187 .special = NULL,
1188 .enum_list = NULL,
1189 .flags = FLAG_HIDE,
1192 .label = "force create mode",
1193 .type = P_OCTAL,
1194 .p_class = P_LOCAL,
1195 .offset = LOCAL_VAR(iCreate_force_mode),
1196 .special = NULL,
1197 .enum_list = NULL,
1198 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1201 .label = "security mask",
1202 .type = P_OCTAL,
1203 .p_class = P_LOCAL,
1204 .offset = LOCAL_VAR(iSecurity_mask),
1205 .special = NULL,
1206 .enum_list = NULL,
1207 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1210 .label = "force security mode",
1211 .type = P_OCTAL,
1212 .p_class = P_LOCAL,
1213 .offset = LOCAL_VAR(iSecurity_force_mode),
1214 .special = NULL,
1215 .enum_list = NULL,
1216 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1219 .label = "directory mask",
1220 .type = P_OCTAL,
1221 .p_class = P_LOCAL,
1222 .offset = LOCAL_VAR(iDir_mask),
1223 .special = NULL,
1224 .enum_list = NULL,
1225 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1228 .label = "directory mode",
1229 .type = P_OCTAL,
1230 .p_class = P_LOCAL,
1231 .offset = LOCAL_VAR(iDir_mask),
1232 .special = NULL,
1233 .enum_list = NULL,
1234 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1237 .label = "force directory mode",
1238 .type = P_OCTAL,
1239 .p_class = P_LOCAL,
1240 .offset = LOCAL_VAR(iDir_force_mode),
1241 .special = NULL,
1242 .enum_list = NULL,
1243 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1246 .label = "directory security mask",
1247 .type = P_OCTAL,
1248 .p_class = P_LOCAL,
1249 .offset = LOCAL_VAR(iDir_Security_mask),
1250 .special = NULL,
1251 .enum_list = NULL,
1252 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1255 .label = "force directory security mode",
1256 .type = P_OCTAL,
1257 .p_class = P_LOCAL,
1258 .offset = LOCAL_VAR(iDir_Security_force_mode),
1259 .special = NULL,
1260 .enum_list = NULL,
1261 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1264 .label = "force unknown acl user",
1265 .type = P_BOOL,
1266 .p_class = P_LOCAL,
1267 .offset = LOCAL_VAR(bForceUnknownAclUser),
1268 .special = NULL,
1269 .enum_list = NULL,
1270 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1273 .label = "inherit permissions",
1274 .type = P_BOOL,
1275 .p_class = P_LOCAL,
1276 .offset = LOCAL_VAR(bInheritPerms),
1277 .special = NULL,
1278 .enum_list = NULL,
1279 .flags = FLAG_ADVANCED | FLAG_SHARE,
1282 .label = "inherit acls",
1283 .type = P_BOOL,
1284 .p_class = P_LOCAL,
1285 .offset = LOCAL_VAR(bInheritACLS),
1286 .special = NULL,
1287 .enum_list = NULL,
1288 .flags = FLAG_ADVANCED | FLAG_SHARE,
1291 .label = "inherit owner",
1292 .type = P_BOOL,
1293 .p_class = P_LOCAL,
1294 .offset = LOCAL_VAR(bInheritOwner),
1295 .special = NULL,
1296 .enum_list = NULL,
1297 .flags = FLAG_ADVANCED | FLAG_SHARE,
1300 .label = "guest only",
1301 .type = P_BOOL,
1302 .p_class = P_LOCAL,
1303 .offset = LOCAL_VAR(bGuest_only),
1304 .special = NULL,
1305 .enum_list = NULL,
1306 .flags = FLAG_ADVANCED | FLAG_SHARE,
1309 .label = "only guest",
1310 .type = P_BOOL,
1311 .p_class = P_LOCAL,
1312 .offset = LOCAL_VAR(bGuest_only),
1313 .special = NULL,
1314 .enum_list = NULL,
1315 .flags = FLAG_HIDE,
1318 .label = "administrative share",
1319 .type = P_BOOL,
1320 .p_class = P_LOCAL,
1321 .offset = LOCAL_VAR(bAdministrative_share),
1322 .special = NULL,
1323 .enum_list = NULL,
1324 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1328 .label = "guest ok",
1329 .type = P_BOOL,
1330 .p_class = P_LOCAL,
1331 .offset = LOCAL_VAR(bGuest_ok),
1332 .special = NULL,
1333 .enum_list = NULL,
1334 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1337 .label = "public",
1338 .type = P_BOOL,
1339 .p_class = P_LOCAL,
1340 .offset = LOCAL_VAR(bGuest_ok),
1341 .special = NULL,
1342 .enum_list = NULL,
1343 .flags = FLAG_HIDE,
1346 .label = "only user",
1347 .type = P_BOOL,
1348 .p_class = P_LOCAL,
1349 .offset = LOCAL_VAR(bOnlyUser),
1350 .special = NULL,
1351 .enum_list = NULL,
1352 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1355 .label = "hosts allow",
1356 .type = P_LIST,
1357 .p_class = P_LOCAL,
1358 .offset = LOCAL_VAR(szHostsallow),
1359 .special = NULL,
1360 .enum_list = NULL,
1361 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1364 .label = "allow hosts",
1365 .type = P_LIST,
1366 .p_class = P_LOCAL,
1367 .offset = LOCAL_VAR(szHostsallow),
1368 .special = NULL,
1369 .enum_list = NULL,
1370 .flags = FLAG_HIDE,
1373 .label = "hosts deny",
1374 .type = P_LIST,
1375 .p_class = P_LOCAL,
1376 .offset = LOCAL_VAR(szHostsdeny),
1377 .special = NULL,
1378 .enum_list = NULL,
1379 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1382 .label = "deny hosts",
1383 .type = P_LIST,
1384 .p_class = P_LOCAL,
1385 .offset = LOCAL_VAR(szHostsdeny),
1386 .special = NULL,
1387 .enum_list = NULL,
1388 .flags = FLAG_HIDE,
1391 .label = "preload modules",
1392 .type = P_LIST,
1393 .p_class = P_GLOBAL,
1394 .offset = GLOBAL_VAR(szPreloadModules),
1395 .special = NULL,
1396 .enum_list = NULL,
1397 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1400 .label = "dedicated keytab file",
1401 .type = P_STRING,
1402 .p_class = P_GLOBAL,
1403 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1404 .special = NULL,
1405 .enum_list = NULL,
1406 .flags = FLAG_ADVANCED,
1409 .label = "kerberos method",
1410 .type = P_ENUM,
1411 .p_class = P_GLOBAL,
1412 .offset = GLOBAL_VAR(iKerberosMethod),
1413 .special = NULL,
1414 .enum_list = enum_kerberos_method,
1415 .flags = FLAG_ADVANCED,
1418 .label = "map untrusted to domain",
1419 .type = P_BOOL,
1420 .p_class = P_GLOBAL,
1421 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1422 .special = NULL,
1423 .enum_list = NULL,
1424 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1428 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1431 .label = "log level",
1432 .type = P_STRING,
1433 .p_class = P_GLOBAL,
1434 .offset = GLOBAL_VAR(szLogLevel),
1435 .special = handle_debug_list,
1436 .enum_list = NULL,
1437 .flags = FLAG_ADVANCED,
1440 .label = "debuglevel",
1441 .type = P_STRING,
1442 .p_class = P_GLOBAL,
1443 .offset = GLOBAL_VAR(szLogLevel),
1444 .special = handle_debug_list,
1445 .enum_list = NULL,
1446 .flags = FLAG_HIDE,
1449 .label = "syslog",
1450 .type = P_INTEGER,
1451 .p_class = P_GLOBAL,
1452 .offset = GLOBAL_VAR(syslog),
1453 .special = NULL,
1454 .enum_list = NULL,
1455 .flags = FLAG_ADVANCED,
1458 .label = "syslog only",
1459 .type = P_BOOL,
1460 .p_class = P_GLOBAL,
1461 .offset = GLOBAL_VAR(bSyslogOnly),
1462 .special = NULL,
1463 .enum_list = NULL,
1464 .flags = FLAG_ADVANCED,
1467 .label = "log file",
1468 .type = P_STRING,
1469 .p_class = P_GLOBAL,
1470 .offset = GLOBAL_VAR(szLogFile),
1471 .special = NULL,
1472 .enum_list = NULL,
1473 .flags = FLAG_ADVANCED,
1476 .label = "max log size",
1477 .type = P_INTEGER,
1478 .p_class = P_GLOBAL,
1479 .offset = GLOBAL_VAR(max_log_size),
1480 .special = NULL,
1481 .enum_list = NULL,
1482 .flags = FLAG_ADVANCED,
1485 .label = "debug timestamp",
1486 .type = P_BOOL,
1487 .p_class = P_GLOBAL,
1488 .offset = GLOBAL_VAR(bTimestampLogs),
1489 .special = NULL,
1490 .enum_list = NULL,
1491 .flags = FLAG_ADVANCED,
1494 .label = "timestamp logs",
1495 .type = P_BOOL,
1496 .p_class = P_GLOBAL,
1497 .offset = GLOBAL_VAR(bTimestampLogs),
1498 .special = NULL,
1499 .enum_list = NULL,
1500 .flags = FLAG_ADVANCED,
1503 .label = "debug prefix timestamp",
1504 .type = P_BOOL,
1505 .p_class = P_GLOBAL,
1506 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1507 .special = NULL,
1508 .enum_list = NULL,
1509 .flags = FLAG_ADVANCED,
1512 .label = "debug hires timestamp",
1513 .type = P_BOOL,
1514 .p_class = P_GLOBAL,
1515 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1516 .special = NULL,
1517 .enum_list = NULL,
1518 .flags = FLAG_ADVANCED,
1521 .label = "debug pid",
1522 .type = P_BOOL,
1523 .p_class = P_GLOBAL,
1524 .offset = GLOBAL_VAR(bDebugPid),
1525 .special = NULL,
1526 .enum_list = NULL,
1527 .flags = FLAG_ADVANCED,
1530 .label = "debug uid",
1531 .type = P_BOOL,
1532 .p_class = P_GLOBAL,
1533 .offset = GLOBAL_VAR(bDebugUid),
1534 .special = NULL,
1535 .enum_list = NULL,
1536 .flags = FLAG_ADVANCED,
1539 .label = "debug class",
1540 .type = P_BOOL,
1541 .p_class = P_GLOBAL,
1542 .offset = GLOBAL_VAR(bDebugClass),
1543 .special = NULL,
1544 .enum_list = NULL,
1545 .flags = FLAG_ADVANCED,
1548 .label = "enable core files",
1549 .type = P_BOOL,
1550 .p_class = P_GLOBAL,
1551 .offset = GLOBAL_VAR(bEnableCoreFiles),
1552 .special = NULL,
1553 .enum_list = NULL,
1554 .flags = FLAG_ADVANCED,
1557 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1560 .label = "allocation roundup size",
1561 .type = P_INTEGER,
1562 .p_class = P_LOCAL,
1563 .offset = LOCAL_VAR(iallocation_roundup_size),
1564 .special = NULL,
1565 .enum_list = NULL,
1566 .flags = FLAG_ADVANCED,
1569 .label = "aio read size",
1570 .type = P_INTEGER,
1571 .p_class = P_LOCAL,
1572 .offset = LOCAL_VAR(iAioReadSize),
1573 .special = NULL,
1574 .enum_list = NULL,
1575 .flags = FLAG_ADVANCED,
1578 .label = "aio write size",
1579 .type = P_INTEGER,
1580 .p_class = P_LOCAL,
1581 .offset = LOCAL_VAR(iAioWriteSize),
1582 .special = NULL,
1583 .enum_list = NULL,
1584 .flags = FLAG_ADVANCED,
1587 .label = "aio write behind",
1588 .type = P_STRING,
1589 .p_class = P_LOCAL,
1590 .offset = LOCAL_VAR(szAioWriteBehind),
1591 .special = NULL,
1592 .enum_list = NULL,
1593 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1596 .label = "smb ports",
1597 .type = P_STRING,
1598 .p_class = P_GLOBAL,
1599 .offset = GLOBAL_VAR(smb_ports),
1600 .special = NULL,
1601 .enum_list = NULL,
1602 .flags = FLAG_ADVANCED,
1605 .label = "large readwrite",
1606 .type = P_BOOL,
1607 .p_class = P_GLOBAL,
1608 .offset = GLOBAL_VAR(bLargeReadwrite),
1609 .special = NULL,
1610 .enum_list = NULL,
1611 .flags = FLAG_ADVANCED,
1614 .label = "max protocol",
1615 .type = P_ENUM,
1616 .p_class = P_GLOBAL,
1617 .offset = GLOBAL_VAR(maxprotocol),
1618 .special = NULL,
1619 .enum_list = enum_protocol,
1620 .flags = FLAG_ADVANCED,
1623 .label = "protocol",
1624 .type = P_ENUM,
1625 .p_class = P_GLOBAL,
1626 .offset = GLOBAL_VAR(maxprotocol),
1627 .special = NULL,
1628 .enum_list = enum_protocol,
1629 .flags = FLAG_ADVANCED,
1632 .label = "min protocol",
1633 .type = P_ENUM,
1634 .p_class = P_GLOBAL,
1635 .offset = GLOBAL_VAR(minprotocol),
1636 .special = NULL,
1637 .enum_list = enum_protocol,
1638 .flags = FLAG_ADVANCED,
1641 .label = "min receivefile size",
1642 .type = P_INTEGER,
1643 .p_class = P_GLOBAL,
1644 .offset = GLOBAL_VAR(iminreceivefile),
1645 .special = NULL,
1646 .enum_list = NULL,
1647 .flags = FLAG_ADVANCED,
1650 .label = "read raw",
1651 .type = P_BOOL,
1652 .p_class = P_GLOBAL,
1653 .offset = GLOBAL_VAR(bReadRaw),
1654 .special = NULL,
1655 .enum_list = NULL,
1656 .flags = FLAG_ADVANCED,
1659 .label = "write raw",
1660 .type = P_BOOL,
1661 .p_class = P_GLOBAL,
1662 .offset = GLOBAL_VAR(bWriteRaw),
1663 .special = NULL,
1664 .enum_list = NULL,
1665 .flags = FLAG_ADVANCED,
1668 .label = "disable netbios",
1669 .type = P_BOOL,
1670 .p_class = P_GLOBAL,
1671 .offset = GLOBAL_VAR(bDisableNetbios),
1672 .special = NULL,
1673 .enum_list = NULL,
1674 .flags = FLAG_ADVANCED,
1677 .label = "reset on zero vc",
1678 .type = P_BOOL,
1679 .p_class = P_GLOBAL,
1680 .offset = GLOBAL_VAR(bResetOnZeroVC),
1681 .special = NULL,
1682 .enum_list = NULL,
1683 .flags = FLAG_ADVANCED,
1686 .label = "log writeable files on exit",
1687 .type = P_BOOL,
1688 .p_class = P_GLOBAL,
1689 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1690 .special = NULL,
1691 .enum_list = NULL,
1692 .flags = FLAG_ADVANCED,
1695 .label = "acl compatibility",
1696 .type = P_ENUM,
1697 .p_class = P_GLOBAL,
1698 .offset = GLOBAL_VAR(iAclCompat),
1699 .special = NULL,
1700 .enum_list = enum_acl_compat_vals,
1701 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1704 .label = "defer sharing violations",
1705 .type = P_BOOL,
1706 .p_class = P_GLOBAL,
1707 .offset = GLOBAL_VAR(bDeferSharingViolations),
1708 .special = NULL,
1709 .enum_list = NULL,
1710 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1713 .label = "ea support",
1714 .type = P_BOOL,
1715 .p_class = P_LOCAL,
1716 .offset = LOCAL_VAR(bEASupport),
1717 .special = NULL,
1718 .enum_list = NULL,
1719 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1722 .label = "nt acl support",
1723 .type = P_BOOL,
1724 .p_class = P_LOCAL,
1725 .offset = LOCAL_VAR(bNTAclSupport),
1726 .special = NULL,
1727 .enum_list = NULL,
1728 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1731 .label = "nt pipe support",
1732 .type = P_BOOL,
1733 .p_class = P_GLOBAL,
1734 .offset = GLOBAL_VAR(bNTPipeSupport),
1735 .special = NULL,
1736 .enum_list = NULL,
1737 .flags = FLAG_ADVANCED,
1740 .label = "nt status support",
1741 .type = P_BOOL,
1742 .p_class = P_GLOBAL,
1743 .offset = GLOBAL_VAR(bNTStatusSupport),
1744 .special = NULL,
1745 .enum_list = NULL,
1746 .flags = FLAG_ADVANCED,
1749 .label = "profile acls",
1750 .type = P_BOOL,
1751 .p_class = P_LOCAL,
1752 .offset = LOCAL_VAR(bProfileAcls),
1753 .special = NULL,
1754 .enum_list = NULL,
1755 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1758 .label = "map acl inherit",
1759 .type = P_BOOL,
1760 .p_class = P_LOCAL,
1761 .offset = LOCAL_VAR(bMap_acl_inherit),
1762 .special = NULL,
1763 .enum_list = NULL,
1764 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1767 .label = "afs share",
1768 .type = P_BOOL,
1769 .p_class = P_LOCAL,
1770 .offset = LOCAL_VAR(bAfs_Share),
1771 .special = NULL,
1772 .enum_list = NULL,
1773 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1776 .label = "max mux",
1777 .type = P_INTEGER,
1778 .p_class = P_GLOBAL,
1779 .offset = GLOBAL_VAR(max_mux),
1780 .special = NULL,
1781 .enum_list = NULL,
1782 .flags = FLAG_ADVANCED,
1785 .label = "max xmit",
1786 .type = P_INTEGER,
1787 .p_class = P_GLOBAL,
1788 .offset = GLOBAL_VAR(max_xmit),
1789 .special = NULL,
1790 .enum_list = NULL,
1791 .flags = FLAG_ADVANCED,
1794 .label = "name resolve order",
1795 .type = P_STRING,
1796 .p_class = P_GLOBAL,
1797 .offset = GLOBAL_VAR(szNameResolveOrder),
1798 .special = NULL,
1799 .enum_list = NULL,
1800 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1803 .label = "max ttl",
1804 .type = P_INTEGER,
1805 .p_class = P_GLOBAL,
1806 .offset = GLOBAL_VAR(max_ttl),
1807 .special = NULL,
1808 .enum_list = NULL,
1809 .flags = FLAG_ADVANCED,
1812 .label = "max wins ttl",
1813 .type = P_INTEGER,
1814 .p_class = P_GLOBAL,
1815 .offset = GLOBAL_VAR(max_wins_ttl),
1816 .special = NULL,
1817 .enum_list = NULL,
1818 .flags = FLAG_ADVANCED,
1821 .label = "min wins ttl",
1822 .type = P_INTEGER,
1823 .p_class = P_GLOBAL,
1824 .offset = GLOBAL_VAR(min_wins_ttl),
1825 .special = NULL,
1826 .enum_list = NULL,
1827 .flags = FLAG_ADVANCED,
1830 .label = "time server",
1831 .type = P_BOOL,
1832 .p_class = P_GLOBAL,
1833 .offset = GLOBAL_VAR(bTimeServer),
1834 .special = NULL,
1835 .enum_list = NULL,
1836 .flags = FLAG_ADVANCED,
1839 .label = "unix extensions",
1840 .type = P_BOOL,
1841 .p_class = P_GLOBAL,
1842 .offset = GLOBAL_VAR(bUnixExtensions),
1843 .special = NULL,
1844 .enum_list = NULL,
1845 .flags = FLAG_ADVANCED,
1848 .label = "use spnego",
1849 .type = P_BOOL,
1850 .p_class = P_GLOBAL,
1851 .offset = GLOBAL_VAR(bUseSpnego),
1852 .special = NULL,
1853 .enum_list = NULL,
1854 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1857 .label = "client signing",
1858 .type = P_ENUM,
1859 .p_class = P_GLOBAL,
1860 .offset = GLOBAL_VAR(client_signing),
1861 .special = NULL,
1862 .enum_list = enum_smb_signing_vals,
1863 .flags = FLAG_ADVANCED,
1866 .label = "server signing",
1867 .type = P_ENUM,
1868 .p_class = P_GLOBAL,
1869 .offset = GLOBAL_VAR(server_signing),
1870 .special = NULL,
1871 .enum_list = enum_smb_signing_vals,
1872 .flags = FLAG_ADVANCED,
1875 .label = "smb encrypt",
1876 .type = P_ENUM,
1877 .p_class = P_LOCAL,
1878 .offset = LOCAL_VAR(ismb_encrypt),
1879 .special = NULL,
1880 .enum_list = enum_smb_signing_vals,
1881 .flags = FLAG_ADVANCED,
1884 .label = "client use spnego",
1885 .type = P_BOOL,
1886 .p_class = P_GLOBAL,
1887 .offset = GLOBAL_VAR(bClientUseSpnego),
1888 .special = NULL,
1889 .enum_list = NULL,
1890 .flags = FLAG_ADVANCED,
1893 .label = "client ldap sasl wrapping",
1894 .type = P_ENUM,
1895 .p_class = P_GLOBAL,
1896 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1897 .special = NULL,
1898 .enum_list = enum_ldap_sasl_wrapping,
1899 .flags = FLAG_ADVANCED,
1902 .label = "enable asu support",
1903 .type = P_BOOL,
1904 .p_class = P_GLOBAL,
1905 .offset = GLOBAL_VAR(bASUSupport),
1906 .special = NULL,
1907 .enum_list = NULL,
1908 .flags = FLAG_ADVANCED,
1911 .label = "svcctl list",
1912 .type = P_LIST,
1913 .p_class = P_GLOBAL,
1914 .offset = GLOBAL_VAR(szServicesList),
1915 .special = NULL,
1916 .enum_list = NULL,
1917 .flags = FLAG_ADVANCED,
1920 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1923 .label = "block size",
1924 .type = P_INTEGER,
1925 .p_class = P_LOCAL,
1926 .offset = LOCAL_VAR(iBlock_size),
1927 .special = NULL,
1928 .enum_list = NULL,
1929 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1932 .label = "deadtime",
1933 .type = P_INTEGER,
1934 .p_class = P_GLOBAL,
1935 .offset = GLOBAL_VAR(deadtime),
1936 .special = NULL,
1937 .enum_list = NULL,
1938 .flags = FLAG_ADVANCED,
1941 .label = "getwd cache",
1942 .type = P_BOOL,
1943 .p_class = P_GLOBAL,
1944 .offset = GLOBAL_VAR(getwd_cache),
1945 .special = NULL,
1946 .enum_list = NULL,
1947 .flags = FLAG_ADVANCED,
1950 .label = "keepalive",
1951 .type = P_INTEGER,
1952 .p_class = P_GLOBAL,
1953 .offset = GLOBAL_VAR(iKeepalive),
1954 .special = NULL,
1955 .enum_list = NULL,
1956 .flags = FLAG_ADVANCED,
1959 .label = "change notify",
1960 .type = P_BOOL,
1961 .p_class = P_LOCAL,
1962 .offset = LOCAL_VAR(bChangeNotify),
1963 .special = NULL,
1964 .enum_list = NULL,
1965 .flags = FLAG_ADVANCED | FLAG_SHARE,
1968 .label = "directory name cache size",
1969 .type = P_INTEGER,
1970 .p_class = P_LOCAL,
1971 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
1972 .special = NULL,
1973 .enum_list = NULL,
1974 .flags = FLAG_ADVANCED | FLAG_SHARE,
1977 .label = "kernel change notify",
1978 .type = P_BOOL,
1979 .p_class = P_LOCAL,
1980 .offset = LOCAL_VAR(bKernelChangeNotify),
1981 .special = NULL,
1982 .enum_list = NULL,
1983 .flags = FLAG_ADVANCED | FLAG_SHARE,
1986 .label = "lpq cache time",
1987 .type = P_INTEGER,
1988 .p_class = P_GLOBAL,
1989 .offset = GLOBAL_VAR(lpqcachetime),
1990 .special = NULL,
1991 .enum_list = NULL,
1992 .flags = FLAG_ADVANCED,
1995 .label = "max smbd processes",
1996 .type = P_INTEGER,
1997 .p_class = P_GLOBAL,
1998 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
1999 .special = NULL,
2000 .enum_list = NULL,
2001 .flags = FLAG_ADVANCED,
2004 .label = "max connections",
2005 .type = P_INTEGER,
2006 .p_class = P_LOCAL,
2007 .offset = LOCAL_VAR(iMaxConnections),
2008 .special = NULL,
2009 .enum_list = NULL,
2010 .flags = FLAG_ADVANCED | FLAG_SHARE,
2013 .label = "paranoid server security",
2014 .type = P_BOOL,
2015 .p_class = P_GLOBAL,
2016 .offset = GLOBAL_VAR(paranoid_server_security),
2017 .special = NULL,
2018 .enum_list = NULL,
2019 .flags = FLAG_ADVANCED,
2022 .label = "max disk size",
2023 .type = P_INTEGER,
2024 .p_class = P_GLOBAL,
2025 .offset = GLOBAL_VAR(maxdisksize),
2026 .special = NULL,
2027 .enum_list = NULL,
2028 .flags = FLAG_ADVANCED,
2031 .label = "max open files",
2032 .type = P_INTEGER,
2033 .p_class = P_GLOBAL,
2034 .offset = GLOBAL_VAR(max_open_files),
2035 .special = NULL,
2036 .enum_list = NULL,
2037 .flags = FLAG_ADVANCED,
2040 .label = "min print space",
2041 .type = P_INTEGER,
2042 .p_class = P_LOCAL,
2043 .offset = LOCAL_VAR(iMinPrintSpace),
2044 .special = NULL,
2045 .enum_list = NULL,
2046 .flags = FLAG_ADVANCED | FLAG_PRINT,
2049 .label = "socket options",
2050 .type = P_STRING,
2051 .p_class = P_GLOBAL,
2052 .offset = GLOBAL_VAR(szSocketOptions),
2053 .special = NULL,
2054 .enum_list = NULL,
2055 .flags = FLAG_ADVANCED,
2058 .label = "strict allocate",
2059 .type = P_BOOL,
2060 .p_class = P_LOCAL,
2061 .offset = LOCAL_VAR(bStrictAllocate),
2062 .special = NULL,
2063 .enum_list = NULL,
2064 .flags = FLAG_ADVANCED | FLAG_SHARE,
2067 .label = "strict sync",
2068 .type = P_BOOL,
2069 .p_class = P_LOCAL,
2070 .offset = LOCAL_VAR(bStrictSync),
2071 .special = NULL,
2072 .enum_list = NULL,
2073 .flags = FLAG_ADVANCED | FLAG_SHARE,
2076 .label = "sync always",
2077 .type = P_BOOL,
2078 .p_class = P_LOCAL,
2079 .offset = LOCAL_VAR(bSyncAlways),
2080 .special = NULL,
2081 .enum_list = NULL,
2082 .flags = FLAG_ADVANCED | FLAG_SHARE,
2085 .label = "use mmap",
2086 .type = P_BOOL,
2087 .p_class = P_GLOBAL,
2088 .offset = GLOBAL_VAR(bUseMmap),
2089 .special = NULL,
2090 .enum_list = NULL,
2091 .flags = FLAG_ADVANCED,
2094 .label = "use sendfile",
2095 .type = P_BOOL,
2096 .p_class = P_LOCAL,
2097 .offset = LOCAL_VAR(bUseSendfile),
2098 .special = NULL,
2099 .enum_list = NULL,
2100 .flags = FLAG_ADVANCED | FLAG_SHARE,
2103 .label = "hostname lookups",
2104 .type = P_BOOL,
2105 .p_class = P_GLOBAL,
2106 .offset = GLOBAL_VAR(bHostnameLookups),
2107 .special = NULL,
2108 .enum_list = NULL,
2109 .flags = FLAG_ADVANCED,
2112 .label = "write cache size",
2113 .type = P_INTEGER,
2114 .p_class = P_LOCAL,
2115 .offset = LOCAL_VAR(iWriteCacheSize),
2116 .special = NULL,
2117 .enum_list = NULL,
2118 .flags = FLAG_ADVANCED | FLAG_SHARE,
2121 .label = "name cache timeout",
2122 .type = P_INTEGER,
2123 .p_class = P_GLOBAL,
2124 .offset = GLOBAL_VAR(name_cache_timeout),
2125 .special = NULL,
2126 .enum_list = NULL,
2127 .flags = FLAG_ADVANCED,
2130 .label = "ctdbd socket",
2131 .type = P_STRING,
2132 .p_class = P_GLOBAL,
2133 .offset = GLOBAL_VAR(ctdbdSocket),
2134 .special = NULL,
2135 .enum_list = NULL,
2136 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2139 .label = "cluster addresses",
2140 .type = P_LIST,
2141 .p_class = P_GLOBAL,
2142 .offset = GLOBAL_VAR(szClusterAddresses),
2143 .special = NULL,
2144 .enum_list = NULL,
2145 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2148 .label = "clustering",
2149 .type = P_BOOL,
2150 .p_class = P_GLOBAL,
2151 .offset = GLOBAL_VAR(clustering),
2152 .special = NULL,
2153 .enum_list = NULL,
2154 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2157 .label = "ctdb timeout",
2158 .type = P_INTEGER,
2159 .p_class = P_GLOBAL,
2160 .offset = GLOBAL_VAR(ctdb_timeout),
2161 .special = NULL,
2162 .enum_list = NULL,
2163 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2166 .label = "ctdb locktime warn threshold",
2167 .type = P_INTEGER,
2168 .p_class = P_GLOBAL,
2169 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2170 .special = NULL,
2171 .enum_list = NULL,
2172 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2175 .label = "smb2 max read",
2176 .type = P_INTEGER,
2177 .p_class = P_GLOBAL,
2178 .offset = GLOBAL_VAR(ismb2_max_read),
2179 .special = NULL,
2180 .enum_list = NULL,
2181 .flags = FLAG_ADVANCED,
2184 .label = "smb2 max write",
2185 .type = P_INTEGER,
2186 .p_class = P_GLOBAL,
2187 .offset = GLOBAL_VAR(ismb2_max_write),
2188 .special = NULL,
2189 .enum_list = NULL,
2190 .flags = FLAG_ADVANCED,
2193 .label = "smb2 max trans",
2194 .type = P_INTEGER,
2195 .p_class = P_GLOBAL,
2196 .offset = GLOBAL_VAR(ismb2_max_trans),
2197 .special = NULL,
2198 .enum_list = NULL,
2199 .flags = FLAG_ADVANCED,
2202 .label = "smb2 max credits",
2203 .type = P_INTEGER,
2204 .p_class = P_GLOBAL,
2205 .offset = GLOBAL_VAR(ismb2_max_credits),
2206 .special = NULL,
2207 .enum_list = NULL,
2208 .flags = FLAG_ADVANCED,
2211 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2214 .label = "max reported print jobs",
2215 .type = P_INTEGER,
2216 .p_class = P_LOCAL,
2217 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2218 .special = NULL,
2219 .enum_list = NULL,
2220 .flags = FLAG_ADVANCED | FLAG_PRINT,
2223 .label = "max print jobs",
2224 .type = P_INTEGER,
2225 .p_class = P_LOCAL,
2226 .offset = LOCAL_VAR(iMaxPrintJobs),
2227 .special = NULL,
2228 .enum_list = NULL,
2229 .flags = FLAG_ADVANCED | FLAG_PRINT,
2232 .label = "load printers",
2233 .type = P_BOOL,
2234 .p_class = P_GLOBAL,
2235 .offset = GLOBAL_VAR(bLoadPrinters),
2236 .special = NULL,
2237 .enum_list = NULL,
2238 .flags = FLAG_ADVANCED | FLAG_PRINT,
2241 .label = "printcap cache time",
2242 .type = P_INTEGER,
2243 .p_class = P_GLOBAL,
2244 .offset = GLOBAL_VAR(PrintcapCacheTime),
2245 .special = NULL,
2246 .enum_list = NULL,
2247 .flags = FLAG_ADVANCED | FLAG_PRINT,
2250 .label = "printcap name",
2251 .type = P_STRING,
2252 .p_class = P_GLOBAL,
2253 .offset = GLOBAL_VAR(szPrintcapname),
2254 .special = NULL,
2255 .enum_list = NULL,
2256 .flags = FLAG_ADVANCED | FLAG_PRINT,
2259 .label = "printcap",
2260 .type = P_STRING,
2261 .p_class = P_GLOBAL,
2262 .offset = GLOBAL_VAR(szPrintcapname),
2263 .special = NULL,
2264 .enum_list = NULL,
2265 .flags = FLAG_HIDE,
2268 .label = "printable",
2269 .type = P_BOOL,
2270 .p_class = P_LOCAL,
2271 .offset = LOCAL_VAR(bPrint_ok),
2272 .special = NULL,
2273 .enum_list = NULL,
2274 .flags = FLAG_ADVANCED | FLAG_PRINT,
2277 .label = "print notify backchannel",
2278 .type = P_BOOL,
2279 .p_class = P_LOCAL,
2280 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2281 .special = NULL,
2282 .enum_list = NULL,
2283 .flags = FLAG_ADVANCED,
2286 .label = "print ok",
2287 .type = P_BOOL,
2288 .p_class = P_LOCAL,
2289 .offset = LOCAL_VAR(bPrint_ok),
2290 .special = NULL,
2291 .enum_list = NULL,
2292 .flags = FLAG_HIDE,
2295 .label = "printing",
2296 .type = P_ENUM,
2297 .p_class = P_LOCAL,
2298 .offset = LOCAL_VAR(iPrinting),
2299 .special = handle_printing,
2300 .enum_list = enum_printing,
2301 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2304 .label = "cups options",
2305 .type = P_STRING,
2306 .p_class = P_LOCAL,
2307 .offset = LOCAL_VAR(szCupsOptions),
2308 .special = NULL,
2309 .enum_list = NULL,
2310 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2313 .label = "cups server",
2314 .type = P_STRING,
2315 .p_class = P_GLOBAL,
2316 .offset = GLOBAL_VAR(szCupsServer),
2317 .special = NULL,
2318 .enum_list = NULL,
2319 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2322 .label = "cups encrypt",
2323 .type = P_ENUM,
2324 .p_class = P_GLOBAL,
2325 .offset = GLOBAL_VAR(CupsEncrypt),
2326 .special = NULL,
2327 .enum_list = enum_bool_auto,
2328 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2332 .label = "cups connection timeout",
2333 .type = P_INTEGER,
2334 .p_class = P_GLOBAL,
2335 .offset = GLOBAL_VAR(cups_connection_timeout),
2336 .special = NULL,
2337 .enum_list = NULL,
2338 .flags = FLAG_ADVANCED,
2341 .label = "iprint server",
2342 .type = P_STRING,
2343 .p_class = P_GLOBAL,
2344 .offset = GLOBAL_VAR(szIPrintServer),
2345 .special = NULL,
2346 .enum_list = NULL,
2347 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2350 .label = "print command",
2351 .type = P_STRING,
2352 .p_class = P_LOCAL,
2353 .offset = LOCAL_VAR(szPrintcommand),
2354 .special = NULL,
2355 .enum_list = NULL,
2356 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2359 .label = "disable spoolss",
2360 .type = P_BOOL,
2361 .p_class = P_GLOBAL,
2362 .offset = GLOBAL_VAR(bDisableSpoolss),
2363 .special = NULL,
2364 .enum_list = NULL,
2365 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2368 .label = "enable spoolss",
2369 .type = P_BOOLREV,
2370 .p_class = P_GLOBAL,
2371 .offset = GLOBAL_VAR(bDisableSpoolss),
2372 .special = NULL,
2373 .enum_list = NULL,
2374 .flags = FLAG_HIDE,
2377 .label = "lpq command",
2378 .type = P_STRING,
2379 .p_class = P_LOCAL,
2380 .offset = LOCAL_VAR(szLpqcommand),
2381 .special = NULL,
2382 .enum_list = NULL,
2383 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2386 .label = "lprm command",
2387 .type = P_STRING,
2388 .p_class = P_LOCAL,
2389 .offset = LOCAL_VAR(szLprmcommand),
2390 .special = NULL,
2391 .enum_list = NULL,
2392 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2395 .label = "lppause command",
2396 .type = P_STRING,
2397 .p_class = P_LOCAL,
2398 .offset = LOCAL_VAR(szLppausecommand),
2399 .special = NULL,
2400 .enum_list = NULL,
2401 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2404 .label = "lpresume command",
2405 .type = P_STRING,
2406 .p_class = P_LOCAL,
2407 .offset = LOCAL_VAR(szLpresumecommand),
2408 .special = NULL,
2409 .enum_list = NULL,
2410 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2413 .label = "queuepause command",
2414 .type = P_STRING,
2415 .p_class = P_LOCAL,
2416 .offset = LOCAL_VAR(szQueuepausecommand),
2417 .special = NULL,
2418 .enum_list = NULL,
2419 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2422 .label = "queueresume command",
2423 .type = P_STRING,
2424 .p_class = P_LOCAL,
2425 .offset = LOCAL_VAR(szQueueresumecommand),
2426 .special = NULL,
2427 .enum_list = NULL,
2428 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2431 .label = "addport command",
2432 .type = P_STRING,
2433 .p_class = P_GLOBAL,
2434 .offset = GLOBAL_VAR(szAddPortCommand),
2435 .special = NULL,
2436 .enum_list = NULL,
2437 .flags = FLAG_ADVANCED,
2440 .label = "enumports command",
2441 .type = P_STRING,
2442 .p_class = P_GLOBAL,
2443 .offset = GLOBAL_VAR(szEnumPortsCommand),
2444 .special = NULL,
2445 .enum_list = NULL,
2446 .flags = FLAG_ADVANCED,
2449 .label = "addprinter command",
2450 .type = P_STRING,
2451 .p_class = P_GLOBAL,
2452 .offset = GLOBAL_VAR(szAddPrinterCommand),
2453 .special = NULL,
2454 .enum_list = NULL,
2455 .flags = FLAG_ADVANCED,
2458 .label = "deleteprinter command",
2459 .type = P_STRING,
2460 .p_class = P_GLOBAL,
2461 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2462 .special = NULL,
2463 .enum_list = NULL,
2464 .flags = FLAG_ADVANCED,
2467 .label = "show add printer wizard",
2468 .type = P_BOOL,
2469 .p_class = P_GLOBAL,
2470 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2471 .special = NULL,
2472 .enum_list = NULL,
2473 .flags = FLAG_ADVANCED,
2476 .label = "os2 driver map",
2477 .type = P_STRING,
2478 .p_class = P_GLOBAL,
2479 .offset = GLOBAL_VAR(szOs2DriverMap),
2480 .special = NULL,
2481 .enum_list = NULL,
2482 .flags = FLAG_ADVANCED,
2486 .label = "printer name",
2487 .type = P_STRING,
2488 .p_class = P_LOCAL,
2489 .offset = LOCAL_VAR(szPrintername),
2490 .special = NULL,
2491 .enum_list = NULL,
2492 .flags = FLAG_ADVANCED | FLAG_PRINT,
2495 .label = "printer",
2496 .type = P_STRING,
2497 .p_class = P_LOCAL,
2498 .offset = LOCAL_VAR(szPrintername),
2499 .special = NULL,
2500 .enum_list = NULL,
2501 .flags = FLAG_HIDE,
2504 .label = "use client driver",
2505 .type = P_BOOL,
2506 .p_class = P_LOCAL,
2507 .offset = LOCAL_VAR(bUseClientDriver),
2508 .special = NULL,
2509 .enum_list = NULL,
2510 .flags = FLAG_ADVANCED | FLAG_PRINT,
2513 .label = "default devmode",
2514 .type = P_BOOL,
2515 .p_class = P_LOCAL,
2516 .offset = LOCAL_VAR(bDefaultDevmode),
2517 .special = NULL,
2518 .enum_list = NULL,
2519 .flags = FLAG_ADVANCED | FLAG_PRINT,
2522 .label = "force printername",
2523 .type = P_BOOL,
2524 .p_class = P_LOCAL,
2525 .offset = LOCAL_VAR(bForcePrintername),
2526 .special = NULL,
2527 .enum_list = NULL,
2528 .flags = FLAG_ADVANCED | FLAG_PRINT,
2531 .label = "printjob username",
2532 .type = P_STRING,
2533 .p_class = P_LOCAL,
2534 .offset = LOCAL_VAR(szPrintjobUsername),
2535 .special = NULL,
2536 .enum_list = NULL,
2537 .flags = FLAG_ADVANCED | FLAG_PRINT,
2540 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2543 .label = "mangling method",
2544 .type = P_STRING,
2545 .p_class = P_GLOBAL,
2546 .offset = GLOBAL_VAR(szManglingMethod),
2547 .special = NULL,
2548 .enum_list = NULL,
2549 .flags = FLAG_ADVANCED,
2552 .label = "mangle prefix",
2553 .type = P_INTEGER,
2554 .p_class = P_GLOBAL,
2555 .offset = GLOBAL_VAR(mangle_prefix),
2556 .special = NULL,
2557 .enum_list = NULL,
2558 .flags = FLAG_ADVANCED,
2562 .label = "default case",
2563 .type = P_ENUM,
2564 .p_class = P_LOCAL,
2565 .offset = LOCAL_VAR(iDefaultCase),
2566 .special = NULL,
2567 .enum_list = enum_case,
2568 .flags = FLAG_ADVANCED | FLAG_SHARE,
2571 .label = "case sensitive",
2572 .type = P_ENUM,
2573 .p_class = P_LOCAL,
2574 .offset = LOCAL_VAR(iCaseSensitive),
2575 .special = NULL,
2576 .enum_list = enum_bool_auto,
2577 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2580 .label = "casesignames",
2581 .type = P_ENUM,
2582 .p_class = P_LOCAL,
2583 .offset = LOCAL_VAR(iCaseSensitive),
2584 .special = NULL,
2585 .enum_list = enum_bool_auto,
2586 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2589 .label = "preserve case",
2590 .type = P_BOOL,
2591 .p_class = P_LOCAL,
2592 .offset = LOCAL_VAR(bCasePreserve),
2593 .special = NULL,
2594 .enum_list = NULL,
2595 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2598 .label = "short preserve case",
2599 .type = P_BOOL,
2600 .p_class = P_LOCAL,
2601 .offset = LOCAL_VAR(bShortCasePreserve),
2602 .special = NULL,
2603 .enum_list = NULL,
2604 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2607 .label = "mangling char",
2608 .type = P_CHAR,
2609 .p_class = P_LOCAL,
2610 .offset = LOCAL_VAR(magic_char),
2611 .special = NULL,
2612 .enum_list = NULL,
2613 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2616 .label = "hide dot files",
2617 .type = P_BOOL,
2618 .p_class = P_LOCAL,
2619 .offset = LOCAL_VAR(bHideDotFiles),
2620 .special = NULL,
2621 .enum_list = NULL,
2622 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2625 .label = "hide special files",
2626 .type = P_BOOL,
2627 .p_class = P_LOCAL,
2628 .offset = LOCAL_VAR(bHideSpecialFiles),
2629 .special = NULL,
2630 .enum_list = NULL,
2631 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2634 .label = "hide unreadable",
2635 .type = P_BOOL,
2636 .p_class = P_LOCAL,
2637 .offset = LOCAL_VAR(bHideUnReadable),
2638 .special = NULL,
2639 .enum_list = NULL,
2640 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2643 .label = "hide unwriteable files",
2644 .type = P_BOOL,
2645 .p_class = P_LOCAL,
2646 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2647 .special = NULL,
2648 .enum_list = NULL,
2649 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2652 .label = "delete veto files",
2653 .type = P_BOOL,
2654 .p_class = P_LOCAL,
2655 .offset = LOCAL_VAR(bDeleteVetoFiles),
2656 .special = NULL,
2657 .enum_list = NULL,
2658 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2661 .label = "veto files",
2662 .type = P_STRING,
2663 .p_class = P_LOCAL,
2664 .offset = LOCAL_VAR(szVetoFiles),
2665 .special = NULL,
2666 .enum_list = NULL,
2667 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2670 .label = "hide files",
2671 .type = P_STRING,
2672 .p_class = P_LOCAL,
2673 .offset = LOCAL_VAR(szHideFiles),
2674 .special = NULL,
2675 .enum_list = NULL,
2676 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2679 .label = "veto oplock files",
2680 .type = P_STRING,
2681 .p_class = P_LOCAL,
2682 .offset = LOCAL_VAR(szVetoOplockFiles),
2683 .special = NULL,
2684 .enum_list = NULL,
2685 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2688 .label = "map archive",
2689 .type = P_BOOL,
2690 .p_class = P_LOCAL,
2691 .offset = LOCAL_VAR(bMap_archive),
2692 .special = NULL,
2693 .enum_list = NULL,
2694 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2697 .label = "map hidden",
2698 .type = P_BOOL,
2699 .p_class = P_LOCAL,
2700 .offset = LOCAL_VAR(bMap_hidden),
2701 .special = NULL,
2702 .enum_list = NULL,
2703 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2706 .label = "map system",
2707 .type = P_BOOL,
2708 .p_class = P_LOCAL,
2709 .offset = LOCAL_VAR(bMap_system),
2710 .special = NULL,
2711 .enum_list = NULL,
2712 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2715 .label = "map readonly",
2716 .type = P_ENUM,
2717 .p_class = P_LOCAL,
2718 .offset = LOCAL_VAR(iMap_readonly),
2719 .special = NULL,
2720 .enum_list = enum_map_readonly,
2721 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2724 .label = "mangled names",
2725 .type = P_BOOL,
2726 .p_class = P_LOCAL,
2727 .offset = LOCAL_VAR(bMangledNames),
2728 .special = NULL,
2729 .enum_list = NULL,
2730 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2733 .label = "max stat cache size",
2734 .type = P_INTEGER,
2735 .p_class = P_GLOBAL,
2736 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2737 .special = NULL,
2738 .enum_list = NULL,
2739 .flags = FLAG_ADVANCED,
2742 .label = "stat cache",
2743 .type = P_BOOL,
2744 .p_class = P_GLOBAL,
2745 .offset = GLOBAL_VAR(bStatCache),
2746 .special = NULL,
2747 .enum_list = NULL,
2748 .flags = FLAG_ADVANCED,
2751 .label = "store dos attributes",
2752 .type = P_BOOL,
2753 .p_class = P_LOCAL,
2754 .offset = LOCAL_VAR(bStoreDosAttributes),
2755 .special = NULL,
2756 .enum_list = NULL,
2757 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2760 .label = "dmapi support",
2761 .type = P_BOOL,
2762 .p_class = P_LOCAL,
2763 .offset = LOCAL_VAR(bDmapiSupport),
2764 .special = NULL,
2765 .enum_list = NULL,
2766 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2770 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2773 .label = "machine password timeout",
2774 .type = P_INTEGER,
2775 .p_class = P_GLOBAL,
2776 .offset = GLOBAL_VAR(machine_password_timeout),
2777 .special = NULL,
2778 .enum_list = NULL,
2779 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2782 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2785 .label = "add user script",
2786 .type = P_STRING,
2787 .p_class = P_GLOBAL,
2788 .offset = GLOBAL_VAR(szAddUserScript),
2789 .special = NULL,
2790 .enum_list = NULL,
2791 .flags = FLAG_ADVANCED,
2794 .label = "rename user script",
2795 .type = P_STRING,
2796 .p_class = P_GLOBAL,
2797 .offset = GLOBAL_VAR(szRenameUserScript),
2798 .special = NULL,
2799 .enum_list = NULL,
2800 .flags = FLAG_ADVANCED,
2803 .label = "delete user script",
2804 .type = P_STRING,
2805 .p_class = P_GLOBAL,
2806 .offset = GLOBAL_VAR(szDelUserScript),
2807 .special = NULL,
2808 .enum_list = NULL,
2809 .flags = FLAG_ADVANCED,
2812 .label = "add group script",
2813 .type = P_STRING,
2814 .p_class = P_GLOBAL,
2815 .offset = GLOBAL_VAR(szAddGroupScript),
2816 .special = NULL,
2817 .enum_list = NULL,
2818 .flags = FLAG_ADVANCED,
2821 .label = "delete group script",
2822 .type = P_STRING,
2823 .p_class = P_GLOBAL,
2824 .offset = GLOBAL_VAR(szDelGroupScript),
2825 .special = NULL,
2826 .enum_list = NULL,
2827 .flags = FLAG_ADVANCED,
2830 .label = "add user to group script",
2831 .type = P_STRING,
2832 .p_class = P_GLOBAL,
2833 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2834 .special = NULL,
2835 .enum_list = NULL,
2836 .flags = FLAG_ADVANCED,
2839 .label = "delete user from group script",
2840 .type = P_STRING,
2841 .p_class = P_GLOBAL,
2842 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2843 .special = NULL,
2844 .enum_list = NULL,
2845 .flags = FLAG_ADVANCED,
2848 .label = "set primary group script",
2849 .type = P_STRING,
2850 .p_class = P_GLOBAL,
2851 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2852 .special = NULL,
2853 .enum_list = NULL,
2854 .flags = FLAG_ADVANCED,
2857 .label = "add machine script",
2858 .type = P_STRING,
2859 .p_class = P_GLOBAL,
2860 .offset = GLOBAL_VAR(szAddMachineScript),
2861 .special = NULL,
2862 .enum_list = NULL,
2863 .flags = FLAG_ADVANCED,
2866 .label = "shutdown script",
2867 .type = P_STRING,
2868 .p_class = P_GLOBAL,
2869 .offset = GLOBAL_VAR(szShutdownScript),
2870 .special = NULL,
2871 .enum_list = NULL,
2872 .flags = FLAG_ADVANCED,
2875 .label = "abort shutdown script",
2876 .type = P_STRING,
2877 .p_class = P_GLOBAL,
2878 .offset = GLOBAL_VAR(szAbortShutdownScript),
2879 .special = NULL,
2880 .enum_list = NULL,
2881 .flags = FLAG_ADVANCED,
2884 .label = "username map script",
2885 .type = P_STRING,
2886 .p_class = P_GLOBAL,
2887 .offset = GLOBAL_VAR(szUsernameMapScript),
2888 .special = NULL,
2889 .enum_list = NULL,
2890 .flags = FLAG_ADVANCED,
2893 .label = "username map cache time",
2894 .type = P_INTEGER,
2895 .p_class = P_GLOBAL,
2896 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2897 .special = NULL,
2898 .enum_list = NULL,
2899 .flags = FLAG_ADVANCED,
2902 .label = "logon script",
2903 .type = P_STRING,
2904 .p_class = P_GLOBAL,
2905 .offset = GLOBAL_VAR(szLogonScript),
2906 .special = NULL,
2907 .enum_list = NULL,
2908 .flags = FLAG_ADVANCED,
2911 .label = "logon path",
2912 .type = P_STRING,
2913 .p_class = P_GLOBAL,
2914 .offset = GLOBAL_VAR(szLogonPath),
2915 .special = NULL,
2916 .enum_list = NULL,
2917 .flags = FLAG_ADVANCED,
2920 .label = "logon drive",
2921 .type = P_STRING,
2922 .p_class = P_GLOBAL,
2923 .offset = GLOBAL_VAR(szLogonDrive),
2924 .special = NULL,
2925 .enum_list = NULL,
2926 .flags = FLAG_ADVANCED,
2929 .label = "logon home",
2930 .type = P_STRING,
2931 .p_class = P_GLOBAL,
2932 .offset = GLOBAL_VAR(szLogonHome),
2933 .special = NULL,
2934 .enum_list = NULL,
2935 .flags = FLAG_ADVANCED,
2938 .label = "domain logons",
2939 .type = P_BOOL,
2940 .p_class = P_GLOBAL,
2941 .offset = GLOBAL_VAR(bDomainLogons),
2942 .special = NULL,
2943 .enum_list = NULL,
2944 .flags = FLAG_ADVANCED,
2948 .label = "init logon delayed hosts",
2949 .type = P_LIST,
2950 .p_class = P_GLOBAL,
2951 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2952 .special = NULL,
2953 .enum_list = NULL,
2954 .flags = FLAG_ADVANCED,
2958 .label = "init logon delay",
2959 .type = P_INTEGER,
2960 .p_class = P_GLOBAL,
2961 .offset = GLOBAL_VAR(InitLogonDelay),
2962 .special = NULL,
2963 .enum_list = NULL,
2964 .flags = FLAG_ADVANCED,
2968 {N_("Browse Options"), P_SEP, P_SEPARATOR},
2971 .label = "os level",
2972 .type = P_INTEGER,
2973 .p_class = P_GLOBAL,
2974 .offset = GLOBAL_VAR(os_level),
2975 .special = NULL,
2976 .enum_list = NULL,
2977 .flags = FLAG_BASIC | FLAG_ADVANCED,
2980 .label = "lm announce",
2981 .type = P_ENUM,
2982 .p_class = P_GLOBAL,
2983 .offset = GLOBAL_VAR(lm_announce),
2984 .special = NULL,
2985 .enum_list = enum_bool_auto,
2986 .flags = FLAG_ADVANCED,
2989 .label = "lm interval",
2990 .type = P_INTEGER,
2991 .p_class = P_GLOBAL,
2992 .offset = GLOBAL_VAR(lm_interval),
2993 .special = NULL,
2994 .enum_list = NULL,
2995 .flags = FLAG_ADVANCED,
2998 .label = "preferred master",
2999 .type = P_ENUM,
3000 .p_class = P_GLOBAL,
3001 .offset = GLOBAL_VAR(iPreferredMaster),
3002 .special = NULL,
3003 .enum_list = enum_bool_auto,
3004 .flags = FLAG_BASIC | FLAG_ADVANCED,
3007 .label = "prefered master",
3008 .type = P_ENUM,
3009 .p_class = P_GLOBAL,
3010 .offset = GLOBAL_VAR(iPreferredMaster),
3011 .special = NULL,
3012 .enum_list = enum_bool_auto,
3013 .flags = FLAG_HIDE,
3016 .label = "local master",
3017 .type = P_BOOL,
3018 .p_class = P_GLOBAL,
3019 .offset = GLOBAL_VAR(bLocalMaster),
3020 .special = NULL,
3021 .enum_list = NULL,
3022 .flags = FLAG_BASIC | FLAG_ADVANCED,
3025 .label = "domain master",
3026 .type = P_ENUM,
3027 .p_class = P_GLOBAL,
3028 .offset = GLOBAL_VAR(iDomainMaster),
3029 .special = NULL,
3030 .enum_list = enum_bool_auto,
3031 .flags = FLAG_BASIC | FLAG_ADVANCED,
3034 .label = "browse list",
3035 .type = P_BOOL,
3036 .p_class = P_GLOBAL,
3037 .offset = GLOBAL_VAR(bBrowseList),
3038 .special = NULL,
3039 .enum_list = NULL,
3040 .flags = FLAG_ADVANCED,
3043 .label = "browseable",
3044 .type = P_BOOL,
3045 .p_class = P_LOCAL,
3046 .offset = LOCAL_VAR(bBrowseable),
3047 .special = NULL,
3048 .enum_list = NULL,
3049 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3052 .label = "browsable",
3053 .type = P_BOOL,
3054 .p_class = P_LOCAL,
3055 .offset = LOCAL_VAR(bBrowseable),
3056 .special = NULL,
3057 .enum_list = NULL,
3058 .flags = FLAG_HIDE,
3061 .label = "access based share enum",
3062 .type = P_BOOL,
3063 .p_class = P_LOCAL,
3064 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3065 .special = NULL,
3066 .enum_list = NULL,
3067 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3070 .label = "enhanced browsing",
3071 .type = P_BOOL,
3072 .p_class = P_GLOBAL,
3073 .offset = GLOBAL_VAR(enhanced_browsing),
3074 .special = NULL,
3075 .enum_list = NULL,
3076 .flags = FLAG_ADVANCED,
3079 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3082 .label = "dns proxy",
3083 .type = P_BOOL,
3084 .p_class = P_GLOBAL,
3085 .offset = GLOBAL_VAR(bDNSproxy),
3086 .special = NULL,
3087 .enum_list = NULL,
3088 .flags = FLAG_ADVANCED,
3091 .label = "wins proxy",
3092 .type = P_BOOL,
3093 .p_class = P_GLOBAL,
3094 .offset = GLOBAL_VAR(bWINSproxy),
3095 .special = NULL,
3096 .enum_list = NULL,
3097 .flags = FLAG_ADVANCED,
3100 .label = "wins server",
3101 .type = P_LIST,
3102 .p_class = P_GLOBAL,
3103 .offset = GLOBAL_VAR(szWINSservers),
3104 .special = NULL,
3105 .enum_list = NULL,
3106 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3109 .label = "wins support",
3110 .type = P_BOOL,
3111 .p_class = P_GLOBAL,
3112 .offset = GLOBAL_VAR(bWINSsupport),
3113 .special = NULL,
3114 .enum_list = NULL,
3115 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3118 .label = "wins hook",
3119 .type = P_STRING,
3120 .p_class = P_GLOBAL,
3121 .offset = GLOBAL_VAR(szWINSHook),
3122 .special = NULL,
3123 .enum_list = NULL,
3124 .flags = FLAG_ADVANCED,
3127 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3130 .label = "blocking locks",
3131 .type = P_BOOL,
3132 .p_class = P_LOCAL,
3133 .offset = LOCAL_VAR(bBlockingLocks),
3134 .special = NULL,
3135 .enum_list = NULL,
3136 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3139 .label = "csc policy",
3140 .type = P_ENUM,
3141 .p_class = P_LOCAL,
3142 .offset = LOCAL_VAR(iCSCPolicy),
3143 .special = NULL,
3144 .enum_list = enum_csc_policy,
3145 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3148 .label = "fake oplocks",
3149 .type = P_BOOL,
3150 .p_class = P_LOCAL,
3151 .offset = LOCAL_VAR(bFakeOplocks),
3152 .special = NULL,
3153 .enum_list = NULL,
3154 .flags = FLAG_ADVANCED | FLAG_SHARE,
3157 .label = "kernel oplocks",
3158 .type = P_BOOL,
3159 .p_class = P_GLOBAL,
3160 .offset = GLOBAL_VAR(bKernelOplocks),
3161 .special = NULL,
3162 .enum_list = NULL,
3163 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3166 .label = "locking",
3167 .type = P_BOOL,
3168 .p_class = P_LOCAL,
3169 .offset = LOCAL_VAR(bLocking),
3170 .special = NULL,
3171 .enum_list = NULL,
3172 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3175 .label = "lock spin time",
3176 .type = P_INTEGER,
3177 .p_class = P_GLOBAL,
3178 .offset = GLOBAL_VAR(iLockSpinTime),
3179 .special = NULL,
3180 .enum_list = NULL,
3181 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3184 .label = "oplocks",
3185 .type = P_BOOL,
3186 .p_class = P_LOCAL,
3187 .offset = LOCAL_VAR(bOpLocks),
3188 .special = NULL,
3189 .enum_list = NULL,
3190 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3193 .label = "level2 oplocks",
3194 .type = P_BOOL,
3195 .p_class = P_LOCAL,
3196 .offset = LOCAL_VAR(bLevel2OpLocks),
3197 .special = NULL,
3198 .enum_list = NULL,
3199 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3202 .label = "oplock break wait time",
3203 .type = P_INTEGER,
3204 .p_class = P_GLOBAL,
3205 .offset = GLOBAL_VAR(oplock_break_wait_time),
3206 .special = NULL,
3207 .enum_list = NULL,
3208 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3211 .label = "oplock contention limit",
3212 .type = P_INTEGER,
3213 .p_class = P_LOCAL,
3214 .offset = LOCAL_VAR(iOplockContentionLimit),
3215 .special = NULL,
3216 .enum_list = NULL,
3217 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3220 .label = "posix locking",
3221 .type = P_BOOL,
3222 .p_class = P_LOCAL,
3223 .offset = LOCAL_VAR(bPosixLocking),
3224 .special = NULL,
3225 .enum_list = NULL,
3226 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3229 .label = "strict locking",
3230 .type = P_ENUM,
3231 .p_class = P_LOCAL,
3232 .offset = LOCAL_VAR(iStrictLocking),
3233 .special = NULL,
3234 .enum_list = enum_bool_auto,
3235 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3238 .label = "share modes",
3239 .type = P_BOOL,
3240 .p_class = P_LOCAL,
3241 .offset = LOCAL_VAR(bShareModes),
3242 .special = NULL,
3243 .enum_list = NULL,
3244 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3247 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3250 .label = "ldap admin dn",
3251 .type = P_STRING,
3252 .p_class = P_GLOBAL,
3253 .offset = GLOBAL_VAR(szLdapAdminDn),
3254 .special = NULL,
3255 .enum_list = NULL,
3256 .flags = FLAG_ADVANCED,
3259 .label = "ldap delete dn",
3260 .type = P_BOOL,
3261 .p_class = P_GLOBAL,
3262 .offset = GLOBAL_VAR(ldap_delete_dn),
3263 .special = NULL,
3264 .enum_list = NULL,
3265 .flags = FLAG_ADVANCED,
3268 .label = "ldap group suffix",
3269 .type = P_STRING,
3270 .p_class = P_GLOBAL,
3271 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3272 .special = NULL,
3273 .enum_list = NULL,
3274 .flags = FLAG_ADVANCED,
3277 .label = "ldap idmap suffix",
3278 .type = P_STRING,
3279 .p_class = P_GLOBAL,
3280 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3281 .special = NULL,
3282 .enum_list = NULL,
3283 .flags = FLAG_ADVANCED,
3286 .label = "ldap machine suffix",
3287 .type = P_STRING,
3288 .p_class = P_GLOBAL,
3289 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3290 .special = NULL,
3291 .enum_list = NULL,
3292 .flags = FLAG_ADVANCED,
3295 .label = "ldap passwd sync",
3296 .type = P_ENUM,
3297 .p_class = P_GLOBAL,
3298 .offset = GLOBAL_VAR(ldap_passwd_sync),
3299 .special = NULL,
3300 .enum_list = enum_ldap_passwd_sync,
3301 .flags = FLAG_ADVANCED,
3304 .label = "ldap password sync",
3305 .type = P_ENUM,
3306 .p_class = P_GLOBAL,
3307 .offset = GLOBAL_VAR(ldap_passwd_sync),
3308 .special = NULL,
3309 .enum_list = enum_ldap_passwd_sync,
3310 .flags = FLAG_HIDE,
3313 .label = "ldap replication sleep",
3314 .type = P_INTEGER,
3315 .p_class = P_GLOBAL,
3316 .offset = GLOBAL_VAR(ldap_replication_sleep),
3317 .special = NULL,
3318 .enum_list = NULL,
3319 .flags = FLAG_ADVANCED,
3322 .label = "ldap suffix",
3323 .type = P_STRING,
3324 .p_class = P_GLOBAL,
3325 .offset = GLOBAL_VAR(szLdapSuffix),
3326 .special = NULL,
3327 .enum_list = NULL,
3328 .flags = FLAG_ADVANCED,
3331 .label = "ldap ssl",
3332 .type = P_ENUM,
3333 .p_class = P_GLOBAL,
3334 .offset = GLOBAL_VAR(ldap_ssl),
3335 .special = NULL,
3336 .enum_list = enum_ldap_ssl,
3337 .flags = FLAG_ADVANCED,
3340 .label = "ldap ssl ads",
3341 .type = P_BOOL,
3342 .p_class = P_GLOBAL,
3343 .offset = GLOBAL_VAR(ldap_ssl_ads),
3344 .special = NULL,
3345 .enum_list = NULL,
3346 .flags = FLAG_ADVANCED,
3349 .label = "ldap deref",
3350 .type = P_ENUM,
3351 .p_class = P_GLOBAL,
3352 .offset = GLOBAL_VAR(ldap_deref),
3353 .special = NULL,
3354 .enum_list = enum_ldap_deref,
3355 .flags = FLAG_ADVANCED,
3358 .label = "ldap follow referral",
3359 .type = P_ENUM,
3360 .p_class = P_GLOBAL,
3361 .offset = GLOBAL_VAR(ldap_follow_referral),
3362 .special = NULL,
3363 .enum_list = enum_bool_auto,
3364 .flags = FLAG_ADVANCED,
3367 .label = "ldap timeout",
3368 .type = P_INTEGER,
3369 .p_class = P_GLOBAL,
3370 .offset = GLOBAL_VAR(ldap_timeout),
3371 .special = NULL,
3372 .enum_list = NULL,
3373 .flags = FLAG_ADVANCED,
3376 .label = "ldap connection timeout",
3377 .type = P_INTEGER,
3378 .p_class = P_GLOBAL,
3379 .offset = GLOBAL_VAR(ldap_connection_timeout),
3380 .special = NULL,
3381 .enum_list = NULL,
3382 .flags = FLAG_ADVANCED,
3385 .label = "ldap page size",
3386 .type = P_INTEGER,
3387 .p_class = P_GLOBAL,
3388 .offset = GLOBAL_VAR(ldap_page_size),
3389 .special = NULL,
3390 .enum_list = NULL,
3391 .flags = FLAG_ADVANCED,
3394 .label = "ldap user suffix",
3395 .type = P_STRING,
3396 .p_class = P_GLOBAL,
3397 .offset = GLOBAL_VAR(szLdapUserSuffix),
3398 .special = NULL,
3399 .enum_list = NULL,
3400 .flags = FLAG_ADVANCED,
3403 .label = "ldap debug level",
3404 .type = P_INTEGER,
3405 .p_class = P_GLOBAL,
3406 .offset = GLOBAL_VAR(ldap_debug_level),
3407 .special = handle_ldap_debug_level,
3408 .enum_list = NULL,
3409 .flags = FLAG_ADVANCED,
3412 .label = "ldap debug threshold",
3413 .type = P_INTEGER,
3414 .p_class = P_GLOBAL,
3415 .offset = GLOBAL_VAR(ldap_debug_threshold),
3416 .special = NULL,
3417 .enum_list = NULL,
3418 .flags = FLAG_ADVANCED,
3421 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3424 .label = "eventlog list",
3425 .type = P_LIST,
3426 .p_class = P_GLOBAL,
3427 .offset = GLOBAL_VAR(szEventLogs),
3428 .special = NULL,
3429 .enum_list = NULL,
3430 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3433 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3436 .label = "add share command",
3437 .type = P_STRING,
3438 .p_class = P_GLOBAL,
3439 .offset = GLOBAL_VAR(szAddShareCommand),
3440 .special = NULL,
3441 .enum_list = NULL,
3442 .flags = FLAG_ADVANCED,
3445 .label = "change share command",
3446 .type = P_STRING,
3447 .p_class = P_GLOBAL,
3448 .offset = GLOBAL_VAR(szChangeShareCommand),
3449 .special = NULL,
3450 .enum_list = NULL,
3451 .flags = FLAG_ADVANCED,
3454 .label = "delete share command",
3455 .type = P_STRING,
3456 .p_class = P_GLOBAL,
3457 .offset = GLOBAL_VAR(szDeleteShareCommand),
3458 .special = NULL,
3459 .enum_list = NULL,
3460 .flags = FLAG_ADVANCED,
3463 .label = "config file",
3464 .type = P_STRING,
3465 .p_class = P_GLOBAL,
3466 .offset = GLOBAL_VAR(szConfigFile),
3467 .special = NULL,
3468 .enum_list = NULL,
3469 .flags = FLAG_HIDE|FLAG_META,
3472 .label = "preload",
3473 .type = P_STRING,
3474 .p_class = P_GLOBAL,
3475 .offset = GLOBAL_VAR(szAutoServices),
3476 .special = NULL,
3477 .enum_list = NULL,
3478 .flags = FLAG_ADVANCED,
3481 .label = "auto services",
3482 .type = P_STRING,
3483 .p_class = P_GLOBAL,
3484 .offset = GLOBAL_VAR(szAutoServices),
3485 .special = NULL,
3486 .enum_list = NULL,
3487 .flags = FLAG_ADVANCED,
3490 .label = "lock directory",
3491 .type = P_STRING,
3492 .p_class = P_GLOBAL,
3493 .offset = GLOBAL_VAR(szLockDir),
3494 .special = NULL,
3495 .enum_list = NULL,
3496 .flags = FLAG_ADVANCED,
3499 .label = "lock dir",
3500 .type = P_STRING,
3501 .p_class = P_GLOBAL,
3502 .offset = GLOBAL_VAR(szLockDir),
3503 .special = NULL,
3504 .enum_list = NULL,
3505 .flags = FLAG_HIDE,
3508 .label = "state directory",
3509 .type = P_STRING,
3510 .p_class = P_GLOBAL,
3511 .offset = GLOBAL_VAR(szStateDir),
3512 .special = NULL,
3513 .enum_list = NULL,
3514 .flags = FLAG_ADVANCED,
3517 .label = "cache directory",
3518 .type = P_STRING,
3519 .p_class = P_GLOBAL,
3520 .offset = GLOBAL_VAR(szCacheDir),
3521 .special = NULL,
3522 .enum_list = NULL,
3523 .flags = FLAG_ADVANCED,
3526 .label = "pid directory",
3527 .type = P_STRING,
3528 .p_class = P_GLOBAL,
3529 .offset = GLOBAL_VAR(szPidDir),
3530 .special = NULL,
3531 .enum_list = NULL,
3532 .flags = FLAG_ADVANCED,
3534 #ifdef WITH_UTMP
3536 .label = "utmp directory",
3537 .type = P_STRING,
3538 .p_class = P_GLOBAL,
3539 .offset = GLOBAL_VAR(szUtmpDir),
3540 .special = NULL,
3541 .enum_list = NULL,
3542 .flags = FLAG_ADVANCED,
3545 .label = "wtmp directory",
3546 .type = P_STRING,
3547 .p_class = P_GLOBAL,
3548 .offset = GLOBAL_VAR(szWtmpDir),
3549 .special = NULL,
3550 .enum_list = NULL,
3551 .flags = FLAG_ADVANCED,
3554 .label = "utmp",
3555 .type = P_BOOL,
3556 .p_class = P_GLOBAL,
3557 .offset = GLOBAL_VAR(bUtmp),
3558 .special = NULL,
3559 .enum_list = NULL,
3560 .flags = FLAG_ADVANCED,
3562 #endif
3564 .label = "default service",
3565 .type = P_STRING,
3566 .p_class = P_GLOBAL,
3567 .offset = GLOBAL_VAR(szDefaultService),
3568 .special = NULL,
3569 .enum_list = NULL,
3570 .flags = FLAG_ADVANCED,
3573 .label = "default",
3574 .type = P_STRING,
3575 .p_class = P_GLOBAL,
3576 .offset = GLOBAL_VAR(szDefaultService),
3577 .special = NULL,
3578 .enum_list = NULL,
3579 .flags = FLAG_ADVANCED,
3582 .label = "message command",
3583 .type = P_STRING,
3584 .p_class = P_GLOBAL,
3585 .offset = GLOBAL_VAR(szMsgCommand),
3586 .special = NULL,
3587 .enum_list = NULL,
3588 .flags = FLAG_ADVANCED,
3591 .label = "dfree cache time",
3592 .type = P_INTEGER,
3593 .p_class = P_LOCAL,
3594 .offset = LOCAL_VAR(iDfreeCacheTime),
3595 .special = NULL,
3596 .enum_list = NULL,
3597 .flags = FLAG_ADVANCED,
3600 .label = "dfree command",
3601 .type = P_STRING,
3602 .p_class = P_LOCAL,
3603 .offset = LOCAL_VAR(szDfree),
3604 .special = NULL,
3605 .enum_list = NULL,
3606 .flags = FLAG_ADVANCED,
3609 .label = "get quota command",
3610 .type = P_STRING,
3611 .p_class = P_GLOBAL,
3612 .offset = GLOBAL_VAR(szGetQuota),
3613 .special = NULL,
3614 .enum_list = NULL,
3615 .flags = FLAG_ADVANCED,
3618 .label = "set quota command",
3619 .type = P_STRING,
3620 .p_class = P_GLOBAL,
3621 .offset = GLOBAL_VAR(szSetQuota),
3622 .special = NULL,
3623 .enum_list = NULL,
3624 .flags = FLAG_ADVANCED,
3627 .label = "remote announce",
3628 .type = P_STRING,
3629 .p_class = P_GLOBAL,
3630 .offset = GLOBAL_VAR(szRemoteAnnounce),
3631 .special = NULL,
3632 .enum_list = NULL,
3633 .flags = FLAG_ADVANCED,
3636 .label = "remote browse sync",
3637 .type = P_STRING,
3638 .p_class = P_GLOBAL,
3639 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3640 .special = NULL,
3641 .enum_list = NULL,
3642 .flags = FLAG_ADVANCED,
3645 .label = "socket address",
3646 .type = P_STRING,
3647 .p_class = P_GLOBAL,
3648 .offset = GLOBAL_VAR(szSocketAddress),
3649 .special = NULL,
3650 .enum_list = NULL,
3651 .flags = FLAG_ADVANCED,
3654 .label = "nmbd bind explicit broadcast",
3655 .type = P_BOOL,
3656 .p_class = P_GLOBAL,
3657 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3658 .special = NULL,
3659 .enum_list = NULL,
3660 .flags = FLAG_ADVANCED,
3663 .label = "homedir map",
3664 .type = P_STRING,
3665 .p_class = P_GLOBAL,
3666 .offset = GLOBAL_VAR(szNISHomeMapName),
3667 .special = NULL,
3668 .enum_list = NULL,
3669 .flags = FLAG_ADVANCED,
3672 .label = "afs username map",
3673 .type = P_STRING,
3674 .p_class = P_GLOBAL,
3675 .offset = GLOBAL_VAR(szAfsUsernameMap),
3676 .special = NULL,
3677 .enum_list = NULL,
3678 .flags = FLAG_ADVANCED,
3681 .label = "afs token lifetime",
3682 .type = P_INTEGER,
3683 .p_class = P_GLOBAL,
3684 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3685 .special = NULL,
3686 .enum_list = NULL,
3687 .flags = FLAG_ADVANCED,
3690 .label = "log nt token command",
3691 .type = P_STRING,
3692 .p_class = P_GLOBAL,
3693 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3694 .special = NULL,
3695 .enum_list = NULL,
3696 .flags = FLAG_ADVANCED,
3699 .label = "NIS homedir",
3700 .type = P_BOOL,
3701 .p_class = P_GLOBAL,
3702 .offset = GLOBAL_VAR(bNISHomeMap),
3703 .special = NULL,
3704 .enum_list = NULL,
3705 .flags = FLAG_ADVANCED,
3708 .label = "-valid",
3709 .type = P_BOOL,
3710 .p_class = P_LOCAL,
3711 .offset = LOCAL_VAR(valid),
3712 .special = NULL,
3713 .enum_list = NULL,
3714 .flags = FLAG_HIDE,
3717 .label = "copy",
3718 .type = P_STRING,
3719 .p_class = P_LOCAL,
3720 .offset = LOCAL_VAR(szCopy),
3721 .special = handle_copy,
3722 .enum_list = NULL,
3723 .flags = FLAG_HIDE,
3726 .label = "include",
3727 .type = P_STRING,
3728 .p_class = P_LOCAL,
3729 .offset = LOCAL_VAR(szInclude),
3730 .special = handle_include,
3731 .enum_list = NULL,
3732 .flags = FLAG_HIDE|FLAG_META,
3735 .label = "preexec",
3736 .type = P_STRING,
3737 .p_class = P_LOCAL,
3738 .offset = LOCAL_VAR(szPreExec),
3739 .special = NULL,
3740 .enum_list = NULL,
3741 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3744 .label = "exec",
3745 .type = P_STRING,
3746 .p_class = P_LOCAL,
3747 .offset = LOCAL_VAR(szPreExec),
3748 .special = NULL,
3749 .enum_list = NULL,
3750 .flags = FLAG_ADVANCED,
3753 .label = "preexec close",
3754 .type = P_BOOL,
3755 .p_class = P_LOCAL,
3756 .offset = LOCAL_VAR(bPreexecClose),
3757 .special = NULL,
3758 .enum_list = NULL,
3759 .flags = FLAG_ADVANCED | FLAG_SHARE,
3762 .label = "postexec",
3763 .type = P_STRING,
3764 .p_class = P_LOCAL,
3765 .offset = LOCAL_VAR(szPostExec),
3766 .special = NULL,
3767 .enum_list = NULL,
3768 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3771 .label = "root preexec",
3772 .type = P_STRING,
3773 .p_class = P_LOCAL,
3774 .offset = LOCAL_VAR(szRootPreExec),
3775 .special = NULL,
3776 .enum_list = NULL,
3777 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3780 .label = "root preexec close",
3781 .type = P_BOOL,
3782 .p_class = P_LOCAL,
3783 .offset = LOCAL_VAR(bRootpreexecClose),
3784 .special = NULL,
3785 .enum_list = NULL,
3786 .flags = FLAG_ADVANCED | FLAG_SHARE,
3789 .label = "root postexec",
3790 .type = P_STRING,
3791 .p_class = P_LOCAL,
3792 .offset = LOCAL_VAR(szRootPostExec),
3793 .special = NULL,
3794 .enum_list = NULL,
3795 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3798 .label = "available",
3799 .type = P_BOOL,
3800 .p_class = P_LOCAL,
3801 .offset = LOCAL_VAR(bAvailable),
3802 .special = NULL,
3803 .enum_list = NULL,
3804 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3807 .label = "registry shares",
3808 .type = P_BOOL,
3809 .p_class = P_GLOBAL,
3810 .offset = GLOBAL_VAR(bRegistryShares),
3811 .special = NULL,
3812 .enum_list = NULL,
3813 .flags = FLAG_ADVANCED,
3816 .label = "usershare allow guests",
3817 .type = P_BOOL,
3818 .p_class = P_GLOBAL,
3819 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3820 .special = NULL,
3821 .enum_list = NULL,
3822 .flags = FLAG_ADVANCED,
3825 .label = "usershare max shares",
3826 .type = P_INTEGER,
3827 .p_class = P_GLOBAL,
3828 .offset = GLOBAL_VAR(iUsershareMaxShares),
3829 .special = NULL,
3830 .enum_list = NULL,
3831 .flags = FLAG_ADVANCED,
3834 .label = "usershare owner only",
3835 .type = P_BOOL,
3836 .p_class = P_GLOBAL,
3837 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3838 .special = NULL,
3839 .enum_list = NULL,
3840 .flags = FLAG_ADVANCED,
3843 .label = "usershare path",
3844 .type = P_STRING,
3845 .p_class = P_GLOBAL,
3846 .offset = GLOBAL_VAR(szUsersharePath),
3847 .special = NULL,
3848 .enum_list = NULL,
3849 .flags = FLAG_ADVANCED,
3852 .label = "usershare prefix allow list",
3853 .type = P_LIST,
3854 .p_class = P_GLOBAL,
3855 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3856 .special = NULL,
3857 .enum_list = NULL,
3858 .flags = FLAG_ADVANCED,
3861 .label = "usershare prefix deny list",
3862 .type = P_LIST,
3863 .p_class = P_GLOBAL,
3864 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3865 .special = NULL,
3866 .enum_list = NULL,
3867 .flags = FLAG_ADVANCED,
3870 .label = "usershare template share",
3871 .type = P_STRING,
3872 .p_class = P_GLOBAL,
3873 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3874 .special = NULL,
3875 .enum_list = NULL,
3876 .flags = FLAG_ADVANCED,
3879 .label = "volume",
3880 .type = P_STRING,
3881 .p_class = P_LOCAL,
3882 .offset = LOCAL_VAR(volume),
3883 .special = NULL,
3884 .enum_list = NULL,
3885 .flags = FLAG_ADVANCED | FLAG_SHARE,
3888 .label = "fstype",
3889 .type = P_STRING,
3890 .p_class = P_LOCAL,
3891 .offset = LOCAL_VAR(fstype),
3892 .special = NULL,
3893 .enum_list = NULL,
3894 .flags = FLAG_ADVANCED | FLAG_SHARE,
3897 .label = "set directory",
3898 .type = P_BOOLREV,
3899 .p_class = P_LOCAL,
3900 .offset = LOCAL_VAR(bNo_set_dir),
3901 .special = NULL,
3902 .enum_list = NULL,
3903 .flags = FLAG_ADVANCED | FLAG_SHARE,
3906 .label = "allow insecure wide links",
3907 .type = P_BOOL,
3908 .p_class = P_GLOBAL,
3909 .offset = GLOBAL_VAR(bAllowInsecureWidelinks),
3910 .special = NULL,
3911 .enum_list = NULL,
3912 .flags = FLAG_ADVANCED,
3915 .label = "wide links",
3916 .type = P_BOOL,
3917 .p_class = P_LOCAL,
3918 .offset = LOCAL_VAR(bWidelinks),
3919 .special = NULL,
3920 .enum_list = NULL,
3921 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3924 .label = "follow symlinks",
3925 .type = P_BOOL,
3926 .p_class = P_LOCAL,
3927 .offset = LOCAL_VAR(bSymlinks),
3928 .special = NULL,
3929 .enum_list = NULL,
3930 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3933 .label = "dont descend",
3934 .type = P_STRING,
3935 .p_class = P_LOCAL,
3936 .offset = LOCAL_VAR(szDontdescend),
3937 .special = NULL,
3938 .enum_list = NULL,
3939 .flags = FLAG_ADVANCED | FLAG_SHARE,
3942 .label = "magic script",
3943 .type = P_STRING,
3944 .p_class = P_LOCAL,
3945 .offset = LOCAL_VAR(szMagicScript),
3946 .special = NULL,
3947 .enum_list = NULL,
3948 .flags = FLAG_ADVANCED | FLAG_SHARE,
3951 .label = "magic output",
3952 .type = P_STRING,
3953 .p_class = P_LOCAL,
3954 .offset = LOCAL_VAR(szMagicOutput),
3955 .special = NULL,
3956 .enum_list = NULL,
3957 .flags = FLAG_ADVANCED | FLAG_SHARE,
3960 .label = "delete readonly",
3961 .type = P_BOOL,
3962 .p_class = P_LOCAL,
3963 .offset = LOCAL_VAR(bDeleteReadonly),
3964 .special = NULL,
3965 .enum_list = NULL,
3966 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3969 .label = "dos filemode",
3970 .type = P_BOOL,
3971 .p_class = P_LOCAL,
3972 .offset = LOCAL_VAR(bDosFilemode),
3973 .special = NULL,
3974 .enum_list = NULL,
3975 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3978 .label = "dos filetimes",
3979 .type = P_BOOL,
3980 .p_class = P_LOCAL,
3981 .offset = LOCAL_VAR(bDosFiletimes),
3982 .special = NULL,
3983 .enum_list = NULL,
3984 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3987 .label = "dos filetime resolution",
3988 .type = P_BOOL,
3989 .p_class = P_LOCAL,
3990 .offset = LOCAL_VAR(bDosFiletimeResolution),
3991 .special = NULL,
3992 .enum_list = NULL,
3993 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3996 .label = "fake directory create times",
3997 .type = P_BOOL,
3998 .p_class = P_LOCAL,
3999 .offset = LOCAL_VAR(bFakeDirCreateTimes),
4000 .special = NULL,
4001 .enum_list = NULL,
4002 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4005 .label = "async smb echo handler",
4006 .type = P_BOOL,
4007 .p_class = P_GLOBAL,
4008 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
4009 .special = NULL,
4010 .enum_list = NULL,
4011 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4014 .label = "multicast dns register",
4015 .type = P_BOOL,
4016 .p_class = P_GLOBAL,
4017 .offset = GLOBAL_VAR(bMulticastDnsRegister),
4018 .special = NULL,
4019 .enum_list = NULL,
4020 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4023 .label = "panic action",
4024 .type = P_STRING,
4025 .p_class = P_GLOBAL,
4026 .offset = GLOBAL_VAR(szPanicAction),
4027 .special = NULL,
4028 .enum_list = NULL,
4029 .flags = FLAG_ADVANCED,
4032 .label = "perfcount module",
4033 .type = P_STRING,
4034 .p_class = P_GLOBAL,
4035 .offset = GLOBAL_VAR(szSMBPerfcountModule),
4036 .special = NULL,
4037 .enum_list = NULL,
4038 .flags = FLAG_ADVANCED,
4041 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4044 .label = "vfs objects",
4045 .type = P_LIST,
4046 .p_class = P_LOCAL,
4047 .offset = LOCAL_VAR(szVfsObjects),
4048 .special = NULL,
4049 .enum_list = NULL,
4050 .flags = FLAG_ADVANCED | FLAG_SHARE,
4053 .label = "vfs object",
4054 .type = P_LIST,
4055 .p_class = P_LOCAL,
4056 .offset = LOCAL_VAR(szVfsObjects),
4057 .special = NULL,
4058 .enum_list = NULL,
4059 .flags = FLAG_HIDE,
4063 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4066 .label = "msdfs root",
4067 .type = P_BOOL,
4068 .p_class = P_LOCAL,
4069 .offset = LOCAL_VAR(bMSDfsRoot),
4070 .special = NULL,
4071 .enum_list = NULL,
4072 .flags = FLAG_ADVANCED | FLAG_SHARE,
4075 .label = "msdfs proxy",
4076 .type = P_STRING,
4077 .p_class = P_LOCAL,
4078 .offset = LOCAL_VAR(szMSDfsProxy),
4079 .special = NULL,
4080 .enum_list = NULL,
4081 .flags = FLAG_ADVANCED | FLAG_SHARE,
4084 .label = "host msdfs",
4085 .type = P_BOOL,
4086 .p_class = P_GLOBAL,
4087 .offset = GLOBAL_VAR(bHostMSDfs),
4088 .special = NULL,
4089 .enum_list = NULL,
4090 .flags = FLAG_ADVANCED,
4093 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4096 .label = "passdb expand explicit",
4097 .type = P_BOOL,
4098 .p_class = P_GLOBAL,
4099 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4100 .special = NULL,
4101 .enum_list = NULL,
4102 .flags = FLAG_ADVANCED,
4105 .label = "idmap backend",
4106 .type = P_STRING,
4107 .p_class = P_GLOBAL,
4108 .offset = GLOBAL_VAR(szIdmapBackend),
4109 .special = handle_idmap_backend,
4110 .enum_list = NULL,
4111 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4114 .label = "idmap cache time",
4115 .type = P_INTEGER,
4116 .p_class = P_GLOBAL,
4117 .offset = GLOBAL_VAR(iIdmapCacheTime),
4118 .special = NULL,
4119 .enum_list = NULL,
4120 .flags = FLAG_ADVANCED,
4123 .label = "idmap negative cache time",
4124 .type = P_INTEGER,
4125 .p_class = P_GLOBAL,
4126 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4127 .special = NULL,
4128 .enum_list = NULL,
4129 .flags = FLAG_ADVANCED,
4132 .label = "idmap uid",
4133 .type = P_STRING,
4134 .p_class = P_GLOBAL,
4135 .offset = GLOBAL_VAR(szIdmapUID),
4136 .special = handle_idmap_uid,
4137 .enum_list = NULL,
4138 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4141 .label = "winbind uid",
4142 .type = P_STRING,
4143 .p_class = P_GLOBAL,
4144 .offset = GLOBAL_VAR(szIdmapUID),
4145 .special = handle_idmap_uid,
4146 .enum_list = NULL,
4147 .flags = FLAG_HIDE,
4150 .label = "idmap gid",
4151 .type = P_STRING,
4152 .p_class = P_GLOBAL,
4153 .offset = GLOBAL_VAR(szIdmapGID),
4154 .special = handle_idmap_gid,
4155 .enum_list = NULL,
4156 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4159 .label = "winbind gid",
4160 .type = P_STRING,
4161 .p_class = P_GLOBAL,
4162 .offset = GLOBAL_VAR(szIdmapGID),
4163 .special = handle_idmap_gid,
4164 .enum_list = NULL,
4165 .flags = FLAG_HIDE,
4168 .label = "template homedir",
4169 .type = P_STRING,
4170 .p_class = P_GLOBAL,
4171 .offset = GLOBAL_VAR(szTemplateHomedir),
4172 .special = NULL,
4173 .enum_list = NULL,
4174 .flags = FLAG_ADVANCED,
4177 .label = "template shell",
4178 .type = P_STRING,
4179 .p_class = P_GLOBAL,
4180 .offset = GLOBAL_VAR(szTemplateShell),
4181 .special = NULL,
4182 .enum_list = NULL,
4183 .flags = FLAG_ADVANCED,
4186 .label = "winbind separator",
4187 .type = P_STRING,
4188 .p_class = P_GLOBAL,
4189 .offset = GLOBAL_VAR(szWinbindSeparator),
4190 .special = NULL,
4191 .enum_list = NULL,
4192 .flags = FLAG_ADVANCED,
4195 .label = "winbind cache time",
4196 .type = P_INTEGER,
4197 .p_class = P_GLOBAL,
4198 .offset = GLOBAL_VAR(winbind_cache_time),
4199 .special = NULL,
4200 .enum_list = NULL,
4201 .flags = FLAG_ADVANCED,
4204 .label = "winbind reconnect delay",
4205 .type = P_INTEGER,
4206 .p_class = P_GLOBAL,
4207 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4208 .special = NULL,
4209 .enum_list = NULL,
4210 .flags = FLAG_ADVANCED,
4213 .label = "winbind max clients",
4214 .type = P_INTEGER,
4215 .p_class = P_GLOBAL,
4216 .offset = GLOBAL_VAR(winbind_max_clients),
4217 .special = NULL,
4218 .enum_list = NULL,
4219 .flags = FLAG_ADVANCED,
4222 .label = "winbind enum users",
4223 .type = P_BOOL,
4224 .p_class = P_GLOBAL,
4225 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4226 .special = NULL,
4227 .enum_list = NULL,
4228 .flags = FLAG_ADVANCED,
4231 .label = "winbind enum groups",
4232 .type = P_BOOL,
4233 .p_class = P_GLOBAL,
4234 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4235 .special = NULL,
4236 .enum_list = NULL,
4237 .flags = FLAG_ADVANCED,
4240 .label = "winbind use default domain",
4241 .type = P_BOOL,
4242 .p_class = P_GLOBAL,
4243 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4244 .special = NULL,
4245 .enum_list = NULL,
4246 .flags = FLAG_ADVANCED,
4249 .label = "winbind trusted domains only",
4250 .type = P_BOOL,
4251 .p_class = P_GLOBAL,
4252 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4253 .special = NULL,
4254 .enum_list = NULL,
4255 .flags = FLAG_ADVANCED,
4258 .label = "winbind nested groups",
4259 .type = P_BOOL,
4260 .p_class = P_GLOBAL,
4261 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4262 .special = NULL,
4263 .enum_list = NULL,
4264 .flags = FLAG_ADVANCED,
4267 .label = "winbind expand groups",
4268 .type = P_INTEGER,
4269 .p_class = P_GLOBAL,
4270 .offset = GLOBAL_VAR(winbind_expand_groups),
4271 .special = NULL,
4272 .enum_list = NULL,
4273 .flags = FLAG_ADVANCED,
4276 .label = "winbind nss info",
4277 .type = P_LIST,
4278 .p_class = P_GLOBAL,
4279 .offset = GLOBAL_VAR(szWinbindNssInfo),
4280 .special = NULL,
4281 .enum_list = NULL,
4282 .flags = FLAG_ADVANCED,
4285 .label = "winbind refresh tickets",
4286 .type = P_BOOL,
4287 .p_class = P_GLOBAL,
4288 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4289 .special = NULL,
4290 .enum_list = NULL,
4291 .flags = FLAG_ADVANCED,
4294 .label = "winbind offline logon",
4295 .type = P_BOOL,
4296 .p_class = P_GLOBAL,
4297 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4298 .special = NULL,
4299 .enum_list = NULL,
4300 .flags = FLAG_ADVANCED,
4303 .label = "winbind normalize names",
4304 .type = P_BOOL,
4305 .p_class = P_GLOBAL,
4306 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4307 .special = NULL,
4308 .enum_list = NULL,
4309 .flags = FLAG_ADVANCED,
4312 .label = "winbind rpc only",
4313 .type = P_BOOL,
4314 .p_class = P_GLOBAL,
4315 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4316 .special = NULL,
4317 .enum_list = NULL,
4318 .flags = FLAG_ADVANCED,
4321 .label = "create krb5 conf",
4322 .type = P_BOOL,
4323 .p_class = P_GLOBAL,
4324 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4325 .special = NULL,
4326 .enum_list = NULL,
4327 .flags = FLAG_ADVANCED,
4330 .label = "ncalrpc dir",
4331 .type = P_STRING,
4332 .p_class = P_GLOBAL,
4333 .offset = GLOBAL_VAR(ncalrpc_dir),
4334 .special = NULL,
4335 .enum_list = NULL,
4336 .flags = FLAG_ADVANCED,
4339 .label = "winbind max domain connections",
4340 .type = P_INTEGER,
4341 .p_class = P_GLOBAL,
4342 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4343 .special = NULL,
4344 .enum_list = NULL,
4345 .flags = FLAG_ADVANCED,
4348 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4351 /***************************************************************************
4352 Initialise the sDefault parameter structure for the printer values.
4353 ***************************************************************************/
4355 static void init_printer_values(struct loadparm_service *pService)
4357 /* choose defaults depending on the type of printing */
4358 switch (pService->iPrinting) {
4359 case PRINT_BSD:
4360 case PRINT_AIX:
4361 case PRINT_LPRNT:
4362 case PRINT_LPROS2:
4363 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4364 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4365 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4366 break;
4368 case PRINT_LPRNG:
4369 case PRINT_PLP:
4370 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4371 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4372 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4373 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4374 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4375 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4376 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4377 break;
4379 case PRINT_CUPS:
4380 case PRINT_IPRINT:
4381 #ifdef HAVE_CUPS
4382 /* set the lpq command to contain the destination printer
4383 name only. This is used by cups_queue_get() */
4384 string_set(&pService->szLpqcommand, "%p");
4385 string_set(&pService->szLprmcommand, "");
4386 string_set(&pService->szPrintcommand, "");
4387 string_set(&pService->szLppausecommand, "");
4388 string_set(&pService->szLpresumecommand, "");
4389 string_set(&pService->szQueuepausecommand, "");
4390 string_set(&pService->szQueueresumecommand, "");
4391 #else
4392 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4393 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4394 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4395 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4396 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4397 string_set(&pService->szQueuepausecommand, "disable '%p'");
4398 string_set(&pService->szQueueresumecommand, "enable '%p'");
4399 #endif /* HAVE_CUPS */
4400 break;
4402 case PRINT_SYSV:
4403 case PRINT_HPUX:
4404 string_set(&pService->szLpqcommand, "lpstat -o%p");
4405 string_set(&pService->szLprmcommand, "cancel %p-%j");
4406 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4407 string_set(&pService->szQueuepausecommand, "disable %p");
4408 string_set(&pService->szQueueresumecommand, "enable %p");
4409 #ifndef HPUX
4410 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4411 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4412 #endif /* HPUX */
4413 break;
4415 case PRINT_QNX:
4416 string_set(&pService->szLpqcommand, "lpq -P%p");
4417 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4418 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4419 break;
4421 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4423 case PRINT_TEST:
4424 case PRINT_VLP: {
4425 const char *tdbfile;
4426 char *tmp;
4428 tdbfile = talloc_asprintf(
4429 talloc_tos(), "tdbfile=%s",
4430 lp_parm_const_string(-1, "vlp", "tdbfile",
4431 "/tmp/vlp.tdb"));
4432 if (tdbfile == NULL) {
4433 tdbfile="tdbfile=/tmp/vlp.tdb";
4436 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4437 tdbfile);
4438 string_set(&pService->szPrintcommand,
4439 tmp ? tmp : "vlp print %p %s");
4440 TALLOC_FREE(tmp);
4442 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4443 tdbfile);
4444 string_set(&pService->szLpqcommand,
4445 tmp ? tmp : "vlp lpq %p");
4446 TALLOC_FREE(tmp);
4448 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4449 tdbfile);
4450 string_set(&pService->szLprmcommand,
4451 tmp ? tmp : "vlp lprm %p %j");
4452 TALLOC_FREE(tmp);
4454 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4455 tdbfile);
4456 string_set(&pService->szLppausecommand,
4457 tmp ? tmp : "vlp lppause %p %j");
4458 TALLOC_FREE(tmp);
4460 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4461 tdbfile);
4462 string_set(&pService->szLpresumecommand,
4463 tmp ? tmp : "vlp lpresume %p %j");
4464 TALLOC_FREE(tmp);
4466 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4467 tdbfile);
4468 string_set(&pService->szQueuepausecommand,
4469 tmp ? tmp : "vlp queuepause %p");
4470 TALLOC_FREE(tmp);
4472 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4473 tdbfile);
4474 string_set(&pService->szQueueresumecommand,
4475 tmp ? tmp : "vlp queueresume %p");
4476 TALLOC_FREE(tmp);
4478 break;
4480 #endif /* DEVELOPER */
4485 * Function to return the default value for the maximum number of open
4486 * file descriptors permitted. This function tries to consult the
4487 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4488 * the smaller of those.
4490 static int max_open_files(void)
4492 int sysctl_max = MAX_OPEN_FILES;
4493 int rlimit_max = MAX_OPEN_FILES;
4495 #ifdef HAVE_SYSCTLBYNAME
4497 size_t size = sizeof(sysctl_max);
4498 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4501 #endif
4503 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4505 struct rlimit rl;
4507 ZERO_STRUCT(rl);
4509 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4510 rlimit_max = rl.rlim_cur;
4512 #if defined(RLIM_INFINITY)
4513 if(rl.rlim_cur == RLIM_INFINITY)
4514 rlimit_max = MAX_OPEN_FILES;
4515 #endif
4517 #endif
4519 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4520 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4521 "minimum Windows limit (%d)\n",
4522 sysctl_max,
4523 MIN_OPEN_FILES_WINDOWS));
4524 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4527 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4528 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4529 "minimum Windows limit (%d)\n",
4530 rlimit_max,
4531 MIN_OPEN_FILES_WINDOWS));
4532 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4535 return MIN(sysctl_max, rlimit_max);
4539 * Common part of freeing allocated data for one parameter.
4541 static void free_one_parameter_common(void *parm_ptr,
4542 struct parm_struct parm)
4544 if ((parm.type == P_STRING) ||
4545 (parm.type == P_USTRING))
4547 string_free((char**)parm_ptr);
4548 } else if (parm.type == P_LIST) {
4549 TALLOC_FREE(*((char***)parm_ptr));
4554 * Free the allocated data for one parameter for a share
4555 * given as a service struct.
4557 static void free_one_parameter(struct loadparm_service *service,
4558 struct parm_struct parm)
4560 void *parm_ptr;
4562 if (parm.p_class != P_LOCAL) {
4563 return;
4566 parm_ptr = lp_parm_ptr(service, &parm);
4568 free_one_parameter_common(parm_ptr, parm);
4572 * Free the allocated parameter data of a share given
4573 * as a service struct.
4575 static void free_parameters(struct loadparm_service *service)
4577 uint32_t i;
4579 for (i=0; parm_table[i].label; i++) {
4580 free_one_parameter(service, parm_table[i]);
4585 * Free the allocated data for one parameter for a given share
4586 * specified by an snum.
4588 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4590 void *parm_ptr;
4592 if (snum < 0) {
4593 parm_ptr = lp_parm_ptr(NULL, &parm);
4594 } else if (parm.p_class != P_LOCAL) {
4595 return;
4596 } else {
4597 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4600 free_one_parameter_common(parm_ptr, parm);
4604 * Free the allocated parameter data for a share specified
4605 * by an snum.
4607 static void free_parameters_by_snum(int snum)
4609 uint32_t i;
4611 for (i=0; parm_table[i].label; i++) {
4612 free_one_parameter_by_snum(snum, parm_table[i]);
4617 * Free the allocated global parameters.
4619 static void free_global_parameters(void)
4621 free_param_opts(&Globals.param_opt);
4622 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4625 static int map_parameter(const char *pszParmName);
4627 struct lp_stored_option {
4628 struct lp_stored_option *prev, *next;
4629 const char *label;
4630 const char *value;
4633 static struct lp_stored_option *stored_options;
4636 save options set by lp_set_cmdline() into a list. This list is
4637 re-applied when we do a globals reset, so that cmdline set options
4638 are sticky across reloads of smb.conf
4640 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4642 struct lp_stored_option *entry, *entry_next;
4643 for (entry = stored_options; entry != NULL; entry = entry_next) {
4644 entry_next = entry->next;
4645 if (strcmp(pszParmName, entry->label) == 0) {
4646 DLIST_REMOVE(stored_options, entry);
4647 talloc_free(entry);
4648 break;
4652 entry = talloc(NULL, struct lp_stored_option);
4653 if (!entry) {
4654 return false;
4657 entry->label = talloc_strdup(entry, pszParmName);
4658 if (!entry->label) {
4659 talloc_free(entry);
4660 return false;
4663 entry->value = talloc_strdup(entry, pszParmValue);
4664 if (!entry->value) {
4665 talloc_free(entry);
4666 return false;
4669 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4671 return true;
4674 static bool apply_lp_set_cmdline(void)
4676 struct lp_stored_option *entry = NULL;
4677 for (entry = stored_options; entry != NULL; entry = entry->next) {
4678 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
4679 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4680 entry->label, entry->value));
4681 return false;
4684 return true;
4687 /***************************************************************************
4688 Initialise the global parameter structure.
4689 ***************************************************************************/
4691 static void init_globals(bool reinit_globals)
4693 static bool done_init = false;
4694 char *s = NULL;
4695 int i;
4697 /* If requested to initialize only once and we've already done it... */
4698 if (!reinit_globals && done_init) {
4699 /* ... then we have nothing more to do */
4700 return;
4703 if (!done_init) {
4704 /* The logfile can be set before this is invoked. Free it if so. */
4705 if (Globals.szLogFile != NULL) {
4706 string_free(&Globals.szLogFile);
4707 Globals.szLogFile = NULL;
4709 done_init = true;
4710 } else {
4711 free_global_parameters();
4714 /* This memset and the free_global_parameters() above will
4715 * wipe out smb.conf options set with lp_set_cmdline(). The
4716 * apply_lp_set_cmdline() call puts these values back in the
4717 * table once the defaults are set */
4718 ZERO_STRUCT(Globals);
4720 for (i = 0; parm_table[i].label; i++) {
4721 if ((parm_table[i].type == P_STRING ||
4722 parm_table[i].type == P_USTRING))
4724 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
4729 string_set(&sDefault.fstype, FSTYPE_STRING);
4730 string_set(&sDefault.szPrintjobUsername, "%U");
4732 init_printer_values(&sDefault);
4735 DEBUG(3, ("Initialising global parameters\n"));
4737 /* Must manually force to upper case here, as this does not go via the handler */
4738 string_set(&Globals.szNetbiosName, myhostname_upper());
4740 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4741 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4743 /* use the new 'hash2' method by default, with a prefix of 1 */
4744 string_set(&Globals.szManglingMethod, "hash2");
4745 Globals.mangle_prefix = 1;
4747 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4749 /* using UTF8 by default allows us to support all chars */
4750 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4752 /* Use codepage 850 as a default for the dos character set */
4753 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4756 * Allow the default PASSWD_CHAT to be overridden in local.h.
4758 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4760 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
4762 string_set(&Globals.szPasswdProgram, "");
4763 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4764 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4765 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4766 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4767 string_set(&Globals.szSocketAddress, "0.0.0.0");
4769 * By default support explicit binding to broadcast
4770 * addresses.
4772 Globals.bNmbdBindExplicitBroadcast = true;
4774 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4775 smb_panic("init_globals: ENOMEM");
4777 string_set(&Globals.szServerString, s);
4778 SAFE_FREE(s);
4779 #ifdef DEVELOPER
4780 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4781 #endif
4783 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4785 string_set(&Globals.szLogonDrive, "");
4786 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4787 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4788 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4790 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4791 string_set(&Globals.szPasswordServer, "*");
4793 Globals.AlgorithmicRidBase = BASE_RID;
4795 Globals.bLoadPrinters = true;
4796 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4798 Globals.ConfigBackend = config_backend;
4800 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4801 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4802 Globals.max_xmit = 0x4104;
4803 Globals.max_mux = 50; /* This is *needed* for profile support. */
4804 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4805 Globals.bDisableSpoolss = false;
4806 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4807 Globals.pwordlevel = 0;
4808 Globals.unamelevel = 0;
4809 Globals.deadtime = 0;
4810 Globals.getwd_cache = true;
4811 Globals.bLargeReadwrite = true;
4812 Globals.max_log_size = 5000;
4813 Globals.max_open_files = max_open_files();
4814 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4815 Globals.maxprotocol = PROTOCOL_NT1;
4816 Globals.minprotocol = PROTOCOL_CORE;
4817 Globals.security = SEC_USER;
4818 Globals.paranoid_server_security = true;
4819 Globals.bEncryptPasswords = true;
4820 Globals.clientSchannel = Auto;
4821 Globals.serverSchannel = Auto;
4822 Globals.bReadRaw = true;
4823 Globals.bWriteRaw = true;
4824 Globals.bNullPasswords = false;
4825 Globals.bObeyPamRestrictions = false;
4826 Globals.syslog = 1;
4827 Globals.bSyslogOnly = false;
4828 Globals.bTimestampLogs = true;
4829 string_set(&Globals.szLogLevel, "0");
4830 Globals.bDebugPrefixTimestamp = false;
4831 Globals.bDebugHiresTimestamp = true;
4832 Globals.bDebugPid = false;
4833 Globals.bDebugUid = false;
4834 Globals.bDebugClass = false;
4835 Globals.bEnableCoreFiles = true;
4836 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4837 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4838 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4839 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4840 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
4841 Globals.lm_interval = 60;
4842 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4843 Globals.bNISHomeMap = false;
4844 #ifdef WITH_NISPLUS_HOME
4845 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4846 #else
4847 string_set(&Globals.szNISHomeMapName, "auto.home");
4848 #endif
4849 #endif
4850 Globals.bTimeServer = false;
4851 Globals.bBindInterfacesOnly = false;
4852 Globals.bUnixPasswdSync = false;
4853 Globals.bPamPasswordChange = false;
4854 Globals.bPasswdChatDebug = false;
4855 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4856 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
4857 Globals.bNTStatusSupport = true; /* Use NT status by default. */
4858 Globals.bStatCache = true; /* use stat cache by default */
4859 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4860 Globals.restrict_anonymous = 0;
4861 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
4862 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
4863 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
4864 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4865 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4866 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4868 Globals.map_to_guest = 0; /* By Default, "Never" */
4869 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4870 Globals.enhanced_browsing = true;
4871 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4872 #ifdef MMAP_BLACKLIST
4873 Globals.bUseMmap = false;
4874 #else
4875 Globals.bUseMmap = true;
4876 #endif
4877 Globals.bUnixExtensions = true;
4878 Globals.bResetOnZeroVC = false;
4879 Globals.bLogWriteableFilesOnExit = false;
4880 Globals.bCreateKrb5Conf = true;
4881 Globals.winbindMaxDomainConnections = 1;
4883 /* hostname lookups can be very expensive and are broken on
4884 a large number of sites (tridge) */
4885 Globals.bHostnameLookups = false;
4887 string_set(&Globals.szPassdbBackend, "tdbsam");
4888 string_set(&Globals.szLdapSuffix, "");
4889 string_set(&Globals.szLdapMachineSuffix, "");
4890 string_set(&Globals.szLdapUserSuffix, "");
4891 string_set(&Globals.szLdapGroupSuffix, "");
4892 string_set(&Globals.szLdapIdmapSuffix, "");
4894 string_set(&Globals.szLdapAdminDn, "");
4895 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4896 Globals.ldap_ssl_ads = false;
4897 Globals.ldap_deref = -1;
4898 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4899 Globals.ldap_delete_dn = false;
4900 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4901 Globals.ldap_follow_referral = Auto;
4902 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4903 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4904 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4906 Globals.ldap_debug_level = 0;
4907 Globals.ldap_debug_threshold = 10;
4909 /* This is what we tell the afs client. in reality we set the token
4910 * to never expire, though, when this runs out the afs client will
4911 * forget the token. Set to 0 to get NEVERDATE.*/
4912 Globals.iAfsTokenLifetime = 604800;
4913 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4915 /* these parameters are set to defaults that are more appropriate
4916 for the increasing samba install base:
4918 as a member of the workgroup, that will possibly become a
4919 _local_ master browser (lm = true). this is opposed to a forced
4920 local master browser startup (pm = true).
4922 doesn't provide WINS server service by default (wsupp = false),
4923 and doesn't provide domain master browser services by default, either.
4927 Globals.bMsAddPrinterWizard = true;
4928 Globals.os_level = 20;
4929 Globals.bLocalMaster = true;
4930 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4931 Globals.bDomainLogons = false;
4932 Globals.bBrowseList = true;
4933 Globals.bWINSsupport = false;
4934 Globals.bWINSproxy = false;
4936 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4937 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4939 Globals.bDNSproxy = true;
4941 /* this just means to use them if they exist */
4942 Globals.bKernelOplocks = true;
4944 Globals.bAllowTrustedDomains = true;
4945 string_set(&Globals.szIdmapBackend, "tdb");
4947 string_set(&Globals.szTemplateShell, "/bin/false");
4948 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4949 string_set(&Globals.szWinbindSeparator, "\\");
4951 string_set(&Globals.szCupsServer, "");
4952 string_set(&Globals.szIPrintServer, "");
4954 string_set(&Globals.ctdbdSocket, "");
4955 Globals.szClusterAddresses = NULL;
4956 Globals.clustering = false;
4957 Globals.ctdb_timeout = 0;
4958 Globals.ctdb_locktime_warn_threshold = 0;
4960 Globals.winbind_cache_time = 300; /* 5 minutes */
4961 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4962 Globals.winbind_max_clients = 200;
4963 Globals.bWinbindEnumUsers = false;
4964 Globals.bWinbindEnumGroups = false;
4965 Globals.bWinbindUseDefaultDomain = false;
4966 Globals.bWinbindTrustedDomainsOnly = false;
4967 Globals.bWinbindNestedGroups = true;
4968 Globals.winbind_expand_groups = 1;
4969 Globals.szWinbindNssInfo = (const char **)str_list_make_v3(NULL, "template", NULL);
4970 Globals.bWinbindRefreshTickets = false;
4971 Globals.bWinbindOfflineLogon = false;
4973 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4974 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4976 Globals.bPassdbExpandExplicit = false;
4978 Globals.name_cache_timeout = 660; /* In seconds */
4980 Globals.bUseSpnego = true;
4981 Globals.bClientUseSpnego = true;
4983 Globals.client_signing = SMB_SIGNING_IF_REQUIRED;
4984 Globals.server_signing = SMB_SIGNING_OFF;
4986 Globals.bDeferSharingViolations = true;
4987 string_set(&Globals.smb_ports, SMB_PORTS);
4989 Globals.bEnablePrivileges = true;
4990 Globals.bHostMSDfs = true;
4991 Globals.bASUSupport = false;
4993 /* User defined shares. */
4994 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4995 smb_panic("init_globals: ENOMEM");
4997 string_set(&Globals.szUsersharePath, s);
4998 SAFE_FREE(s);
4999 string_set(&Globals.szUsershareTemplateShare, "");
5000 Globals.iUsershareMaxShares = 0;
5001 /* By default disallow sharing of directories not owned by the sharer. */
5002 Globals.bUsershareOwnerOnly = true;
5003 /* By default disallow guest access to usershares. */
5004 Globals.bUsershareAllowGuests = false;
5006 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5008 /* By default no shares out of the registry */
5009 Globals.bRegistryShares = false;
5011 Globals.iminreceivefile = 0;
5013 Globals.bMapUntrustedToDomain = false;
5014 Globals.bMulticastDnsRegister = true;
5016 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5017 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5018 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5019 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5021 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5023 /* Now put back the settings that were set with lp_set_cmdline() */
5024 apply_lp_set_cmdline();
5027 /*******************************************************************
5028 Convenience routine to grab string parameters into temporary memory
5029 and run standard_sub_basic on them. The buffers can be written to by
5030 callers without affecting the source string.
5031 ********************************************************************/
5033 static char *lp_string(const char *s)
5035 char *ret;
5036 TALLOC_CTX *ctx = talloc_tos();
5038 /* The follow debug is useful for tracking down memory problems
5039 especially if you have an inner loop that is calling a lp_*()
5040 function that returns a string. Perhaps this debug should be
5041 present all the time? */
5043 #if 0
5044 DEBUG(10, ("lp_string(%s)\n", s));
5045 #endif
5046 if (!s) {
5047 return NULL;
5050 ret = talloc_sub_basic(ctx,
5051 get_current_username(),
5052 current_user_info.domain,
5054 if (trim_char(ret, '\"', '\"')) {
5055 if (strchr(ret,'\"') != NULL) {
5056 TALLOC_FREE(ret);
5057 ret = talloc_sub_basic(ctx,
5058 get_current_username(),
5059 current_user_info.domain,
5063 return ret;
5067 In this section all the functions that are used to access the
5068 parameters from the rest of the program are defined
5071 #define FN_GLOBAL_STRING(fn_name,ptr) \
5072 char *fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5073 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5074 const char *fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5075 #define FN_GLOBAL_LIST(fn_name,ptr) \
5076 const char **fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5077 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5078 bool fn_name(void) {return(*(bool *)(&Globals.ptr));}
5079 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5080 char fn_name(void) {return(*(char *)(&Globals.ptr));}
5081 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5082 int fn_name(void) {return(*(int *)(&Globals.ptr));}
5084 #define FN_LOCAL_STRING(fn_name,val) \
5085 char *lp_ ## fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5086 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5087 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5088 #define FN_LOCAL_LIST(fn_name,val) \
5089 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5090 #define FN_LOCAL_BOOL(fn_name,val) \
5091 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5092 #define FN_LOCAL_INTEGER(fn_name,val) \
5093 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5095 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5096 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5097 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5098 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5099 #define FN_LOCAL_CHAR(fn_name,val) \
5100 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5102 FN_GLOBAL_CONST_STRING(lp_smb_ports, smb_ports)
5103 FN_GLOBAL_CONST_STRING(lp_dos_charset, dos_charset)
5104 FN_GLOBAL_CONST_STRING(lp_unix_charset, unix_charset)
5105 FN_GLOBAL_STRING(lp_logfile, szLogFile)
5106 FN_GLOBAL_STRING(lp_configfile, szConfigFile)
5107 FN_GLOBAL_CONST_STRING(lp_smb_passwd_file, szSMBPasswdFile)
5108 FN_GLOBAL_CONST_STRING(lp_private_dir, szPrivateDir)
5109 FN_GLOBAL_STRING(lp_serverstring, szServerString)
5110 FN_GLOBAL_INTEGER(lp_printcap_cache_time, PrintcapCacheTime)
5111 FN_GLOBAL_STRING(lp_addport_cmd, szAddPortCommand)
5112 FN_GLOBAL_STRING(lp_enumports_cmd, szEnumPortsCommand)
5113 FN_GLOBAL_STRING(lp_addprinter_cmd, szAddPrinterCommand)
5114 FN_GLOBAL_STRING(lp_deleteprinter_cmd, szDeletePrinterCommand)
5115 FN_GLOBAL_STRING(lp_os2_driver_map, szOs2DriverMap)
5116 FN_GLOBAL_CONST_STRING(lp_lockdir, szLockDir)
5117 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5118 * build process or in smb.conf, we use that value. Otherwise they
5119 * default to the value of lp_lockdir(). */
5120 const char *lp_statedir(void) {
5121 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5122 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5123 return(*(char **)(&Globals.szStateDir) ?
5124 *(char **)(&Globals.szStateDir) : "");
5125 else
5126 return(*(char **)(&Globals.szLockDir) ?
5127 *(char **)(&Globals.szLockDir) : "");
5129 const char *lp_cachedir(void) {
5130 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5131 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5132 return(*(char **)(&Globals.szCacheDir) ?
5133 *(char **)(&Globals.szCacheDir) : "");
5134 else
5135 return(*(char **)(&Globals.szLockDir) ?
5136 *(char **)(&Globals.szLockDir) : "");
5138 FN_GLOBAL_CONST_STRING(lp_piddir, szPidDir)
5139 FN_GLOBAL_STRING(lp_mangling_method, szManglingMethod)
5140 FN_GLOBAL_INTEGER(lp_mangle_prefix, mangle_prefix)
5141 FN_GLOBAL_CONST_STRING(lp_utmpdir, szUtmpDir)
5142 FN_GLOBAL_CONST_STRING(lp_wtmpdir, szWtmpDir)
5143 FN_GLOBAL_BOOL(lp_utmp, bUtmp)
5144 FN_GLOBAL_STRING(lp_rootdir, szRootdir)
5145 FN_GLOBAL_STRING(lp_perfcount_module, szSMBPerfcountModule)
5146 FN_GLOBAL_STRING(lp_defaultservice, szDefaultService)
5147 FN_GLOBAL_STRING(lp_msg_command, szMsgCommand)
5148 FN_GLOBAL_STRING(lp_get_quota_command, szGetQuota)
5149 FN_GLOBAL_STRING(lp_set_quota_command, szSetQuota)
5150 FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
5151 FN_GLOBAL_STRING(lp_passwd_program, szPasswdProgram)
5152 FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
5153 FN_GLOBAL_CONST_STRING(lp_passwordserver, szPasswordServer)
5154 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, szNameResolveOrder)
5155 FN_GLOBAL_CONST_STRING(lp_workgroup, szWorkgroup)
5156 FN_GLOBAL_CONST_STRING(lp_netbios_name, szNetbiosName)
5157 FN_GLOBAL_CONST_STRING(lp_netbios_scope, szNetbiosScope)
5158 FN_GLOBAL_CONST_STRING(lp_realm, szRealmUpper)
5159 FN_GLOBAL_CONST_STRING(lp_dnsdomain, szDnsDomain)
5160 FN_GLOBAL_CONST_STRING(lp_afs_username_map, szAfsUsernameMap)
5161 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, iAfsTokenLifetime)
5162 FN_GLOBAL_STRING(lp_log_nt_token_command, szLogNtTokenCommand)
5163 FN_GLOBAL_STRING(lp_username_map, szUsernameMap)
5164 FN_GLOBAL_CONST_STRING(lp_logon_script, szLogonScript)
5165 FN_GLOBAL_CONST_STRING(lp_logon_path, szLogonPath)
5166 FN_GLOBAL_CONST_STRING(lp_logon_drive, szLogonDrive)
5167 FN_GLOBAL_CONST_STRING(lp_logon_home, szLogonHome)
5168 FN_GLOBAL_STRING(lp_remote_announce, szRemoteAnnounce)
5169 FN_GLOBAL_STRING(lp_remote_browse_sync, szRemoteBrowseSync)
5170 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, bNmbdBindExplicitBroadcast)
5171 FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
5172 FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
5173 FN_GLOBAL_STRING(lp_nis_home_map_name, szNISHomeMapName)
5174 FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
5175 FN_GLOBAL_CONST_STRING(lp_passdb_backend, szPassdbBackend)
5176 FN_GLOBAL_LIST(lp_preload_modules, szPreloadModules)
5177 FN_GLOBAL_STRING(lp_panic_action, szPanicAction)
5178 FN_GLOBAL_STRING(lp_adduser_script, szAddUserScript)
5179 FN_GLOBAL_STRING(lp_renameuser_script, szRenameUserScript)
5180 FN_GLOBAL_STRING(lp_deluser_script, szDelUserScript)
5182 FN_GLOBAL_CONST_STRING(lp_guestaccount, szGuestaccount)
5183 FN_GLOBAL_STRING(lp_addgroup_script, szAddGroupScript)
5184 FN_GLOBAL_STRING(lp_delgroup_script, szDelGroupScript)
5185 FN_GLOBAL_STRING(lp_addusertogroup_script, szAddUserToGroupScript)
5186 FN_GLOBAL_STRING(lp_deluserfromgroup_script, szDelUserFromGroupScript)
5187 FN_GLOBAL_STRING(lp_setprimarygroup_script, szSetPrimaryGroupScript)
5189 FN_GLOBAL_STRING(lp_addmachine_script, szAddMachineScript)
5191 FN_GLOBAL_STRING(lp_shutdown_script, szShutdownScript)
5192 FN_GLOBAL_STRING(lp_abort_shutdown_script, szAbortShutdownScript)
5193 FN_GLOBAL_STRING(lp_username_map_script, szUsernameMapScript)
5194 FN_GLOBAL_INTEGER(lp_username_map_cache_time, iUsernameMapCacheTime)
5196 FN_GLOBAL_STRING(lp_check_password_script, szCheckPasswordScript)
5198 FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
5199 FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
5200 FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
5201 FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
5202 FN_GLOBAL_INTEGER(lp_acl_compatibility, iAclCompat)
5203 FN_GLOBAL_BOOL(lp_winbind_enum_users, bWinbindEnumUsers)
5204 FN_GLOBAL_BOOL(lp_winbind_enum_groups, bWinbindEnumGroups)
5205 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, bWinbindUseDefaultDomain)
5206 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5207 FN_GLOBAL_BOOL(lp_winbind_nested_groups, bWinbindNestedGroups)
5208 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, winbind_expand_groups)
5209 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, bWinbindRefreshTickets)
5210 FN_GLOBAL_BOOL(lp_winbind_offline_logon, bWinbindOfflineLogon)
5211 FN_GLOBAL_BOOL(lp_winbind_normalize_names, bWinbindNormalizeNames)
5212 FN_GLOBAL_BOOL(lp_winbind_rpc_only, bWinbindRpcOnly)
5213 FN_GLOBAL_BOOL(lp_create_krb5_conf, bCreateKrb5Conf)
5214 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5215 winbindMaxDomainConnections)
5217 int lp_winbind_max_domain_connections(void)
5219 if (lp_winbind_offline_logon() &&
5220 lp_winbind_max_domain_connections_int() > 1) {
5221 DEBUG(1, ("offline logons active, restricting max domain "
5222 "connections to 1\n"));
5223 return 1;
5225 return MAX(1, lp_winbind_max_domain_connections_int());
5228 FN_GLOBAL_CONST_STRING(lp_idmap_backend, szIdmapBackend)
5229 FN_GLOBAL_INTEGER(lp_idmap_cache_time, iIdmapCacheTime)
5230 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, iIdmapNegativeCacheTime)
5231 FN_GLOBAL_INTEGER(lp_keepalive, iKeepalive)
5232 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, bPassdbExpandExplicit)
5234 FN_GLOBAL_STRING(lp_ldap_suffix, szLdapSuffix)
5235 FN_GLOBAL_STRING(lp_ldap_admin_dn, szLdapAdminDn)
5236 FN_GLOBAL_INTEGER(lp_ldap_ssl, ldap_ssl)
5237 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, ldap_ssl_ads)
5238 FN_GLOBAL_INTEGER(lp_ldap_deref, ldap_deref)
5239 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, ldap_follow_referral)
5240 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, ldap_passwd_sync)
5241 FN_GLOBAL_BOOL(lp_ldap_delete_dn, ldap_delete_dn)
5242 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, ldap_replication_sleep)
5243 FN_GLOBAL_INTEGER(lp_ldap_timeout, ldap_timeout)
5244 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, ldap_connection_timeout)
5245 FN_GLOBAL_INTEGER(lp_ldap_page_size, ldap_page_size)
5246 FN_GLOBAL_INTEGER(lp_ldap_debug_level, ldap_debug_level)
5247 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, ldap_debug_threshold)
5248 FN_GLOBAL_STRING(lp_add_share_cmd, szAddShareCommand)
5249 FN_GLOBAL_STRING(lp_change_share_cmd, szChangeShareCommand)
5250 FN_GLOBAL_STRING(lp_delete_share_cmd, szDeleteShareCommand)
5251 FN_GLOBAL_STRING(lp_usershare_path, szUsersharePath)
5252 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, szUsersharePrefixAllowList)
5253 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, szUsersharePrefixDenyList)
5255 FN_GLOBAL_LIST(lp_eventlog_list, szEventLogs)
5257 FN_GLOBAL_BOOL(lp_registry_shares, bRegistryShares)
5258 FN_GLOBAL_BOOL(lp_usershare_allow_guests, bUsershareAllowGuests)
5259 FN_GLOBAL_BOOL(lp_usershare_owner_only, bUsershareOwnerOnly)
5260 FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
5261 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, bResetOnZeroVC)
5262 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit, bLogWriteableFilesOnExit)
5263 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, bMsAddPrinterWizard)
5264 FN_GLOBAL_BOOL(lp_dns_proxy, bDNSproxy)
5265 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, bWINSsupport)
5266 FN_GLOBAL_BOOL(lp_wins_proxy, bWINSproxy)
5267 FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
5268 FN_GLOBAL_BOOL(lp_domain_logons, bDomainLogons)
5269 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, szInitLogonDelayedHosts)
5270 FN_GLOBAL_INTEGER(lp_init_logon_delay, InitLogonDelay)
5271 FN_GLOBAL_BOOL(lp_load_printers, bLoadPrinters)
5272 FN_GLOBAL_BOOL(_lp_readraw, bReadRaw)
5273 FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
5274 FN_GLOBAL_BOOL(_lp_writeraw, bWriteRaw)
5275 FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
5276 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
5277 FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
5278 FN_GLOBAL_INTEGER(lp_client_schannel, clientSchannel)
5279 FN_GLOBAL_INTEGER(lp_server_schannel, serverSchannel)
5280 FN_GLOBAL_BOOL(lp_syslog_only, bSyslogOnly)
5281 FN_GLOBAL_BOOL(lp_timestamp_logs, bTimestampLogs)
5282 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, bDebugPrefixTimestamp)
5283 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, bDebugHiresTimestamp)
5284 FN_GLOBAL_BOOL(lp_debug_pid, bDebugPid)
5285 FN_GLOBAL_BOOL(lp_debug_uid, bDebugUid)
5286 FN_GLOBAL_BOOL(lp_debug_class, bDebugClass)
5287 FN_GLOBAL_BOOL(lp_enable_core_files, bEnableCoreFiles)
5288 FN_GLOBAL_BOOL(lp_browse_list, bBrowseList)
5289 FN_GLOBAL_BOOL(lp_nis_home_map, bNISHomeMap)
5290 static FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
5291 FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
5292 FN_GLOBAL_BOOL(lp_pam_password_change, bPamPasswordChange)
5293 FN_GLOBAL_BOOL(lp_unix_password_sync, bUnixPasswdSync)
5294 FN_GLOBAL_BOOL(lp_passwd_chat_debug, bPasswdChatDebug)
5295 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, iPasswdChatTimeout)
5296 FN_GLOBAL_BOOL(lp_nt_pipe_support, bNTPipeSupport)
5297 FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
5298 FN_GLOBAL_BOOL(lp_stat_cache, bStatCache)
5299 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, iMaxStatCacheSize)
5300 FN_GLOBAL_BOOL(lp_allow_trusted_domains, bAllowTrustedDomains)
5301 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, bMapUntrustedToDomain)
5302 FN_GLOBAL_INTEGER(lp_restrict_anonymous, restrict_anonymous)
5303 FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
5304 FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
5305 FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
5306 FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
5307 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
5308 FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
5309 FN_GLOBAL_BOOL(lp_kernel_oplocks, bKernelOplocks)
5310 FN_GLOBAL_BOOL(lp_enhanced_browsing, enhanced_browsing)
5311 FN_GLOBAL_BOOL(lp_use_mmap, bUseMmap)
5312 FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
5313 FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
5314 FN_GLOBAL_BOOL(lp_client_use_spnego, bClientUseSpnego)
5315 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
5316 FN_GLOBAL_BOOL(lp_send_spnego_principal, send_spnego_principal)
5317 FN_GLOBAL_BOOL(lp_hostname_lookups, bHostnameLookups)
5318 FN_GLOBAL_CONST_STRING(lp_dedicated_keytab_file, szDedicatedKeytabFile)
5319 FN_GLOBAL_INTEGER(lp_kerberos_method, iKerberosMethod)
5320 FN_GLOBAL_BOOL(lp_defer_sharing_violations, bDeferSharingViolations)
5321 FN_GLOBAL_BOOL(lp_enable_privileges, bEnablePrivileges)
5322 FN_GLOBAL_BOOL(lp_enable_asu_support, bASUSupport)
5323 FN_GLOBAL_INTEGER(lp_os_level, os_level)
5324 FN_GLOBAL_INTEGER(lp_max_ttl, max_ttl)
5325 FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
5326 FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
5327 FN_GLOBAL_INTEGER(lp_max_log_size, max_log_size)
5328 FN_GLOBAL_INTEGER(lp_max_open_files, max_open_files)
5329 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, open_files_db_hash_size)
5330 FN_GLOBAL_INTEGER(lp_maxxmit, max_xmit)
5331 FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
5332 FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
5333 FN_GLOBAL_INTEGER(lp_usernamelevel, unamelevel)
5334 FN_GLOBAL_INTEGER(lp_deadtime, deadtime)
5335 FN_GLOBAL_BOOL(lp_getwd_cache, getwd_cache)
5336 static FN_GLOBAL_INTEGER(_lp_maxprotocol, maxprotocol)
5337 int lp_maxprotocol(void)
5339 int ret = _lp_maxprotocol();
5340 if ((ret >= PROTOCOL_SMB2_02) && (lp_security() == SEC_SHARE)) {
5341 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5342 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5343 lp_do_parameter(-1, "max protocol", "NT1");
5344 return PROTOCOL_NT1;
5346 return ret;
5348 FN_GLOBAL_INTEGER(lp_minprotocol, minprotocol)
5349 FN_GLOBAL_INTEGER(lp_security, security)
5350 FN_GLOBAL_LIST(lp_auth_methods, AuthMethods)
5351 FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
5352 FN_GLOBAL_INTEGER(lp_maxdisksize, maxdisksize)
5353 FN_GLOBAL_INTEGER(lp_lpqcachetime, lpqcachetime)
5354 FN_GLOBAL_INTEGER(lp_max_smbd_processes, iMaxSmbdProcesses)
5355 FN_GLOBAL_BOOL(_lp_disable_spoolss, bDisableSpoolss)
5356 FN_GLOBAL_INTEGER(lp_syslog, syslog)
5357 FN_GLOBAL_INTEGER(lp_lm_announce, lm_announce)
5358 FN_GLOBAL_INTEGER(lp_lm_interval, lm_interval)
5359 FN_GLOBAL_INTEGER(lp_machine_password_timeout, machine_password_timeout)
5360 FN_GLOBAL_INTEGER(lp_map_to_guest, map_to_guest)
5361 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, oplock_break_wait_time)
5362 FN_GLOBAL_INTEGER(lp_lock_spin_time, iLockSpinTime)
5363 FN_GLOBAL_INTEGER(lp_usershare_max_shares, iUsershareMaxShares)
5364 FN_GLOBAL_CONST_STRING(lp_socket_options, szSocketOptions)
5365 FN_GLOBAL_INTEGER(lp_config_backend, ConfigBackend)
5366 FN_GLOBAL_INTEGER(lp_smb2_max_read, ismb2_max_read)
5367 FN_GLOBAL_INTEGER(lp_smb2_max_write, ismb2_max_write)
5368 FN_GLOBAL_INTEGER(lp_smb2_max_trans, ismb2_max_trans)
5369 int lp_smb2_max_credits(void)
5371 if (Globals.ismb2_max_credits == 0) {
5372 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5374 return Globals.ismb2_max_credits;
5376 FN_GLOBAL_LIST(lp_svcctl_list, szServicesList)
5377 FN_GLOBAL_STRING(lp_cups_server, szCupsServer)
5378 int lp_cups_encrypt(void)
5380 int result = 0;
5381 #ifdef HAVE_HTTPCONNECTENCRYPT
5382 switch (Globals.CupsEncrypt) {
5383 case Auto:
5384 result = HTTP_ENCRYPT_REQUIRED;
5385 break;
5386 case true:
5387 result = HTTP_ENCRYPT_ALWAYS;
5388 break;
5389 case false:
5390 result = HTTP_ENCRYPT_NEVER;
5391 break;
5393 #endif
5394 return result;
5396 FN_GLOBAL_STRING(lp_iprint_server, szIPrintServer)
5397 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, cups_connection_timeout)
5398 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, ctdbdSocket)
5399 FN_GLOBAL_LIST(lp_cluster_addresses, szClusterAddresses)
5400 FN_GLOBAL_BOOL(lp_clustering, clustering)
5401 FN_GLOBAL_INTEGER(lp_ctdb_timeout, ctdb_timeout)
5402 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5403 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, bAsyncSMBEchoHandler)
5404 FN_GLOBAL_BOOL(lp_multicast_dns_register, bMulticastDnsRegister)
5405 FN_GLOBAL_BOOL(lp_allow_insecure_widelinks, bAllowInsecureWidelinks)
5406 FN_GLOBAL_INTEGER(lp_winbind_cache_time, winbind_cache_time)
5407 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, winbind_reconnect_delay)
5408 FN_GLOBAL_INTEGER(lp_winbind_max_clients, winbind_max_clients)
5409 FN_GLOBAL_LIST(lp_winbind_nss_info, szWinbindNssInfo)
5410 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, AlgorithmicRidBase)
5411 FN_GLOBAL_INTEGER(lp_name_cache_timeout, name_cache_timeout)
5412 FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
5413 FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
5414 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5416 FN_GLOBAL_CONST_STRING(lp_ncalrpc_dir, ncalrpc_dir)
5418 #include "lib/param/param_functions.c"
5420 FN_LOCAL_STRING(servicename, szService)
5421 FN_LOCAL_CONST_STRING(const_servicename, szService)
5423 /* local prototypes */
5425 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5426 static const char *get_boolean(bool bool_value);
5427 static int getservicebyname(const char *pszServiceName,
5428 struct loadparm_service *pserviceDest);
5429 static void copy_service(struct loadparm_service *pserviceDest,
5430 struct loadparm_service *pserviceSource,
5431 struct bitmap *pcopymapDest);
5432 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5433 void *userdata);
5434 static bool do_section(const char *pszSectionName, void *userdata);
5435 static void init_copymap(struct loadparm_service *pservice);
5436 static bool hash_a_service(const char *name, int number);
5437 static void free_service_byindex(int iService);
5438 static void show_parameter(int parmIndex);
5439 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5442 * This is a helper function for parametrical options support. It returns a
5443 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5444 * parametrical functions are quite simple
5446 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
5447 const char *option)
5449 bool global_section = false;
5450 char* param_key;
5451 struct parmlist_entry *data;
5453 if (service == NULL) {
5454 data = Globals.param_opt;
5455 global_section = true;
5456 } else {
5457 data = service->param_opt;
5460 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5461 DEBUG(0,("asprintf failed!\n"));
5462 return NULL;
5465 while (data) {
5466 if (strwicmp(data->key, param_key) == 0) {
5467 string_free(&param_key);
5468 return data;
5470 data = data->next;
5473 if (!global_section) {
5474 /* Try to fetch the same option but from globals */
5475 /* but only if we are not already working with Globals */
5476 data = Globals.param_opt;
5477 while (data) {
5478 if (strwicmp(data->key, param_key) == 0) {
5479 string_free(&param_key);
5480 return data;
5482 data = data->next;
5486 string_free(&param_key);
5488 return NULL;
5492 * This is a helper function for parametrical options support. It returns a
5493 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5494 * parametrical functions are quite simple
5496 static struct parmlist_entry *get_parametrics(int snum, const char *type,
5497 const char *option)
5499 if (snum >= iNumServices) return NULL;
5501 if (snum < 0) {
5502 return get_parametrics_by_service(NULL, type, option);
5503 } else {
5504 return get_parametrics_by_service(ServicePtrs[snum], type, option);
5509 #define MISSING_PARAMETER(name) \
5510 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5512 /*******************************************************************
5513 convenience routine to return int parameters.
5514 ********************************************************************/
5515 static int lp_int(const char *s)
5518 if (!s || !*s) {
5519 MISSING_PARAMETER(lp_int);
5520 return (-1);
5523 return (int)strtol(s, NULL, 0);
5526 /*******************************************************************
5527 convenience routine to return unsigned long parameters.
5528 ********************************************************************/
5529 static unsigned long lp_ulong(const char *s)
5532 if (!s || !*s) {
5533 MISSING_PARAMETER(lp_ulong);
5534 return (0);
5537 return strtoul(s, NULL, 0);
5540 /*******************************************************************
5541 convenience routine to return boolean parameters.
5542 ********************************************************************/
5543 static bool lp_bool(const char *s)
5545 bool ret = false;
5547 if (!s || !*s) {
5548 MISSING_PARAMETER(lp_bool);
5549 return false;
5552 if (!set_boolean(s, &ret)) {
5553 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5554 return false;
5557 return ret;
5560 /*******************************************************************
5561 convenience routine to return enum parameters.
5562 ********************************************************************/
5563 static int lp_enum(const char *s,const struct enum_list *_enum)
5565 int i;
5567 if (!s || !*s || !_enum) {
5568 MISSING_PARAMETER(lp_enum);
5569 return (-1);
5572 for (i=0; _enum[i].name; i++) {
5573 if (strequal(_enum[i].name,s))
5574 return _enum[i].value;
5577 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5578 return (-1);
5581 #undef MISSING_PARAMETER
5583 /* Return parametric option from a given service. Type is a part of option before ':' */
5584 /* Parametric option has following syntax: 'Type: option = value' */
5585 /* the returned value is talloced on the talloc_tos() */
5586 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5588 struct parmlist_entry *data = get_parametrics(snum, type, option);
5590 if (data == NULL||data->value==NULL) {
5591 if (def) {
5592 return lp_string(def);
5593 } else {
5594 return NULL;
5598 return lp_string(data->value);
5601 /* Return parametric option from a given service. Type is a part of option before ':' */
5602 /* Parametric option has following syntax: 'Type: option = value' */
5603 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5605 struct parmlist_entry *data = get_parametrics(snum, type, option);
5607 if (data == NULL||data->value==NULL)
5608 return def;
5610 return data->value;
5613 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
5615 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
5617 if (data == NULL||data->value==NULL)
5618 return NULL;
5620 return data->value;
5624 /* Return parametric option from a given service. Type is a part of option before ':' */
5625 /* Parametric option has following syntax: 'Type: option = value' */
5627 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5629 struct parmlist_entry *data = get_parametrics(snum, type, option);
5631 if (data == NULL||data->value==NULL)
5632 return (const char **)def;
5634 if (data->list==NULL) {
5635 data->list = str_list_make_v3(NULL, data->value, NULL);
5638 return (const char **)data->list;
5641 /* Return parametric option from a given service. Type is a part of option before ':' */
5642 /* Parametric option has following syntax: 'Type: option = value' */
5644 int lp_parm_int(int snum, const char *type, const char *option, int def)
5646 struct parmlist_entry *data = get_parametrics(snum, type, option);
5648 if (data && data->value && *data->value)
5649 return lp_int(data->value);
5651 return def;
5654 /* Return parametric option from a given service. Type is a part of option before ':' */
5655 /* Parametric option has following syntax: 'Type: option = value' */
5657 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5659 struct parmlist_entry *data = get_parametrics(snum, type, option);
5661 if (data && data->value && *data->value)
5662 return lp_ulong(data->value);
5664 return def;
5667 /* Return parametric option from a given service. Type is a part of option before ':' */
5668 /* Parametric option has following syntax: 'Type: option = value' */
5670 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5672 struct parmlist_entry *data = get_parametrics(snum, type, option);
5674 if (data && data->value && *data->value)
5675 return lp_bool(data->value);
5677 return def;
5680 /* Return parametric option from a given service. Type is a part of option before ':' */
5681 /* Parametric option has following syntax: 'Type: option = value' */
5683 int lp_parm_enum(int snum, const char *type, const char *option,
5684 const struct enum_list *_enum, int def)
5686 struct parmlist_entry *data = get_parametrics(snum, type, option);
5688 if (data && data->value && *data->value && _enum)
5689 return lp_enum(data->value, _enum);
5691 return def;
5695 /***************************************************************************
5696 Initialise a service to the defaults.
5697 ***************************************************************************/
5699 static void init_service(struct loadparm_service *pservice)
5701 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
5702 copy_service(pservice, &sDefault, NULL);
5707 * free a param_opts structure.
5708 * param_opts handling should be moved to talloc;
5709 * then this whole functions reduces to a TALLOC_FREE().
5712 static void free_param_opts(struct parmlist_entry **popts)
5714 struct parmlist_entry *opt, *next_opt;
5716 if (popts == NULL) {
5717 return;
5720 if (*popts != NULL) {
5721 DEBUG(5, ("Freeing parametrics:\n"));
5723 opt = *popts;
5724 while (opt != NULL) {
5725 string_free(&opt->key);
5726 string_free(&opt->value);
5727 TALLOC_FREE(opt->list);
5728 next_opt = opt->next;
5729 SAFE_FREE(opt);
5730 opt = next_opt;
5732 *popts = NULL;
5735 /***************************************************************************
5736 Free the dynamically allocated parts of a service struct.
5737 ***************************************************************************/
5739 static void free_service(struct loadparm_service *pservice)
5741 if (!pservice)
5742 return;
5744 if (pservice->szService)
5745 DEBUG(5, ("free_service: Freeing service %s\n",
5746 pservice->szService));
5748 free_parameters(pservice);
5750 string_free(&pservice->szService);
5751 TALLOC_FREE(pservice->copymap);
5753 free_param_opts(&pservice->param_opt);
5755 ZERO_STRUCTP(pservice);
5759 /***************************************************************************
5760 remove a service indexed in the ServicePtrs array from the ServiceHash
5761 and free the dynamically allocated parts
5762 ***************************************************************************/
5764 static void free_service_byindex(int idx)
5766 if ( !LP_SNUM_OK(idx) )
5767 return;
5769 ServicePtrs[idx]->valid = false;
5770 invalid_services[num_invalid_services++] = idx;
5772 /* we have to cleanup the hash record */
5774 if (ServicePtrs[idx]->szService) {
5775 char *canon_name = canonicalize_servicename(
5776 talloc_tos(),
5777 ServicePtrs[idx]->szService );
5779 dbwrap_delete_bystring(ServiceHash, canon_name );
5780 TALLOC_FREE(canon_name);
5783 free_service(ServicePtrs[idx]);
5786 /***************************************************************************
5787 Add a new service to the services array initialising it with the given
5788 service.
5789 ***************************************************************************/
5791 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5793 int i;
5794 struct loadparm_service tservice;
5795 int num_to_alloc = iNumServices + 1;
5797 tservice = *pservice;
5799 /* it might already exist */
5800 if (name) {
5801 i = getservicebyname(name, NULL);
5802 if (i >= 0) {
5803 return (i);
5807 /* find an invalid one */
5808 i = iNumServices;
5809 if (num_invalid_services > 0) {
5810 i = invalid_services[--num_invalid_services];
5813 /* if not, then create one */
5814 if (i == iNumServices) {
5815 struct loadparm_service **tsp;
5816 int *tinvalid;
5818 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5819 if (tsp == NULL) {
5820 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5821 return (-1);
5823 ServicePtrs = tsp;
5824 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5825 if (!ServicePtrs[iNumServices]) {
5826 DEBUG(0,("add_a_service: out of memory!\n"));
5827 return (-1);
5829 iNumServices++;
5831 /* enlarge invalid_services here for now... */
5832 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5833 num_to_alloc);
5834 if (tinvalid == NULL) {
5835 DEBUG(0,("add_a_service: failed to enlarge "
5836 "invalid_services!\n"));
5837 return (-1);
5839 invalid_services = tinvalid;
5840 } else {
5841 free_service_byindex(i);
5844 ServicePtrs[i]->valid = true;
5846 init_service(ServicePtrs[i]);
5847 copy_service(ServicePtrs[i], &tservice, NULL);
5848 if (name)
5849 string_set(&ServicePtrs[i]->szService, name);
5851 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5852 i, ServicePtrs[i]->szService));
5854 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5855 return (-1);
5858 return (i);
5861 /***************************************************************************
5862 Convert a string to uppercase and remove whitespaces.
5863 ***************************************************************************/
5865 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5867 char *result;
5869 if ( !src ) {
5870 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5871 return NULL;
5874 result = talloc_strdup(ctx, src);
5875 SMB_ASSERT(result != NULL);
5877 strlower_m(result);
5878 return result;
5881 /***************************************************************************
5882 Add a name/index pair for the services array to the hash table.
5883 ***************************************************************************/
5885 static bool hash_a_service(const char *name, int idx)
5887 char *canon_name;
5889 if ( !ServiceHash ) {
5890 DEBUG(10,("hash_a_service: creating servicehash\n"));
5891 ServiceHash = db_open_rbt(NULL);
5892 if ( !ServiceHash ) {
5893 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5894 return false;
5898 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5899 idx, name));
5901 canon_name = canonicalize_servicename(talloc_tos(), name );
5903 dbwrap_store_bystring(ServiceHash, canon_name,
5904 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5905 TDB_REPLACE);
5907 TALLOC_FREE(canon_name);
5909 return true;
5912 /***************************************************************************
5913 Add a new home service, with the specified home directory, defaults coming
5914 from service ifrom.
5915 ***************************************************************************/
5917 bool lp_add_home(const char *pszHomename, int iDefaultService,
5918 const char *user, const char *pszHomedir)
5920 int i;
5922 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5923 pszHomedir[0] == '\0') {
5924 return false;
5927 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5929 if (i < 0)
5930 return false;
5932 if (!(*(ServicePtrs[iDefaultService]->szPath))
5933 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5934 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5937 if (!(*(ServicePtrs[i]->comment))) {
5938 char *comment = NULL;
5939 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5940 return false;
5942 string_set(&ServicePtrs[i]->comment, comment);
5943 SAFE_FREE(comment);
5946 /* set the browseable flag from the global default */
5948 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5949 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
5951 ServicePtrs[i]->autoloaded = true;
5953 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5954 user, ServicePtrs[i]->szPath ));
5956 return true;
5959 /***************************************************************************
5960 Add a new service, based on an old one.
5961 ***************************************************************************/
5963 int lp_add_service(const char *pszService, int iDefaultService)
5965 if (iDefaultService < 0) {
5966 return add_a_service(&sDefault, pszService);
5969 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5972 /***************************************************************************
5973 Add the IPC service.
5974 ***************************************************************************/
5976 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5978 char *comment = NULL;
5979 int i = add_a_service(&sDefault, ipc_name);
5981 if (i < 0)
5982 return false;
5984 if (asprintf(&comment, "IPC Service (%s)",
5985 Globals.szServerString) < 0) {
5986 return false;
5989 string_set(&ServicePtrs[i]->szPath, tmpdir());
5990 string_set(&ServicePtrs[i]->szUsername, "");
5991 string_set(&ServicePtrs[i]->comment, comment);
5992 string_set(&ServicePtrs[i]->fstype, "IPC");
5993 ServicePtrs[i]->iMaxConnections = 0;
5994 ServicePtrs[i]->bAvailable = true;
5995 ServicePtrs[i]->bRead_only = true;
5996 ServicePtrs[i]->bGuest_only = false;
5997 ServicePtrs[i]->bAdministrative_share = true;
5998 ServicePtrs[i]->bGuest_ok = guest_ok;
5999 ServicePtrs[i]->bPrint_ok = false;
6000 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6002 DEBUG(3, ("adding IPC service\n"));
6004 SAFE_FREE(comment);
6005 return true;
6008 /***************************************************************************
6009 Add a new printer service, with defaults coming from service iFrom.
6010 ***************************************************************************/
6012 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6014 const char *comment = "From Printcap";
6015 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6017 if (i < 0)
6018 return false;
6020 /* note that we do NOT default the availability flag to true - */
6021 /* we take it from the default service passed. This allows all */
6022 /* dynamic printers to be disabled by disabling the [printers] */
6023 /* entry (if/when the 'available' keyword is implemented!). */
6025 /* the printer name is set to the service name. */
6026 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6027 string_set(&ServicePtrs[i]->comment, comment);
6029 /* set the browseable flag from the gloabl default */
6030 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6032 /* Printers cannot be read_only. */
6033 ServicePtrs[i]->bRead_only = false;
6034 /* No share modes on printer services. */
6035 ServicePtrs[i]->bShareModes = false;
6036 /* No oplocks on printer services. */
6037 ServicePtrs[i]->bOpLocks = false;
6038 /* Printer services must be printable. */
6039 ServicePtrs[i]->bPrint_ok = true;
6041 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6043 return true;
6047 /***************************************************************************
6048 Check whether the given parameter name is valid.
6049 Parametric options (names containing a colon) are considered valid.
6050 ***************************************************************************/
6052 bool lp_parameter_is_valid(const char *pszParmName)
6054 return ((map_parameter(pszParmName) != -1) ||
6055 (strchr(pszParmName, ':') != NULL));
6058 /***************************************************************************
6059 Check whether the given name is the name of a global parameter.
6060 Returns true for strings belonging to parameters of class
6061 P_GLOBAL, false for all other strings, also for parametric options
6062 and strings not belonging to any option.
6063 ***************************************************************************/
6065 bool lp_parameter_is_global(const char *pszParmName)
6067 int num = map_parameter(pszParmName);
6069 if (num >= 0) {
6070 return (parm_table[num].p_class == P_GLOBAL);
6073 return false;
6076 /**************************************************************************
6077 Check whether the given name is the canonical name of a parameter.
6078 Returns false if it is not a valid parameter Name.
6079 For parametric options, true is returned.
6080 **************************************************************************/
6082 bool lp_parameter_is_canonical(const char *parm_name)
6084 if (!lp_parameter_is_valid(parm_name)) {
6085 return false;
6088 return (map_parameter(parm_name) ==
6089 map_parameter_canonical(parm_name, NULL));
6092 /**************************************************************************
6093 Determine the canonical name for a parameter.
6094 Indicate when it is an inverse (boolean) synonym instead of a
6095 "usual" synonym.
6096 **************************************************************************/
6098 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6099 bool *inverse)
6101 int num;
6103 if (!lp_parameter_is_valid(parm_name)) {
6104 *canon_parm = NULL;
6105 return false;
6108 num = map_parameter_canonical(parm_name, inverse);
6109 if (num < 0) {
6110 /* parametric option */
6111 *canon_parm = parm_name;
6112 } else {
6113 *canon_parm = parm_table[num].label;
6116 return true;
6120 /**************************************************************************
6121 Determine the canonical name for a parameter.
6122 Turn the value given into the inverse boolean expression when
6123 the synonym is an invers boolean synonym.
6125 Return true if parm_name is a valid parameter name and
6126 in case it is an invers boolean synonym, if the val string could
6127 successfully be converted to the reverse bool.
6128 Return false in all other cases.
6129 **************************************************************************/
6131 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6132 const char *val,
6133 const char **canon_parm,
6134 const char **canon_val)
6136 int num;
6137 bool inverse;
6139 if (!lp_parameter_is_valid(parm_name)) {
6140 *canon_parm = NULL;
6141 *canon_val = NULL;
6142 return false;
6145 num = map_parameter_canonical(parm_name, &inverse);
6146 if (num < 0) {
6147 /* parametric option */
6148 *canon_parm = parm_name;
6149 *canon_val = val;
6150 } else {
6151 *canon_parm = parm_table[num].label;
6152 if (inverse) {
6153 if (!lp_invert_boolean(val, canon_val)) {
6154 *canon_val = NULL;
6155 return false;
6157 } else {
6158 *canon_val = val;
6162 return true;
6165 /***************************************************************************
6166 Map a parameter's string representation to something we can use.
6167 Returns false if the parameter string is not recognised, else TRUE.
6168 ***************************************************************************/
6170 static int map_parameter(const char *pszParmName)
6172 int iIndex;
6174 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6175 return (-1);
6177 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6178 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6179 return (iIndex);
6181 /* Warn only if it isn't parametric option */
6182 if (strchr(pszParmName, ':') == NULL)
6183 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6184 /* We do return 'fail' for parametric options as well because they are
6185 stored in different storage
6187 return (-1);
6190 /***************************************************************************
6191 Map a parameter's string representation to the index of the canonical
6192 form of the parameter (it might be a synonym).
6193 Returns -1 if the parameter string is not recognised.
6194 ***************************************************************************/
6196 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6198 int parm_num, canon_num;
6199 bool loc_inverse = false;
6201 parm_num = map_parameter(pszParmName);
6202 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6203 /* invalid, parametric or no canidate for synonyms ... */
6204 goto done;
6207 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6208 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6209 parm_num = canon_num;
6210 goto done;
6214 done:
6215 if (inverse != NULL) {
6216 *inverse = loc_inverse;
6218 return parm_num;
6221 /***************************************************************************
6222 return true if parameter number parm1 is a synonym of parameter
6223 number parm2 (parm2 being the principal name).
6224 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6225 false otherwise.
6226 ***************************************************************************/
6228 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6230 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
6231 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
6232 (parm_table[parm1].flags & FLAG_HIDE) &&
6233 !(parm_table[parm2].flags & FLAG_HIDE))
6235 if (inverse != NULL) {
6236 if ((parm_table[parm1].type == P_BOOLREV) &&
6237 (parm_table[parm2].type == P_BOOL))
6239 *inverse = true;
6240 } else {
6241 *inverse = false;
6244 return true;
6246 return false;
6249 /***************************************************************************
6250 Show one parameter's name, type, [values,] and flags.
6251 (helper functions for show_parameter_list)
6252 ***************************************************************************/
6254 static void show_parameter(int parmIndex)
6256 int enumIndex, flagIndex;
6257 int parmIndex2;
6258 bool hadFlag;
6259 bool hadSyn;
6260 bool inverse;
6261 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6262 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6263 "P_ENUM", "P_SEP"};
6264 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6265 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6266 FLAG_HIDE};
6267 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6268 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6269 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
6271 printf("%s=%s", parm_table[parmIndex].label,
6272 type[parm_table[parmIndex].type]);
6273 if (parm_table[parmIndex].type == P_ENUM) {
6274 printf(",");
6275 for (enumIndex=0;
6276 parm_table[parmIndex].enum_list[enumIndex].name;
6277 enumIndex++)
6279 printf("%s%s",
6280 enumIndex ? "|" : "",
6281 parm_table[parmIndex].enum_list[enumIndex].name);
6284 printf(",");
6285 hadFlag = false;
6286 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6287 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6288 printf("%s%s",
6289 hadFlag ? "|" : "",
6290 flag_names[flagIndex]);
6291 hadFlag = true;
6295 /* output synonyms */
6296 hadSyn = false;
6297 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6298 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6299 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6300 parm_table[parmIndex2].label);
6301 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6302 if (!hadSyn) {
6303 printf(" (synonyms: ");
6304 hadSyn = true;
6305 } else {
6306 printf(", ");
6308 printf("%s%s", parm_table[parmIndex2].label,
6309 inverse ? "[i]" : "");
6312 if (hadSyn) {
6313 printf(")");
6316 printf("\n");
6319 /***************************************************************************
6320 Show all parameter's name, type, [values,] and flags.
6321 ***************************************************************************/
6323 void show_parameter_list(void)
6325 int classIndex, parmIndex;
6326 const char *section_names[] = { "local", "global", NULL};
6328 for (classIndex=0; section_names[classIndex]; classIndex++) {
6329 printf("[%s]\n", section_names[classIndex]);
6330 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6331 if (parm_table[parmIndex].p_class == classIndex) {
6332 show_parameter(parmIndex);
6338 /***************************************************************************
6339 Check if a given string correctly represents a boolean value.
6340 ***************************************************************************/
6342 bool lp_string_is_valid_boolean(const char *parm_value)
6344 return set_boolean(parm_value, NULL);
6347 /***************************************************************************
6348 Get the standard string representation of a boolean value ("yes" or "no")
6349 ***************************************************************************/
6351 static const char *get_boolean(bool bool_value)
6353 static const char *yes_str = "yes";
6354 static const char *no_str = "no";
6356 return (bool_value ? yes_str : no_str);
6359 /***************************************************************************
6360 Provide the string of the negated boolean value associated to the boolean
6361 given as a string. Returns false if the passed string does not correctly
6362 represent a boolean.
6363 ***************************************************************************/
6365 bool lp_invert_boolean(const char *str, const char **inverse_str)
6367 bool val;
6369 if (!set_boolean(str, &val)) {
6370 return false;
6373 *inverse_str = get_boolean(!val);
6374 return true;
6377 /***************************************************************************
6378 Provide the canonical string representation of a boolean value given
6379 as a string. Return true on success, false if the string given does
6380 not correctly represent a boolean.
6381 ***************************************************************************/
6383 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6385 bool val;
6387 if (!set_boolean(str, &val)) {
6388 return false;
6391 *canon_str = get_boolean(val);
6392 return true;
6395 /***************************************************************************
6396 Find a service by name. Otherwise works like get_service.
6397 ***************************************************************************/
6399 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6401 int iService = -1;
6402 char *canon_name;
6403 TDB_DATA data;
6404 NTSTATUS status;
6406 if (ServiceHash == NULL) {
6407 return -1;
6410 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6412 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
6413 &data);
6415 if (NT_STATUS_IS_OK(status) &&
6416 (data.dptr != NULL) &&
6417 (data.dsize == sizeof(iService)))
6419 iService = *(int *)data.dptr;
6422 TALLOC_FREE(canon_name);
6424 if ((iService != -1) && (LP_SNUM_OK(iService))
6425 && (pserviceDest != NULL)) {
6426 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6429 return (iService);
6432 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6433 struct loadparm_service *lp_service(const char *pszServiceName)
6435 int iService = getservicebyname(pszServiceName, NULL);
6436 if (iService == -1 || !LP_SNUM_OK(iService)) {
6437 return NULL;
6439 return ServicePtrs[iService];
6442 struct loadparm_service *lp_servicebynum(int snum)
6444 if ((snum == -1) || !LP_SNUM_OK(snum)) {
6445 return NULL;
6447 return ServicePtrs[snum];
6450 struct loadparm_service *lp_default_loadparm_service()
6452 return &sDefault;
6456 /***************************************************************************
6457 Copy a service structure to another.
6458 If pcopymapDest is NULL then copy all fields
6459 ***************************************************************************/
6462 * Add a parametric option to a parmlist_entry,
6463 * replacing old value, if already present.
6465 static void set_param_opt(struct parmlist_entry **opt_list,
6466 const char *opt_name,
6467 const char *opt_value,
6468 unsigned priority)
6470 struct parmlist_entry *new_opt, *opt;
6471 bool not_added;
6473 if (opt_list == NULL) {
6474 return;
6477 opt = *opt_list;
6478 not_added = true;
6480 /* Traverse destination */
6481 while (opt) {
6482 /* If we already have same option, override it */
6483 if (strwicmp(opt->key, opt_name) == 0) {
6484 if ((opt->priority & FLAG_CMDLINE) &&
6485 !(priority & FLAG_CMDLINE)) {
6486 /* it's been marked as not to be
6487 overridden */
6488 return;
6490 string_free(&opt->value);
6491 TALLOC_FREE(opt->list);
6492 opt->value = SMB_STRDUP(opt_value);
6493 opt->priority = priority;
6494 not_added = false;
6495 break;
6497 opt = opt->next;
6499 if (not_added) {
6500 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
6501 new_opt->key = SMB_STRDUP(opt_name);
6502 new_opt->value = SMB_STRDUP(opt_value);
6503 new_opt->list = NULL;
6504 new_opt->priority = priority;
6505 DLIST_ADD(*opt_list, new_opt);
6509 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6510 struct bitmap *pcopymapDest)
6512 int i;
6513 bool bcopyall = (pcopymapDest == NULL);
6514 struct parmlist_entry *data;
6516 for (i = 0; parm_table[i].label; i++)
6517 if (parm_table[i].p_class == P_LOCAL &&
6518 (bcopyall || bitmap_query(pcopymapDest,i))) {
6519 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6520 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6522 switch (parm_table[i].type) {
6523 case P_BOOL:
6524 case P_BOOLREV:
6525 *(bool *)dest_ptr = *(bool *)src_ptr;
6526 break;
6528 case P_INTEGER:
6529 case P_ENUM:
6530 case P_OCTAL:
6531 *(int *)dest_ptr = *(int *)src_ptr;
6532 break;
6534 case P_CHAR:
6535 *(char *)dest_ptr = *(char *)src_ptr;
6536 break;
6538 case P_STRING:
6539 string_set((char **)dest_ptr,
6540 *(char **)src_ptr);
6541 break;
6543 case P_USTRING:
6545 char *upper_string = strupper_talloc(talloc_tos(),
6546 *(char **)src_ptr);
6547 string_set((char **)dest_ptr,
6548 upper_string);
6549 TALLOC_FREE(upper_string);
6550 break;
6552 case P_LIST:
6553 TALLOC_FREE(*((char ***)dest_ptr));
6554 *((char ***)dest_ptr) = str_list_copy(NULL,
6555 *(const char ***)src_ptr);
6556 break;
6557 default:
6558 break;
6562 if (bcopyall) {
6563 init_copymap(pserviceDest);
6564 if (pserviceSource->copymap)
6565 bitmap_copy(pserviceDest->copymap,
6566 pserviceSource->copymap);
6569 data = pserviceSource->param_opt;
6570 while (data) {
6571 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6572 data = data->next;
6576 /***************************************************************************
6577 Check a service for consistency. Return false if the service is in any way
6578 incomplete or faulty, else true.
6579 ***************************************************************************/
6581 bool service_ok(int iService)
6583 bool bRetval;
6585 bRetval = true;
6586 if (ServicePtrs[iService]->szService[0] == '\0') {
6587 DEBUG(0, ("The following message indicates an internal error:\n"));
6588 DEBUG(0, ("No service name in service entry.\n"));
6589 bRetval = false;
6592 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6593 /* I can't see why you'd want a non-printable printer service... */
6594 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6595 if (!ServicePtrs[iService]->bPrint_ok) {
6596 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6597 ServicePtrs[iService]->szService));
6598 ServicePtrs[iService]->bPrint_ok = true;
6600 /* [printers] service must also be non-browsable. */
6601 if (ServicePtrs[iService]->bBrowseable)
6602 ServicePtrs[iService]->bBrowseable = false;
6605 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6606 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6607 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6609 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6610 ServicePtrs[iService]->szService));
6611 ServicePtrs[iService]->bAvailable = false;
6614 /* If a service is flagged unavailable, log the fact at level 1. */
6615 if (!ServicePtrs[iService]->bAvailable)
6616 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6617 ServicePtrs[iService]->szService));
6619 return (bRetval);
6622 static struct smbconf_ctx *lp_smbconf_ctx(void)
6624 sbcErr err;
6625 static struct smbconf_ctx *conf_ctx = NULL;
6627 if (conf_ctx == NULL) {
6628 err = smbconf_init(NULL, &conf_ctx, "registry:");
6629 if (!SBC_ERROR_IS_OK(err)) {
6630 DEBUG(1, ("error initializing registry configuration: "
6631 "%s\n", sbcErrorString(err)));
6632 conf_ctx = NULL;
6636 return conf_ctx;
6639 static bool process_smbconf_service(struct smbconf_service *service)
6641 uint32_t count;
6642 bool ret;
6644 if (service == NULL) {
6645 return false;
6648 ret = do_section(service->name, NULL);
6649 if (ret != true) {
6650 return false;
6652 for (count = 0; count < service->num_params; count++) {
6653 ret = do_parameter(service->param_names[count],
6654 service->param_values[count],
6655 NULL);
6656 if (ret != true) {
6657 return false;
6660 if (iServiceIndex >= 0) {
6661 return service_ok(iServiceIndex);
6663 return true;
6667 * load a service from registry and activate it
6669 bool process_registry_service(const char *service_name)
6671 sbcErr err;
6672 struct smbconf_service *service = NULL;
6673 TALLOC_CTX *mem_ctx = talloc_stackframe();
6674 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6675 bool ret = false;
6677 if (conf_ctx == NULL) {
6678 goto done;
6681 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6683 if (!smbconf_share_exists(conf_ctx, service_name)) {
6685 * Registry does not contain data for this service (yet),
6686 * but make sure lp_load doesn't return false.
6688 ret = true;
6689 goto done;
6692 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6693 if (!SBC_ERROR_IS_OK(err)) {
6694 goto done;
6697 ret = process_smbconf_service(service);
6698 if (!ret) {
6699 goto done;
6702 /* store the csn */
6703 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6705 done:
6706 TALLOC_FREE(mem_ctx);
6707 return ret;
6711 * process_registry_globals
6713 static bool process_registry_globals(void)
6715 bool ret;
6717 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6719 ret = do_parameter("registry shares", "yes", NULL);
6720 if (!ret) {
6721 return ret;
6724 return process_registry_service(GLOBAL_NAME);
6727 bool process_registry_shares(void)
6729 sbcErr err;
6730 uint32_t count;
6731 struct smbconf_service **service = NULL;
6732 uint32_t num_shares = 0;
6733 TALLOC_CTX *mem_ctx = talloc_stackframe();
6734 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6735 bool ret = false;
6737 if (conf_ctx == NULL) {
6738 goto done;
6741 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6742 if (!SBC_ERROR_IS_OK(err)) {
6743 goto done;
6746 ret = true;
6748 for (count = 0; count < num_shares; count++) {
6749 if (strequal(service[count]->name, GLOBAL_NAME)) {
6750 continue;
6752 ret = process_smbconf_service(service[count]);
6753 if (!ret) {
6754 goto done;
6758 /* store the csn */
6759 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6761 done:
6762 TALLOC_FREE(mem_ctx);
6763 return ret;
6767 * reload those shares from registry that are already
6768 * activated in the services array.
6770 static bool reload_registry_shares(void)
6772 int i;
6773 bool ret = true;
6775 for (i = 0; i < iNumServices; i++) {
6776 if (!VALID(i)) {
6777 continue;
6780 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
6781 continue;
6784 ret = process_registry_service(ServicePtrs[i]->szService);
6785 if (!ret) {
6786 goto done;
6790 done:
6791 return ret;
6795 #define MAX_INCLUDE_DEPTH 100
6797 static uint8_t include_depth;
6799 static struct file_lists {
6800 struct file_lists *next;
6801 char *name;
6802 char *subfname;
6803 time_t modtime;
6804 } *file_lists = NULL;
6806 /*******************************************************************
6807 Keep a linked list of all config files so we know when one has changed
6808 it's date and needs to be reloaded.
6809 ********************************************************************/
6811 static void add_to_file_list(const char *fname, const char *subfname)
6813 struct file_lists *f = file_lists;
6815 while (f) {
6816 if (f->name && !strcmp(f->name, fname))
6817 break;
6818 f = f->next;
6821 if (!f) {
6822 f = SMB_MALLOC_P(struct file_lists);
6823 if (!f)
6824 return;
6825 f->next = file_lists;
6826 f->name = SMB_STRDUP(fname);
6827 if (!f->name) {
6828 SAFE_FREE(f);
6829 return;
6831 f->subfname = SMB_STRDUP(subfname);
6832 if (!f->subfname) {
6833 SAFE_FREE(f->name);
6834 SAFE_FREE(f);
6835 return;
6837 file_lists = f;
6838 f->modtime = file_modtime(subfname);
6839 } else {
6840 time_t t = file_modtime(subfname);
6841 if (t)
6842 f->modtime = t;
6844 return;
6848 * Free the file lists
6850 static void free_file_list(void)
6852 struct file_lists *f;
6853 struct file_lists *next;
6855 f = file_lists;
6856 while( f ) {
6857 next = f->next;
6858 SAFE_FREE( f->name );
6859 SAFE_FREE( f->subfname );
6860 SAFE_FREE( f );
6861 f = next;
6863 file_lists = NULL;
6868 * Utility function for outsiders to check if we're running on registry.
6870 bool lp_config_backend_is_registry(void)
6872 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6876 * Utility function to check if the config backend is FILE.
6878 bool lp_config_backend_is_file(void)
6880 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6883 /*******************************************************************
6884 Check if a config file has changed date.
6885 ********************************************************************/
6887 bool lp_file_list_changed(void)
6889 struct file_lists *f = file_lists;
6891 DEBUG(6, ("lp_file_list_changed()\n"));
6893 while (f) {
6894 time_t mod_time;
6896 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6897 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6899 if (conf_ctx == NULL) {
6900 return false;
6902 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6903 NULL))
6905 DEBUGADD(6, ("registry config changed\n"));
6906 return true;
6908 } else {
6909 char *n2 = NULL;
6910 n2 = talloc_sub_basic(talloc_tos(),
6911 get_current_username(),
6912 current_user_info.domain,
6913 f->name);
6914 if (!n2) {
6915 return false;
6917 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6918 f->name, n2, ctime(&f->modtime)));
6920 mod_time = file_modtime(n2);
6922 if (mod_time &&
6923 ((f->modtime != mod_time) ||
6924 (f->subfname == NULL) ||
6925 (strcmp(n2, f->subfname) != 0)))
6927 DEBUGADD(6,
6928 ("file %s modified: %s\n", n2,
6929 ctime(&mod_time)));
6930 f->modtime = mod_time;
6931 SAFE_FREE(f->subfname);
6932 f->subfname = SMB_STRDUP(n2);
6933 TALLOC_FREE(n2);
6934 return true;
6936 TALLOC_FREE(n2);
6938 f = f->next;
6940 return false;
6945 * Initialize iconv conversion descriptors.
6947 * This is called the first time it is needed, and also called again
6948 * every time the configuration is reloaded, because the charset or
6949 * codepage might have changed.
6951 static void init_iconv(void)
6953 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
6954 lp_unix_charset(),
6955 true, global_iconv_handle);
6958 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6960 if (strcmp(*ptr, pszParmValue) != 0) {
6961 string_set(ptr, pszParmValue);
6962 init_iconv();
6964 return true;
6967 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6969 bool is_utf8 = false;
6970 size_t len = strlen(pszParmValue);
6972 if (len == 4 || len == 5) {
6973 /* Don't use StrCaseCmp here as we don't want to
6974 initialize iconv. */
6975 if ((toupper_m(pszParmValue[0]) == 'U') &&
6976 (toupper_m(pszParmValue[1]) == 'T') &&
6977 (toupper_m(pszParmValue[2]) == 'F')) {
6978 if (len == 4) {
6979 if (pszParmValue[3] == '8') {
6980 is_utf8 = true;
6982 } else {
6983 if (pszParmValue[3] == '-' &&
6984 pszParmValue[4] == '8') {
6985 is_utf8 = true;
6991 if (strcmp(*ptr, pszParmValue) != 0) {
6992 if (is_utf8) {
6993 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6994 "be UTF8, using (default value) %s instead.\n",
6995 DEFAULT_DOS_CHARSET));
6996 pszParmValue = DEFAULT_DOS_CHARSET;
6998 string_set(ptr, pszParmValue);
6999 init_iconv();
7001 return true;
7004 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7006 bool ret = true;
7007 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
7008 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
7010 ret &= string_set(&Globals.szRealm, pszParmValue);
7011 ret &= string_set(&Globals.szRealmUpper, realm);
7012 ret &= string_set(&Globals.szDnsDomain, dnsdomain);
7013 TALLOC_FREE(realm);
7014 TALLOC_FREE(dnsdomain);
7016 return ret;
7019 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7021 TALLOC_FREE(Globals.szNetbiosAliases);
7022 Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
7023 return set_netbios_aliases(Globals.szNetbiosAliases);
7026 /***************************************************************************
7027 Handle the include operation.
7028 ***************************************************************************/
7029 static bool bAllowIncludeRegistry = true;
7031 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7033 char *fname;
7035 if (include_depth >= MAX_INCLUDE_DEPTH) {
7036 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7037 include_depth));
7038 return false;
7041 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7042 if (!bAllowIncludeRegistry) {
7043 return true;
7045 if (bInGlobalSection) {
7046 bool ret;
7047 include_depth++;
7048 ret = process_registry_globals();
7049 include_depth--;
7050 return ret;
7051 } else {
7052 DEBUG(1, ("\"include = registry\" only effective "
7053 "in %s section\n", GLOBAL_NAME));
7054 return false;
7058 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7059 current_user_info.domain,
7060 pszParmValue);
7062 add_to_file_list(pszParmValue, fname);
7064 string_set(ptr, fname);
7066 if (file_exist(fname)) {
7067 bool ret;
7068 include_depth++;
7069 ret = pm_process(fname, do_section, do_parameter, NULL);
7070 include_depth--;
7071 TALLOC_FREE(fname);
7072 return ret;
7075 DEBUG(2, ("Can't find include file %s\n", fname));
7076 TALLOC_FREE(fname);
7077 return true;
7080 /***************************************************************************
7081 Handle the interpretation of the copy parameter.
7082 ***************************************************************************/
7084 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7086 bool bRetval;
7087 int iTemp;
7088 struct loadparm_service serviceTemp;
7090 string_set(ptr, pszParmValue);
7092 init_service(&serviceTemp);
7094 bRetval = false;
7096 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7098 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7099 if (iTemp == iServiceIndex) {
7100 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7101 } else {
7102 copy_service(ServicePtrs[iServiceIndex],
7103 &serviceTemp,
7104 ServicePtrs[iServiceIndex]->copymap);
7105 bRetval = true;
7107 } else {
7108 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7109 bRetval = false;
7112 free_service(&serviceTemp);
7113 return (bRetval);
7116 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7118 Globals.ldap_debug_level = lp_int(pszParmValue);
7119 init_ldap_debugging();
7120 return true;
7123 /***************************************************************************
7124 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7125 parameters is:
7127 [global]
7129 idmap uid = 1000-1999
7130 idmap gid = 700-899
7132 We only do simple parsing checks here. The strings are parsed into useful
7133 structures in the idmap daemon code.
7135 ***************************************************************************/
7137 /* Some lp_ routines to return idmap [ug]id information */
7139 static uid_t idmap_uid_low, idmap_uid_high;
7140 static gid_t idmap_gid_low, idmap_gid_high;
7142 bool lp_idmap_uid(uid_t *low, uid_t *high)
7144 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7145 return false;
7147 if (low)
7148 *low = idmap_uid_low;
7150 if (high)
7151 *high = idmap_uid_high;
7153 return true;
7156 bool lp_idmap_gid(gid_t *low, gid_t *high)
7158 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7159 return false;
7161 if (low)
7162 *low = idmap_gid_low;
7164 if (high)
7165 *high = idmap_gid_high;
7167 return true;
7170 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7172 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7174 return true;
7177 /* Do some simple checks on "idmap [ug]id" parameter values */
7179 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7181 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7183 return true;
7186 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7188 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7190 return true;
7193 /***************************************************************************
7194 Handle the DEBUG level list.
7195 ***************************************************************************/
7197 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
7199 string_set(ptr, pszParmValueIn);
7200 return debug_parse_levels(pszParmValueIn);
7203 /***************************************************************************
7204 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7205 ***************************************************************************/
7207 static const char *append_ldap_suffix( const char *str )
7209 const char *suffix_string;
7212 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7213 Globals.szLdapSuffix );
7214 if ( !suffix_string ) {
7215 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7216 return "";
7219 return suffix_string;
7222 const char *lp_ldap_machine_suffix(void)
7224 if (Globals.szLdapMachineSuffix[0])
7225 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7227 return lp_string(Globals.szLdapSuffix);
7230 const char *lp_ldap_user_suffix(void)
7232 if (Globals.szLdapUserSuffix[0])
7233 return append_ldap_suffix(Globals.szLdapUserSuffix);
7235 return lp_string(Globals.szLdapSuffix);
7238 const char *lp_ldap_group_suffix(void)
7240 if (Globals.szLdapGroupSuffix[0])
7241 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7243 return lp_string(Globals.szLdapSuffix);
7246 const char *lp_ldap_idmap_suffix(void)
7248 if (Globals.szLdapIdmapSuffix[0])
7249 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7251 return lp_string(Globals.szLdapSuffix);
7254 /****************************************************************************
7255 set the value for a P_ENUM
7256 ***************************************************************************/
7258 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7259 int *ptr )
7261 int i;
7263 for (i = 0; parm->enum_list[i].name; i++) {
7264 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7265 *ptr = parm->enum_list[i].value;
7266 return;
7269 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7270 pszParmValue, parm->label));
7273 /***************************************************************************
7274 ***************************************************************************/
7276 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7278 static int parm_num = -1;
7279 struct loadparm_service *s;
7281 if ( parm_num == -1 )
7282 parm_num = map_parameter( "printing" );
7284 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7286 if ( snum < 0 )
7287 s = &sDefault;
7288 else
7289 s = ServicePtrs[snum];
7291 init_printer_values( s );
7293 return true;
7297 /***************************************************************************
7298 Initialise a copymap.
7299 ***************************************************************************/
7301 static void init_copymap(struct loadparm_service *pservice)
7303 int i;
7305 TALLOC_FREE(pservice->copymap);
7307 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7308 if (!pservice->copymap)
7309 DEBUG(0,
7310 ("Couldn't allocate copymap!! (size %d)\n",
7311 (int)NUMPARAMETERS));
7312 else
7313 for (i = 0; i < NUMPARAMETERS; i++)
7314 bitmap_set(pservice->copymap, i);
7318 return the parameter pointer for a parameter
7320 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7322 if (service == NULL) {
7323 if (parm->p_class == P_LOCAL)
7324 return (void *)(((char *)&sDefault)+parm->offset);
7325 else if (parm->p_class == P_GLOBAL)
7326 return (void *)(((char *)&Globals)+parm->offset);
7327 else return NULL;
7328 } else {
7329 return (void *)(((char *)service) + parm->offset);
7333 /***************************************************************************
7334 Return the local pointer to a parameter given the service number and parameter
7335 ***************************************************************************/
7337 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7339 return lp_parm_ptr(ServicePtrs[snum], parm);
7342 /***************************************************************************
7343 Process a parameter for a particular service number. If snum < 0
7344 then assume we are in the globals.
7345 ***************************************************************************/
7347 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7349 int parmnum, i;
7350 void *parm_ptr = NULL; /* where we are going to store the result */
7351 struct parmlist_entry **opt_list;
7353 parmnum = map_parameter(pszParmName);
7355 if (parmnum < 0) {
7356 if (strchr(pszParmName, ':') == NULL) {
7357 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7358 pszParmName));
7359 return true;
7363 * We've got a parametric option
7366 opt_list = (snum < 0)
7367 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7368 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7370 return true;
7373 /* if it's already been set by the command line, then we don't
7374 override here */
7375 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7376 return true;
7379 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7380 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7381 pszParmName));
7384 /* we might point at a service, the default service or a global */
7385 if (snum < 0) {
7386 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7387 } else {
7388 if (parm_table[parmnum].p_class == P_GLOBAL) {
7389 DEBUG(0,
7390 ("Global parameter %s found in service section!\n",
7391 pszParmName));
7392 return true;
7394 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7397 if (snum >= 0) {
7398 if (!ServicePtrs[snum]->copymap)
7399 init_copymap(ServicePtrs[snum]);
7401 /* this handles the aliases - set the copymap for other entries with
7402 the same data pointer */
7403 for (i = 0; parm_table[i].label; i++) {
7404 if ((parm_table[i].offset == parm_table[parmnum].offset)
7405 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
7406 bitmap_clear(ServicePtrs[snum]->copymap, i);
7411 /* if it is a special case then go ahead */
7412 if (parm_table[parmnum].special) {
7413 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7414 (char **)parm_ptr);
7417 /* now switch on the type of variable it is */
7418 switch (parm_table[parmnum].type)
7420 case P_BOOL:
7421 *(bool *)parm_ptr = lp_bool(pszParmValue);
7422 break;
7424 case P_BOOLREV:
7425 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7426 break;
7428 case P_INTEGER:
7429 *(int *)parm_ptr = lp_int(pszParmValue);
7430 break;
7432 case P_CHAR:
7433 *(char *)parm_ptr = *pszParmValue;
7434 break;
7436 case P_OCTAL:
7437 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7438 if ( i != 1 ) {
7439 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7441 break;
7443 case P_BYTES:
7445 uint64_t val;
7446 if (conv_str_size_error(pszParmValue, &val)) {
7447 if (val <= INT_MAX) {
7448 *(int *)parm_ptr = (int)val;
7449 break;
7453 DEBUG(0,("lp_do_parameter(%s): value is not "
7454 "a valid size specifier!\n", pszParmValue));
7455 return false;
7458 case P_LIST:
7459 case P_CMDLIST:
7460 TALLOC_FREE(*((char ***)parm_ptr));
7461 *(char ***)parm_ptr = str_list_make_v3(
7462 NULL, pszParmValue, NULL);
7463 break;
7465 case P_STRING:
7466 string_set((char **)parm_ptr, pszParmValue);
7467 break;
7469 case P_USTRING:
7471 char *upper_string = strupper_talloc(talloc_tos(),
7472 pszParmValue);
7473 string_set((char **)parm_ptr, upper_string);
7474 TALLOC_FREE(upper_string);
7475 break;
7477 case P_ENUM:
7478 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7479 break;
7480 case P_SEP:
7481 break;
7484 return true;
7487 /***************************************************************************
7488 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7489 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7490 ***************************************************************************/
7492 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7494 int parmnum, i;
7495 parmnum = map_parameter(pszParmName);
7496 if (parmnum >= 0) {
7497 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7498 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7499 return false;
7501 parm_table[parmnum].flags |= FLAG_CMDLINE;
7503 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7504 * be grouped in the table, so we don't have to search the
7505 * whole table */
7506 for (i=parmnum-1;
7507 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7508 && parm_table[i].p_class == parm_table[parmnum].p_class;
7509 i--) {
7510 parm_table[i].flags |= FLAG_CMDLINE;
7512 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
7513 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
7514 parm_table[i].flags |= FLAG_CMDLINE;
7517 if (store_values) {
7518 store_lp_set_cmdline(pszParmName, pszParmValue);
7520 return true;
7523 /* it might be parametric */
7524 if (strchr(pszParmName, ':') != NULL) {
7525 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7526 if (store_values) {
7527 store_lp_set_cmdline(pszParmName, pszParmValue);
7529 return true;
7532 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7533 return true;
7536 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7538 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7541 /***************************************************************************
7542 Process a parameter.
7543 ***************************************************************************/
7545 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7546 void *userdata)
7548 if (!bInGlobalSection && bGlobalOnly)
7549 return true;
7551 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7553 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7554 pszParmName, pszParmValue));
7558 set a option from the commandline in 'a=b' format. Use to support --option
7560 bool lp_set_option(const char *option)
7562 char *p, *s;
7563 bool ret;
7565 s = talloc_strdup(NULL, option);
7566 if (!s) {
7567 return false;
7570 p = strchr(s, '=');
7571 if (!p) {
7572 talloc_free(s);
7573 return false;
7576 *p = 0;
7578 /* skip white spaces after the = sign */
7579 do {
7580 p++;
7581 } while (*p == ' ');
7583 ret = lp_set_cmdline(s, p);
7584 talloc_free(s);
7585 return ret;
7588 /**************************************************************************
7589 Print a parameter of the specified type.
7590 ***************************************************************************/
7592 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7594 /* For the seperation of lists values that we print below */
7595 const char *list_sep = ", ";
7596 int i;
7597 switch (p->type)
7599 case P_ENUM:
7600 for (i = 0; p->enum_list[i].name; i++) {
7601 if (*(int *)ptr == p->enum_list[i].value) {
7602 fprintf(f, "%s",
7603 p->enum_list[i].name);
7604 break;
7607 break;
7609 case P_BOOL:
7610 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7611 break;
7613 case P_BOOLREV:
7614 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7615 break;
7617 case P_INTEGER:
7618 case P_BYTES:
7619 fprintf(f, "%d", *(int *)ptr);
7620 break;
7622 case P_CHAR:
7623 fprintf(f, "%c", *(char *)ptr);
7624 break;
7626 case P_OCTAL: {
7627 int val = *(int *)ptr;
7628 if (val == -1) {
7629 fprintf(f, "-1");
7630 } else {
7631 fprintf(f, "0%o", val);
7633 break;
7636 case P_CMDLIST:
7637 list_sep = " ";
7638 /* fall through */
7639 case P_LIST:
7640 if ((char ***)ptr && *(char ***)ptr) {
7641 char **list = *(char ***)ptr;
7642 for (; *list; list++) {
7643 /* surround strings with whitespace in double quotes */
7644 if (*(list+1) == NULL) {
7645 /* last item, no extra separator */
7646 list_sep = "";
7648 if ( strchr_m( *list, ' ' ) ) {
7649 fprintf(f, "\"%s\"%s", *list, list_sep);
7650 } else {
7651 fprintf(f, "%s%s", *list, list_sep);
7655 break;
7657 case P_STRING:
7658 case P_USTRING:
7659 if (*(char **)ptr) {
7660 fprintf(f, "%s", *(char **)ptr);
7662 break;
7663 case P_SEP:
7664 break;
7668 /***************************************************************************
7669 Check if two parameters are equal.
7670 ***************************************************************************/
7672 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7674 switch (type) {
7675 case P_BOOL:
7676 case P_BOOLREV:
7677 return (*((bool *)ptr1) == *((bool *)ptr2));
7679 case P_INTEGER:
7680 case P_ENUM:
7681 case P_OCTAL:
7682 case P_BYTES:
7683 return (*((int *)ptr1) == *((int *)ptr2));
7685 case P_CHAR:
7686 return (*((char *)ptr1) == *((char *)ptr2));
7688 case P_LIST:
7689 case P_CMDLIST:
7690 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7692 case P_STRING:
7693 case P_USTRING:
7695 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7696 if (p1 && !*p1)
7697 p1 = NULL;
7698 if (p2 && !*p2)
7699 p2 = NULL;
7700 return (p1 == p2 || strequal(p1, p2));
7702 case P_SEP:
7703 break;
7705 return false;
7708 /***************************************************************************
7709 Initialize any local varients in the sDefault table.
7710 ***************************************************************************/
7712 void init_locals(void)
7714 /* None as yet. */
7717 /***************************************************************************
7718 Process a new section (service). At this stage all sections are services.
7719 Later we'll have special sections that permit server parameters to be set.
7720 Returns true on success, false on failure.
7721 ***************************************************************************/
7723 static bool do_section(const char *pszSectionName, void *userdata)
7725 bool bRetval;
7726 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7727 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7728 bRetval = false;
7730 /* if we were in a global section then do the local inits */
7731 if (bInGlobalSection && !isglobal)
7732 init_locals();
7734 /* if we've just struck a global section, note the fact. */
7735 bInGlobalSection = isglobal;
7737 /* check for multiple global sections */
7738 if (bInGlobalSection) {
7739 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7740 return true;
7743 if (!bInGlobalSection && bGlobalOnly)
7744 return true;
7746 /* if we have a current service, tidy it up before moving on */
7747 bRetval = true;
7749 if (iServiceIndex >= 0)
7750 bRetval = service_ok(iServiceIndex);
7752 /* if all is still well, move to the next record in the services array */
7753 if (bRetval) {
7754 /* We put this here to avoid an odd message order if messages are */
7755 /* issued by the post-processing of a previous section. */
7756 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7758 iServiceIndex = add_a_service(&sDefault, pszSectionName);
7759 if (iServiceIndex < 0) {
7760 DEBUG(0, ("Failed to add a new service\n"));
7761 return false;
7763 /* Clean all parametric options for service */
7764 /* They will be added during parsing again */
7765 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7768 return bRetval;
7772 /***************************************************************************
7773 Determine if a partcular base parameter is currentl set to the default value.
7774 ***************************************************************************/
7776 static bool is_default(int i)
7778 if (!defaults_saved)
7779 return false;
7780 switch (parm_table[i].type) {
7781 case P_LIST:
7782 case P_CMDLIST:
7783 return str_list_equal((const char **)parm_table[i].def.lvalue,
7784 *(const char ***)lp_parm_ptr(NULL,
7785 &parm_table[i]));
7786 case P_STRING:
7787 case P_USTRING:
7788 return strequal(parm_table[i].def.svalue,
7789 *(char **)lp_parm_ptr(NULL,
7790 &parm_table[i]));
7791 case P_BOOL:
7792 case P_BOOLREV:
7793 return parm_table[i].def.bvalue ==
7794 *(bool *)lp_parm_ptr(NULL,
7795 &parm_table[i]);
7796 case P_CHAR:
7797 return parm_table[i].def.cvalue ==
7798 *(char *)lp_parm_ptr(NULL,
7799 &parm_table[i]);
7800 case P_INTEGER:
7801 case P_OCTAL:
7802 case P_ENUM:
7803 case P_BYTES:
7804 return parm_table[i].def.ivalue ==
7805 *(int *)lp_parm_ptr(NULL,
7806 &parm_table[i]);
7807 case P_SEP:
7808 break;
7810 return false;
7813 /***************************************************************************
7814 Display the contents of the global structure.
7815 ***************************************************************************/
7817 static void dump_globals(FILE *f)
7819 int i;
7820 struct parmlist_entry *data;
7822 fprintf(f, "[global]\n");
7824 for (i = 0; parm_table[i].label; i++)
7825 if (parm_table[i].p_class == P_GLOBAL &&
7826 !(parm_table[i].flags & FLAG_META) &&
7827 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
7828 if (defaults_saved && is_default(i))
7829 continue;
7830 fprintf(f, "\t%s = ", parm_table[i].label);
7831 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7832 &parm_table[i]),
7834 fprintf(f, "\n");
7836 if (Globals.param_opt != NULL) {
7837 data = Globals.param_opt;
7838 while(data) {
7839 fprintf(f, "\t%s = %s\n", data->key, data->value);
7840 data = data->next;
7846 /***************************************************************************
7847 Return true if a local parameter is currently set to the global default.
7848 ***************************************************************************/
7850 bool lp_is_default(int snum, struct parm_struct *parm)
7852 return equal_parameter(parm->type,
7853 lp_parm_ptr(ServicePtrs[snum], parm),
7854 lp_parm_ptr(NULL, parm));
7857 /***************************************************************************
7858 Display the contents of a single services record.
7859 ***************************************************************************/
7861 static void dump_a_service(struct loadparm_service *pService, FILE * f)
7863 int i;
7864 struct parmlist_entry *data;
7866 if (pService != &sDefault)
7867 fprintf(f, "[%s]\n", pService->szService);
7869 for (i = 0; parm_table[i].label; i++) {
7871 if (parm_table[i].p_class == P_LOCAL &&
7872 !(parm_table[i].flags & FLAG_META) &&
7873 (*parm_table[i].label != '-') &&
7874 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7876 if (pService == &sDefault) {
7877 if (defaults_saved && is_default(i))
7878 continue;
7879 } else {
7880 if (equal_parameter(parm_table[i].type,
7881 lp_parm_ptr(pService, &parm_table[i]),
7882 lp_parm_ptr(NULL, &parm_table[i])))
7883 continue;
7886 fprintf(f, "\t%s = ", parm_table[i].label);
7887 print_parameter(&parm_table[i],
7888 lp_parm_ptr(pService, &parm_table[i]),
7890 fprintf(f, "\n");
7894 if (pService->param_opt != NULL) {
7895 data = pService->param_opt;
7896 while(data) {
7897 fprintf(f, "\t%s = %s\n", data->key, data->value);
7898 data = data->next;
7903 /***************************************************************************
7904 Display the contents of a parameter of a single services record.
7905 ***************************************************************************/
7907 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7909 int i;
7910 bool result = false;
7911 parm_class p_class;
7912 unsigned flag = 0;
7913 fstring local_parm_name;
7914 char *parm_opt;
7915 const char *parm_opt_value;
7917 /* check for parametrical option */
7918 fstrcpy( local_parm_name, parm_name);
7919 parm_opt = strchr( local_parm_name, ':');
7921 if (parm_opt) {
7922 *parm_opt = '\0';
7923 parm_opt++;
7924 if (strlen(parm_opt)) {
7925 parm_opt_value = lp_parm_const_string( snum,
7926 local_parm_name, parm_opt, NULL);
7927 if (parm_opt_value) {
7928 printf( "%s\n", parm_opt_value);
7929 result = true;
7932 return result;
7935 /* check for a key and print the value */
7936 if (isGlobal) {
7937 p_class = P_GLOBAL;
7938 flag = FLAG_GLOBAL;
7939 } else
7940 p_class = P_LOCAL;
7942 for (i = 0; parm_table[i].label; i++) {
7943 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7944 !(parm_table[i].flags & FLAG_META) &&
7945 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7946 (*parm_table[i].label != '-') &&
7947 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7949 void *ptr;
7951 if (isGlobal) {
7952 ptr = lp_parm_ptr(NULL,
7953 &parm_table[i]);
7954 } else {
7955 ptr = lp_parm_ptr(ServicePtrs[snum],
7956 &parm_table[i]);
7959 print_parameter(&parm_table[i],
7960 ptr, f);
7961 fprintf(f, "\n");
7962 result = true;
7963 break;
7967 return result;
7970 /***************************************************************************
7971 Return info about the requested parameter (given as a string).
7972 Return NULL when the string is not a valid parameter name.
7973 ***************************************************************************/
7975 struct parm_struct *lp_get_parameter(const char *param_name)
7977 int num = map_parameter(param_name);
7979 if (num < 0) {
7980 return NULL;
7983 return &parm_table[num];
7986 /***************************************************************************
7987 Return info about the next parameter in a service.
7988 snum==GLOBAL_SECTION_SNUM gives the globals.
7989 Return NULL when out of parameters.
7990 ***************************************************************************/
7992 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7994 if (snum < 0) {
7995 /* do the globals */
7996 for (; parm_table[*i].label; (*i)++) {
7997 if (parm_table[*i].p_class == P_SEPARATOR)
7998 return &parm_table[(*i)++];
8000 if ((*parm_table[*i].label == '-'))
8001 continue;
8003 if ((*i) > 0
8004 && (parm_table[*i].offset ==
8005 parm_table[(*i) - 1].offset)
8006 && (parm_table[*i].p_class ==
8007 parm_table[(*i) - 1].p_class))
8008 continue;
8010 if (is_default(*i) && !allparameters)
8011 continue;
8013 return &parm_table[(*i)++];
8015 } else {
8016 struct loadparm_service *pService = ServicePtrs[snum];
8018 for (; parm_table[*i].label; (*i)++) {
8019 if (parm_table[*i].p_class == P_SEPARATOR)
8020 return &parm_table[(*i)++];
8022 if (parm_table[*i].p_class == P_LOCAL &&
8023 (*parm_table[*i].label != '-') &&
8024 ((*i) == 0 ||
8025 (parm_table[*i].offset !=
8026 parm_table[(*i) - 1].offset)))
8028 if (allparameters ||
8029 !equal_parameter(parm_table[*i].type,
8030 lp_parm_ptr(pService,
8031 &parm_table[*i]),
8032 lp_parm_ptr(NULL,
8033 &parm_table[*i])))
8035 return &parm_table[(*i)++];
8041 return NULL;
8045 #if 0
8046 /***************************************************************************
8047 Display the contents of a single copy structure.
8048 ***************************************************************************/
8049 static void dump_copy_map(bool *pcopymap)
8051 int i;
8052 if (!pcopymap)
8053 return;
8055 printf("\n\tNon-Copied parameters:\n");
8057 for (i = 0; parm_table[i].label; i++)
8058 if (parm_table[i].p_class == P_LOCAL &&
8059 parm_table[i].ptr && !pcopymap[i] &&
8060 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8062 printf("\t\t%s\n", parm_table[i].label);
8065 #endif
8067 /***************************************************************************
8068 Return TRUE if the passed service number is within range.
8069 ***************************************************************************/
8071 bool lp_snum_ok(int iService)
8073 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8076 /***************************************************************************
8077 Auto-load some home services.
8078 ***************************************************************************/
8080 static void lp_add_auto_services(char *str)
8082 char *s;
8083 char *p;
8084 int homes;
8085 char *saveptr;
8087 if (!str)
8088 return;
8090 s = SMB_STRDUP(str);
8091 if (!s)
8092 return;
8094 homes = lp_servicenumber(HOMES_NAME);
8096 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8097 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8098 char *home;
8100 if (lp_servicenumber(p) >= 0)
8101 continue;
8103 home = get_user_home_dir(talloc_tos(), p);
8105 if (home && home[0] && homes >= 0)
8106 lp_add_home(p, homes, p, home);
8108 TALLOC_FREE(home);
8110 SAFE_FREE(s);
8113 /***************************************************************************
8114 Auto-load one printer.
8115 ***************************************************************************/
8117 void lp_add_one_printer(const char *name, const char *comment,
8118 const char *location, void *pdata)
8120 int printers = lp_servicenumber(PRINTERS_NAME);
8121 int i;
8123 if (lp_servicenumber(name) < 0) {
8124 lp_add_printer(name, printers);
8125 if ((i = lp_servicenumber(name)) >= 0) {
8126 string_set(&ServicePtrs[i]->comment, comment);
8127 ServicePtrs[i]->autoloaded = true;
8132 /***************************************************************************
8133 Have we loaded a services file yet?
8134 ***************************************************************************/
8136 bool lp_loaded(void)
8138 return (bLoaded);
8141 /***************************************************************************
8142 Unload unused services.
8143 ***************************************************************************/
8145 void lp_killunused(struct smbd_server_connection *sconn,
8146 bool (*snumused) (struct smbd_server_connection *, int))
8148 int i;
8149 for (i = 0; i < iNumServices; i++) {
8150 if (!VALID(i))
8151 continue;
8153 /* don't kill autoloaded or usershare services */
8154 if ( ServicePtrs[i]->autoloaded ||
8155 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8156 continue;
8159 if (!snumused || !snumused(sconn, i)) {
8160 free_service_byindex(i);
8166 * Kill all except autoloaded and usershare services - convenience wrapper
8168 void lp_kill_all_services(void)
8170 lp_killunused(NULL, NULL);
8173 /***************************************************************************
8174 Unload a service.
8175 ***************************************************************************/
8177 void lp_killservice(int iServiceIn)
8179 if (VALID(iServiceIn)) {
8180 free_service_byindex(iServiceIn);
8184 /***************************************************************************
8185 Save the curent values of all global and sDefault parameters into the
8186 defaults union. This allows swat and testparm to show only the
8187 changed (ie. non-default) parameters.
8188 ***************************************************************************/
8190 static void lp_save_defaults(void)
8192 int i;
8193 for (i = 0; parm_table[i].label; i++) {
8194 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
8195 && parm_table[i].p_class == parm_table[i - 1].p_class)
8196 continue;
8197 switch (parm_table[i].type) {
8198 case P_LIST:
8199 case P_CMDLIST:
8200 parm_table[i].def.lvalue = str_list_copy(
8201 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8202 break;
8203 case P_STRING:
8204 case P_USTRING:
8205 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8206 break;
8207 case P_BOOL:
8208 case P_BOOLREV:
8209 parm_table[i].def.bvalue =
8210 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8211 break;
8212 case P_CHAR:
8213 parm_table[i].def.cvalue =
8214 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8215 break;
8216 case P_INTEGER:
8217 case P_OCTAL:
8218 case P_ENUM:
8219 case P_BYTES:
8220 parm_table[i].def.ivalue =
8221 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8222 break;
8223 case P_SEP:
8224 break;
8227 defaults_saved = true;
8230 /***********************************************************
8231 If we should send plaintext/LANMAN passwords in the clinet
8232 ************************************************************/
8234 static void set_allowed_client_auth(void)
8236 if (Globals.bClientNTLMv2Auth) {
8237 Globals.bClientLanManAuth = false;
8239 if (!Globals.bClientLanManAuth) {
8240 Globals.bClientPlaintextAuth = false;
8244 /***************************************************************************
8245 JRA.
8246 The following code allows smbd to read a user defined share file.
8247 Yes, this is my intent. Yes, I'm comfortable with that...
8249 THE FOLLOWING IS SECURITY CRITICAL CODE.
8251 It washes your clothes, it cleans your house, it guards you while you sleep...
8252 Do not f%^k with it....
8253 ***************************************************************************/
8255 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8257 /***************************************************************************
8258 Check allowed stat state of a usershare file.
8259 Ensure we print out who is dicking with us so the admin can
8260 get their sorry ass fired.
8261 ***************************************************************************/
8263 static bool check_usershare_stat(const char *fname,
8264 const SMB_STRUCT_STAT *psbuf)
8266 if (!S_ISREG(psbuf->st_ex_mode)) {
8267 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8268 "not a regular file\n",
8269 fname, (unsigned int)psbuf->st_ex_uid ));
8270 return false;
8273 /* Ensure this doesn't have the other write bit set. */
8274 if (psbuf->st_ex_mode & S_IWOTH) {
8275 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8276 "public write. Refusing to allow as a usershare file.\n",
8277 fname, (unsigned int)psbuf->st_ex_uid ));
8278 return false;
8281 /* Should be 10k or less. */
8282 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8283 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8284 "too large (%u) to be a user share file.\n",
8285 fname, (unsigned int)psbuf->st_ex_uid,
8286 (unsigned int)psbuf->st_ex_size ));
8287 return false;
8290 return true;
8293 /***************************************************************************
8294 Parse the contents of a usershare file.
8295 ***************************************************************************/
8297 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8298 SMB_STRUCT_STAT *psbuf,
8299 const char *servicename,
8300 int snum,
8301 char **lines,
8302 int numlines,
8303 char **pp_sharepath,
8304 char **pp_comment,
8305 char **pp_cp_servicename,
8306 struct security_descriptor **ppsd,
8307 bool *pallow_guest)
8309 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8310 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8311 int us_vers;
8312 SMB_STRUCT_DIR *dp;
8313 SMB_STRUCT_STAT sbuf;
8314 char *sharepath = NULL;
8315 char *comment = NULL;
8317 *pp_sharepath = NULL;
8318 *pp_comment = NULL;
8320 *pallow_guest = false;
8322 if (numlines < 4) {
8323 return USERSHARE_MALFORMED_FILE;
8326 if (strcmp(lines[0], "#VERSION 1") == 0) {
8327 us_vers = 1;
8328 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8329 us_vers = 2;
8330 if (numlines < 5) {
8331 return USERSHARE_MALFORMED_FILE;
8333 } else {
8334 return USERSHARE_BAD_VERSION;
8337 if (strncmp(lines[1], "path=", 5) != 0) {
8338 return USERSHARE_MALFORMED_PATH;
8341 sharepath = talloc_strdup(ctx, &lines[1][5]);
8342 if (!sharepath) {
8343 return USERSHARE_POSIX_ERR;
8345 trim_string(sharepath, " ", " ");
8347 if (strncmp(lines[2], "comment=", 8) != 0) {
8348 return USERSHARE_MALFORMED_COMMENT_DEF;
8351 comment = talloc_strdup(ctx, &lines[2][8]);
8352 if (!comment) {
8353 return USERSHARE_POSIX_ERR;
8355 trim_string(comment, " ", " ");
8356 trim_char(comment, '"', '"');
8358 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8359 return USERSHARE_MALFORMED_ACL_DEF;
8362 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8363 return USERSHARE_ACL_ERR;
8366 if (us_vers == 2) {
8367 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8368 return USERSHARE_MALFORMED_ACL_DEF;
8370 if (lines[4][9] == 'y') {
8371 *pallow_guest = true;
8374 /* Backwards compatible extension to file version #2. */
8375 if (numlines > 5) {
8376 if (strncmp(lines[5], "sharename=", 10) != 0) {
8377 return USERSHARE_MALFORMED_SHARENAME_DEF;
8379 if (!strequal(&lines[5][10], servicename)) {
8380 return USERSHARE_BAD_SHARENAME;
8382 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8383 if (!*pp_cp_servicename) {
8384 return USERSHARE_POSIX_ERR;
8389 if (*pp_cp_servicename == NULL) {
8390 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8391 if (!*pp_cp_servicename) {
8392 return USERSHARE_POSIX_ERR;
8396 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8397 /* Path didn't change, no checks needed. */
8398 *pp_sharepath = sharepath;
8399 *pp_comment = comment;
8400 return USERSHARE_OK;
8403 /* The path *must* be absolute. */
8404 if (sharepath[0] != '/') {
8405 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8406 servicename, sharepath));
8407 return USERSHARE_PATH_NOT_ABSOLUTE;
8410 /* If there is a usershare prefix deny list ensure one of these paths
8411 doesn't match the start of the user given path. */
8412 if (prefixdenylist) {
8413 int i;
8414 for ( i=0; prefixdenylist[i]; i++ ) {
8415 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8416 servicename, i, prefixdenylist[i], sharepath ));
8417 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8418 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8419 "usershare prefix deny list entries.\n",
8420 servicename, sharepath));
8421 return USERSHARE_PATH_IS_DENIED;
8426 /* If there is a usershare prefix allow list ensure one of these paths
8427 does match the start of the user given path. */
8429 if (prefixallowlist) {
8430 int i;
8431 for ( i=0; prefixallowlist[i]; i++ ) {
8432 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8433 servicename, i, prefixallowlist[i], sharepath ));
8434 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8435 break;
8438 if (prefixallowlist[i] == NULL) {
8439 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8440 "usershare prefix allow list entries.\n",
8441 servicename, sharepath));
8442 return USERSHARE_PATH_NOT_ALLOWED;
8446 /* Ensure this is pointing to a directory. */
8447 dp = sys_opendir(sharepath);
8449 if (!dp) {
8450 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8451 servicename, sharepath));
8452 return USERSHARE_PATH_NOT_DIRECTORY;
8455 /* Ensure the owner of the usershare file has permission to share
8456 this directory. */
8458 if (sys_stat(sharepath, &sbuf, false) == -1) {
8459 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8460 servicename, sharepath, strerror(errno) ));
8461 sys_closedir(dp);
8462 return USERSHARE_POSIX_ERR;
8465 sys_closedir(dp);
8467 if (!S_ISDIR(sbuf.st_ex_mode)) {
8468 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8469 servicename, sharepath ));
8470 return USERSHARE_PATH_NOT_DIRECTORY;
8473 /* Check if sharing is restricted to owner-only. */
8474 /* psbuf is the stat of the usershare definition file,
8475 sbuf is the stat of the target directory to be shared. */
8477 if (lp_usershare_owner_only()) {
8478 /* root can share anything. */
8479 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8480 return USERSHARE_PATH_NOT_ALLOWED;
8484 *pp_sharepath = sharepath;
8485 *pp_comment = comment;
8486 return USERSHARE_OK;
8489 /***************************************************************************
8490 Deal with a usershare file.
8491 Returns:
8492 >= 0 - snum
8493 -1 - Bad name, invalid contents.
8494 - service name already existed and not a usershare, problem
8495 with permissions to share directory etc.
8496 ***************************************************************************/
8498 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8500 SMB_STRUCT_STAT sbuf;
8501 SMB_STRUCT_STAT lsbuf;
8502 char *fname = NULL;
8503 char *sharepath = NULL;
8504 char *comment = NULL;
8505 char *cp_service_name = NULL;
8506 char **lines = NULL;
8507 int numlines = 0;
8508 int fd = -1;
8509 int iService = -1;
8510 TALLOC_CTX *ctx = talloc_stackframe();
8511 struct security_descriptor *psd = NULL;
8512 bool guest_ok = false;
8513 char *canon_name = NULL;
8514 bool added_service = false;
8515 int ret = -1;
8517 /* Ensure share name doesn't contain invalid characters. */
8518 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8519 DEBUG(0,("process_usershare_file: share name %s contains "
8520 "invalid characters (any of %s)\n",
8521 file_name, INVALID_SHARENAME_CHARS ));
8522 goto out;
8525 canon_name = canonicalize_servicename(ctx, file_name);
8526 if (!canon_name) {
8527 goto out;
8530 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8531 if (!fname) {
8532 goto out;
8535 /* Minimize the race condition by doing an lstat before we
8536 open and fstat. Ensure this isn't a symlink link. */
8538 if (sys_lstat(fname, &lsbuf, false) != 0) {
8539 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8540 fname, strerror(errno) ));
8541 goto out;
8544 /* This must be a regular file, not a symlink, directory or
8545 other strange filetype. */
8546 if (!check_usershare_stat(fname, &lsbuf)) {
8547 goto out;
8551 TDB_DATA data;
8552 NTSTATUS status;
8554 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
8555 canon_name, &data);
8557 iService = -1;
8559 if (NT_STATUS_IS_OK(status) &&
8560 (data.dptr != NULL) &&
8561 (data.dsize == sizeof(iService)))
8563 iService = *(int *)data.dptr;
8567 if (iService != -1 &&
8568 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8569 &lsbuf.st_ex_mtime) == 0) {
8570 /* Nothing changed - Mark valid and return. */
8571 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8572 canon_name ));
8573 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8574 ret = iService;
8575 goto out;
8578 /* Try and open the file read only - no symlinks allowed. */
8579 #ifdef O_NOFOLLOW
8580 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8581 #else
8582 fd = sys_open(fname, O_RDONLY, 0);
8583 #endif
8585 if (fd == -1) {
8586 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8587 fname, strerror(errno) ));
8588 goto out;
8591 /* Now fstat to be *SURE* it's a regular file. */
8592 if (sys_fstat(fd, &sbuf, false) != 0) {
8593 close(fd);
8594 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8595 fname, strerror(errno) ));
8596 goto out;
8599 /* Is it the same dev/inode as was lstated ? */
8600 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8601 close(fd);
8602 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8603 "Symlink spoofing going on ?\n", fname ));
8604 goto out;
8607 /* This must be a regular file, not a symlink, directory or
8608 other strange filetype. */
8609 if (!check_usershare_stat(fname, &sbuf)) {
8610 goto out;
8613 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8615 close(fd);
8616 if (lines == NULL) {
8617 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8618 fname, (unsigned int)sbuf.st_ex_uid ));
8619 goto out;
8622 if (parse_usershare_file(ctx, &sbuf, file_name,
8623 iService, lines, numlines, &sharepath,
8624 &comment, &cp_service_name,
8625 &psd, &guest_ok) != USERSHARE_OK) {
8626 goto out;
8629 /* Everything ok - add the service possibly using a template. */
8630 if (iService < 0) {
8631 const struct loadparm_service *sp = &sDefault;
8632 if (snum_template != -1) {
8633 sp = ServicePtrs[snum_template];
8636 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8637 DEBUG(0, ("process_usershare_file: Failed to add "
8638 "new service %s\n", cp_service_name));
8639 goto out;
8642 added_service = true;
8644 /* Read only is controlled by usershare ACL below. */
8645 ServicePtrs[iService]->bRead_only = false;
8648 /* Write the ACL of the new/modified share. */
8649 if (!set_share_security(canon_name, psd)) {
8650 DEBUG(0, ("process_usershare_file: Failed to set share "
8651 "security for user share %s\n",
8652 canon_name ));
8653 goto out;
8656 /* If from a template it may be marked invalid. */
8657 ServicePtrs[iService]->valid = true;
8659 /* Set the service as a valid usershare. */
8660 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8662 /* Set guest access. */
8663 if (lp_usershare_allow_guests()) {
8664 ServicePtrs[iService]->bGuest_ok = guest_ok;
8667 /* And note when it was loaded. */
8668 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8669 string_set(&ServicePtrs[iService]->szPath, sharepath);
8670 string_set(&ServicePtrs[iService]->comment, comment);
8672 ret = iService;
8674 out:
8676 if (ret == -1 && iService != -1 && added_service) {
8677 lp_remove_service(iService);
8680 TALLOC_FREE(lines);
8681 TALLOC_FREE(ctx);
8682 return ret;
8685 /***************************************************************************
8686 Checks if a usershare entry has been modified since last load.
8687 ***************************************************************************/
8689 static bool usershare_exists(int iService, struct timespec *last_mod)
8691 SMB_STRUCT_STAT lsbuf;
8692 const char *usersharepath = Globals.szUsersharePath;
8693 char *fname;
8695 if (asprintf(&fname, "%s/%s",
8696 usersharepath,
8697 ServicePtrs[iService]->szService) < 0) {
8698 return false;
8701 if (sys_lstat(fname, &lsbuf, false) != 0) {
8702 SAFE_FREE(fname);
8703 return false;
8706 if (!S_ISREG(lsbuf.st_ex_mode)) {
8707 SAFE_FREE(fname);
8708 return false;
8711 SAFE_FREE(fname);
8712 *last_mod = lsbuf.st_ex_mtime;
8713 return true;
8716 /***************************************************************************
8717 Load a usershare service by name. Returns a valid servicenumber or -1.
8718 ***************************************************************************/
8720 int load_usershare_service(const char *servicename)
8722 SMB_STRUCT_STAT sbuf;
8723 const char *usersharepath = Globals.szUsersharePath;
8724 int max_user_shares = Globals.iUsershareMaxShares;
8725 int snum_template = -1;
8727 if (*usersharepath == 0 || max_user_shares == 0) {
8728 return -1;
8731 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8732 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8733 usersharepath, strerror(errno) ));
8734 return -1;
8737 if (!S_ISDIR(sbuf.st_ex_mode)) {
8738 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8739 usersharepath ));
8740 return -1;
8744 * This directory must be owned by root, and have the 't' bit set.
8745 * It also must not be writable by "other".
8748 #ifdef S_ISVTX
8749 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8750 #else
8751 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8752 #endif
8753 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8754 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8755 usersharepath ));
8756 return -1;
8759 /* Ensure the template share exists if it's set. */
8760 if (Globals.szUsershareTemplateShare[0]) {
8761 /* We can't use lp_servicenumber here as we are recommending that
8762 template shares have -valid=false set. */
8763 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8764 if (ServicePtrs[snum_template]->szService &&
8765 strequal(ServicePtrs[snum_template]->szService,
8766 Globals.szUsershareTemplateShare)) {
8767 break;
8771 if (snum_template == -1) {
8772 DEBUG(0,("load_usershare_service: usershare template share %s "
8773 "does not exist.\n",
8774 Globals.szUsershareTemplateShare ));
8775 return -1;
8779 return process_usershare_file(usersharepath, servicename, snum_template);
8782 /***************************************************************************
8783 Load all user defined shares from the user share directory.
8784 We only do this if we're enumerating the share list.
8785 This is the function that can delete usershares that have
8786 been removed.
8787 ***************************************************************************/
8789 int load_usershare_shares(struct smbd_server_connection *sconn)
8791 SMB_STRUCT_DIR *dp;
8792 SMB_STRUCT_STAT sbuf;
8793 SMB_STRUCT_DIRENT *de;
8794 int num_usershares = 0;
8795 int max_user_shares = Globals.iUsershareMaxShares;
8796 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8797 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8798 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8799 int iService;
8800 int snum_template = -1;
8801 const char *usersharepath = Globals.szUsersharePath;
8802 int ret = lp_numservices();
8804 if (max_user_shares == 0 || *usersharepath == '\0') {
8805 return lp_numservices();
8808 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8809 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8810 usersharepath, strerror(errno) ));
8811 return ret;
8815 * This directory must be owned by root, and have the 't' bit set.
8816 * It also must not be writable by "other".
8819 #ifdef S_ISVTX
8820 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8821 #else
8822 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8823 #endif
8824 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8825 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8826 usersharepath ));
8827 return ret;
8830 /* Ensure the template share exists if it's set. */
8831 if (Globals.szUsershareTemplateShare[0]) {
8832 /* We can't use lp_servicenumber here as we are recommending that
8833 template shares have -valid=false set. */
8834 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8835 if (ServicePtrs[snum_template]->szService &&
8836 strequal(ServicePtrs[snum_template]->szService,
8837 Globals.szUsershareTemplateShare)) {
8838 break;
8842 if (snum_template == -1) {
8843 DEBUG(0,("load_usershare_shares: usershare template share %s "
8844 "does not exist.\n",
8845 Globals.szUsershareTemplateShare ));
8846 return ret;
8850 /* Mark all existing usershares as pending delete. */
8851 for (iService = iNumServices - 1; iService >= 0; iService--) {
8852 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8853 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8857 dp = sys_opendir(usersharepath);
8858 if (!dp) {
8859 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8860 usersharepath, strerror(errno) ));
8861 return ret;
8864 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8865 (de = sys_readdir(dp));
8866 num_dir_entries++ ) {
8867 int r;
8868 const char *n = de->d_name;
8870 /* Ignore . and .. */
8871 if (*n == '.') {
8872 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8873 continue;
8877 if (n[0] == ':') {
8878 /* Temporary file used when creating a share. */
8879 num_tmp_dir_entries++;
8882 /* Allow 20% tmp entries. */
8883 if (num_tmp_dir_entries > allowed_tmp_entries) {
8884 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8885 "in directory %s\n",
8886 num_tmp_dir_entries, usersharepath));
8887 break;
8890 r = process_usershare_file(usersharepath, n, snum_template);
8891 if (r == 0) {
8892 /* Update the services count. */
8893 num_usershares++;
8894 if (num_usershares >= max_user_shares) {
8895 DEBUG(0,("load_usershare_shares: max user shares reached "
8896 "on file %s in directory %s\n",
8897 n, usersharepath ));
8898 break;
8900 } else if (r == -1) {
8901 num_bad_dir_entries++;
8904 /* Allow 20% bad entries. */
8905 if (num_bad_dir_entries > allowed_bad_entries) {
8906 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8907 "in directory %s\n",
8908 num_bad_dir_entries, usersharepath));
8909 break;
8912 /* Allow 20% bad entries. */
8913 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8914 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8915 "in directory %s\n",
8916 num_dir_entries, usersharepath));
8917 break;
8921 sys_closedir(dp);
8923 /* Sweep through and delete any non-refreshed usershares that are
8924 not currently in use. */
8925 for (iService = iNumServices - 1; iService >= 0; iService--) {
8926 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8927 if (conn_snum_used(sconn, iService)) {
8928 continue;
8930 /* Remove from the share ACL db. */
8931 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8932 lp_servicename(iService) ));
8933 delete_share_security(lp_servicename(iService));
8934 free_service_byindex(iService);
8938 return lp_numservices();
8941 /********************************************************
8942 Destroy global resources allocated in this file
8943 ********************************************************/
8945 void gfree_loadparm(void)
8947 int i;
8949 free_file_list();
8951 /* Free resources allocated to services */
8953 for ( i = 0; i < iNumServices; i++ ) {
8954 if ( VALID(i) ) {
8955 free_service_byindex(i);
8959 SAFE_FREE( ServicePtrs );
8960 iNumServices = 0;
8962 /* Now release all resources allocated to global
8963 parameters and the default service */
8965 free_global_parameters();
8969 /***************************************************************************
8970 Allow client apps to specify that they are a client
8971 ***************************************************************************/
8972 static void lp_set_in_client(bool b)
8974 in_client = b;
8978 /***************************************************************************
8979 Determine if we're running in a client app
8980 ***************************************************************************/
8981 static bool lp_is_in_client(void)
8983 return in_client;
8986 /***************************************************************************
8987 Load the services array from the services file. Return true on success,
8988 false on failure.
8989 ***************************************************************************/
8991 static bool lp_load_ex(const char *pszFname,
8992 bool global_only,
8993 bool save_defaults,
8994 bool add_ipc,
8995 bool initialize_globals,
8996 bool allow_include_registry,
8997 bool load_all_shares)
8999 char *n2 = NULL;
9000 bool bRetval;
9002 bRetval = false;
9004 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9006 bInGlobalSection = true;
9007 bGlobalOnly = global_only;
9008 bAllowIncludeRegistry = allow_include_registry;
9010 init_globals(initialize_globals);
9012 free_file_list();
9014 if (save_defaults) {
9015 init_locals();
9016 lp_save_defaults();
9019 if (!initialize_globals) {
9020 free_param_opts(&Globals.param_opt);
9021 apply_lp_set_cmdline();
9024 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9026 /* We get sections first, so have to start 'behind' to make up */
9027 iServiceIndex = -1;
9029 if (lp_config_backend_is_file()) {
9030 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9031 current_user_info.domain,
9032 pszFname);
9033 if (!n2) {
9034 smb_panic("lp_load_ex: out of memory");
9037 add_to_file_list(pszFname, n2);
9039 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9040 TALLOC_FREE(n2);
9042 /* finish up the last section */
9043 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9044 if (bRetval) {
9045 if (iServiceIndex >= 0) {
9046 bRetval = service_ok(iServiceIndex);
9050 if (lp_config_backend_is_registry()) {
9051 /* config backend changed to registry in config file */
9053 * We need to use this extra global variable here to
9054 * survive restart: init_globals uses this as a default
9055 * for ConfigBackend. Otherwise, init_globals would
9056 * send us into an endless loop here.
9058 config_backend = CONFIG_BACKEND_REGISTRY;
9059 /* start over */
9060 DEBUG(1, ("lp_load_ex: changing to config backend "
9061 "registry\n"));
9062 init_globals(true);
9063 lp_kill_all_services();
9064 return lp_load_ex(pszFname, global_only, save_defaults,
9065 add_ipc, initialize_globals,
9066 allow_include_registry,
9067 load_all_shares);
9069 } else if (lp_config_backend_is_registry()) {
9070 bRetval = process_registry_globals();
9071 } else {
9072 DEBUG(0, ("Illegal config backend given: %d\n",
9073 lp_config_backend()));
9074 bRetval = false;
9077 if (bRetval && lp_registry_shares()) {
9078 if (load_all_shares) {
9079 bRetval = process_registry_shares();
9080 } else {
9081 bRetval = reload_registry_shares();
9085 lp_add_auto_services(lp_auto_services());
9087 if (add_ipc) {
9088 /* When 'restrict anonymous = 2' guest connections to ipc$
9089 are denied */
9090 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9091 if ( lp_enable_asu_support() ) {
9092 lp_add_ipc("ADMIN$", false);
9096 set_server_role();
9097 set_allowed_client_auth();
9099 if (lp_security() == SEC_SHARE) {
9100 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9101 } else if (lp_security() == SEC_SERVER) {
9102 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9105 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9106 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9107 lp_passwordserver()));
9110 bLoaded = true;
9112 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9113 /* if bWINSsupport is true and we are in the client */
9114 if (lp_is_in_client() && Globals.bWINSsupport) {
9115 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9118 init_iconv();
9120 fault_configure(smb_panic_s3);
9122 bAllowIncludeRegistry = true;
9124 return (bRetval);
9127 bool lp_load(const char *pszFname,
9128 bool global_only,
9129 bool save_defaults,
9130 bool add_ipc,
9131 bool initialize_globals)
9133 return lp_load_ex(pszFname,
9134 global_only,
9135 save_defaults,
9136 add_ipc,
9137 initialize_globals,
9138 true, /* allow_include_registry */
9139 false); /* load_all_shares*/
9142 bool lp_load_initial_only(const char *pszFname)
9144 return lp_load_ex(pszFname,
9145 true, /* global only */
9146 false, /* save_defaults */
9147 false, /* add_ipc */
9148 true, /* initialize_globals */
9149 false, /* allow_include_registry */
9150 false); /* load_all_shares*/
9154 * most common lp_load wrapper, loading only the globals
9156 bool lp_load_global(const char *file_name)
9158 return lp_load_ex(file_name,
9159 true, /* global_only */
9160 false, /* save_defaults */
9161 false, /* add_ipc */
9162 true, /* initialize_globals */
9163 true, /* allow_include_registry */
9164 false); /* load_all_shares*/
9168 * lp_load wrapper, especially for clients
9170 bool lp_load_client(const char *file_name)
9172 lp_set_in_client(true);
9174 return lp_load_global(file_name);
9178 * lp_load wrapper, loading only globals, but intended
9179 * for subsequent calls, not reinitializing the globals
9180 * to default values
9182 bool lp_load_global_no_reinit(const char *file_name)
9184 return lp_load_ex(file_name,
9185 true, /* global_only */
9186 false, /* save_defaults */
9187 false, /* add_ipc */
9188 false, /* initialize_globals */
9189 true, /* allow_include_registry */
9190 false); /* load_all_shares*/
9194 * lp_load wrapper, especially for clients, no reinitialization
9196 bool lp_load_client_no_reinit(const char *file_name)
9198 lp_set_in_client(true);
9200 return lp_load_global_no_reinit(file_name);
9203 bool lp_load_with_registry_shares(const char *pszFname,
9204 bool global_only,
9205 bool save_defaults,
9206 bool add_ipc,
9207 bool initialize_globals)
9209 return lp_load_ex(pszFname,
9210 global_only,
9211 save_defaults,
9212 add_ipc,
9213 initialize_globals,
9214 true, /* allow_include_registry */
9215 true); /* load_all_shares*/
9218 /***************************************************************************
9219 Return the max number of services.
9220 ***************************************************************************/
9222 int lp_numservices(void)
9224 return (iNumServices);
9227 /***************************************************************************
9228 Display the contents of the services array in human-readable form.
9229 ***************************************************************************/
9231 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9233 int iService;
9235 if (show_defaults)
9236 defaults_saved = false;
9238 dump_globals(f);
9240 dump_a_service(&sDefault, f);
9242 for (iService = 0; iService < maxtoprint; iService++) {
9243 fprintf(f,"\n");
9244 lp_dump_one(f, show_defaults, iService);
9248 /***************************************************************************
9249 Display the contents of one service in human-readable form.
9250 ***************************************************************************/
9252 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9254 if (VALID(snum)) {
9255 if (ServicePtrs[snum]->szService[0] == '\0')
9256 return;
9257 dump_a_service(ServicePtrs[snum], f);
9261 /***************************************************************************
9262 Return the number of the service with the given name, or -1 if it doesn't
9263 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9264 getservicebyname()! This works ONLY if all services have been loaded, and
9265 does not copy the found service.
9266 ***************************************************************************/
9268 int lp_servicenumber(const char *pszServiceName)
9270 int iService;
9271 fstring serviceName;
9273 if (!pszServiceName) {
9274 return GLOBAL_SECTION_SNUM;
9277 for (iService = iNumServices - 1; iService >= 0; iService--) {
9278 if (VALID(iService) && ServicePtrs[iService]->szService) {
9280 * The substitution here is used to support %U is
9281 * service names
9283 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9284 standard_sub_basic(get_current_username(),
9285 current_user_info.domain,
9286 serviceName,sizeof(serviceName));
9287 if (strequal(serviceName, pszServiceName)) {
9288 break;
9293 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9294 struct timespec last_mod;
9296 if (!usershare_exists(iService, &last_mod)) {
9297 /* Remove the share security tdb entry for it. */
9298 delete_share_security(lp_servicename(iService));
9299 /* Remove it from the array. */
9300 free_service_byindex(iService);
9301 /* Doesn't exist anymore. */
9302 return GLOBAL_SECTION_SNUM;
9305 /* Has it been modified ? If so delete and reload. */
9306 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9307 &last_mod) < 0) {
9308 /* Remove it from the array. */
9309 free_service_byindex(iService);
9310 /* and now reload it. */
9311 iService = load_usershare_service(pszServiceName);
9315 if (iService < 0) {
9316 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9317 return GLOBAL_SECTION_SNUM;
9320 return (iService);
9323 bool share_defined(const char *service_name)
9325 return (lp_servicenumber(service_name) != -1);
9328 /*******************************************************************
9329 A useful volume label function.
9330 ********************************************************************/
9332 const char *volume_label(int snum)
9334 char *ret;
9335 const char *label = lp_volume(snum);
9336 if (!*label) {
9337 label = lp_servicename(snum);
9340 /* This returns a 33 byte guarenteed null terminated string. */
9341 ret = talloc_strndup(talloc_tos(), label, 32);
9342 if (!ret) {
9343 return "";
9345 return ret;
9348 /*******************************************************************
9349 Get the default server type we will announce as via nmbd.
9350 ********************************************************************/
9352 int lp_default_server_announce(void)
9354 int default_server_announce = 0;
9355 default_server_announce |= SV_TYPE_WORKSTATION;
9356 default_server_announce |= SV_TYPE_SERVER;
9357 default_server_announce |= SV_TYPE_SERVER_UNIX;
9359 /* note that the flag should be set only if we have a
9360 printer service but nmbd doesn't actually load the
9361 services so we can't tell --jerry */
9363 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9365 default_server_announce |= SV_TYPE_SERVER_NT;
9366 default_server_announce |= SV_TYPE_NT;
9368 switch (lp_server_role()) {
9369 case ROLE_DOMAIN_MEMBER:
9370 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9371 break;
9372 case ROLE_DOMAIN_PDC:
9373 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9374 break;
9375 case ROLE_DOMAIN_BDC:
9376 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9377 break;
9378 case ROLE_STANDALONE:
9379 default:
9380 break;
9382 if (lp_time_server())
9383 default_server_announce |= SV_TYPE_TIME_SOURCE;
9385 if (lp_host_msdfs())
9386 default_server_announce |= SV_TYPE_DFS_SERVER;
9388 return default_server_announce;
9391 /***********************************************************
9392 If we are PDC then prefer us as DMB
9393 ************************************************************/
9395 bool lp_domain_master(void)
9397 if (Globals.iDomainMaster == Auto)
9398 return (lp_server_role() == ROLE_DOMAIN_PDC);
9400 return (bool)Globals.iDomainMaster;
9403 /***********************************************************
9404 If we are PDC then prefer us as DMB
9405 ************************************************************/
9407 bool lp_domain_master_true_or_auto(void)
9409 if (Globals.iDomainMaster) /* auto or yes */
9410 return true;
9412 return false;
9415 /***********************************************************
9416 If we are DMB then prefer us as LMB
9417 ************************************************************/
9419 bool lp_preferred_master(void)
9421 if (Globals.iPreferredMaster == Auto)
9422 return (lp_local_master() && lp_domain_master());
9424 return (bool)Globals.iPreferredMaster;
9427 /*******************************************************************
9428 Remove a service.
9429 ********************************************************************/
9431 void lp_remove_service(int snum)
9433 ServicePtrs[snum]->valid = false;
9434 invalid_services[num_invalid_services++] = snum;
9437 /*******************************************************************
9438 Copy a service.
9439 ********************************************************************/
9441 void lp_copy_service(int snum, const char *new_name)
9443 do_section(new_name, NULL);
9444 if (snum >= 0) {
9445 snum = lp_servicenumber(new_name);
9446 if (snum >= 0)
9447 lp_do_parameter(snum, "copy", lp_servicename(snum));
9452 /***********************************************************
9453 Set the global name resolution order (used in smbclient).
9454 ************************************************************/
9456 void lp_set_name_resolve_order(const char *new_order)
9458 string_set(&Globals.szNameResolveOrder, new_order);
9461 const char *lp_printername(int snum)
9463 const char *ret = lp__printername(snum);
9464 if (ret == NULL || (ret != NULL && *ret == '\0'))
9465 ret = lp_const_servicename(snum);
9467 return ret;
9471 /***********************************************************
9472 Allow daemons such as winbindd to fix their logfile name.
9473 ************************************************************/
9475 void lp_set_logfile(const char *name)
9477 string_set(&Globals.szLogFile, name);
9478 debug_set_logfile(name);
9481 /*******************************************************************
9482 Return the max print jobs per queue.
9483 ********************************************************************/
9485 int lp_maxprintjobs(int snum)
9487 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9488 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9489 maxjobs = PRINT_MAX_JOBID - 1;
9491 return maxjobs;
9494 const char *lp_printcapname(void)
9496 if ((Globals.szPrintcapname != NULL) &&
9497 (Globals.szPrintcapname[0] != '\0'))
9498 return Globals.szPrintcapname;
9500 if (sDefault.iPrinting == PRINT_CUPS) {
9501 #ifdef HAVE_CUPS
9502 return "cups";
9503 #else
9504 return "lpstat";
9505 #endif
9508 if (sDefault.iPrinting == PRINT_BSD)
9509 return "/etc/printcap";
9511 return PRINTCAP_NAME;
9514 static uint32 spoolss_state;
9516 bool lp_disable_spoolss( void )
9518 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9519 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9521 return spoolss_state == SVCCTL_STOPPED ? true : false;
9524 void lp_set_spoolss_state( uint32 state )
9526 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9528 spoolss_state = state;
9531 uint32 lp_get_spoolss_state( void )
9533 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9536 /*******************************************************************
9537 Ensure we don't use sendfile if server smb signing is active.
9538 ********************************************************************/
9540 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9542 bool sign_active = false;
9544 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9545 if (get_Protocol() < PROTOCOL_NT1) {
9546 return false;
9548 if (signing_state) {
9549 sign_active = smb_signing_is_active(signing_state);
9551 return (lp__use_sendfile(snum) &&
9552 (get_remote_arch() != RA_WIN95) &&
9553 !sign_active);
9556 /*******************************************************************
9557 Turn off sendfile if we find the underlying OS doesn't support it.
9558 ********************************************************************/
9560 void set_use_sendfile(int snum, bool val)
9562 if (LP_SNUM_OK(snum))
9563 ServicePtrs[snum]->bUseSendfile = val;
9564 else
9565 sDefault.bUseSendfile = val;
9568 /*******************************************************************
9569 Turn off storing DOS attributes if this share doesn't support it.
9570 ********************************************************************/
9572 void set_store_dos_attributes(int snum, bool val)
9574 if (!LP_SNUM_OK(snum))
9575 return;
9576 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9579 void lp_set_mangling_method(const char *new_method)
9581 string_set(&Globals.szManglingMethod, new_method);
9584 /*******************************************************************
9585 Global state for POSIX pathname processing.
9586 ********************************************************************/
9588 static bool posix_pathnames;
9590 bool lp_posix_pathnames(void)
9592 return posix_pathnames;
9595 /*******************************************************************
9596 Change everything needed to ensure POSIX pathname processing (currently
9597 not much).
9598 ********************************************************************/
9600 void lp_set_posix_pathnames(void)
9602 posix_pathnames = true;
9605 /*******************************************************************
9606 Global state for POSIX lock processing - CIFS unix extensions.
9607 ********************************************************************/
9609 bool posix_default_lock_was_set;
9610 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9612 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9614 if (posix_default_lock_was_set) {
9615 return posix_cifsx_locktype;
9616 } else {
9617 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9621 /*******************************************************************
9622 ********************************************************************/
9624 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9626 posix_default_lock_was_set = true;
9627 posix_cifsx_locktype = val;
9630 int lp_min_receive_file_size(void)
9632 if (Globals.iminreceivefile < 0) {
9633 return 0;
9635 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9638 /*******************************************************************
9639 If socket address is an empty character string, it is necessary to
9640 define it as "0.0.0.0".
9641 ********************************************************************/
9643 const char *lp_socket_address(void)
9645 char *sock_addr = Globals.szSocketAddress;
9647 if (sock_addr[0] == '\0'){
9648 string_set(&Globals.szSocketAddress, "0.0.0.0");
9650 return Globals.szSocketAddress;
9653 /*******************************************************************
9654 Safe wide links checks.
9655 This helper function always verify the validity of wide links,
9656 even after a configuration file reload.
9657 ********************************************************************/
9659 static bool lp_widelinks_internal(int snum)
9661 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9662 sDefault.bWidelinks);
9665 void widelinks_warning(int snum)
9667 if (lp_allow_insecure_widelinks()) {
9668 return;
9671 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9672 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9673 "These parameters are incompatible. "
9674 "Wide links will be disabled for this share.\n",
9675 lp_servicename(snum) ));
9679 bool lp_widelinks(int snum)
9681 /* wide links is always incompatible with unix extensions */
9682 if (lp_unix_extensions()) {
9684 * Unless we have "allow insecure widelinks"
9685 * turned on.
9687 if (!lp_allow_insecure_widelinks()) {
9688 return false;
9692 return lp_widelinks_internal(snum);
9695 bool lp_writeraw(void)
9697 if (lp_async_smb_echo_handler()) {
9698 return false;
9700 return _lp_writeraw();
9703 bool lp_readraw(void)
9705 if (lp_async_smb_echo_handler()) {
9706 return false;
9708 return _lp_readraw();