Replace all uses of setXX[ug]id() and setgroups with samba_setXX[ug]id() calls.
[Samba/id10ts.git] / source3 / param / loadparm.c
blobba57553802a25f9e5c0ebd562ffdd52d72e23562
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14 Copyright (C) Andrew Bartlett 2011
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 3 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 * Load parameters.
33 * This module provides suitable callback functions for the params
34 * module. It builds the internal table of service details which is
35 * then used by the rest of the server.
37 * To add a parameter:
39 * 1) add it to the global or service structure definition
40 * 2) add it to the parm_table
41 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42 * 4) If it's a global then initialise it in init_globals. If a local
43 * (ie. service) parameter then initialise it in the sDefault structure
46 * Notes:
47 * The configuration file is processed sequentially for speed. It is NOT
48 * accessed randomly as happens in 'real' Windows. For this reason, there
49 * is a fair bit of sequence-dependent code here - ie., code which assumes
50 * that certain things happen before others. In particular, the code which
51 * happens at the boundary between sections is delicately poised, so be
52 * careful!
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "printing.h"
60 #include "lib/smbconf/smbconf.h"
61 #include "lib/smbconf/smbconf_init.h"
62 #include "lib/param/loadparm.h"
64 #include "ads.h"
65 #include "../librpc/gen_ndr/svcctl.h"
66 #include "intl.h"
67 #include "../libcli/smb/smb_signing.h"
68 #include "dbwrap/dbwrap.h"
69 #include "dbwrap/dbwrap_rbt.h"
70 #include "../lib/util/bitmap.h"
71 #include "../source4/dns_server/dns_update.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
75 #endif
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
81 #ifdef CLUSTER_SUPPORT
82 #include "ctdb_private.h"
83 #endif
85 bool bLoaded = false;
87 extern userdom_struct current_user_info;
89 /* the special value for the include parameter
90 * to be interpreted not as a file name but to
91 * trigger loading of the global smb.conf options
92 * from registry. */
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
95 #endif
97 static bool in_client = false; /* Not in the client by default */
98 static struct smbconf_csn conf_last_csn;
100 #define CONFIG_BACKEND_FILE 0
101 #define CONFIG_BACKEND_REGISTRY 1
103 static int config_backend = CONFIG_BACKEND_FILE;
105 /* some helpful bits */
106 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
107 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
109 #define USERSHARE_VALID 1
110 #define USERSHARE_PENDING_DELETE 2
112 static bool defaults_saved = false;
114 #define LOADPARM_EXTRA_GLOBALS \
115 struct parmlist_entry *param_opt; \
116 char *szRealm; \
117 char *szLogLevel; \
118 int iminreceivefile; \
119 char *szPrintcapname; \
120 int CupsEncrypt; \
121 int iPreferredMaster; \
122 int iDomainMaster; \
123 char *szLdapMachineSuffix; \
124 char *szLdapUserSuffix; \
125 char *szLdapIdmapSuffix; \
126 char *szLdapGroupSuffix; \
127 char *szStateDir; \
128 char *szCacheDir; \
129 char *szSocketAddress; \
130 char *szUsershareTemplateShare; \
131 char *szIdmapUID; \
132 char *szIdmapGID; \
133 int winbindMaxDomainConnections; \
134 int ismb2_max_credits;
136 #include "param/param_global.h"
138 static struct loadparm_global Globals;
140 /* This is a default service used to prime a services structure */
141 static struct loadparm_service sDefault =
143 .valid = true,
144 .autoloaded = false,
145 .usershare = 0,
146 .usershare_last_mod = {0, 0},
147 .szService = NULL,
148 .szPath = NULL,
149 .szUsername = NULL,
150 .szInvalidUsers = NULL,
151 .szValidUsers = NULL,
152 .szAdminUsers = NULL,
153 .szCopy = NULL,
154 .szInclude = NULL,
155 .szPreExec = NULL,
156 .szPostExec = NULL,
157 .szRootPreExec = NULL,
158 .szRootPostExec = NULL,
159 .szCupsOptions = NULL,
160 .szPrintcommand = NULL,
161 .szLpqcommand = NULL,
162 .szLprmcommand = NULL,
163 .szLppausecommand = NULL,
164 .szLpresumecommand = NULL,
165 .szQueuepausecommand = NULL,
166 .szQueueresumecommand = NULL,
167 .szPrintername = NULL,
168 .szPrintjobUsername = NULL,
169 .szDontdescend = NULL,
170 .szHostsallow = NULL,
171 .szHostsdeny = NULL,
172 .szMagicScript = NULL,
173 .szMagicOutput = NULL,
174 .szVetoFiles = NULL,
175 .szHideFiles = NULL,
176 .szVetoOplockFiles = NULL,
177 .comment = NULL,
178 .force_user = NULL,
179 .force_group = NULL,
180 .readlist = NULL,
181 .writelist = NULL,
182 .printer_admin = NULL,
183 .volume = NULL,
184 .fstype = NULL,
185 .szVfsObjects = NULL,
186 .szMSDfsProxy = NULL,
187 .szAioWriteBehind = NULL,
188 .szDfree = NULL,
189 .iMinPrintSpace = 0,
190 .iMaxPrintJobs = 1000,
191 .iMaxReportedPrintJobs = 0,
192 .iWriteCacheSize = 0,
193 .iCreate_mask = 0744,
194 .iCreate_force_mode = 0,
195 .iSecurity_mask = 0777,
196 .iSecurity_force_mode = 0,
197 .iDir_mask = 0755,
198 .iDir_force_mode = 0,
199 .iDir_Security_mask = 0777,
200 .iDir_Security_force_mode = 0,
201 .iMaxConnections = 0,
202 .iDefaultCase = CASE_LOWER,
203 .iPrinting = DEFAULT_PRINTING,
204 .iOplockContentionLimit = 2,
205 .iCSCPolicy = 0,
206 .iBlock_size = 1024,
207 .iDfreeCacheTime = 0,
208 .bPreexecClose = false,
209 .bRootpreexecClose = false,
210 .iCaseSensitive = Auto,
211 .bCasePreserve = true,
212 .bShortCasePreserve = true,
213 .bHideDotFiles = true,
214 .bHideSpecialFiles = false,
215 .bHideUnReadable = false,
216 .bHideUnWriteableFiles = false,
217 .bBrowseable = true,
218 .bAccessBasedShareEnum = false,
219 .bAvailable = true,
220 .bRead_only = true,
221 .bNo_set_dir = true,
222 .bGuest_only = false,
223 .bAdministrative_share = false,
224 .bGuest_ok = false,
225 .bPrint_ok = false,
226 .bPrintNotifyBackchannel = true,
227 .bMap_system = false,
228 .bMap_hidden = false,
229 .bMap_archive = true,
230 .bStoreDosAttributes = false,
231 .bDmapiSupport = false,
232 .bLocking = true,
233 .iStrictLocking = Auto,
234 .bPosixLocking = true,
235 .bShareModes = true,
236 .bOpLocks = true,
237 .bKernelOplocks = false,
238 .bLevel2OpLocks = true,
239 .bOnlyUser = false,
240 .bMangledNames = true,
241 .bWidelinks = false,
242 .bSymlinks = true,
243 .bSyncAlways = false,
244 .bStrictAllocate = false,
245 .bStrictSync = false,
246 .magic_char = '~',
247 .copymap = NULL,
248 .bDeleteReadonly = false,
249 .bFakeOplocks = false,
250 .bDeleteVetoFiles = false,
251 .bDosFilemode = false,
252 .bDosFiletimes = true,
253 .bDosFiletimeResolution = false,
254 .bFakeDirCreateTimes = false,
255 .bBlockingLocks = true,
256 .bInheritPerms = false,
257 .bInheritACLS = false,
258 .bInheritOwner = false,
259 .bMSDfsRoot = false,
260 .bUseClientDriver = false,
261 .bDefaultDevmode = true,
262 .bForcePrintername = false,
263 .bNTAclSupport = true,
264 .bForceUnknownAclUser = false,
265 .bUseSendfile = false,
266 .bProfileAcls = false,
267 .bMap_acl_inherit = false,
268 .bAfs_Share = false,
269 .bEASupport = false,
270 .bAclCheckPermissions = true,
271 .bAclMapFullControl = true,
272 .bAclGroupControl = false,
273 .bChangeNotify = true,
274 .bKernelChangeNotify = true,
275 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
276 .iAioReadSize = 0,
277 .iAioWriteSize = 0,
278 .iMap_readonly = MAP_READONLY_YES,
279 #ifdef BROKEN_DIRECTORY_HANDLING
280 .iDirectoryNameCacheSize = 0,
281 #else
282 .iDirectoryNameCacheSize = 100,
283 #endif
284 .ismb_encrypt = Auto,
285 .param_opt = NULL,
286 .dummy = ""
289 /* local variables */
290 static struct loadparm_service **ServicePtrs = NULL;
291 static int iNumServices = 0;
292 static int iServiceIndex = 0;
293 static struct db_context *ServiceHash;
294 static int *invalid_services = NULL;
295 static int num_invalid_services = 0;
296 static bool bInGlobalSection = true;
297 static bool bGlobalOnly = false;
299 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
301 /* prototypes for the special type handlers */
302 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
303 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
304 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
305 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
306 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
307 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
308 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
309 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
310 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
311 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
312 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
313 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
315 static void set_allowed_client_auth(void);
317 static void add_to_file_list(const char *fname, const char *subfname);
318 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
319 static void free_param_opts(struct parmlist_entry **popts);
321 #include "lib/param/param_enums.c"
323 static const struct enum_list enum_printing[] = {
324 {PRINT_SYSV, "sysv"},
325 {PRINT_AIX, "aix"},
326 {PRINT_HPUX, "hpux"},
327 {PRINT_BSD, "bsd"},
328 {PRINT_QNX, "qnx"},
329 {PRINT_PLP, "plp"},
330 {PRINT_LPRNG, "lprng"},
331 {PRINT_CUPS, "cups"},
332 {PRINT_IPRINT, "iprint"},
333 {PRINT_LPRNT, "nt"},
334 {PRINT_LPROS2, "os2"},
335 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
336 {PRINT_TEST, "test"},
337 {PRINT_VLP, "vlp"},
338 #endif /* DEVELOPER */
339 {-1, NULL}
342 static const struct enum_list enum_ldap_sasl_wrapping[] = {
343 {0, "plain"},
344 {ADS_AUTH_SASL_SIGN, "sign"},
345 {ADS_AUTH_SASL_SEAL, "seal"},
346 {-1, NULL}
349 static const struct enum_list enum_ldap_ssl[] = {
350 {LDAP_SSL_OFF, "no"},
351 {LDAP_SSL_OFF, "off"},
352 {LDAP_SSL_START_TLS, "start tls"},
353 {LDAP_SSL_START_TLS, "start_tls"},
354 {-1, NULL}
357 /* LDAP Dereferencing Alias types */
358 #define SAMBA_LDAP_DEREF_NEVER 0
359 #define SAMBA_LDAP_DEREF_SEARCHING 1
360 #define SAMBA_LDAP_DEREF_FINDING 2
361 #define SAMBA_LDAP_DEREF_ALWAYS 3
363 static const struct enum_list enum_ldap_deref[] = {
364 {SAMBA_LDAP_DEREF_NEVER, "never"},
365 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
366 {SAMBA_LDAP_DEREF_FINDING, "finding"},
367 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
368 {-1, "auto"}
371 static const struct enum_list enum_ldap_passwd_sync[] = {
372 {LDAP_PASSWD_SYNC_OFF, "no"},
373 {LDAP_PASSWD_SYNC_OFF, "off"},
374 {LDAP_PASSWD_SYNC_ON, "yes"},
375 {LDAP_PASSWD_SYNC_ON, "on"},
376 {LDAP_PASSWD_SYNC_ONLY, "only"},
377 {-1, NULL}
380 static const struct enum_list enum_map_readonly[] = {
381 {MAP_READONLY_NO, "no"},
382 {MAP_READONLY_NO, "false"},
383 {MAP_READONLY_NO, "0"},
384 {MAP_READONLY_YES, "yes"},
385 {MAP_READONLY_YES, "true"},
386 {MAP_READONLY_YES, "1"},
387 {MAP_READONLY_PERMISSIONS, "permissions"},
388 {MAP_READONLY_PERMISSIONS, "perms"},
389 {-1, NULL}
392 static const struct enum_list enum_case[] = {
393 {CASE_LOWER, "lower"},
394 {CASE_UPPER, "upper"},
395 {-1, NULL}
399 /* ACL compatibility options. */
400 static const struct enum_list enum_acl_compat_vals[] = {
401 { ACL_COMPAT_AUTO, "auto" },
402 { ACL_COMPAT_WINNT, "winnt" },
403 { ACL_COMPAT_WIN2K, "win2k" },
404 { -1, NULL}
408 Do you want session setups at user level security with a invalid
409 password to be rejected or allowed in as guest? WinNT rejects them
410 but it can be a pain as it means "net view" needs to use a password
412 You have 3 choices in the setting of map_to_guest:
414 "Never" means session setups with an invalid password
415 are rejected. This is the default.
417 "Bad User" means session setups with an invalid password
418 are rejected, unless the username does not exist, in which case it
419 is treated as a guest login
421 "Bad Password" means session setups with an invalid password
422 are treated as a guest login
424 Note that map_to_guest only has an effect in user or server
425 level security.
428 static const struct enum_list enum_map_to_guest[] = {
429 {NEVER_MAP_TO_GUEST, "Never"},
430 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
431 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
432 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
433 {-1, NULL}
436 /* Config backend options */
438 static const struct enum_list enum_config_backend[] = {
439 {CONFIG_BACKEND_FILE, "file"},
440 {CONFIG_BACKEND_REGISTRY, "registry"},
441 {-1, NULL}
444 /* ADS kerberos ticket verification options */
446 static const struct enum_list enum_kerberos_method[] = {
447 {KERBEROS_VERIFY_SECRETS, "default"},
448 {KERBEROS_VERIFY_SECRETS, "secrets only"},
449 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
450 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
451 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
452 {-1, NULL}
455 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
457 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
458 * screen in SWAT. This is used to exclude parameters as well as to squash all
459 * parameters that have been duplicated by pseudonyms.
461 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
462 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
463 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
464 * respective views.
466 * NOTE2: Handling of duplicated (synonym) parameters:
467 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
468 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
469 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
470 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
473 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
474 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
476 static struct parm_struct parm_table[] = {
477 {N_("Base Options"), P_SEP, P_SEPARATOR},
480 .label = "dos charset",
481 .type = P_STRING,
482 .p_class = P_GLOBAL,
483 .offset = GLOBAL_VAR(dos_charset),
484 .special = handle_dos_charset,
485 .enum_list = NULL,
486 .flags = FLAG_ADVANCED
489 .label = "unix charset",
490 .type = P_STRING,
491 .p_class = P_GLOBAL,
492 .offset = GLOBAL_VAR(unix_charset),
493 .special = handle_charset,
494 .enum_list = NULL,
495 .flags = FLAG_ADVANCED
498 .label = "comment",
499 .type = P_STRING,
500 .p_class = P_LOCAL,
501 .offset = LOCAL_VAR(comment),
502 .special = NULL,
503 .enum_list = NULL,
504 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
507 .label = "path",
508 .type = P_STRING,
509 .p_class = P_LOCAL,
510 .offset = LOCAL_VAR(szPath),
511 .special = NULL,
512 .enum_list = NULL,
513 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
516 .label = "directory",
517 .type = P_STRING,
518 .p_class = P_LOCAL,
519 .offset = LOCAL_VAR(szPath),
520 .special = NULL,
521 .enum_list = NULL,
522 .flags = FLAG_HIDE,
525 .label = "workgroup",
526 .type = P_USTRING,
527 .p_class = P_GLOBAL,
528 .offset = GLOBAL_VAR(szWorkgroup),
529 .special = NULL,
530 .enum_list = NULL,
531 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
534 .label = "realm",
535 .type = P_STRING,
536 .p_class = P_GLOBAL,
537 .offset = GLOBAL_VAR(szRealm),
538 .special = handle_realm,
539 .enum_list = NULL,
540 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
543 .label = "netbios name",
544 .type = P_USTRING,
545 .p_class = P_GLOBAL,
546 .offset = GLOBAL_VAR(szNetbiosName),
547 .special = NULL,
548 .enum_list = NULL,
549 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
552 .label = "netbios aliases",
553 .type = P_LIST,
554 .p_class = P_GLOBAL,
555 .offset = GLOBAL_VAR(szNetbiosAliases),
556 .special = handle_netbios_aliases,
557 .enum_list = NULL,
558 .flags = FLAG_ADVANCED,
561 .label = "netbios scope",
562 .type = P_USTRING,
563 .p_class = P_GLOBAL,
564 .offset = GLOBAL_VAR(szNetbiosScope),
565 .special = NULL,
566 .enum_list = NULL,
567 .flags = FLAG_ADVANCED,
570 .label = "server string",
571 .type = P_STRING,
572 .p_class = P_GLOBAL,
573 .offset = GLOBAL_VAR(szServerString),
574 .special = NULL,
575 .enum_list = NULL,
576 .flags = FLAG_BASIC | FLAG_ADVANCED,
579 .label = "interfaces",
580 .type = P_LIST,
581 .p_class = P_GLOBAL,
582 .offset = GLOBAL_VAR(szInterfaces),
583 .special = NULL,
584 .enum_list = NULL,
585 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
588 .label = "bind interfaces only",
589 .type = P_BOOL,
590 .p_class = P_GLOBAL,
591 .offset = GLOBAL_VAR(bBindInterfacesOnly),
592 .special = NULL,
593 .enum_list = NULL,
594 .flags = FLAG_ADVANCED | FLAG_WIZARD,
597 .label = "config backend",
598 .type = P_ENUM,
599 .p_class = P_GLOBAL,
600 .offset = GLOBAL_VAR(ConfigBackend),
601 .special = NULL,
602 .enum_list = enum_config_backend,
603 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
606 .label = "server role",
607 .type = P_ENUM,
608 .p_class = P_GLOBAL,
609 .offset = GLOBAL_VAR(ServerRole),
610 .special = NULL,
611 .enum_list = enum_server_role,
612 .flags = FLAG_BASIC | FLAG_ADVANCED,
615 {N_("Security Options"), P_SEP, P_SEPARATOR},
618 .label = "security",
619 .type = P_ENUM,
620 .p_class = P_GLOBAL,
621 .offset = GLOBAL_VAR(security),
622 .special = NULL,
623 .enum_list = enum_security,
624 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
627 .label = "auth methods",
628 .type = P_LIST,
629 .p_class = P_GLOBAL,
630 .offset = GLOBAL_VAR(AuthMethods),
631 .special = NULL,
632 .enum_list = NULL,
633 .flags = FLAG_ADVANCED,
636 .label = "encrypt passwords",
637 .type = P_BOOL,
638 .p_class = P_GLOBAL,
639 .offset = GLOBAL_VAR(bEncryptPasswords),
640 .special = NULL,
641 .enum_list = NULL,
642 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
645 .label = "client schannel",
646 .type = P_ENUM,
647 .p_class = P_GLOBAL,
648 .offset = GLOBAL_VAR(clientSchannel),
649 .special = NULL,
650 .enum_list = enum_bool_auto,
651 .flags = FLAG_BASIC | FLAG_ADVANCED,
654 .label = "server schannel",
655 .type = P_ENUM,
656 .p_class = P_GLOBAL,
657 .offset = GLOBAL_VAR(serverSchannel),
658 .special = NULL,
659 .enum_list = enum_bool_auto,
660 .flags = FLAG_BASIC | FLAG_ADVANCED,
663 .label = "allow trusted domains",
664 .type = P_BOOL,
665 .p_class = P_GLOBAL,
666 .offset = GLOBAL_VAR(bAllowTrustedDomains),
667 .special = NULL,
668 .enum_list = NULL,
669 .flags = FLAG_ADVANCED,
672 .label = "map to guest",
673 .type = P_ENUM,
674 .p_class = P_GLOBAL,
675 .offset = GLOBAL_VAR(map_to_guest),
676 .special = NULL,
677 .enum_list = enum_map_to_guest,
678 .flags = FLAG_ADVANCED,
681 .label = "null passwords",
682 .type = P_BOOL,
683 .p_class = P_GLOBAL,
684 .offset = GLOBAL_VAR(bNullPasswords),
685 .special = NULL,
686 .enum_list = NULL,
687 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
690 .label = "obey pam restrictions",
691 .type = P_BOOL,
692 .p_class = P_GLOBAL,
693 .offset = GLOBAL_VAR(bObeyPamRestrictions),
694 .special = NULL,
695 .enum_list = NULL,
696 .flags = FLAG_ADVANCED,
699 .label = "password server",
700 .type = P_STRING,
701 .p_class = P_GLOBAL,
702 .offset = GLOBAL_VAR(szPasswordServer),
703 .special = NULL,
704 .enum_list = NULL,
705 .flags = FLAG_ADVANCED | FLAG_WIZARD,
708 .label = "smb passwd file",
709 .type = P_STRING,
710 .p_class = P_GLOBAL,
711 .offset = GLOBAL_VAR(szSMBPasswdFile),
712 .special = NULL,
713 .enum_list = NULL,
714 .flags = FLAG_ADVANCED,
717 .label = "private dir",
718 .type = P_STRING,
719 .p_class = P_GLOBAL,
720 .offset = GLOBAL_VAR(szPrivateDir),
721 .special = NULL,
722 .enum_list = NULL,
723 .flags = FLAG_ADVANCED,
726 .label = "private directory",
727 .type = P_STRING,
728 .p_class = P_GLOBAL,
729 .offset = GLOBAL_VAR(szPrivateDir),
730 .special = NULL,
731 .enum_list = NULL,
732 .flags = FLAG_HIDE,
735 .label = "passdb backend",
736 .type = P_STRING,
737 .p_class = P_GLOBAL,
738 .offset = GLOBAL_VAR(passdb_backend),
739 .special = NULL,
740 .enum_list = NULL,
741 .flags = FLAG_ADVANCED | FLAG_WIZARD,
744 .label = "algorithmic rid base",
745 .type = P_INTEGER,
746 .p_class = P_GLOBAL,
747 .offset = GLOBAL_VAR(AlgorithmicRidBase),
748 .special = NULL,
749 .enum_list = NULL,
750 .flags = FLAG_ADVANCED,
753 .label = "root directory",
754 .type = P_STRING,
755 .p_class = P_GLOBAL,
756 .offset = GLOBAL_VAR(szRootdir),
757 .special = NULL,
758 .enum_list = NULL,
759 .flags = FLAG_ADVANCED,
762 .label = "root dir",
763 .type = P_STRING,
764 .p_class = P_GLOBAL,
765 .offset = GLOBAL_VAR(szRootdir),
766 .special = NULL,
767 .enum_list = NULL,
768 .flags = FLAG_HIDE,
771 .label = "root",
772 .type = P_STRING,
773 .p_class = P_GLOBAL,
774 .offset = GLOBAL_VAR(szRootdir),
775 .special = NULL,
776 .enum_list = NULL,
777 .flags = FLAG_HIDE,
780 .label = "guest account",
781 .type = P_STRING,
782 .p_class = P_GLOBAL,
783 .offset = GLOBAL_VAR(szGuestaccount),
784 .special = NULL,
785 .enum_list = NULL,
786 .flags = FLAG_BASIC | FLAG_ADVANCED,
789 .label = "enable privileges",
790 .type = P_BOOL,
791 .p_class = P_GLOBAL,
792 .offset = GLOBAL_VAR(bEnablePrivileges),
793 .special = NULL,
794 .enum_list = NULL,
795 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
799 .label = "pam password change",
800 .type = P_BOOL,
801 .p_class = P_GLOBAL,
802 .offset = GLOBAL_VAR(bPamPasswordChange),
803 .special = NULL,
804 .enum_list = NULL,
805 .flags = FLAG_ADVANCED,
808 .label = "passwd program",
809 .type = P_STRING,
810 .p_class = P_GLOBAL,
811 .offset = GLOBAL_VAR(szPasswdProgram),
812 .special = NULL,
813 .enum_list = NULL,
814 .flags = FLAG_ADVANCED,
817 .label = "passwd chat",
818 .type = P_STRING,
819 .p_class = P_GLOBAL,
820 .offset = GLOBAL_VAR(szPasswdChat),
821 .special = NULL,
822 .enum_list = NULL,
823 .flags = FLAG_ADVANCED,
826 .label = "passwd chat debug",
827 .type = P_BOOL,
828 .p_class = P_GLOBAL,
829 .offset = GLOBAL_VAR(bPasswdChatDebug),
830 .special = NULL,
831 .enum_list = NULL,
832 .flags = FLAG_ADVANCED,
835 .label = "passwd chat timeout",
836 .type = P_INTEGER,
837 .p_class = P_GLOBAL,
838 .offset = GLOBAL_VAR(iPasswdChatTimeout),
839 .special = NULL,
840 .enum_list = NULL,
841 .flags = FLAG_ADVANCED,
844 .label = "check password script",
845 .type = P_STRING,
846 .p_class = P_GLOBAL,
847 .offset = GLOBAL_VAR(szCheckPasswordScript),
848 .special = NULL,
849 .enum_list = NULL,
850 .flags = FLAG_ADVANCED,
853 .label = "username map",
854 .type = P_STRING,
855 .p_class = P_GLOBAL,
856 .offset = GLOBAL_VAR(szUsernameMap),
857 .special = NULL,
858 .enum_list = NULL,
859 .flags = FLAG_ADVANCED,
862 .label = "password level",
863 .type = P_INTEGER,
864 .p_class = P_GLOBAL,
865 .offset = GLOBAL_VAR(pwordlevel),
866 .special = NULL,
867 .enum_list = NULL,
868 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
871 .label = "username level",
872 .type = P_INTEGER,
873 .p_class = P_GLOBAL,
874 .offset = GLOBAL_VAR(unamelevel),
875 .special = NULL,
876 .enum_list = NULL,
877 .flags = FLAG_ADVANCED,
880 .label = "unix password sync",
881 .type = P_BOOL,
882 .p_class = P_GLOBAL,
883 .offset = GLOBAL_VAR(bUnixPasswdSync),
884 .special = NULL,
885 .enum_list = NULL,
886 .flags = FLAG_ADVANCED,
889 .label = "restrict anonymous",
890 .type = P_INTEGER,
891 .p_class = P_GLOBAL,
892 .offset = GLOBAL_VAR(restrict_anonymous),
893 .special = NULL,
894 .enum_list = NULL,
895 .flags = FLAG_ADVANCED,
898 .label = "lanman auth",
899 .type = P_BOOL,
900 .p_class = P_GLOBAL,
901 .offset = GLOBAL_VAR(bLanmanAuth),
902 .special = NULL,
903 .enum_list = NULL,
904 .flags = FLAG_ADVANCED,
907 .label = "ntlm auth",
908 .type = P_BOOL,
909 .p_class = P_GLOBAL,
910 .offset = GLOBAL_VAR(bNTLMAuth),
911 .special = NULL,
912 .enum_list = NULL,
913 .flags = FLAG_ADVANCED,
916 .label = "client NTLMv2 auth",
917 .type = P_BOOL,
918 .p_class = P_GLOBAL,
919 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
920 .special = NULL,
921 .enum_list = NULL,
922 .flags = FLAG_ADVANCED,
925 .label = "client lanman auth",
926 .type = P_BOOL,
927 .p_class = P_GLOBAL,
928 .offset = GLOBAL_VAR(bClientLanManAuth),
929 .special = NULL,
930 .enum_list = NULL,
931 .flags = FLAG_ADVANCED,
934 .label = "client plaintext auth",
935 .type = P_BOOL,
936 .p_class = P_GLOBAL,
937 .offset = GLOBAL_VAR(bClientPlaintextAuth),
938 .special = NULL,
939 .enum_list = NULL,
940 .flags = FLAG_ADVANCED,
943 .label = "client use spnego principal",
944 .type = P_BOOL,
945 .p_class = P_GLOBAL,
946 .offset = GLOBAL_VAR(client_use_spnego_principal),
947 .special = NULL,
948 .enum_list = NULL,
949 .flags = FLAG_ADVANCED,
952 .label = "username",
953 .type = P_STRING,
954 .p_class = P_LOCAL,
955 .offset = LOCAL_VAR(szUsername),
956 .special = NULL,
957 .enum_list = NULL,
958 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
961 .label = "user",
962 .type = P_STRING,
963 .p_class = P_LOCAL,
964 .offset = LOCAL_VAR(szUsername),
965 .special = NULL,
966 .enum_list = NULL,
967 .flags = FLAG_HIDE,
970 .label = "users",
971 .type = P_STRING,
972 .p_class = P_LOCAL,
973 .offset = LOCAL_VAR(szUsername),
974 .special = NULL,
975 .enum_list = NULL,
976 .flags = FLAG_HIDE,
979 .label = "invalid users",
980 .type = P_LIST,
981 .p_class = P_LOCAL,
982 .offset = LOCAL_VAR(szInvalidUsers),
983 .special = NULL,
984 .enum_list = NULL,
985 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
988 .label = "valid users",
989 .type = P_LIST,
990 .p_class = P_LOCAL,
991 .offset = LOCAL_VAR(szValidUsers),
992 .special = NULL,
993 .enum_list = NULL,
994 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
997 .label = "admin users",
998 .type = P_LIST,
999 .p_class = P_LOCAL,
1000 .offset = LOCAL_VAR(szAdminUsers),
1001 .special = NULL,
1002 .enum_list = NULL,
1003 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1006 .label = "read list",
1007 .type = P_LIST,
1008 .p_class = P_LOCAL,
1009 .offset = LOCAL_VAR(readlist),
1010 .special = NULL,
1011 .enum_list = NULL,
1012 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1015 .label = "write list",
1016 .type = P_LIST,
1017 .p_class = P_LOCAL,
1018 .offset = LOCAL_VAR(writelist),
1019 .special = NULL,
1020 .enum_list = NULL,
1021 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1024 .label = "printer admin",
1025 .type = P_LIST,
1026 .p_class = P_LOCAL,
1027 .offset = LOCAL_VAR(printer_admin),
1028 .special = NULL,
1029 .enum_list = NULL,
1030 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1033 .label = "force user",
1034 .type = P_STRING,
1035 .p_class = P_LOCAL,
1036 .offset = LOCAL_VAR(force_user),
1037 .special = NULL,
1038 .enum_list = NULL,
1039 .flags = FLAG_ADVANCED | FLAG_SHARE,
1042 .label = "force group",
1043 .type = P_STRING,
1044 .p_class = P_LOCAL,
1045 .offset = LOCAL_VAR(force_group),
1046 .special = NULL,
1047 .enum_list = NULL,
1048 .flags = FLAG_ADVANCED | FLAG_SHARE,
1051 .label = "group",
1052 .type = P_STRING,
1053 .p_class = P_LOCAL,
1054 .offset = LOCAL_VAR(force_group),
1055 .special = NULL,
1056 .enum_list = NULL,
1057 .flags = FLAG_ADVANCED,
1060 .label = "read only",
1061 .type = P_BOOL,
1062 .p_class = P_LOCAL,
1063 .offset = LOCAL_VAR(bRead_only),
1064 .special = NULL,
1065 .enum_list = NULL,
1066 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1069 .label = "write ok",
1070 .type = P_BOOLREV,
1071 .p_class = P_LOCAL,
1072 .offset = LOCAL_VAR(bRead_only),
1073 .special = NULL,
1074 .enum_list = NULL,
1075 .flags = FLAG_HIDE,
1078 .label = "writeable",
1079 .type = P_BOOLREV,
1080 .p_class = P_LOCAL,
1081 .offset = LOCAL_VAR(bRead_only),
1082 .special = NULL,
1083 .enum_list = NULL,
1084 .flags = FLAG_HIDE,
1087 .label = "writable",
1088 .type = P_BOOLREV,
1089 .p_class = P_LOCAL,
1090 .offset = LOCAL_VAR(bRead_only),
1091 .special = NULL,
1092 .enum_list = NULL,
1093 .flags = FLAG_HIDE,
1096 .label = "acl check permissions",
1097 .type = P_BOOL,
1098 .p_class = P_LOCAL,
1099 .offset = LOCAL_VAR(bAclCheckPermissions),
1100 .special = NULL,
1101 .enum_list = NULL,
1102 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1105 .label = "acl group control",
1106 .type = P_BOOL,
1107 .p_class = P_LOCAL,
1108 .offset = LOCAL_VAR(bAclGroupControl),
1109 .special = NULL,
1110 .enum_list = NULL,
1111 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1114 .label = "acl map full control",
1115 .type = P_BOOL,
1116 .p_class = P_LOCAL,
1117 .offset = LOCAL_VAR(bAclMapFullControl),
1118 .special = NULL,
1119 .enum_list = NULL,
1120 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1123 .label = "create mask",
1124 .type = P_OCTAL,
1125 .p_class = P_LOCAL,
1126 .offset = LOCAL_VAR(iCreate_mask),
1127 .special = NULL,
1128 .enum_list = NULL,
1129 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1132 .label = "create mode",
1133 .type = P_OCTAL,
1134 .p_class = P_LOCAL,
1135 .offset = LOCAL_VAR(iCreate_mask),
1136 .special = NULL,
1137 .enum_list = NULL,
1138 .flags = FLAG_HIDE,
1141 .label = "force create mode",
1142 .type = P_OCTAL,
1143 .p_class = P_LOCAL,
1144 .offset = LOCAL_VAR(iCreate_force_mode),
1145 .special = NULL,
1146 .enum_list = NULL,
1147 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1150 .label = "security mask",
1151 .type = P_OCTAL,
1152 .p_class = P_LOCAL,
1153 .offset = LOCAL_VAR(iSecurity_mask),
1154 .special = NULL,
1155 .enum_list = NULL,
1156 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1159 .label = "force security mode",
1160 .type = P_OCTAL,
1161 .p_class = P_LOCAL,
1162 .offset = LOCAL_VAR(iSecurity_force_mode),
1163 .special = NULL,
1164 .enum_list = NULL,
1165 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1168 .label = "directory mask",
1169 .type = P_OCTAL,
1170 .p_class = P_LOCAL,
1171 .offset = LOCAL_VAR(iDir_mask),
1172 .special = NULL,
1173 .enum_list = NULL,
1174 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1177 .label = "directory mode",
1178 .type = P_OCTAL,
1179 .p_class = P_LOCAL,
1180 .offset = LOCAL_VAR(iDir_mask),
1181 .special = NULL,
1182 .enum_list = NULL,
1183 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1186 .label = "force directory mode",
1187 .type = P_OCTAL,
1188 .p_class = P_LOCAL,
1189 .offset = LOCAL_VAR(iDir_force_mode),
1190 .special = NULL,
1191 .enum_list = NULL,
1192 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1195 .label = "directory security mask",
1196 .type = P_OCTAL,
1197 .p_class = P_LOCAL,
1198 .offset = LOCAL_VAR(iDir_Security_mask),
1199 .special = NULL,
1200 .enum_list = NULL,
1201 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1204 .label = "force directory security mode",
1205 .type = P_OCTAL,
1206 .p_class = P_LOCAL,
1207 .offset = LOCAL_VAR(iDir_Security_force_mode),
1208 .special = NULL,
1209 .enum_list = NULL,
1210 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1213 .label = "force unknown acl user",
1214 .type = P_BOOL,
1215 .p_class = P_LOCAL,
1216 .offset = LOCAL_VAR(bForceUnknownAclUser),
1217 .special = NULL,
1218 .enum_list = NULL,
1219 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1222 .label = "inherit permissions",
1223 .type = P_BOOL,
1224 .p_class = P_LOCAL,
1225 .offset = LOCAL_VAR(bInheritPerms),
1226 .special = NULL,
1227 .enum_list = NULL,
1228 .flags = FLAG_ADVANCED | FLAG_SHARE,
1231 .label = "inherit acls",
1232 .type = P_BOOL,
1233 .p_class = P_LOCAL,
1234 .offset = LOCAL_VAR(bInheritACLS),
1235 .special = NULL,
1236 .enum_list = NULL,
1237 .flags = FLAG_ADVANCED | FLAG_SHARE,
1240 .label = "inherit owner",
1241 .type = P_BOOL,
1242 .p_class = P_LOCAL,
1243 .offset = LOCAL_VAR(bInheritOwner),
1244 .special = NULL,
1245 .enum_list = NULL,
1246 .flags = FLAG_ADVANCED | FLAG_SHARE,
1249 .label = "guest only",
1250 .type = P_BOOL,
1251 .p_class = P_LOCAL,
1252 .offset = LOCAL_VAR(bGuest_only),
1253 .special = NULL,
1254 .enum_list = NULL,
1255 .flags = FLAG_ADVANCED | FLAG_SHARE,
1258 .label = "only guest",
1259 .type = P_BOOL,
1260 .p_class = P_LOCAL,
1261 .offset = LOCAL_VAR(bGuest_only),
1262 .special = NULL,
1263 .enum_list = NULL,
1264 .flags = FLAG_HIDE,
1267 .label = "administrative share",
1268 .type = P_BOOL,
1269 .p_class = P_LOCAL,
1270 .offset = LOCAL_VAR(bAdministrative_share),
1271 .special = NULL,
1272 .enum_list = NULL,
1273 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1277 .label = "guest ok",
1278 .type = P_BOOL,
1279 .p_class = P_LOCAL,
1280 .offset = LOCAL_VAR(bGuest_ok),
1281 .special = NULL,
1282 .enum_list = NULL,
1283 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1286 .label = "public",
1287 .type = P_BOOL,
1288 .p_class = P_LOCAL,
1289 .offset = LOCAL_VAR(bGuest_ok),
1290 .special = NULL,
1291 .enum_list = NULL,
1292 .flags = FLAG_HIDE,
1295 .label = "only user",
1296 .type = P_BOOL,
1297 .p_class = P_LOCAL,
1298 .offset = LOCAL_VAR(bOnlyUser),
1299 .special = NULL,
1300 .enum_list = NULL,
1301 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1304 .label = "hosts allow",
1305 .type = P_LIST,
1306 .p_class = P_LOCAL,
1307 .offset = LOCAL_VAR(szHostsallow),
1308 .special = NULL,
1309 .enum_list = NULL,
1310 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1313 .label = "allow hosts",
1314 .type = P_LIST,
1315 .p_class = P_LOCAL,
1316 .offset = LOCAL_VAR(szHostsallow),
1317 .special = NULL,
1318 .enum_list = NULL,
1319 .flags = FLAG_HIDE,
1322 .label = "hosts deny",
1323 .type = P_LIST,
1324 .p_class = P_LOCAL,
1325 .offset = LOCAL_VAR(szHostsdeny),
1326 .special = NULL,
1327 .enum_list = NULL,
1328 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1331 .label = "deny hosts",
1332 .type = P_LIST,
1333 .p_class = P_LOCAL,
1334 .offset = LOCAL_VAR(szHostsdeny),
1335 .special = NULL,
1336 .enum_list = NULL,
1337 .flags = FLAG_HIDE,
1340 .label = "preload modules",
1341 .type = P_LIST,
1342 .p_class = P_GLOBAL,
1343 .offset = GLOBAL_VAR(szPreloadModules),
1344 .special = NULL,
1345 .enum_list = NULL,
1346 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1349 .label = "dedicated keytab file",
1350 .type = P_STRING,
1351 .p_class = P_GLOBAL,
1352 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1353 .special = NULL,
1354 .enum_list = NULL,
1355 .flags = FLAG_ADVANCED,
1358 .label = "kerberos method",
1359 .type = P_ENUM,
1360 .p_class = P_GLOBAL,
1361 .offset = GLOBAL_VAR(iKerberosMethod),
1362 .special = NULL,
1363 .enum_list = enum_kerberos_method,
1364 .flags = FLAG_ADVANCED,
1367 .label = "map untrusted to domain",
1368 .type = P_BOOL,
1369 .p_class = P_GLOBAL,
1370 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1371 .special = NULL,
1372 .enum_list = NULL,
1373 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1377 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1380 .label = "log level",
1381 .type = P_STRING,
1382 .p_class = P_GLOBAL,
1383 .offset = GLOBAL_VAR(szLogLevel),
1384 .special = handle_debug_list,
1385 .enum_list = NULL,
1386 .flags = FLAG_ADVANCED,
1389 .label = "debuglevel",
1390 .type = P_STRING,
1391 .p_class = P_GLOBAL,
1392 .offset = GLOBAL_VAR(szLogLevel),
1393 .special = handle_debug_list,
1394 .enum_list = NULL,
1395 .flags = FLAG_HIDE,
1398 .label = "syslog",
1399 .type = P_INTEGER,
1400 .p_class = P_GLOBAL,
1401 .offset = GLOBAL_VAR(syslog),
1402 .special = NULL,
1403 .enum_list = NULL,
1404 .flags = FLAG_ADVANCED,
1407 .label = "syslog only",
1408 .type = P_BOOL,
1409 .p_class = P_GLOBAL,
1410 .offset = GLOBAL_VAR(bSyslogOnly),
1411 .special = NULL,
1412 .enum_list = NULL,
1413 .flags = FLAG_ADVANCED,
1416 .label = "log file",
1417 .type = P_STRING,
1418 .p_class = P_GLOBAL,
1419 .offset = GLOBAL_VAR(logfile),
1420 .special = NULL,
1421 .enum_list = NULL,
1422 .flags = FLAG_ADVANCED,
1425 .label = "max log size",
1426 .type = P_BYTES,
1427 .p_class = P_GLOBAL,
1428 .offset = GLOBAL_VAR(max_log_size),
1429 .special = NULL,
1430 .enum_list = NULL,
1431 .flags = FLAG_ADVANCED,
1434 .label = "debug timestamp",
1435 .type = P_BOOL,
1436 .p_class = P_GLOBAL,
1437 .offset = GLOBAL_VAR(bTimestampLogs),
1438 .special = NULL,
1439 .enum_list = NULL,
1440 .flags = FLAG_ADVANCED,
1443 .label = "timestamp logs",
1444 .type = P_BOOL,
1445 .p_class = P_GLOBAL,
1446 .offset = GLOBAL_VAR(bTimestampLogs),
1447 .special = NULL,
1448 .enum_list = NULL,
1449 .flags = FLAG_ADVANCED,
1452 .label = "debug prefix timestamp",
1453 .type = P_BOOL,
1454 .p_class = P_GLOBAL,
1455 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1456 .special = NULL,
1457 .enum_list = NULL,
1458 .flags = FLAG_ADVANCED,
1461 .label = "debug hires timestamp",
1462 .type = P_BOOL,
1463 .p_class = P_GLOBAL,
1464 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1465 .special = NULL,
1466 .enum_list = NULL,
1467 .flags = FLAG_ADVANCED,
1470 .label = "debug pid",
1471 .type = P_BOOL,
1472 .p_class = P_GLOBAL,
1473 .offset = GLOBAL_VAR(bDebugPid),
1474 .special = NULL,
1475 .enum_list = NULL,
1476 .flags = FLAG_ADVANCED,
1479 .label = "debug uid",
1480 .type = P_BOOL,
1481 .p_class = P_GLOBAL,
1482 .offset = GLOBAL_VAR(bDebugUid),
1483 .special = NULL,
1484 .enum_list = NULL,
1485 .flags = FLAG_ADVANCED,
1488 .label = "debug class",
1489 .type = P_BOOL,
1490 .p_class = P_GLOBAL,
1491 .offset = GLOBAL_VAR(bDebugClass),
1492 .special = NULL,
1493 .enum_list = NULL,
1494 .flags = FLAG_ADVANCED,
1497 .label = "enable core files",
1498 .type = P_BOOL,
1499 .p_class = P_GLOBAL,
1500 .offset = GLOBAL_VAR(bEnableCoreFiles),
1501 .special = NULL,
1502 .enum_list = NULL,
1503 .flags = FLAG_ADVANCED,
1506 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1509 .label = "allocation roundup size",
1510 .type = P_BYTES,
1511 .p_class = P_LOCAL,
1512 .offset = LOCAL_VAR(iallocation_roundup_size),
1513 .special = NULL,
1514 .enum_list = NULL,
1515 .flags = FLAG_ADVANCED,
1518 .label = "aio read size",
1519 .type = P_BYTES,
1520 .p_class = P_LOCAL,
1521 .offset = LOCAL_VAR(iAioReadSize),
1522 .special = NULL,
1523 .enum_list = NULL,
1524 .flags = FLAG_ADVANCED,
1527 .label = "aio write size",
1528 .type = P_BYTES,
1529 .p_class = P_LOCAL,
1530 .offset = LOCAL_VAR(iAioWriteSize),
1531 .special = NULL,
1532 .enum_list = NULL,
1533 .flags = FLAG_ADVANCED,
1536 .label = "aio write behind",
1537 .type = P_STRING,
1538 .p_class = P_LOCAL,
1539 .offset = LOCAL_VAR(szAioWriteBehind),
1540 .special = NULL,
1541 .enum_list = NULL,
1542 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1545 .label = "smb ports",
1546 .type = P_STRING,
1547 .p_class = P_GLOBAL,
1548 .offset = GLOBAL_VAR(smb_ports),
1549 .special = NULL,
1550 .enum_list = NULL,
1551 .flags = FLAG_ADVANCED,
1554 .label = "large readwrite",
1555 .type = P_BOOL,
1556 .p_class = P_GLOBAL,
1557 .offset = GLOBAL_VAR(bLargeReadwrite),
1558 .special = NULL,
1559 .enum_list = NULL,
1560 .flags = FLAG_ADVANCED,
1563 .label = "server max protocol",
1564 .type = P_ENUM,
1565 .p_class = P_GLOBAL,
1566 .offset = GLOBAL_VAR(srv_maxprotocol),
1567 .special = NULL,
1568 .enum_list = enum_protocol,
1569 .flags = FLAG_ADVANCED,
1572 .label = "max protocol",
1573 .type = P_ENUM,
1574 .p_class = P_GLOBAL,
1575 .offset = GLOBAL_VAR(srv_maxprotocol),
1576 .special = NULL,
1577 .enum_list = enum_protocol,
1578 .flags = FLAG_ADVANCED,
1581 .label = "protocol",
1582 .type = P_ENUM,
1583 .p_class = P_GLOBAL,
1584 .offset = GLOBAL_VAR(srv_maxprotocol),
1585 .special = NULL,
1586 .enum_list = enum_protocol,
1587 .flags = FLAG_ADVANCED,
1590 .label = "server min protocol",
1591 .type = P_ENUM,
1592 .p_class = P_GLOBAL,
1593 .offset = GLOBAL_VAR(srv_minprotocol),
1594 .special = NULL,
1595 .enum_list = enum_protocol,
1596 .flags = FLAG_ADVANCED,
1599 .label = "min protocol",
1600 .type = P_ENUM,
1601 .p_class = P_GLOBAL,
1602 .offset = GLOBAL_VAR(srv_minprotocol),
1603 .special = NULL,
1604 .enum_list = enum_protocol,
1605 .flags = FLAG_ADVANCED,
1608 .label = "min receivefile size",
1609 .type = P_BYTES,
1610 .p_class = P_GLOBAL,
1611 .offset = GLOBAL_VAR(iminreceivefile),
1612 .special = NULL,
1613 .enum_list = NULL,
1614 .flags = FLAG_ADVANCED,
1617 .label = "read raw",
1618 .type = P_BOOL,
1619 .p_class = P_GLOBAL,
1620 .offset = GLOBAL_VAR(bReadRaw),
1621 .special = NULL,
1622 .enum_list = NULL,
1623 .flags = FLAG_ADVANCED,
1626 .label = "write raw",
1627 .type = P_BOOL,
1628 .p_class = P_GLOBAL,
1629 .offset = GLOBAL_VAR(bWriteRaw),
1630 .special = NULL,
1631 .enum_list = NULL,
1632 .flags = FLAG_ADVANCED,
1635 .label = "disable netbios",
1636 .type = P_BOOL,
1637 .p_class = P_GLOBAL,
1638 .offset = GLOBAL_VAR(bDisableNetbios),
1639 .special = NULL,
1640 .enum_list = NULL,
1641 .flags = FLAG_ADVANCED,
1644 .label = "reset on zero vc",
1645 .type = P_BOOL,
1646 .p_class = P_GLOBAL,
1647 .offset = GLOBAL_VAR(bResetOnZeroVC),
1648 .special = NULL,
1649 .enum_list = NULL,
1650 .flags = FLAG_ADVANCED,
1653 .label = "log writeable files on exit",
1654 .type = P_BOOL,
1655 .p_class = P_GLOBAL,
1656 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1657 .special = NULL,
1658 .enum_list = NULL,
1659 .flags = FLAG_ADVANCED,
1662 .label = "acl compatibility",
1663 .type = P_ENUM,
1664 .p_class = P_GLOBAL,
1665 .offset = GLOBAL_VAR(iAclCompat),
1666 .special = NULL,
1667 .enum_list = enum_acl_compat_vals,
1668 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1671 .label = "defer sharing violations",
1672 .type = P_BOOL,
1673 .p_class = P_GLOBAL,
1674 .offset = GLOBAL_VAR(bDeferSharingViolations),
1675 .special = NULL,
1676 .enum_list = NULL,
1677 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1680 .label = "ea support",
1681 .type = P_BOOL,
1682 .p_class = P_LOCAL,
1683 .offset = LOCAL_VAR(bEASupport),
1684 .special = NULL,
1685 .enum_list = NULL,
1686 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1689 .label = "nt acl support",
1690 .type = P_BOOL,
1691 .p_class = P_LOCAL,
1692 .offset = LOCAL_VAR(bNTAclSupport),
1693 .special = NULL,
1694 .enum_list = NULL,
1695 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1698 .label = "nt pipe support",
1699 .type = P_BOOL,
1700 .p_class = P_GLOBAL,
1701 .offset = GLOBAL_VAR(bNTPipeSupport),
1702 .special = NULL,
1703 .enum_list = NULL,
1704 .flags = FLAG_ADVANCED,
1707 .label = "nt status support",
1708 .type = P_BOOL,
1709 .p_class = P_GLOBAL,
1710 .offset = GLOBAL_VAR(bNTStatusSupport),
1711 .special = NULL,
1712 .enum_list = NULL,
1713 .flags = FLAG_ADVANCED,
1716 .label = "profile acls",
1717 .type = P_BOOL,
1718 .p_class = P_LOCAL,
1719 .offset = LOCAL_VAR(bProfileAcls),
1720 .special = NULL,
1721 .enum_list = NULL,
1722 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1725 .label = "map acl inherit",
1726 .type = P_BOOL,
1727 .p_class = P_LOCAL,
1728 .offset = LOCAL_VAR(bMap_acl_inherit),
1729 .special = NULL,
1730 .enum_list = NULL,
1731 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1734 .label = "afs share",
1735 .type = P_BOOL,
1736 .p_class = P_LOCAL,
1737 .offset = LOCAL_VAR(bAfs_Share),
1738 .special = NULL,
1739 .enum_list = NULL,
1740 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1743 .label = "max mux",
1744 .type = P_INTEGER,
1745 .p_class = P_GLOBAL,
1746 .offset = GLOBAL_VAR(max_mux),
1747 .special = NULL,
1748 .enum_list = NULL,
1749 .flags = FLAG_ADVANCED,
1752 .label = "max xmit",
1753 .type = P_BYTES,
1754 .p_class = P_GLOBAL,
1755 .offset = GLOBAL_VAR(max_xmit),
1756 .special = NULL,
1757 .enum_list = NULL,
1758 .flags = FLAG_ADVANCED,
1761 .label = "name resolve order",
1762 .type = P_STRING,
1763 .p_class = P_GLOBAL,
1764 .offset = GLOBAL_VAR(szNameResolveOrder),
1765 .special = NULL,
1766 .enum_list = NULL,
1767 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1770 .label = "max ttl",
1771 .type = P_INTEGER,
1772 .p_class = P_GLOBAL,
1773 .offset = GLOBAL_VAR(max_ttl),
1774 .special = NULL,
1775 .enum_list = NULL,
1776 .flags = FLAG_ADVANCED,
1779 .label = "max wins ttl",
1780 .type = P_INTEGER,
1781 .p_class = P_GLOBAL,
1782 .offset = GLOBAL_VAR(max_wins_ttl),
1783 .special = NULL,
1784 .enum_list = NULL,
1785 .flags = FLAG_ADVANCED,
1788 .label = "min wins ttl",
1789 .type = P_INTEGER,
1790 .p_class = P_GLOBAL,
1791 .offset = GLOBAL_VAR(min_wins_ttl),
1792 .special = NULL,
1793 .enum_list = NULL,
1794 .flags = FLAG_ADVANCED,
1797 .label = "time server",
1798 .type = P_BOOL,
1799 .p_class = P_GLOBAL,
1800 .offset = GLOBAL_VAR(bTimeServer),
1801 .special = NULL,
1802 .enum_list = NULL,
1803 .flags = FLAG_ADVANCED,
1806 .label = "unix extensions",
1807 .type = P_BOOL,
1808 .p_class = P_GLOBAL,
1809 .offset = GLOBAL_VAR(bUnixExtensions),
1810 .special = NULL,
1811 .enum_list = NULL,
1812 .flags = FLAG_ADVANCED,
1815 .label = "use spnego",
1816 .type = P_BOOL,
1817 .p_class = P_GLOBAL,
1818 .offset = GLOBAL_VAR(bUseSpnego),
1819 .special = NULL,
1820 .enum_list = NULL,
1821 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1824 .label = "client signing",
1825 .type = P_ENUM,
1826 .p_class = P_GLOBAL,
1827 .offset = GLOBAL_VAR(client_signing),
1828 .special = NULL,
1829 .enum_list = enum_smb_signing_vals,
1830 .flags = FLAG_ADVANCED,
1833 .label = "server signing",
1834 .type = P_ENUM,
1835 .p_class = P_GLOBAL,
1836 .offset = GLOBAL_VAR(server_signing),
1837 .special = NULL,
1838 .enum_list = enum_smb_signing_vals,
1839 .flags = FLAG_ADVANCED,
1842 .label = "smb encrypt",
1843 .type = P_ENUM,
1844 .p_class = P_LOCAL,
1845 .offset = LOCAL_VAR(ismb_encrypt),
1846 .special = NULL,
1847 .enum_list = enum_smb_signing_vals,
1848 .flags = FLAG_ADVANCED,
1851 .label = "client use spnego",
1852 .type = P_BOOL,
1853 .p_class = P_GLOBAL,
1854 .offset = GLOBAL_VAR(bClientUseSpnego),
1855 .special = NULL,
1856 .enum_list = NULL,
1857 .flags = FLAG_ADVANCED,
1860 .label = "client ldap sasl wrapping",
1861 .type = P_ENUM,
1862 .p_class = P_GLOBAL,
1863 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1864 .special = NULL,
1865 .enum_list = enum_ldap_sasl_wrapping,
1866 .flags = FLAG_ADVANCED,
1869 .label = "enable asu support",
1870 .type = P_BOOL,
1871 .p_class = P_GLOBAL,
1872 .offset = GLOBAL_VAR(bASUSupport),
1873 .special = NULL,
1874 .enum_list = NULL,
1875 .flags = FLAG_ADVANCED,
1878 .label = "svcctl list",
1879 .type = P_LIST,
1880 .p_class = P_GLOBAL,
1881 .offset = GLOBAL_VAR(szServicesList),
1882 .special = NULL,
1883 .enum_list = NULL,
1884 .flags = FLAG_ADVANCED,
1887 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1890 .label = "block size",
1891 .type = P_BYTES,
1892 .p_class = P_LOCAL,
1893 .offset = LOCAL_VAR(iBlock_size),
1894 .special = NULL,
1895 .enum_list = NULL,
1896 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1899 .label = "deadtime",
1900 .type = P_INTEGER,
1901 .p_class = P_GLOBAL,
1902 .offset = GLOBAL_VAR(deadtime),
1903 .special = NULL,
1904 .enum_list = NULL,
1905 .flags = FLAG_ADVANCED,
1908 .label = "getwd cache",
1909 .type = P_BOOL,
1910 .p_class = P_GLOBAL,
1911 .offset = GLOBAL_VAR(getwd_cache),
1912 .special = NULL,
1913 .enum_list = NULL,
1914 .flags = FLAG_ADVANCED,
1917 .label = "keepalive",
1918 .type = P_INTEGER,
1919 .p_class = P_GLOBAL,
1920 .offset = GLOBAL_VAR(iKeepalive),
1921 .special = NULL,
1922 .enum_list = NULL,
1923 .flags = FLAG_ADVANCED,
1926 .label = "change notify",
1927 .type = P_BOOL,
1928 .p_class = P_LOCAL,
1929 .offset = LOCAL_VAR(bChangeNotify),
1930 .special = NULL,
1931 .enum_list = NULL,
1932 .flags = FLAG_ADVANCED | FLAG_SHARE,
1935 .label = "directory name cache size",
1936 .type = P_INTEGER,
1937 .p_class = P_LOCAL,
1938 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
1939 .special = NULL,
1940 .enum_list = NULL,
1941 .flags = FLAG_ADVANCED | FLAG_SHARE,
1944 .label = "kernel change notify",
1945 .type = P_BOOL,
1946 .p_class = P_LOCAL,
1947 .offset = LOCAL_VAR(bKernelChangeNotify),
1948 .special = NULL,
1949 .enum_list = NULL,
1950 .flags = FLAG_ADVANCED | FLAG_SHARE,
1953 .label = "lpq cache time",
1954 .type = P_INTEGER,
1955 .p_class = P_GLOBAL,
1956 .offset = GLOBAL_VAR(lpqcachetime),
1957 .special = NULL,
1958 .enum_list = NULL,
1959 .flags = FLAG_ADVANCED,
1962 .label = "max smbd processes",
1963 .type = P_INTEGER,
1964 .p_class = P_GLOBAL,
1965 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
1966 .special = NULL,
1967 .enum_list = NULL,
1968 .flags = FLAG_ADVANCED,
1971 .label = "max connections",
1972 .type = P_INTEGER,
1973 .p_class = P_LOCAL,
1974 .offset = LOCAL_VAR(iMaxConnections),
1975 .special = NULL,
1976 .enum_list = NULL,
1977 .flags = FLAG_ADVANCED | FLAG_SHARE,
1980 .label = "paranoid server security",
1981 .type = P_BOOL,
1982 .p_class = P_GLOBAL,
1983 .offset = GLOBAL_VAR(paranoid_server_security),
1984 .special = NULL,
1985 .enum_list = NULL,
1986 .flags = FLAG_ADVANCED,
1989 .label = "max disk size",
1990 .type = P_BYTES,
1991 .p_class = P_GLOBAL,
1992 .offset = GLOBAL_VAR(maxdisksize),
1993 .special = NULL,
1994 .enum_list = NULL,
1995 .flags = FLAG_ADVANCED,
1998 .label = "max open files",
1999 .type = P_INTEGER,
2000 .p_class = P_GLOBAL,
2001 .offset = GLOBAL_VAR(max_open_files),
2002 .special = NULL,
2003 .enum_list = NULL,
2004 .flags = FLAG_ADVANCED,
2007 .label = "min print space",
2008 .type = P_INTEGER,
2009 .p_class = P_LOCAL,
2010 .offset = LOCAL_VAR(iMinPrintSpace),
2011 .special = NULL,
2012 .enum_list = NULL,
2013 .flags = FLAG_ADVANCED | FLAG_PRINT,
2016 .label = "socket options",
2017 .type = P_STRING,
2018 .p_class = P_GLOBAL,
2019 .offset = GLOBAL_VAR(socket_options),
2020 .special = NULL,
2021 .enum_list = NULL,
2022 .flags = FLAG_ADVANCED,
2025 .label = "strict allocate",
2026 .type = P_BOOL,
2027 .p_class = P_LOCAL,
2028 .offset = LOCAL_VAR(bStrictAllocate),
2029 .special = NULL,
2030 .enum_list = NULL,
2031 .flags = FLAG_ADVANCED | FLAG_SHARE,
2034 .label = "strict sync",
2035 .type = P_BOOL,
2036 .p_class = P_LOCAL,
2037 .offset = LOCAL_VAR(bStrictSync),
2038 .special = NULL,
2039 .enum_list = NULL,
2040 .flags = FLAG_ADVANCED | FLAG_SHARE,
2043 .label = "sync always",
2044 .type = P_BOOL,
2045 .p_class = P_LOCAL,
2046 .offset = LOCAL_VAR(bSyncAlways),
2047 .special = NULL,
2048 .enum_list = NULL,
2049 .flags = FLAG_ADVANCED | FLAG_SHARE,
2052 .label = "use mmap",
2053 .type = P_BOOL,
2054 .p_class = P_GLOBAL,
2055 .offset = GLOBAL_VAR(bUseMmap),
2056 .special = NULL,
2057 .enum_list = NULL,
2058 .flags = FLAG_ADVANCED,
2061 .label = "use sendfile",
2062 .type = P_BOOL,
2063 .p_class = P_LOCAL,
2064 .offset = LOCAL_VAR(bUseSendfile),
2065 .special = NULL,
2066 .enum_list = NULL,
2067 .flags = FLAG_ADVANCED | FLAG_SHARE,
2070 .label = "hostname lookups",
2071 .type = P_BOOL,
2072 .p_class = P_GLOBAL,
2073 .offset = GLOBAL_VAR(bHostnameLookups),
2074 .special = NULL,
2075 .enum_list = NULL,
2076 .flags = FLAG_ADVANCED,
2079 .label = "write cache size",
2080 .type = P_BYTES,
2081 .p_class = P_LOCAL,
2082 .offset = LOCAL_VAR(iWriteCacheSize),
2083 .special = NULL,
2084 .enum_list = NULL,
2085 .flags = FLAG_ADVANCED | FLAG_SHARE,
2088 .label = "name cache timeout",
2089 .type = P_INTEGER,
2090 .p_class = P_GLOBAL,
2091 .offset = GLOBAL_VAR(name_cache_timeout),
2092 .special = NULL,
2093 .enum_list = NULL,
2094 .flags = FLAG_ADVANCED,
2097 .label = "ctdbd socket",
2098 .type = P_STRING,
2099 .p_class = P_GLOBAL,
2100 .offset = GLOBAL_VAR(ctdbdSocket),
2101 .special = NULL,
2102 .enum_list = NULL,
2103 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2106 .label = "cluster addresses",
2107 .type = P_LIST,
2108 .p_class = P_GLOBAL,
2109 .offset = GLOBAL_VAR(szClusterAddresses),
2110 .special = NULL,
2111 .enum_list = NULL,
2112 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2115 .label = "clustering",
2116 .type = P_BOOL,
2117 .p_class = P_GLOBAL,
2118 .offset = GLOBAL_VAR(clustering),
2119 .special = NULL,
2120 .enum_list = NULL,
2121 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2124 .label = "ctdb timeout",
2125 .type = P_INTEGER,
2126 .p_class = P_GLOBAL,
2127 .offset = GLOBAL_VAR(ctdb_timeout),
2128 .special = NULL,
2129 .enum_list = NULL,
2130 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2133 .label = "ctdb locktime warn threshold",
2134 .type = P_INTEGER,
2135 .p_class = P_GLOBAL,
2136 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2137 .special = NULL,
2138 .enum_list = NULL,
2139 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2142 .label = "smb2 max read",
2143 .type = P_BYTES,
2144 .p_class = P_GLOBAL,
2145 .offset = GLOBAL_VAR(ismb2_max_read),
2146 .special = NULL,
2147 .enum_list = NULL,
2148 .flags = FLAG_ADVANCED,
2151 .label = "smb2 max write",
2152 .type = P_BYTES,
2153 .p_class = P_GLOBAL,
2154 .offset = GLOBAL_VAR(ismb2_max_write),
2155 .special = NULL,
2156 .enum_list = NULL,
2157 .flags = FLAG_ADVANCED,
2160 .label = "smb2 max trans",
2161 .type = P_BYTES,
2162 .p_class = P_GLOBAL,
2163 .offset = GLOBAL_VAR(ismb2_max_trans),
2164 .special = NULL,
2165 .enum_list = NULL,
2166 .flags = FLAG_ADVANCED,
2169 .label = "smb2 max credits",
2170 .type = P_INTEGER,
2171 .p_class = P_GLOBAL,
2172 .offset = GLOBAL_VAR(ismb2_max_credits),
2173 .special = NULL,
2174 .enum_list = NULL,
2175 .flags = FLAG_ADVANCED,
2178 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2181 .label = "max reported print jobs",
2182 .type = P_INTEGER,
2183 .p_class = P_LOCAL,
2184 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2185 .special = NULL,
2186 .enum_list = NULL,
2187 .flags = FLAG_ADVANCED | FLAG_PRINT,
2190 .label = "max print jobs",
2191 .type = P_INTEGER,
2192 .p_class = P_LOCAL,
2193 .offset = LOCAL_VAR(iMaxPrintJobs),
2194 .special = NULL,
2195 .enum_list = NULL,
2196 .flags = FLAG_ADVANCED | FLAG_PRINT,
2199 .label = "load printers",
2200 .type = P_BOOL,
2201 .p_class = P_GLOBAL,
2202 .offset = GLOBAL_VAR(bLoadPrinters),
2203 .special = NULL,
2204 .enum_list = NULL,
2205 .flags = FLAG_ADVANCED | FLAG_PRINT,
2208 .label = "printcap cache time",
2209 .type = P_INTEGER,
2210 .p_class = P_GLOBAL,
2211 .offset = GLOBAL_VAR(PrintcapCacheTime),
2212 .special = NULL,
2213 .enum_list = NULL,
2214 .flags = FLAG_ADVANCED | FLAG_PRINT,
2217 .label = "printcap name",
2218 .type = P_STRING,
2219 .p_class = P_GLOBAL,
2220 .offset = GLOBAL_VAR(szPrintcapname),
2221 .special = NULL,
2222 .enum_list = NULL,
2223 .flags = FLAG_ADVANCED | FLAG_PRINT,
2226 .label = "printcap",
2227 .type = P_STRING,
2228 .p_class = P_GLOBAL,
2229 .offset = GLOBAL_VAR(szPrintcapname),
2230 .special = NULL,
2231 .enum_list = NULL,
2232 .flags = FLAG_HIDE,
2235 .label = "printable",
2236 .type = P_BOOL,
2237 .p_class = P_LOCAL,
2238 .offset = LOCAL_VAR(bPrint_ok),
2239 .special = NULL,
2240 .enum_list = NULL,
2241 .flags = FLAG_ADVANCED | FLAG_PRINT,
2244 .label = "print notify backchannel",
2245 .type = P_BOOL,
2246 .p_class = P_LOCAL,
2247 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2248 .special = NULL,
2249 .enum_list = NULL,
2250 .flags = FLAG_ADVANCED,
2253 .label = "print ok",
2254 .type = P_BOOL,
2255 .p_class = P_LOCAL,
2256 .offset = LOCAL_VAR(bPrint_ok),
2257 .special = NULL,
2258 .enum_list = NULL,
2259 .flags = FLAG_HIDE,
2262 .label = "printing",
2263 .type = P_ENUM,
2264 .p_class = P_LOCAL,
2265 .offset = LOCAL_VAR(iPrinting),
2266 .special = handle_printing,
2267 .enum_list = enum_printing,
2268 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2271 .label = "cups options",
2272 .type = P_STRING,
2273 .p_class = P_LOCAL,
2274 .offset = LOCAL_VAR(szCupsOptions),
2275 .special = NULL,
2276 .enum_list = NULL,
2277 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2280 .label = "cups server",
2281 .type = P_STRING,
2282 .p_class = P_GLOBAL,
2283 .offset = GLOBAL_VAR(szCupsServer),
2284 .special = NULL,
2285 .enum_list = NULL,
2286 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2289 .label = "cups encrypt",
2290 .type = P_ENUM,
2291 .p_class = P_GLOBAL,
2292 .offset = GLOBAL_VAR(CupsEncrypt),
2293 .special = NULL,
2294 .enum_list = enum_bool_auto,
2295 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2299 .label = "cups connection timeout",
2300 .type = P_INTEGER,
2301 .p_class = P_GLOBAL,
2302 .offset = GLOBAL_VAR(cups_connection_timeout),
2303 .special = NULL,
2304 .enum_list = NULL,
2305 .flags = FLAG_ADVANCED,
2308 .label = "iprint server",
2309 .type = P_STRING,
2310 .p_class = P_GLOBAL,
2311 .offset = GLOBAL_VAR(szIPrintServer),
2312 .special = NULL,
2313 .enum_list = NULL,
2314 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2317 .label = "print command",
2318 .type = P_STRING,
2319 .p_class = P_LOCAL,
2320 .offset = LOCAL_VAR(szPrintcommand),
2321 .special = NULL,
2322 .enum_list = NULL,
2323 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2326 .label = "disable spoolss",
2327 .type = P_BOOL,
2328 .p_class = P_GLOBAL,
2329 .offset = GLOBAL_VAR(bDisableSpoolss),
2330 .special = NULL,
2331 .enum_list = NULL,
2332 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2335 .label = "enable spoolss",
2336 .type = P_BOOLREV,
2337 .p_class = P_GLOBAL,
2338 .offset = GLOBAL_VAR(bDisableSpoolss),
2339 .special = NULL,
2340 .enum_list = NULL,
2341 .flags = FLAG_HIDE,
2344 .label = "lpq command",
2345 .type = P_STRING,
2346 .p_class = P_LOCAL,
2347 .offset = LOCAL_VAR(szLpqcommand),
2348 .special = NULL,
2349 .enum_list = NULL,
2350 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2353 .label = "lprm command",
2354 .type = P_STRING,
2355 .p_class = P_LOCAL,
2356 .offset = LOCAL_VAR(szLprmcommand),
2357 .special = NULL,
2358 .enum_list = NULL,
2359 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2362 .label = "lppause command",
2363 .type = P_STRING,
2364 .p_class = P_LOCAL,
2365 .offset = LOCAL_VAR(szLppausecommand),
2366 .special = NULL,
2367 .enum_list = NULL,
2368 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2371 .label = "lpresume command",
2372 .type = P_STRING,
2373 .p_class = P_LOCAL,
2374 .offset = LOCAL_VAR(szLpresumecommand),
2375 .special = NULL,
2376 .enum_list = NULL,
2377 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2380 .label = "queuepause command",
2381 .type = P_STRING,
2382 .p_class = P_LOCAL,
2383 .offset = LOCAL_VAR(szQueuepausecommand),
2384 .special = NULL,
2385 .enum_list = NULL,
2386 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2389 .label = "queueresume command",
2390 .type = P_STRING,
2391 .p_class = P_LOCAL,
2392 .offset = LOCAL_VAR(szQueueresumecommand),
2393 .special = NULL,
2394 .enum_list = NULL,
2395 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2398 .label = "addport command",
2399 .type = P_STRING,
2400 .p_class = P_GLOBAL,
2401 .offset = GLOBAL_VAR(szAddPortCommand),
2402 .special = NULL,
2403 .enum_list = NULL,
2404 .flags = FLAG_ADVANCED,
2407 .label = "enumports command",
2408 .type = P_STRING,
2409 .p_class = P_GLOBAL,
2410 .offset = GLOBAL_VAR(szEnumPortsCommand),
2411 .special = NULL,
2412 .enum_list = NULL,
2413 .flags = FLAG_ADVANCED,
2416 .label = "addprinter command",
2417 .type = P_STRING,
2418 .p_class = P_GLOBAL,
2419 .offset = GLOBAL_VAR(szAddPrinterCommand),
2420 .special = NULL,
2421 .enum_list = NULL,
2422 .flags = FLAG_ADVANCED,
2425 .label = "deleteprinter command",
2426 .type = P_STRING,
2427 .p_class = P_GLOBAL,
2428 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2429 .special = NULL,
2430 .enum_list = NULL,
2431 .flags = FLAG_ADVANCED,
2434 .label = "show add printer wizard",
2435 .type = P_BOOL,
2436 .p_class = P_GLOBAL,
2437 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2438 .special = NULL,
2439 .enum_list = NULL,
2440 .flags = FLAG_ADVANCED,
2443 .label = "os2 driver map",
2444 .type = P_STRING,
2445 .p_class = P_GLOBAL,
2446 .offset = GLOBAL_VAR(szOs2DriverMap),
2447 .special = NULL,
2448 .enum_list = NULL,
2449 .flags = FLAG_ADVANCED,
2453 .label = "printer name",
2454 .type = P_STRING,
2455 .p_class = P_LOCAL,
2456 .offset = LOCAL_VAR(szPrintername),
2457 .special = NULL,
2458 .enum_list = NULL,
2459 .flags = FLAG_ADVANCED | FLAG_PRINT,
2462 .label = "printer",
2463 .type = P_STRING,
2464 .p_class = P_LOCAL,
2465 .offset = LOCAL_VAR(szPrintername),
2466 .special = NULL,
2467 .enum_list = NULL,
2468 .flags = FLAG_HIDE,
2471 .label = "use client driver",
2472 .type = P_BOOL,
2473 .p_class = P_LOCAL,
2474 .offset = LOCAL_VAR(bUseClientDriver),
2475 .special = NULL,
2476 .enum_list = NULL,
2477 .flags = FLAG_ADVANCED | FLAG_PRINT,
2480 .label = "default devmode",
2481 .type = P_BOOL,
2482 .p_class = P_LOCAL,
2483 .offset = LOCAL_VAR(bDefaultDevmode),
2484 .special = NULL,
2485 .enum_list = NULL,
2486 .flags = FLAG_ADVANCED | FLAG_PRINT,
2489 .label = "force printername",
2490 .type = P_BOOL,
2491 .p_class = P_LOCAL,
2492 .offset = LOCAL_VAR(bForcePrintername),
2493 .special = NULL,
2494 .enum_list = NULL,
2495 .flags = FLAG_ADVANCED | FLAG_PRINT,
2498 .label = "printjob username",
2499 .type = P_STRING,
2500 .p_class = P_LOCAL,
2501 .offset = LOCAL_VAR(szPrintjobUsername),
2502 .special = NULL,
2503 .enum_list = NULL,
2504 .flags = FLAG_ADVANCED | FLAG_PRINT,
2507 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2510 .label = "mangling method",
2511 .type = P_STRING,
2512 .p_class = P_GLOBAL,
2513 .offset = GLOBAL_VAR(szManglingMethod),
2514 .special = NULL,
2515 .enum_list = NULL,
2516 .flags = FLAG_ADVANCED,
2519 .label = "mangle prefix",
2520 .type = P_INTEGER,
2521 .p_class = P_GLOBAL,
2522 .offset = GLOBAL_VAR(mangle_prefix),
2523 .special = NULL,
2524 .enum_list = NULL,
2525 .flags = FLAG_ADVANCED,
2529 .label = "default case",
2530 .type = P_ENUM,
2531 .p_class = P_LOCAL,
2532 .offset = LOCAL_VAR(iDefaultCase),
2533 .special = NULL,
2534 .enum_list = enum_case,
2535 .flags = FLAG_ADVANCED | FLAG_SHARE,
2538 .label = "case sensitive",
2539 .type = P_ENUM,
2540 .p_class = P_LOCAL,
2541 .offset = LOCAL_VAR(iCaseSensitive),
2542 .special = NULL,
2543 .enum_list = enum_bool_auto,
2544 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2547 .label = "casesignames",
2548 .type = P_ENUM,
2549 .p_class = P_LOCAL,
2550 .offset = LOCAL_VAR(iCaseSensitive),
2551 .special = NULL,
2552 .enum_list = enum_bool_auto,
2553 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2556 .label = "preserve case",
2557 .type = P_BOOL,
2558 .p_class = P_LOCAL,
2559 .offset = LOCAL_VAR(bCasePreserve),
2560 .special = NULL,
2561 .enum_list = NULL,
2562 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2565 .label = "short preserve case",
2566 .type = P_BOOL,
2567 .p_class = P_LOCAL,
2568 .offset = LOCAL_VAR(bShortCasePreserve),
2569 .special = NULL,
2570 .enum_list = NULL,
2571 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2574 .label = "mangling char",
2575 .type = P_CHAR,
2576 .p_class = P_LOCAL,
2577 .offset = LOCAL_VAR(magic_char),
2578 .special = NULL,
2579 .enum_list = NULL,
2580 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2583 .label = "hide dot files",
2584 .type = P_BOOL,
2585 .p_class = P_LOCAL,
2586 .offset = LOCAL_VAR(bHideDotFiles),
2587 .special = NULL,
2588 .enum_list = NULL,
2589 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2592 .label = "hide special files",
2593 .type = P_BOOL,
2594 .p_class = P_LOCAL,
2595 .offset = LOCAL_VAR(bHideSpecialFiles),
2596 .special = NULL,
2597 .enum_list = NULL,
2598 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2601 .label = "hide unreadable",
2602 .type = P_BOOL,
2603 .p_class = P_LOCAL,
2604 .offset = LOCAL_VAR(bHideUnReadable),
2605 .special = NULL,
2606 .enum_list = NULL,
2607 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2610 .label = "hide unwriteable files",
2611 .type = P_BOOL,
2612 .p_class = P_LOCAL,
2613 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2614 .special = NULL,
2615 .enum_list = NULL,
2616 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2619 .label = "delete veto files",
2620 .type = P_BOOL,
2621 .p_class = P_LOCAL,
2622 .offset = LOCAL_VAR(bDeleteVetoFiles),
2623 .special = NULL,
2624 .enum_list = NULL,
2625 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2628 .label = "veto files",
2629 .type = P_STRING,
2630 .p_class = P_LOCAL,
2631 .offset = LOCAL_VAR(szVetoFiles),
2632 .special = NULL,
2633 .enum_list = NULL,
2634 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2637 .label = "hide files",
2638 .type = P_STRING,
2639 .p_class = P_LOCAL,
2640 .offset = LOCAL_VAR(szHideFiles),
2641 .special = NULL,
2642 .enum_list = NULL,
2643 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2646 .label = "veto oplock files",
2647 .type = P_STRING,
2648 .p_class = P_LOCAL,
2649 .offset = LOCAL_VAR(szVetoOplockFiles),
2650 .special = NULL,
2651 .enum_list = NULL,
2652 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2655 .label = "map archive",
2656 .type = P_BOOL,
2657 .p_class = P_LOCAL,
2658 .offset = LOCAL_VAR(bMap_archive),
2659 .special = NULL,
2660 .enum_list = NULL,
2661 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2664 .label = "map hidden",
2665 .type = P_BOOL,
2666 .p_class = P_LOCAL,
2667 .offset = LOCAL_VAR(bMap_hidden),
2668 .special = NULL,
2669 .enum_list = NULL,
2670 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2673 .label = "map system",
2674 .type = P_BOOL,
2675 .p_class = P_LOCAL,
2676 .offset = LOCAL_VAR(bMap_system),
2677 .special = NULL,
2678 .enum_list = NULL,
2679 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2682 .label = "map readonly",
2683 .type = P_ENUM,
2684 .p_class = P_LOCAL,
2685 .offset = LOCAL_VAR(iMap_readonly),
2686 .special = NULL,
2687 .enum_list = enum_map_readonly,
2688 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2691 .label = "mangled names",
2692 .type = P_BOOL,
2693 .p_class = P_LOCAL,
2694 .offset = LOCAL_VAR(bMangledNames),
2695 .special = NULL,
2696 .enum_list = NULL,
2697 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2700 .label = "max stat cache size",
2701 .type = P_INTEGER,
2702 .p_class = P_GLOBAL,
2703 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2704 .special = NULL,
2705 .enum_list = NULL,
2706 .flags = FLAG_ADVANCED,
2709 .label = "stat cache",
2710 .type = P_BOOL,
2711 .p_class = P_GLOBAL,
2712 .offset = GLOBAL_VAR(bStatCache),
2713 .special = NULL,
2714 .enum_list = NULL,
2715 .flags = FLAG_ADVANCED,
2718 .label = "store dos attributes",
2719 .type = P_BOOL,
2720 .p_class = P_LOCAL,
2721 .offset = LOCAL_VAR(bStoreDosAttributes),
2722 .special = NULL,
2723 .enum_list = NULL,
2724 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2727 .label = "dmapi support",
2728 .type = P_BOOL,
2729 .p_class = P_LOCAL,
2730 .offset = LOCAL_VAR(bDmapiSupport),
2731 .special = NULL,
2732 .enum_list = NULL,
2733 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2737 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2740 .label = "machine password timeout",
2741 .type = P_INTEGER,
2742 .p_class = P_GLOBAL,
2743 .offset = GLOBAL_VAR(machine_password_timeout),
2744 .special = NULL,
2745 .enum_list = NULL,
2746 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2749 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2752 .label = "add user script",
2753 .type = P_STRING,
2754 .p_class = P_GLOBAL,
2755 .offset = GLOBAL_VAR(szAddUserScript),
2756 .special = NULL,
2757 .enum_list = NULL,
2758 .flags = FLAG_ADVANCED,
2761 .label = "rename user script",
2762 .type = P_STRING,
2763 .p_class = P_GLOBAL,
2764 .offset = GLOBAL_VAR(szRenameUserScript),
2765 .special = NULL,
2766 .enum_list = NULL,
2767 .flags = FLAG_ADVANCED,
2770 .label = "delete user script",
2771 .type = P_STRING,
2772 .p_class = P_GLOBAL,
2773 .offset = GLOBAL_VAR(szDelUserScript),
2774 .special = NULL,
2775 .enum_list = NULL,
2776 .flags = FLAG_ADVANCED,
2779 .label = "add group script",
2780 .type = P_STRING,
2781 .p_class = P_GLOBAL,
2782 .offset = GLOBAL_VAR(szAddGroupScript),
2783 .special = NULL,
2784 .enum_list = NULL,
2785 .flags = FLAG_ADVANCED,
2788 .label = "delete group script",
2789 .type = P_STRING,
2790 .p_class = P_GLOBAL,
2791 .offset = GLOBAL_VAR(szDelGroupScript),
2792 .special = NULL,
2793 .enum_list = NULL,
2794 .flags = FLAG_ADVANCED,
2797 .label = "add user to group script",
2798 .type = P_STRING,
2799 .p_class = P_GLOBAL,
2800 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2801 .special = NULL,
2802 .enum_list = NULL,
2803 .flags = FLAG_ADVANCED,
2806 .label = "delete user from group script",
2807 .type = P_STRING,
2808 .p_class = P_GLOBAL,
2809 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2810 .special = NULL,
2811 .enum_list = NULL,
2812 .flags = FLAG_ADVANCED,
2815 .label = "set primary group script",
2816 .type = P_STRING,
2817 .p_class = P_GLOBAL,
2818 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2819 .special = NULL,
2820 .enum_list = NULL,
2821 .flags = FLAG_ADVANCED,
2824 .label = "add machine script",
2825 .type = P_STRING,
2826 .p_class = P_GLOBAL,
2827 .offset = GLOBAL_VAR(szAddMachineScript),
2828 .special = NULL,
2829 .enum_list = NULL,
2830 .flags = FLAG_ADVANCED,
2833 .label = "shutdown script",
2834 .type = P_STRING,
2835 .p_class = P_GLOBAL,
2836 .offset = GLOBAL_VAR(szShutdownScript),
2837 .special = NULL,
2838 .enum_list = NULL,
2839 .flags = FLAG_ADVANCED,
2842 .label = "abort shutdown script",
2843 .type = P_STRING,
2844 .p_class = P_GLOBAL,
2845 .offset = GLOBAL_VAR(szAbortShutdownScript),
2846 .special = NULL,
2847 .enum_list = NULL,
2848 .flags = FLAG_ADVANCED,
2851 .label = "username map script",
2852 .type = P_STRING,
2853 .p_class = P_GLOBAL,
2854 .offset = GLOBAL_VAR(szUsernameMapScript),
2855 .special = NULL,
2856 .enum_list = NULL,
2857 .flags = FLAG_ADVANCED,
2860 .label = "username map cache time",
2861 .type = P_INTEGER,
2862 .p_class = P_GLOBAL,
2863 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2864 .special = NULL,
2865 .enum_list = NULL,
2866 .flags = FLAG_ADVANCED,
2869 .label = "logon script",
2870 .type = P_STRING,
2871 .p_class = P_GLOBAL,
2872 .offset = GLOBAL_VAR(szLogonScript),
2873 .special = NULL,
2874 .enum_list = NULL,
2875 .flags = FLAG_ADVANCED,
2878 .label = "logon path",
2879 .type = P_STRING,
2880 .p_class = P_GLOBAL,
2881 .offset = GLOBAL_VAR(szLogonPath),
2882 .special = NULL,
2883 .enum_list = NULL,
2884 .flags = FLAG_ADVANCED,
2887 .label = "logon drive",
2888 .type = P_STRING,
2889 .p_class = P_GLOBAL,
2890 .offset = GLOBAL_VAR(szLogonDrive),
2891 .special = NULL,
2892 .enum_list = NULL,
2893 .flags = FLAG_ADVANCED,
2896 .label = "logon home",
2897 .type = P_STRING,
2898 .p_class = P_GLOBAL,
2899 .offset = GLOBAL_VAR(szLogonHome),
2900 .special = NULL,
2901 .enum_list = NULL,
2902 .flags = FLAG_ADVANCED,
2905 .label = "domain logons",
2906 .type = P_BOOL,
2907 .p_class = P_GLOBAL,
2908 .offset = GLOBAL_VAR(bDomainLogons),
2909 .special = NULL,
2910 .enum_list = NULL,
2911 .flags = FLAG_ADVANCED,
2915 .label = "init logon delayed hosts",
2916 .type = P_LIST,
2917 .p_class = P_GLOBAL,
2918 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2919 .special = NULL,
2920 .enum_list = NULL,
2921 .flags = FLAG_ADVANCED,
2925 .label = "init logon delay",
2926 .type = P_INTEGER,
2927 .p_class = P_GLOBAL,
2928 .offset = GLOBAL_VAR(InitLogonDelay),
2929 .special = NULL,
2930 .enum_list = NULL,
2931 .flags = FLAG_ADVANCED,
2935 {N_("Browse Options"), P_SEP, P_SEPARATOR},
2938 .label = "os level",
2939 .type = P_INTEGER,
2940 .p_class = P_GLOBAL,
2941 .offset = GLOBAL_VAR(os_level),
2942 .special = NULL,
2943 .enum_list = NULL,
2944 .flags = FLAG_BASIC | FLAG_ADVANCED,
2947 .label = "lm announce",
2948 .type = P_ENUM,
2949 .p_class = P_GLOBAL,
2950 .offset = GLOBAL_VAR(lm_announce),
2951 .special = NULL,
2952 .enum_list = enum_bool_auto,
2953 .flags = FLAG_ADVANCED,
2956 .label = "lm interval",
2957 .type = P_INTEGER,
2958 .p_class = P_GLOBAL,
2959 .offset = GLOBAL_VAR(lm_interval),
2960 .special = NULL,
2961 .enum_list = NULL,
2962 .flags = FLAG_ADVANCED,
2965 .label = "preferred master",
2966 .type = P_ENUM,
2967 .p_class = P_GLOBAL,
2968 .offset = GLOBAL_VAR(iPreferredMaster),
2969 .special = NULL,
2970 .enum_list = enum_bool_auto,
2971 .flags = FLAG_BASIC | FLAG_ADVANCED,
2974 .label = "prefered master",
2975 .type = P_ENUM,
2976 .p_class = P_GLOBAL,
2977 .offset = GLOBAL_VAR(iPreferredMaster),
2978 .special = NULL,
2979 .enum_list = enum_bool_auto,
2980 .flags = FLAG_HIDE,
2983 .label = "local master",
2984 .type = P_BOOL,
2985 .p_class = P_GLOBAL,
2986 .offset = GLOBAL_VAR(bLocalMaster),
2987 .special = NULL,
2988 .enum_list = NULL,
2989 .flags = FLAG_BASIC | FLAG_ADVANCED,
2992 .label = "domain master",
2993 .type = P_ENUM,
2994 .p_class = P_GLOBAL,
2995 .offset = GLOBAL_VAR(iDomainMaster),
2996 .special = NULL,
2997 .enum_list = enum_bool_auto,
2998 .flags = FLAG_BASIC | FLAG_ADVANCED,
3001 .label = "browse list",
3002 .type = P_BOOL,
3003 .p_class = P_GLOBAL,
3004 .offset = GLOBAL_VAR(bBrowseList),
3005 .special = NULL,
3006 .enum_list = NULL,
3007 .flags = FLAG_ADVANCED,
3010 .label = "browseable",
3011 .type = P_BOOL,
3012 .p_class = P_LOCAL,
3013 .offset = LOCAL_VAR(bBrowseable),
3014 .special = NULL,
3015 .enum_list = NULL,
3016 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3019 .label = "browsable",
3020 .type = P_BOOL,
3021 .p_class = P_LOCAL,
3022 .offset = LOCAL_VAR(bBrowseable),
3023 .special = NULL,
3024 .enum_list = NULL,
3025 .flags = FLAG_HIDE,
3028 .label = "access based share enum",
3029 .type = P_BOOL,
3030 .p_class = P_LOCAL,
3031 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3032 .special = NULL,
3033 .enum_list = NULL,
3034 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3037 .label = "enhanced browsing",
3038 .type = P_BOOL,
3039 .p_class = P_GLOBAL,
3040 .offset = GLOBAL_VAR(enhanced_browsing),
3041 .special = NULL,
3042 .enum_list = NULL,
3043 .flags = FLAG_ADVANCED,
3046 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3049 .label = "dns proxy",
3050 .type = P_BOOL,
3051 .p_class = P_GLOBAL,
3052 .offset = GLOBAL_VAR(bWINSdnsProxy),
3053 .special = NULL,
3054 .enum_list = NULL,
3055 .flags = FLAG_ADVANCED,
3058 .label = "wins proxy",
3059 .type = P_BOOL,
3060 .p_class = P_GLOBAL,
3061 .offset = GLOBAL_VAR(bWINSproxy),
3062 .special = NULL,
3063 .enum_list = NULL,
3064 .flags = FLAG_ADVANCED,
3067 .label = "wins server",
3068 .type = P_LIST,
3069 .p_class = P_GLOBAL,
3070 .offset = GLOBAL_VAR(szWINSservers),
3071 .special = NULL,
3072 .enum_list = NULL,
3073 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3076 .label = "wins support",
3077 .type = P_BOOL,
3078 .p_class = P_GLOBAL,
3079 .offset = GLOBAL_VAR(bWINSsupport),
3080 .special = NULL,
3081 .enum_list = NULL,
3082 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3085 .label = "wins hook",
3086 .type = P_STRING,
3087 .p_class = P_GLOBAL,
3088 .offset = GLOBAL_VAR(szWINSHook),
3089 .special = NULL,
3090 .enum_list = NULL,
3091 .flags = FLAG_ADVANCED,
3094 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3097 .label = "blocking locks",
3098 .type = P_BOOL,
3099 .p_class = P_LOCAL,
3100 .offset = LOCAL_VAR(bBlockingLocks),
3101 .special = NULL,
3102 .enum_list = NULL,
3103 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3106 .label = "csc policy",
3107 .type = P_ENUM,
3108 .p_class = P_LOCAL,
3109 .offset = LOCAL_VAR(iCSCPolicy),
3110 .special = NULL,
3111 .enum_list = enum_csc_policy,
3112 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3115 .label = "fake oplocks",
3116 .type = P_BOOL,
3117 .p_class = P_LOCAL,
3118 .offset = LOCAL_VAR(bFakeOplocks),
3119 .special = NULL,
3120 .enum_list = NULL,
3121 .flags = FLAG_ADVANCED | FLAG_SHARE,
3124 .label = "kernel oplocks",
3125 .type = P_BOOL,
3126 .p_class = P_LOCAL,
3127 .offset = LOCAL_VAR(bKernelOplocks),
3128 .special = NULL,
3129 .enum_list = NULL,
3130 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3133 .label = "locking",
3134 .type = P_BOOL,
3135 .p_class = P_LOCAL,
3136 .offset = LOCAL_VAR(bLocking),
3137 .special = NULL,
3138 .enum_list = NULL,
3139 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3142 .label = "lock spin time",
3143 .type = P_INTEGER,
3144 .p_class = P_GLOBAL,
3145 .offset = GLOBAL_VAR(iLockSpinTime),
3146 .special = NULL,
3147 .enum_list = NULL,
3148 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3151 .label = "oplocks",
3152 .type = P_BOOL,
3153 .p_class = P_LOCAL,
3154 .offset = LOCAL_VAR(bOpLocks),
3155 .special = NULL,
3156 .enum_list = NULL,
3157 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3160 .label = "level2 oplocks",
3161 .type = P_BOOL,
3162 .p_class = P_LOCAL,
3163 .offset = LOCAL_VAR(bLevel2OpLocks),
3164 .special = NULL,
3165 .enum_list = NULL,
3166 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3169 .label = "oplock break wait time",
3170 .type = P_INTEGER,
3171 .p_class = P_GLOBAL,
3172 .offset = GLOBAL_VAR(oplock_break_wait_time),
3173 .special = NULL,
3174 .enum_list = NULL,
3175 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3178 .label = "oplock contention limit",
3179 .type = P_INTEGER,
3180 .p_class = P_LOCAL,
3181 .offset = LOCAL_VAR(iOplockContentionLimit),
3182 .special = NULL,
3183 .enum_list = NULL,
3184 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3187 .label = "posix locking",
3188 .type = P_BOOL,
3189 .p_class = P_LOCAL,
3190 .offset = LOCAL_VAR(bPosixLocking),
3191 .special = NULL,
3192 .enum_list = NULL,
3193 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3196 .label = "strict locking",
3197 .type = P_ENUM,
3198 .p_class = P_LOCAL,
3199 .offset = LOCAL_VAR(iStrictLocking),
3200 .special = NULL,
3201 .enum_list = enum_bool_auto,
3202 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3205 .label = "share modes",
3206 .type = P_BOOL,
3207 .p_class = P_LOCAL,
3208 .offset = LOCAL_VAR(bShareModes),
3209 .special = NULL,
3210 .enum_list = NULL,
3211 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3214 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3217 .label = "ldap admin dn",
3218 .type = P_STRING,
3219 .p_class = P_GLOBAL,
3220 .offset = GLOBAL_VAR(szLdapAdminDn),
3221 .special = NULL,
3222 .enum_list = NULL,
3223 .flags = FLAG_ADVANCED,
3226 .label = "ldap delete dn",
3227 .type = P_BOOL,
3228 .p_class = P_GLOBAL,
3229 .offset = GLOBAL_VAR(ldap_delete_dn),
3230 .special = NULL,
3231 .enum_list = NULL,
3232 .flags = FLAG_ADVANCED,
3235 .label = "ldap group suffix",
3236 .type = P_STRING,
3237 .p_class = P_GLOBAL,
3238 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3239 .special = NULL,
3240 .enum_list = NULL,
3241 .flags = FLAG_ADVANCED,
3244 .label = "ldap idmap suffix",
3245 .type = P_STRING,
3246 .p_class = P_GLOBAL,
3247 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3248 .special = NULL,
3249 .enum_list = NULL,
3250 .flags = FLAG_ADVANCED,
3253 .label = "ldap machine suffix",
3254 .type = P_STRING,
3255 .p_class = P_GLOBAL,
3256 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3257 .special = NULL,
3258 .enum_list = NULL,
3259 .flags = FLAG_ADVANCED,
3262 .label = "ldap passwd sync",
3263 .type = P_ENUM,
3264 .p_class = P_GLOBAL,
3265 .offset = GLOBAL_VAR(ldap_passwd_sync),
3266 .special = NULL,
3267 .enum_list = enum_ldap_passwd_sync,
3268 .flags = FLAG_ADVANCED,
3271 .label = "ldap password sync",
3272 .type = P_ENUM,
3273 .p_class = P_GLOBAL,
3274 .offset = GLOBAL_VAR(ldap_passwd_sync),
3275 .special = NULL,
3276 .enum_list = enum_ldap_passwd_sync,
3277 .flags = FLAG_HIDE,
3280 .label = "ldap replication sleep",
3281 .type = P_INTEGER,
3282 .p_class = P_GLOBAL,
3283 .offset = GLOBAL_VAR(ldap_replication_sleep),
3284 .special = NULL,
3285 .enum_list = NULL,
3286 .flags = FLAG_ADVANCED,
3289 .label = "ldap suffix",
3290 .type = P_STRING,
3291 .p_class = P_GLOBAL,
3292 .offset = GLOBAL_VAR(szLdapSuffix),
3293 .special = NULL,
3294 .enum_list = NULL,
3295 .flags = FLAG_ADVANCED,
3298 .label = "ldap ssl",
3299 .type = P_ENUM,
3300 .p_class = P_GLOBAL,
3301 .offset = GLOBAL_VAR(ldap_ssl),
3302 .special = NULL,
3303 .enum_list = enum_ldap_ssl,
3304 .flags = FLAG_ADVANCED,
3307 .label = "ldap ssl ads",
3308 .type = P_BOOL,
3309 .p_class = P_GLOBAL,
3310 .offset = GLOBAL_VAR(ldap_ssl_ads),
3311 .special = NULL,
3312 .enum_list = NULL,
3313 .flags = FLAG_ADVANCED,
3316 .label = "ldap deref",
3317 .type = P_ENUM,
3318 .p_class = P_GLOBAL,
3319 .offset = GLOBAL_VAR(ldap_deref),
3320 .special = NULL,
3321 .enum_list = enum_ldap_deref,
3322 .flags = FLAG_ADVANCED,
3325 .label = "ldap follow referral",
3326 .type = P_ENUM,
3327 .p_class = P_GLOBAL,
3328 .offset = GLOBAL_VAR(ldap_follow_referral),
3329 .special = NULL,
3330 .enum_list = enum_bool_auto,
3331 .flags = FLAG_ADVANCED,
3334 .label = "ldap timeout",
3335 .type = P_INTEGER,
3336 .p_class = P_GLOBAL,
3337 .offset = GLOBAL_VAR(ldap_timeout),
3338 .special = NULL,
3339 .enum_list = NULL,
3340 .flags = FLAG_ADVANCED,
3343 .label = "ldap connection timeout",
3344 .type = P_INTEGER,
3345 .p_class = P_GLOBAL,
3346 .offset = GLOBAL_VAR(ldap_connection_timeout),
3347 .special = NULL,
3348 .enum_list = NULL,
3349 .flags = FLAG_ADVANCED,
3352 .label = "ldap page size",
3353 .type = P_INTEGER,
3354 .p_class = P_GLOBAL,
3355 .offset = GLOBAL_VAR(ldap_page_size),
3356 .special = NULL,
3357 .enum_list = NULL,
3358 .flags = FLAG_ADVANCED,
3361 .label = "ldap user suffix",
3362 .type = P_STRING,
3363 .p_class = P_GLOBAL,
3364 .offset = GLOBAL_VAR(szLdapUserSuffix),
3365 .special = NULL,
3366 .enum_list = NULL,
3367 .flags = FLAG_ADVANCED,
3370 .label = "ldap debug level",
3371 .type = P_INTEGER,
3372 .p_class = P_GLOBAL,
3373 .offset = GLOBAL_VAR(ldap_debug_level),
3374 .special = handle_ldap_debug_level,
3375 .enum_list = NULL,
3376 .flags = FLAG_ADVANCED,
3379 .label = "ldap debug threshold",
3380 .type = P_INTEGER,
3381 .p_class = P_GLOBAL,
3382 .offset = GLOBAL_VAR(ldap_debug_threshold),
3383 .special = NULL,
3384 .enum_list = NULL,
3385 .flags = FLAG_ADVANCED,
3388 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3391 .label = "eventlog list",
3392 .type = P_LIST,
3393 .p_class = P_GLOBAL,
3394 .offset = GLOBAL_VAR(szEventLogs),
3395 .special = NULL,
3396 .enum_list = NULL,
3397 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3400 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3403 .label = "add share command",
3404 .type = P_STRING,
3405 .p_class = P_GLOBAL,
3406 .offset = GLOBAL_VAR(szAddShareCommand),
3407 .special = NULL,
3408 .enum_list = NULL,
3409 .flags = FLAG_ADVANCED,
3412 .label = "change share command",
3413 .type = P_STRING,
3414 .p_class = P_GLOBAL,
3415 .offset = GLOBAL_VAR(szChangeShareCommand),
3416 .special = NULL,
3417 .enum_list = NULL,
3418 .flags = FLAG_ADVANCED,
3421 .label = "delete share command",
3422 .type = P_STRING,
3423 .p_class = P_GLOBAL,
3424 .offset = GLOBAL_VAR(szDeleteShareCommand),
3425 .special = NULL,
3426 .enum_list = NULL,
3427 .flags = FLAG_ADVANCED,
3430 .label = "config file",
3431 .type = P_STRING,
3432 .p_class = P_GLOBAL,
3433 .offset = GLOBAL_VAR(szConfigFile),
3434 .special = NULL,
3435 .enum_list = NULL,
3436 .flags = FLAG_HIDE|FLAG_META,
3439 .label = "preload",
3440 .type = P_STRING,
3441 .p_class = P_GLOBAL,
3442 .offset = GLOBAL_VAR(szAutoServices),
3443 .special = NULL,
3444 .enum_list = NULL,
3445 .flags = FLAG_ADVANCED,
3448 .label = "auto services",
3449 .type = P_STRING,
3450 .p_class = P_GLOBAL,
3451 .offset = GLOBAL_VAR(szAutoServices),
3452 .special = NULL,
3453 .enum_list = NULL,
3454 .flags = FLAG_ADVANCED,
3457 .label = "lock directory",
3458 .type = P_STRING,
3459 .p_class = P_GLOBAL,
3460 .offset = GLOBAL_VAR(szLockDir),
3461 .special = NULL,
3462 .enum_list = NULL,
3463 .flags = FLAG_ADVANCED,
3466 .label = "lock dir",
3467 .type = P_STRING,
3468 .p_class = P_GLOBAL,
3469 .offset = GLOBAL_VAR(szLockDir),
3470 .special = NULL,
3471 .enum_list = NULL,
3472 .flags = FLAG_HIDE,
3475 .label = "state directory",
3476 .type = P_STRING,
3477 .p_class = P_GLOBAL,
3478 .offset = GLOBAL_VAR(szStateDir),
3479 .special = NULL,
3480 .enum_list = NULL,
3481 .flags = FLAG_ADVANCED,
3484 .label = "cache directory",
3485 .type = P_STRING,
3486 .p_class = P_GLOBAL,
3487 .offset = GLOBAL_VAR(szCacheDir),
3488 .special = NULL,
3489 .enum_list = NULL,
3490 .flags = FLAG_ADVANCED,
3493 .label = "pid directory",
3494 .type = P_STRING,
3495 .p_class = P_GLOBAL,
3496 .offset = GLOBAL_VAR(szPidDir),
3497 .special = NULL,
3498 .enum_list = NULL,
3499 .flags = FLAG_ADVANCED,
3501 #ifdef WITH_UTMP
3503 .label = "utmp directory",
3504 .type = P_STRING,
3505 .p_class = P_GLOBAL,
3506 .offset = GLOBAL_VAR(szUtmpDir),
3507 .special = NULL,
3508 .enum_list = NULL,
3509 .flags = FLAG_ADVANCED,
3512 .label = "wtmp directory",
3513 .type = P_STRING,
3514 .p_class = P_GLOBAL,
3515 .offset = GLOBAL_VAR(szWtmpDir),
3516 .special = NULL,
3517 .enum_list = NULL,
3518 .flags = FLAG_ADVANCED,
3521 .label = "utmp",
3522 .type = P_BOOL,
3523 .p_class = P_GLOBAL,
3524 .offset = GLOBAL_VAR(bUtmp),
3525 .special = NULL,
3526 .enum_list = NULL,
3527 .flags = FLAG_ADVANCED,
3529 #endif
3531 .label = "default service",
3532 .type = P_STRING,
3533 .p_class = P_GLOBAL,
3534 .offset = GLOBAL_VAR(szDefaultService),
3535 .special = NULL,
3536 .enum_list = NULL,
3537 .flags = FLAG_ADVANCED,
3540 .label = "default",
3541 .type = P_STRING,
3542 .p_class = P_GLOBAL,
3543 .offset = GLOBAL_VAR(szDefaultService),
3544 .special = NULL,
3545 .enum_list = NULL,
3546 .flags = FLAG_ADVANCED,
3549 .label = "message command",
3550 .type = P_STRING,
3551 .p_class = P_GLOBAL,
3552 .offset = GLOBAL_VAR(szMsgCommand),
3553 .special = NULL,
3554 .enum_list = NULL,
3555 .flags = FLAG_ADVANCED,
3558 .label = "dfree cache time",
3559 .type = P_INTEGER,
3560 .p_class = P_LOCAL,
3561 .offset = LOCAL_VAR(iDfreeCacheTime),
3562 .special = NULL,
3563 .enum_list = NULL,
3564 .flags = FLAG_ADVANCED,
3567 .label = "dfree command",
3568 .type = P_STRING,
3569 .p_class = P_LOCAL,
3570 .offset = LOCAL_VAR(szDfree),
3571 .special = NULL,
3572 .enum_list = NULL,
3573 .flags = FLAG_ADVANCED,
3576 .label = "get quota command",
3577 .type = P_STRING,
3578 .p_class = P_GLOBAL,
3579 .offset = GLOBAL_VAR(szGetQuota),
3580 .special = NULL,
3581 .enum_list = NULL,
3582 .flags = FLAG_ADVANCED,
3585 .label = "set quota command",
3586 .type = P_STRING,
3587 .p_class = P_GLOBAL,
3588 .offset = GLOBAL_VAR(szSetQuota),
3589 .special = NULL,
3590 .enum_list = NULL,
3591 .flags = FLAG_ADVANCED,
3594 .label = "remote announce",
3595 .type = P_STRING,
3596 .p_class = P_GLOBAL,
3597 .offset = GLOBAL_VAR(szRemoteAnnounce),
3598 .special = NULL,
3599 .enum_list = NULL,
3600 .flags = FLAG_ADVANCED,
3603 .label = "remote browse sync",
3604 .type = P_STRING,
3605 .p_class = P_GLOBAL,
3606 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3607 .special = NULL,
3608 .enum_list = NULL,
3609 .flags = FLAG_ADVANCED,
3612 .label = "socket address",
3613 .type = P_STRING,
3614 .p_class = P_GLOBAL,
3615 .offset = GLOBAL_VAR(szSocketAddress),
3616 .special = NULL,
3617 .enum_list = NULL,
3618 .flags = FLAG_ADVANCED,
3621 .label = "nmbd bind explicit broadcast",
3622 .type = P_BOOL,
3623 .p_class = P_GLOBAL,
3624 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3625 .special = NULL,
3626 .enum_list = NULL,
3627 .flags = FLAG_ADVANCED,
3630 .label = "homedir map",
3631 .type = P_STRING,
3632 .p_class = P_GLOBAL,
3633 .offset = GLOBAL_VAR(szNISHomeMapName),
3634 .special = NULL,
3635 .enum_list = NULL,
3636 .flags = FLAG_ADVANCED,
3639 .label = "afs username map",
3640 .type = P_STRING,
3641 .p_class = P_GLOBAL,
3642 .offset = GLOBAL_VAR(szAfsUsernameMap),
3643 .special = NULL,
3644 .enum_list = NULL,
3645 .flags = FLAG_ADVANCED,
3648 .label = "afs token lifetime",
3649 .type = P_INTEGER,
3650 .p_class = P_GLOBAL,
3651 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3652 .special = NULL,
3653 .enum_list = NULL,
3654 .flags = FLAG_ADVANCED,
3657 .label = "log nt token command",
3658 .type = P_STRING,
3659 .p_class = P_GLOBAL,
3660 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3661 .special = NULL,
3662 .enum_list = NULL,
3663 .flags = FLAG_ADVANCED,
3666 .label = "NIS homedir",
3667 .type = P_BOOL,
3668 .p_class = P_GLOBAL,
3669 .offset = GLOBAL_VAR(bNISHomeMap),
3670 .special = NULL,
3671 .enum_list = NULL,
3672 .flags = FLAG_ADVANCED,
3675 .label = "-valid",
3676 .type = P_BOOL,
3677 .p_class = P_LOCAL,
3678 .offset = LOCAL_VAR(valid),
3679 .special = NULL,
3680 .enum_list = NULL,
3681 .flags = FLAG_HIDE,
3684 .label = "copy",
3685 .type = P_STRING,
3686 .p_class = P_LOCAL,
3687 .offset = LOCAL_VAR(szCopy),
3688 .special = handle_copy,
3689 .enum_list = NULL,
3690 .flags = FLAG_HIDE,
3693 .label = "include",
3694 .type = P_STRING,
3695 .p_class = P_LOCAL,
3696 .offset = LOCAL_VAR(szInclude),
3697 .special = handle_include,
3698 .enum_list = NULL,
3699 .flags = FLAG_HIDE|FLAG_META,
3702 .label = "preexec",
3703 .type = P_STRING,
3704 .p_class = P_LOCAL,
3705 .offset = LOCAL_VAR(szPreExec),
3706 .special = NULL,
3707 .enum_list = NULL,
3708 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3711 .label = "exec",
3712 .type = P_STRING,
3713 .p_class = P_LOCAL,
3714 .offset = LOCAL_VAR(szPreExec),
3715 .special = NULL,
3716 .enum_list = NULL,
3717 .flags = FLAG_ADVANCED,
3720 .label = "preexec close",
3721 .type = P_BOOL,
3722 .p_class = P_LOCAL,
3723 .offset = LOCAL_VAR(bPreexecClose),
3724 .special = NULL,
3725 .enum_list = NULL,
3726 .flags = FLAG_ADVANCED | FLAG_SHARE,
3729 .label = "postexec",
3730 .type = P_STRING,
3731 .p_class = P_LOCAL,
3732 .offset = LOCAL_VAR(szPostExec),
3733 .special = NULL,
3734 .enum_list = NULL,
3735 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3738 .label = "root preexec",
3739 .type = P_STRING,
3740 .p_class = P_LOCAL,
3741 .offset = LOCAL_VAR(szRootPreExec),
3742 .special = NULL,
3743 .enum_list = NULL,
3744 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3747 .label = "root preexec close",
3748 .type = P_BOOL,
3749 .p_class = P_LOCAL,
3750 .offset = LOCAL_VAR(bRootpreexecClose),
3751 .special = NULL,
3752 .enum_list = NULL,
3753 .flags = FLAG_ADVANCED | FLAG_SHARE,
3756 .label = "root postexec",
3757 .type = P_STRING,
3758 .p_class = P_LOCAL,
3759 .offset = LOCAL_VAR(szRootPostExec),
3760 .special = NULL,
3761 .enum_list = NULL,
3762 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3765 .label = "available",
3766 .type = P_BOOL,
3767 .p_class = P_LOCAL,
3768 .offset = LOCAL_VAR(bAvailable),
3769 .special = NULL,
3770 .enum_list = NULL,
3771 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3774 .label = "registry shares",
3775 .type = P_BOOL,
3776 .p_class = P_GLOBAL,
3777 .offset = GLOBAL_VAR(bRegistryShares),
3778 .special = NULL,
3779 .enum_list = NULL,
3780 .flags = FLAG_ADVANCED,
3783 .label = "usershare allow guests",
3784 .type = P_BOOL,
3785 .p_class = P_GLOBAL,
3786 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3787 .special = NULL,
3788 .enum_list = NULL,
3789 .flags = FLAG_ADVANCED,
3792 .label = "usershare max shares",
3793 .type = P_INTEGER,
3794 .p_class = P_GLOBAL,
3795 .offset = GLOBAL_VAR(iUsershareMaxShares),
3796 .special = NULL,
3797 .enum_list = NULL,
3798 .flags = FLAG_ADVANCED,
3801 .label = "usershare owner only",
3802 .type = P_BOOL,
3803 .p_class = P_GLOBAL,
3804 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3805 .special = NULL,
3806 .enum_list = NULL,
3807 .flags = FLAG_ADVANCED,
3810 .label = "usershare path",
3811 .type = P_STRING,
3812 .p_class = P_GLOBAL,
3813 .offset = GLOBAL_VAR(szUsersharePath),
3814 .special = NULL,
3815 .enum_list = NULL,
3816 .flags = FLAG_ADVANCED,
3819 .label = "usershare prefix allow list",
3820 .type = P_LIST,
3821 .p_class = P_GLOBAL,
3822 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3823 .special = NULL,
3824 .enum_list = NULL,
3825 .flags = FLAG_ADVANCED,
3828 .label = "usershare prefix deny list",
3829 .type = P_LIST,
3830 .p_class = P_GLOBAL,
3831 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3832 .special = NULL,
3833 .enum_list = NULL,
3834 .flags = FLAG_ADVANCED,
3837 .label = "usershare template share",
3838 .type = P_STRING,
3839 .p_class = P_GLOBAL,
3840 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3841 .special = NULL,
3842 .enum_list = NULL,
3843 .flags = FLAG_ADVANCED,
3846 .label = "volume",
3847 .type = P_STRING,
3848 .p_class = P_LOCAL,
3849 .offset = LOCAL_VAR(volume),
3850 .special = NULL,
3851 .enum_list = NULL,
3852 .flags = FLAG_ADVANCED | FLAG_SHARE,
3855 .label = "fstype",
3856 .type = P_STRING,
3857 .p_class = P_LOCAL,
3858 .offset = LOCAL_VAR(fstype),
3859 .special = NULL,
3860 .enum_list = NULL,
3861 .flags = FLAG_ADVANCED | FLAG_SHARE,
3864 .label = "set directory",
3865 .type = P_BOOLREV,
3866 .p_class = P_LOCAL,
3867 .offset = LOCAL_VAR(bNo_set_dir),
3868 .special = NULL,
3869 .enum_list = NULL,
3870 .flags = FLAG_ADVANCED | FLAG_SHARE,
3873 .label = "allow insecure wide links",
3874 .type = P_BOOL,
3875 .p_class = P_GLOBAL,
3876 .offset = GLOBAL_VAR(bAllowInsecureWidelinks),
3877 .special = NULL,
3878 .enum_list = NULL,
3879 .flags = FLAG_ADVANCED,
3882 .label = "wide links",
3883 .type = P_BOOL,
3884 .p_class = P_LOCAL,
3885 .offset = LOCAL_VAR(bWidelinks),
3886 .special = NULL,
3887 .enum_list = NULL,
3888 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3891 .label = "follow symlinks",
3892 .type = P_BOOL,
3893 .p_class = P_LOCAL,
3894 .offset = LOCAL_VAR(bSymlinks),
3895 .special = NULL,
3896 .enum_list = NULL,
3897 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3900 .label = "dont descend",
3901 .type = P_STRING,
3902 .p_class = P_LOCAL,
3903 .offset = LOCAL_VAR(szDontdescend),
3904 .special = NULL,
3905 .enum_list = NULL,
3906 .flags = FLAG_ADVANCED | FLAG_SHARE,
3909 .label = "magic script",
3910 .type = P_STRING,
3911 .p_class = P_LOCAL,
3912 .offset = LOCAL_VAR(szMagicScript),
3913 .special = NULL,
3914 .enum_list = NULL,
3915 .flags = FLAG_ADVANCED | FLAG_SHARE,
3918 .label = "magic output",
3919 .type = P_STRING,
3920 .p_class = P_LOCAL,
3921 .offset = LOCAL_VAR(szMagicOutput),
3922 .special = NULL,
3923 .enum_list = NULL,
3924 .flags = FLAG_ADVANCED | FLAG_SHARE,
3927 .label = "delete readonly",
3928 .type = P_BOOL,
3929 .p_class = P_LOCAL,
3930 .offset = LOCAL_VAR(bDeleteReadonly),
3931 .special = NULL,
3932 .enum_list = NULL,
3933 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3936 .label = "dos filemode",
3937 .type = P_BOOL,
3938 .p_class = P_LOCAL,
3939 .offset = LOCAL_VAR(bDosFilemode),
3940 .special = NULL,
3941 .enum_list = NULL,
3942 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3945 .label = "dos filetimes",
3946 .type = P_BOOL,
3947 .p_class = P_LOCAL,
3948 .offset = LOCAL_VAR(bDosFiletimes),
3949 .special = NULL,
3950 .enum_list = NULL,
3951 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3954 .label = "dos filetime resolution",
3955 .type = P_BOOL,
3956 .p_class = P_LOCAL,
3957 .offset = LOCAL_VAR(bDosFiletimeResolution),
3958 .special = NULL,
3959 .enum_list = NULL,
3960 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3963 .label = "fake directory create times",
3964 .type = P_BOOL,
3965 .p_class = P_LOCAL,
3966 .offset = LOCAL_VAR(bFakeDirCreateTimes),
3967 .special = NULL,
3968 .enum_list = NULL,
3969 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3972 .label = "async smb echo handler",
3973 .type = P_BOOL,
3974 .p_class = P_GLOBAL,
3975 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
3976 .special = NULL,
3977 .enum_list = NULL,
3978 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3981 .label = "multicast dns register",
3982 .type = P_BOOL,
3983 .p_class = P_GLOBAL,
3984 .offset = GLOBAL_VAR(bMulticastDnsRegister),
3985 .special = NULL,
3986 .enum_list = NULL,
3987 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3990 .label = "panic action",
3991 .type = P_STRING,
3992 .p_class = P_GLOBAL,
3993 .offset = GLOBAL_VAR(szPanicAction),
3994 .special = NULL,
3995 .enum_list = NULL,
3996 .flags = FLAG_ADVANCED,
3999 .label = "perfcount module",
4000 .type = P_STRING,
4001 .p_class = P_GLOBAL,
4002 .offset = GLOBAL_VAR(szSMBPerfcountModule),
4003 .special = NULL,
4004 .enum_list = NULL,
4005 .flags = FLAG_ADVANCED,
4008 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4011 .label = "vfs objects",
4012 .type = P_LIST,
4013 .p_class = P_LOCAL,
4014 .offset = LOCAL_VAR(szVfsObjects),
4015 .special = NULL,
4016 .enum_list = NULL,
4017 .flags = FLAG_ADVANCED | FLAG_SHARE,
4020 .label = "vfs object",
4021 .type = P_LIST,
4022 .p_class = P_LOCAL,
4023 .offset = LOCAL_VAR(szVfsObjects),
4024 .special = NULL,
4025 .enum_list = NULL,
4026 .flags = FLAG_HIDE,
4030 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4033 .label = "msdfs root",
4034 .type = P_BOOL,
4035 .p_class = P_LOCAL,
4036 .offset = LOCAL_VAR(bMSDfsRoot),
4037 .special = NULL,
4038 .enum_list = NULL,
4039 .flags = FLAG_ADVANCED | FLAG_SHARE,
4042 .label = "msdfs proxy",
4043 .type = P_STRING,
4044 .p_class = P_LOCAL,
4045 .offset = LOCAL_VAR(szMSDfsProxy),
4046 .special = NULL,
4047 .enum_list = NULL,
4048 .flags = FLAG_ADVANCED | FLAG_SHARE,
4051 .label = "host msdfs",
4052 .type = P_BOOL,
4053 .p_class = P_GLOBAL,
4054 .offset = GLOBAL_VAR(bHostMSDfs),
4055 .special = NULL,
4056 .enum_list = NULL,
4057 .flags = FLAG_ADVANCED,
4060 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4063 .label = "passdb expand explicit",
4064 .type = P_BOOL,
4065 .p_class = P_GLOBAL,
4066 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4067 .special = NULL,
4068 .enum_list = NULL,
4069 .flags = FLAG_ADVANCED,
4072 .label = "idmap backend",
4073 .type = P_STRING,
4074 .p_class = P_GLOBAL,
4075 .offset = GLOBAL_VAR(szIdmapBackend),
4076 .special = handle_idmap_backend,
4077 .enum_list = NULL,
4078 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4081 .label = "idmap cache time",
4082 .type = P_INTEGER,
4083 .p_class = P_GLOBAL,
4084 .offset = GLOBAL_VAR(iIdmapCacheTime),
4085 .special = NULL,
4086 .enum_list = NULL,
4087 .flags = FLAG_ADVANCED,
4090 .label = "idmap negative cache time",
4091 .type = P_INTEGER,
4092 .p_class = P_GLOBAL,
4093 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4094 .special = NULL,
4095 .enum_list = NULL,
4096 .flags = FLAG_ADVANCED,
4099 .label = "idmap uid",
4100 .type = P_STRING,
4101 .p_class = P_GLOBAL,
4102 .offset = GLOBAL_VAR(szIdmapUID),
4103 .special = handle_idmap_uid,
4104 .enum_list = NULL,
4105 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4108 .label = "winbind uid",
4109 .type = P_STRING,
4110 .p_class = P_GLOBAL,
4111 .offset = GLOBAL_VAR(szIdmapUID),
4112 .special = handle_idmap_uid,
4113 .enum_list = NULL,
4114 .flags = FLAG_HIDE,
4117 .label = "idmap gid",
4118 .type = P_STRING,
4119 .p_class = P_GLOBAL,
4120 .offset = GLOBAL_VAR(szIdmapGID),
4121 .special = handle_idmap_gid,
4122 .enum_list = NULL,
4123 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4126 .label = "winbind gid",
4127 .type = P_STRING,
4128 .p_class = P_GLOBAL,
4129 .offset = GLOBAL_VAR(szIdmapGID),
4130 .special = handle_idmap_gid,
4131 .enum_list = NULL,
4132 .flags = FLAG_HIDE,
4135 .label = "template homedir",
4136 .type = P_STRING,
4137 .p_class = P_GLOBAL,
4138 .offset = GLOBAL_VAR(szTemplateHomedir),
4139 .special = NULL,
4140 .enum_list = NULL,
4141 .flags = FLAG_ADVANCED,
4144 .label = "template shell",
4145 .type = P_STRING,
4146 .p_class = P_GLOBAL,
4147 .offset = GLOBAL_VAR(szTemplateShell),
4148 .special = NULL,
4149 .enum_list = NULL,
4150 .flags = FLAG_ADVANCED,
4153 .label = "winbind separator",
4154 .type = P_STRING,
4155 .p_class = P_GLOBAL,
4156 .offset = GLOBAL_VAR(szWinbindSeparator),
4157 .special = NULL,
4158 .enum_list = NULL,
4159 .flags = FLAG_ADVANCED,
4162 .label = "winbind cache time",
4163 .type = P_INTEGER,
4164 .p_class = P_GLOBAL,
4165 .offset = GLOBAL_VAR(winbind_cache_time),
4166 .special = NULL,
4167 .enum_list = NULL,
4168 .flags = FLAG_ADVANCED,
4171 .label = "winbind reconnect delay",
4172 .type = P_INTEGER,
4173 .p_class = P_GLOBAL,
4174 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4175 .special = NULL,
4176 .enum_list = NULL,
4177 .flags = FLAG_ADVANCED,
4180 .label = "winbind max clients",
4181 .type = P_INTEGER,
4182 .p_class = P_GLOBAL,
4183 .offset = GLOBAL_VAR(winbind_max_clients),
4184 .special = NULL,
4185 .enum_list = NULL,
4186 .flags = FLAG_ADVANCED,
4189 .label = "winbind enum users",
4190 .type = P_BOOL,
4191 .p_class = P_GLOBAL,
4192 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4193 .special = NULL,
4194 .enum_list = NULL,
4195 .flags = FLAG_ADVANCED,
4198 .label = "winbind enum groups",
4199 .type = P_BOOL,
4200 .p_class = P_GLOBAL,
4201 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4202 .special = NULL,
4203 .enum_list = NULL,
4204 .flags = FLAG_ADVANCED,
4207 .label = "winbind use default domain",
4208 .type = P_BOOL,
4209 .p_class = P_GLOBAL,
4210 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4211 .special = NULL,
4212 .enum_list = NULL,
4213 .flags = FLAG_ADVANCED,
4216 .label = "winbind trusted domains only",
4217 .type = P_BOOL,
4218 .p_class = P_GLOBAL,
4219 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4220 .special = NULL,
4221 .enum_list = NULL,
4222 .flags = FLAG_ADVANCED,
4225 .label = "winbind nested groups",
4226 .type = P_BOOL,
4227 .p_class = P_GLOBAL,
4228 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4229 .special = NULL,
4230 .enum_list = NULL,
4231 .flags = FLAG_ADVANCED,
4234 .label = "winbind expand groups",
4235 .type = P_INTEGER,
4236 .p_class = P_GLOBAL,
4237 .offset = GLOBAL_VAR(winbind_expand_groups),
4238 .special = NULL,
4239 .enum_list = NULL,
4240 .flags = FLAG_ADVANCED,
4243 .label = "winbind nss info",
4244 .type = P_LIST,
4245 .p_class = P_GLOBAL,
4246 .offset = GLOBAL_VAR(szWinbindNssInfo),
4247 .special = NULL,
4248 .enum_list = NULL,
4249 .flags = FLAG_ADVANCED,
4252 .label = "winbind refresh tickets",
4253 .type = P_BOOL,
4254 .p_class = P_GLOBAL,
4255 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4256 .special = NULL,
4257 .enum_list = NULL,
4258 .flags = FLAG_ADVANCED,
4261 .label = "winbind offline logon",
4262 .type = P_BOOL,
4263 .p_class = P_GLOBAL,
4264 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4265 .special = NULL,
4266 .enum_list = NULL,
4267 .flags = FLAG_ADVANCED,
4270 .label = "winbind normalize names",
4271 .type = P_BOOL,
4272 .p_class = P_GLOBAL,
4273 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4274 .special = NULL,
4275 .enum_list = NULL,
4276 .flags = FLAG_ADVANCED,
4279 .label = "winbind rpc only",
4280 .type = P_BOOL,
4281 .p_class = P_GLOBAL,
4282 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4283 .special = NULL,
4284 .enum_list = NULL,
4285 .flags = FLAG_ADVANCED,
4288 .label = "create krb5 conf",
4289 .type = P_BOOL,
4290 .p_class = P_GLOBAL,
4291 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4292 .special = NULL,
4293 .enum_list = NULL,
4294 .flags = FLAG_ADVANCED,
4297 .label = "ncalrpc dir",
4298 .type = P_STRING,
4299 .p_class = P_GLOBAL,
4300 .offset = GLOBAL_VAR(ncalrpc_dir),
4301 .special = NULL,
4302 .enum_list = NULL,
4303 .flags = FLAG_ADVANCED,
4306 .label = "winbind max domain connections",
4307 .type = P_INTEGER,
4308 .p_class = P_GLOBAL,
4309 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4310 .special = NULL,
4311 .enum_list = NULL,
4312 .flags = FLAG_ADVANCED,
4315 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4318 /***************************************************************************
4319 Initialise the sDefault parameter structure for the printer values.
4320 ***************************************************************************/
4322 static void init_printer_values(struct loadparm_service *pService)
4324 /* choose defaults depending on the type of printing */
4325 switch (pService->iPrinting) {
4326 case PRINT_BSD:
4327 case PRINT_AIX:
4328 case PRINT_LPRNT:
4329 case PRINT_LPROS2:
4330 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4331 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4332 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4333 break;
4335 case PRINT_LPRNG:
4336 case PRINT_PLP:
4337 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4338 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4339 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4340 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4341 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4342 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4343 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4344 break;
4346 case PRINT_CUPS:
4347 case PRINT_IPRINT:
4348 #ifdef HAVE_CUPS
4349 /* set the lpq command to contain the destination printer
4350 name only. This is used by cups_queue_get() */
4351 string_set(&pService->szLpqcommand, "%p");
4352 string_set(&pService->szLprmcommand, "");
4353 string_set(&pService->szPrintcommand, "");
4354 string_set(&pService->szLppausecommand, "");
4355 string_set(&pService->szLpresumecommand, "");
4356 string_set(&pService->szQueuepausecommand, "");
4357 string_set(&pService->szQueueresumecommand, "");
4358 #else
4359 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4360 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4361 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4362 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4363 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4364 string_set(&pService->szQueuepausecommand, "disable '%p'");
4365 string_set(&pService->szQueueresumecommand, "enable '%p'");
4366 #endif /* HAVE_CUPS */
4367 break;
4369 case PRINT_SYSV:
4370 case PRINT_HPUX:
4371 string_set(&pService->szLpqcommand, "lpstat -o%p");
4372 string_set(&pService->szLprmcommand, "cancel %p-%j");
4373 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4374 string_set(&pService->szQueuepausecommand, "disable %p");
4375 string_set(&pService->szQueueresumecommand, "enable %p");
4376 #ifndef HPUX
4377 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4378 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4379 #endif /* HPUX */
4380 break;
4382 case PRINT_QNX:
4383 string_set(&pService->szLpqcommand, "lpq -P%p");
4384 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4385 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4386 break;
4388 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4390 case PRINT_TEST:
4391 case PRINT_VLP: {
4392 const char *tdbfile;
4393 char *tmp;
4395 tdbfile = talloc_asprintf(
4396 talloc_tos(), "tdbfile=%s",
4397 lp_parm_const_string(-1, "vlp", "tdbfile",
4398 "/tmp/vlp.tdb"));
4399 if (tdbfile == NULL) {
4400 tdbfile="tdbfile=/tmp/vlp.tdb";
4403 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4404 tdbfile);
4405 string_set(&pService->szPrintcommand,
4406 tmp ? tmp : "vlp print %p %s");
4407 TALLOC_FREE(tmp);
4409 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4410 tdbfile);
4411 string_set(&pService->szLpqcommand,
4412 tmp ? tmp : "vlp lpq %p");
4413 TALLOC_FREE(tmp);
4415 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4416 tdbfile);
4417 string_set(&pService->szLprmcommand,
4418 tmp ? tmp : "vlp lprm %p %j");
4419 TALLOC_FREE(tmp);
4421 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4422 tdbfile);
4423 string_set(&pService->szLppausecommand,
4424 tmp ? tmp : "vlp lppause %p %j");
4425 TALLOC_FREE(tmp);
4427 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4428 tdbfile);
4429 string_set(&pService->szLpresumecommand,
4430 tmp ? tmp : "vlp lpresume %p %j");
4431 TALLOC_FREE(tmp);
4433 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4434 tdbfile);
4435 string_set(&pService->szQueuepausecommand,
4436 tmp ? tmp : "vlp queuepause %p");
4437 TALLOC_FREE(tmp);
4439 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4440 tdbfile);
4441 string_set(&pService->szQueueresumecommand,
4442 tmp ? tmp : "vlp queueresume %p");
4443 TALLOC_FREE(tmp);
4445 break;
4447 #endif /* DEVELOPER */
4452 * Function to return the default value for the maximum number of open
4453 * file descriptors permitted. This function tries to consult the
4454 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4455 * the smaller of those.
4457 static int max_open_files(void)
4459 int sysctl_max = MAX_OPEN_FILES;
4460 int rlimit_max = MAX_OPEN_FILES;
4462 #ifdef HAVE_SYSCTLBYNAME
4464 size_t size = sizeof(sysctl_max);
4465 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4468 #endif
4470 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4472 struct rlimit rl;
4474 ZERO_STRUCT(rl);
4476 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4477 rlimit_max = rl.rlim_cur;
4479 #if defined(RLIM_INFINITY)
4480 if(rl.rlim_cur == RLIM_INFINITY)
4481 rlimit_max = MAX_OPEN_FILES;
4482 #endif
4484 #endif
4486 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4487 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4488 "minimum Windows limit (%d)\n",
4489 sysctl_max,
4490 MIN_OPEN_FILES_WINDOWS));
4491 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4494 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4495 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4496 "minimum Windows limit (%d)\n",
4497 rlimit_max,
4498 MIN_OPEN_FILES_WINDOWS));
4499 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4502 return MIN(sysctl_max, rlimit_max);
4506 * Common part of freeing allocated data for one parameter.
4508 static void free_one_parameter_common(void *parm_ptr,
4509 struct parm_struct parm)
4511 if ((parm.type == P_STRING) ||
4512 (parm.type == P_USTRING))
4514 string_free((char**)parm_ptr);
4515 } else if (parm.type == P_LIST) {
4516 TALLOC_FREE(*((char***)parm_ptr));
4521 * Free the allocated data for one parameter for a share
4522 * given as a service struct.
4524 static void free_one_parameter(struct loadparm_service *service,
4525 struct parm_struct parm)
4527 void *parm_ptr;
4529 if (parm.p_class != P_LOCAL) {
4530 return;
4533 parm_ptr = lp_parm_ptr(service, &parm);
4535 free_one_parameter_common(parm_ptr, parm);
4539 * Free the allocated parameter data of a share given
4540 * as a service struct.
4542 static void free_parameters(struct loadparm_service *service)
4544 uint32_t i;
4546 for (i=0; parm_table[i].label; i++) {
4547 free_one_parameter(service, parm_table[i]);
4552 * Free the allocated data for one parameter for a given share
4553 * specified by an snum.
4555 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4557 void *parm_ptr;
4559 if (snum < 0) {
4560 parm_ptr = lp_parm_ptr(NULL, &parm);
4561 } else if (parm.p_class != P_LOCAL) {
4562 return;
4563 } else {
4564 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4567 free_one_parameter_common(parm_ptr, parm);
4571 * Free the allocated parameter data for a share specified
4572 * by an snum.
4574 static void free_parameters_by_snum(int snum)
4576 uint32_t i;
4578 for (i=0; parm_table[i].label; i++) {
4579 free_one_parameter_by_snum(snum, parm_table[i]);
4584 * Free the allocated global parameters.
4586 static void free_global_parameters(void)
4588 free_param_opts(&Globals.param_opt);
4589 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4592 static int map_parameter(const char *pszParmName);
4594 struct lp_stored_option {
4595 struct lp_stored_option *prev, *next;
4596 const char *label;
4597 const char *value;
4600 static struct lp_stored_option *stored_options;
4603 save options set by lp_set_cmdline() into a list. This list is
4604 re-applied when we do a globals reset, so that cmdline set options
4605 are sticky across reloads of smb.conf
4607 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4609 struct lp_stored_option *entry, *entry_next;
4610 for (entry = stored_options; entry != NULL; entry = entry_next) {
4611 entry_next = entry->next;
4612 if (strcmp(pszParmName, entry->label) == 0) {
4613 DLIST_REMOVE(stored_options, entry);
4614 talloc_free(entry);
4615 break;
4619 entry = talloc(NULL, struct lp_stored_option);
4620 if (!entry) {
4621 return false;
4624 entry->label = talloc_strdup(entry, pszParmName);
4625 if (!entry->label) {
4626 talloc_free(entry);
4627 return false;
4630 entry->value = talloc_strdup(entry, pszParmValue);
4631 if (!entry->value) {
4632 talloc_free(entry);
4633 return false;
4636 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4638 return true;
4641 static bool apply_lp_set_cmdline(void)
4643 struct lp_stored_option *entry = NULL;
4644 for (entry = stored_options; entry != NULL; entry = entry->next) {
4645 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
4646 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4647 entry->label, entry->value));
4648 return false;
4651 return true;
4654 /***************************************************************************
4655 Initialise the global parameter structure.
4656 ***************************************************************************/
4658 static void init_globals(bool reinit_globals)
4660 static bool done_init = false;
4661 char *s = NULL;
4662 int i;
4664 /* If requested to initialize only once and we've already done it... */
4665 if (!reinit_globals && done_init) {
4666 /* ... then we have nothing more to do */
4667 return;
4670 if (!done_init) {
4671 /* The logfile can be set before this is invoked. Free it if so. */
4672 if (Globals.logfile != NULL) {
4673 string_free(&Globals.logfile);
4674 Globals.logfile = NULL;
4676 done_init = true;
4677 } else {
4678 free_global_parameters();
4681 /* This memset and the free_global_parameters() above will
4682 * wipe out smb.conf options set with lp_set_cmdline(). The
4683 * apply_lp_set_cmdline() call puts these values back in the
4684 * table once the defaults are set */
4685 ZERO_STRUCT(Globals);
4687 for (i = 0; parm_table[i].label; i++) {
4688 if ((parm_table[i].type == P_STRING ||
4689 parm_table[i].type == P_USTRING))
4691 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
4696 string_set(&sDefault.fstype, FSTYPE_STRING);
4697 string_set(&sDefault.szPrintjobUsername, "%U");
4699 init_printer_values(&sDefault);
4702 DEBUG(3, ("Initialising global parameters\n"));
4704 /* Must manually force to upper case here, as this does not go via the handler */
4705 string_set(&Globals.szNetbiosName, myhostname_upper());
4707 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4708 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4710 /* use the new 'hash2' method by default, with a prefix of 1 */
4711 string_set(&Globals.szManglingMethod, "hash2");
4712 Globals.mangle_prefix = 1;
4714 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4716 /* using UTF8 by default allows us to support all chars */
4717 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4719 /* Use codepage 850 as a default for the dos character set */
4720 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4723 * Allow the default PASSWD_CHAT to be overridden in local.h.
4725 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4727 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
4729 string_set(&Globals.szPasswdProgram, "");
4730 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4731 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4732 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4733 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4734 string_set(&Globals.szSocketAddress, "0.0.0.0");
4736 * By default support explicit binding to broadcast
4737 * addresses.
4739 Globals.bNmbdBindExplicitBroadcast = true;
4741 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4742 smb_panic("init_globals: ENOMEM");
4744 string_set(&Globals.szServerString, s);
4745 SAFE_FREE(s);
4746 #ifdef DEVELOPER
4747 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4748 #endif
4750 string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
4752 string_set(&Globals.szLogonDrive, "");
4753 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4754 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4755 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4757 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4758 string_set(&Globals.szPasswordServer, "*");
4760 Globals.AlgorithmicRidBase = BASE_RID;
4762 Globals.bLoadPrinters = true;
4763 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4765 Globals.ConfigBackend = config_backend;
4766 Globals.ServerRole = ROLE_AUTO;
4768 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4769 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4770 Globals.max_xmit = 0x4104;
4771 Globals.max_mux = 50; /* This is *needed* for profile support. */
4772 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4773 Globals.bDisableSpoolss = false;
4774 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4775 Globals.pwordlevel = 0;
4776 Globals.unamelevel = 0;
4777 Globals.deadtime = 0;
4778 Globals.getwd_cache = true;
4779 Globals.bLargeReadwrite = true;
4780 Globals.max_log_size = 5000;
4781 Globals.max_open_files = max_open_files();
4782 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4783 Globals.srv_maxprotocol = PROTOCOL_SMB2_10;
4784 Globals.srv_minprotocol = PROTOCOL_LANMAN1;
4785 Globals.security = SEC_USER;
4786 Globals.paranoid_server_security = true;
4787 Globals.bEncryptPasswords = true;
4788 Globals.clientSchannel = Auto;
4789 Globals.serverSchannel = Auto;
4790 Globals.bReadRaw = true;
4791 Globals.bWriteRaw = true;
4792 Globals.bNullPasswords = false;
4793 Globals.bObeyPamRestrictions = false;
4794 Globals.syslog = 1;
4795 Globals.bSyslogOnly = false;
4796 Globals.bTimestampLogs = true;
4797 string_set(&Globals.szLogLevel, "0");
4798 Globals.bDebugPrefixTimestamp = false;
4799 Globals.bDebugHiresTimestamp = true;
4800 Globals.bDebugPid = false;
4801 Globals.bDebugUid = false;
4802 Globals.bDebugClass = false;
4803 Globals.bEnableCoreFiles = true;
4804 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4805 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4806 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4807 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4808 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
4809 Globals.lm_interval = 60;
4810 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4811 Globals.bNISHomeMap = false;
4812 #ifdef WITH_NISPLUS_HOME
4813 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4814 #else
4815 string_set(&Globals.szNISHomeMapName, "auto.home");
4816 #endif
4817 #endif
4818 Globals.bTimeServer = false;
4819 Globals.bBindInterfacesOnly = false;
4820 Globals.bUnixPasswdSync = false;
4821 Globals.bPamPasswordChange = false;
4822 Globals.bPasswdChatDebug = false;
4823 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4824 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
4825 Globals.bNTStatusSupport = true; /* Use NT status by default. */
4826 Globals.bStatCache = true; /* use stat cache by default */
4827 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4828 Globals.restrict_anonymous = 0;
4829 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
4830 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
4831 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
4832 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4833 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4834 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4836 Globals.map_to_guest = 0; /* By Default, "Never" */
4837 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4838 Globals.enhanced_browsing = true;
4839 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4840 #ifdef MMAP_BLACKLIST
4841 Globals.bUseMmap = false;
4842 #else
4843 Globals.bUseMmap = true;
4844 #endif
4845 Globals.bUnixExtensions = true;
4846 Globals.bResetOnZeroVC = false;
4847 Globals.bLogWriteableFilesOnExit = false;
4848 Globals.bCreateKrb5Conf = true;
4849 Globals.winbindMaxDomainConnections = 1;
4851 /* hostname lookups can be very expensive and are broken on
4852 a large number of sites (tridge) */
4853 Globals.bHostnameLookups = false;
4855 string_set(&Globals.passdb_backend, "tdbsam");
4856 string_set(&Globals.szLdapSuffix, "");
4857 string_set(&Globals.szLdapMachineSuffix, "");
4858 string_set(&Globals.szLdapUserSuffix, "");
4859 string_set(&Globals.szLdapGroupSuffix, "");
4860 string_set(&Globals.szLdapIdmapSuffix, "");
4862 string_set(&Globals.szLdapAdminDn, "");
4863 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4864 Globals.ldap_ssl_ads = false;
4865 Globals.ldap_deref = -1;
4866 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4867 Globals.ldap_delete_dn = false;
4868 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4869 Globals.ldap_follow_referral = Auto;
4870 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4871 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4872 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4874 Globals.ldap_debug_level = 0;
4875 Globals.ldap_debug_threshold = 10;
4877 /* This is what we tell the afs client. in reality we set the token
4878 * to never expire, though, when this runs out the afs client will
4879 * forget the token. Set to 0 to get NEVERDATE.*/
4880 Globals.iAfsTokenLifetime = 604800;
4881 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4883 /* these parameters are set to defaults that are more appropriate
4884 for the increasing samba install base:
4886 as a member of the workgroup, that will possibly become a
4887 _local_ master browser (lm = true). this is opposed to a forced
4888 local master browser startup (pm = true).
4890 doesn't provide WINS server service by default (wsupp = false),
4891 and doesn't provide domain master browser services by default, either.
4895 Globals.bMsAddPrinterWizard = true;
4896 Globals.os_level = 20;
4897 Globals.bLocalMaster = true;
4898 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4899 Globals.bDomainLogons = false;
4900 Globals.bBrowseList = true;
4901 Globals.bWINSsupport = false;
4902 Globals.bWINSproxy = false;
4904 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4905 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4907 Globals.bWINSdnsProxy = true;
4909 Globals.bAllowTrustedDomains = true;
4910 string_set(&Globals.szIdmapBackend, "tdb");
4912 string_set(&Globals.szTemplateShell, "/bin/false");
4913 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4914 string_set(&Globals.szWinbindSeparator, "\\");
4916 string_set(&Globals.szCupsServer, "");
4917 string_set(&Globals.szIPrintServer, "");
4919 string_set(&Globals.ctdbdSocket, "");
4920 Globals.szClusterAddresses = NULL;
4921 Globals.clustering = false;
4922 Globals.ctdb_timeout = 0;
4923 Globals.ctdb_locktime_warn_threshold = 0;
4925 Globals.winbind_cache_time = 300; /* 5 minutes */
4926 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4927 Globals.winbind_max_clients = 200;
4928 Globals.bWinbindEnumUsers = false;
4929 Globals.bWinbindEnumGroups = false;
4930 Globals.bWinbindUseDefaultDomain = false;
4931 Globals.bWinbindTrustedDomainsOnly = false;
4932 Globals.bWinbindNestedGroups = true;
4933 Globals.winbind_expand_groups = 1;
4934 Globals.szWinbindNssInfo = (const char **)str_list_make_v3(NULL, "template", NULL);
4935 Globals.bWinbindRefreshTickets = false;
4936 Globals.bWinbindOfflineLogon = false;
4938 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4939 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4941 Globals.bPassdbExpandExplicit = false;
4943 Globals.name_cache_timeout = 660; /* In seconds */
4945 Globals.bUseSpnego = true;
4946 Globals.bClientUseSpnego = true;
4948 Globals.client_signing = SMB_SIGNING_DEFAULT;
4949 Globals.server_signing = SMB_SIGNING_DEFAULT;
4951 Globals.bDeferSharingViolations = true;
4952 string_set(&Globals.smb_ports, SMB_PORTS);
4954 Globals.bEnablePrivileges = true;
4955 Globals.bHostMSDfs = true;
4956 Globals.bASUSupport = false;
4958 /* User defined shares. */
4959 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4960 smb_panic("init_globals: ENOMEM");
4962 string_set(&Globals.szUsersharePath, s);
4963 SAFE_FREE(s);
4964 string_set(&Globals.szUsershareTemplateShare, "");
4965 Globals.iUsershareMaxShares = 0;
4966 /* By default disallow sharing of directories not owned by the sharer. */
4967 Globals.bUsershareOwnerOnly = true;
4968 /* By default disallow guest access to usershares. */
4969 Globals.bUsershareAllowGuests = false;
4971 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4973 /* By default no shares out of the registry */
4974 Globals.bRegistryShares = false;
4976 Globals.iminreceivefile = 0;
4978 Globals.bMapUntrustedToDomain = false;
4979 Globals.bMulticastDnsRegister = true;
4981 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
4982 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
4983 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
4984 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
4986 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
4988 /* Now put back the settings that were set with lp_set_cmdline() */
4989 apply_lp_set_cmdline();
4992 /*******************************************************************
4993 Convenience routine to grab string parameters into temporary memory
4994 and run standard_sub_basic on them. The buffers can be written to by
4995 callers without affecting the source string.
4996 ********************************************************************/
4998 static char *lp_string(const char *s)
5000 char *ret;
5001 TALLOC_CTX *ctx = talloc_tos();
5003 /* The follow debug is useful for tracking down memory problems
5004 especially if you have an inner loop that is calling a lp_*()
5005 function that returns a string. Perhaps this debug should be
5006 present all the time? */
5008 #if 0
5009 DEBUG(10, ("lp_string(%s)\n", s));
5010 #endif
5011 if (!s) {
5012 return NULL;
5015 ret = talloc_sub_basic(ctx,
5016 get_current_username(),
5017 current_user_info.domain,
5019 if (trim_char(ret, '\"', '\"')) {
5020 if (strchr(ret,'\"') != NULL) {
5021 TALLOC_FREE(ret);
5022 ret = talloc_sub_basic(ctx,
5023 get_current_username(),
5024 current_user_info.domain,
5028 return ret;
5032 In this section all the functions that are used to access the
5033 parameters from the rest of the program are defined
5036 #define FN_GLOBAL_STRING(fn_name,ptr) \
5037 char *lp_ ## fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5038 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5039 const char *lp_ ## fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5040 #define FN_GLOBAL_LIST(fn_name,ptr) \
5041 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5042 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5043 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
5044 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5045 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
5046 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5047 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
5049 #define FN_LOCAL_STRING(fn_name,val) \
5050 char *lp_ ## fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5051 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5052 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5053 #define FN_LOCAL_LIST(fn_name,val) \
5054 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5055 #define FN_LOCAL_BOOL(fn_name,val) \
5056 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5057 #define FN_LOCAL_INTEGER(fn_name,val) \
5058 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5060 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5061 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5062 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5063 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5064 #define FN_LOCAL_CHAR(fn_name,val) \
5065 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5068 static FN_GLOBAL_BOOL(domain_logons, bDomainLogons)
5069 static FN_GLOBAL_BOOL(_readraw, bReadRaw)
5070 static FN_GLOBAL_BOOL(time_server, bTimeServer)
5071 static FN_GLOBAL_BOOL(_writeraw, bWriteRaw)
5072 static FN_GLOBAL_CONST_STRING(_ctdbd_socket, ctdbdSocket)
5073 static FN_GLOBAL_INTEGER(_server_role, ServerRole)
5075 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5076 * build process or in smb.conf, we use that value. Otherwise they
5077 * default to the value of lp_lockdir(). */
5078 const char *lp_statedir(void) {
5079 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5080 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5081 return(*(char **)(&Globals.szStateDir) ?
5082 *(char **)(&Globals.szStateDir) : "");
5083 else
5084 return(*(char **)(&Globals.szLockDir) ?
5085 *(char **)(&Globals.szLockDir) : "");
5087 const char *lp_cachedir(void) {
5088 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5089 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5090 return(*(char **)(&Globals.szCacheDir) ?
5091 *(char **)(&Globals.szCacheDir) : "");
5092 else
5093 return(*(char **)(&Globals.szLockDir) ?
5094 *(char **)(&Globals.szLockDir) : "");
5096 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
5097 winbindMaxDomainConnections)
5099 int lp_winbind_max_domain_connections(void)
5101 if (lp_winbind_offline_logon() &&
5102 lp_winbind_max_domain_connections_int() > 1) {
5103 DEBUG(1, ("offline logons active, restricting max domain "
5104 "connections to 1\n"));
5105 return 1;
5107 return MAX(1, lp_winbind_max_domain_connections_int());
5110 int lp_smb2_max_credits(void)
5112 if (Globals.ismb2_max_credits == 0) {
5113 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5115 return Globals.ismb2_max_credits;
5117 int lp_cups_encrypt(void)
5119 int result = 0;
5120 #ifdef HAVE_HTTPCONNECTENCRYPT
5121 switch (Globals.CupsEncrypt) {
5122 case Auto:
5123 result = HTTP_ENCRYPT_REQUIRED;
5124 break;
5125 case true:
5126 result = HTTP_ENCRYPT_ALWAYS;
5127 break;
5128 case false:
5129 result = HTTP_ENCRYPT_NEVER;
5130 break;
5132 #endif
5133 return result;
5136 /* These functions remain in source3/param for now */
5138 FN_GLOBAL_CONST_STRING(name_resolve_order, szNameResolveOrder)
5139 FN_GLOBAL_CONST_STRING(smb_ports, smb_ports)
5140 FN_GLOBAL_INTEGER(security, security)
5141 FN_GLOBAL_INTEGER(usershare_max_shares, iUsershareMaxShares)
5142 FN_GLOBAL_STRING(configfile, szConfigFile)
5144 #include "lib/param/param_functions.c"
5146 FN_LOCAL_STRING(servicename, szService)
5147 FN_LOCAL_CONST_STRING(const_servicename, szService)
5149 /* local prototypes */
5151 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5152 static const char *get_boolean(bool bool_value);
5153 static int getservicebyname(const char *pszServiceName,
5154 struct loadparm_service *pserviceDest);
5155 static void copy_service(struct loadparm_service *pserviceDest,
5156 struct loadparm_service *pserviceSource,
5157 struct bitmap *pcopymapDest);
5158 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5159 void *userdata);
5160 static bool do_section(const char *pszSectionName, void *userdata);
5161 static void init_copymap(struct loadparm_service *pservice);
5162 static bool hash_a_service(const char *name, int number);
5163 static void free_service_byindex(int iService);
5164 static void show_parameter(int parmIndex);
5165 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5168 * This is a helper function for parametrical options support. It returns a
5169 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5170 * parametrical functions are quite simple
5172 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
5173 const char *option)
5175 bool global_section = false;
5176 char* param_key;
5177 struct parmlist_entry *data;
5179 if (service == NULL) {
5180 data = Globals.param_opt;
5181 global_section = true;
5182 } else {
5183 data = service->param_opt;
5186 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5187 DEBUG(0,("asprintf failed!\n"));
5188 return NULL;
5191 while (data) {
5192 if (strwicmp(data->key, param_key) == 0) {
5193 string_free(&param_key);
5194 return data;
5196 data = data->next;
5199 if (!global_section) {
5200 /* Try to fetch the same option but from globals */
5201 /* but only if we are not already working with Globals */
5202 data = Globals.param_opt;
5203 while (data) {
5204 if (strwicmp(data->key, param_key) == 0) {
5205 string_free(&param_key);
5206 return data;
5208 data = data->next;
5212 string_free(&param_key);
5214 return NULL;
5218 * This is a helper function for parametrical options support. It returns a
5219 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5220 * parametrical functions are quite simple
5222 static struct parmlist_entry *get_parametrics(int snum, const char *type,
5223 const char *option)
5225 if (snum >= iNumServices) return NULL;
5227 if (snum < 0) {
5228 return get_parametrics_by_service(NULL, type, option);
5229 } else {
5230 return get_parametrics_by_service(ServicePtrs[snum], type, option);
5235 #define MISSING_PARAMETER(name) \
5236 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5238 /*******************************************************************
5239 convenience routine to return int parameters.
5240 ********************************************************************/
5241 static int lp_int(const char *s)
5244 if (!s || !*s) {
5245 MISSING_PARAMETER(lp_int);
5246 return (-1);
5249 return (int)strtol(s, NULL, 0);
5252 /*******************************************************************
5253 convenience routine to return unsigned long parameters.
5254 ********************************************************************/
5255 static unsigned long lp_ulong(const char *s)
5258 if (!s || !*s) {
5259 MISSING_PARAMETER(lp_ulong);
5260 return (0);
5263 return strtoul(s, NULL, 0);
5266 /*******************************************************************
5267 convenience routine to return boolean parameters.
5268 ********************************************************************/
5269 static bool lp_bool(const char *s)
5271 bool ret = false;
5273 if (!s || !*s) {
5274 MISSING_PARAMETER(lp_bool);
5275 return false;
5278 if (!set_boolean(s, &ret)) {
5279 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5280 return false;
5283 return ret;
5286 /*******************************************************************
5287 convenience routine to return enum parameters.
5288 ********************************************************************/
5289 static int lp_enum(const char *s,const struct enum_list *_enum)
5291 int i;
5293 if (!s || !*s || !_enum) {
5294 MISSING_PARAMETER(lp_enum);
5295 return (-1);
5298 for (i=0; _enum[i].name; i++) {
5299 if (strequal(_enum[i].name,s))
5300 return _enum[i].value;
5303 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5304 return (-1);
5307 #undef MISSING_PARAMETER
5309 /* Return parametric option from a given service. Type is a part of option before ':' */
5310 /* Parametric option has following syntax: 'Type: option = value' */
5311 /* the returned value is talloced on the talloc_tos() */
5312 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5314 struct parmlist_entry *data = get_parametrics(snum, type, option);
5316 if (data == NULL||data->value==NULL) {
5317 if (def) {
5318 return lp_string(def);
5319 } else {
5320 return NULL;
5324 return lp_string(data->value);
5327 /* Return parametric option from a given service. Type is a part of option before ':' */
5328 /* Parametric option has following syntax: 'Type: option = value' */
5329 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5331 struct parmlist_entry *data = get_parametrics(snum, type, option);
5333 if (data == NULL||data->value==NULL)
5334 return def;
5336 return data->value;
5339 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
5341 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
5343 if (data == NULL||data->value==NULL)
5344 return NULL;
5346 return data->value;
5350 /* Return parametric option from a given service. Type is a part of option before ':' */
5351 /* Parametric option has following syntax: 'Type: option = value' */
5353 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5355 struct parmlist_entry *data = get_parametrics(snum, type, option);
5357 if (data == NULL||data->value==NULL)
5358 return (const char **)def;
5360 if (data->list==NULL) {
5361 data->list = str_list_make_v3(NULL, data->value, NULL);
5364 return (const char **)data->list;
5367 /* Return parametric option from a given service. Type is a part of option before ':' */
5368 /* Parametric option has following syntax: 'Type: option = value' */
5370 int lp_parm_int(int snum, const char *type, const char *option, int def)
5372 struct parmlist_entry *data = get_parametrics(snum, type, option);
5374 if (data && data->value && *data->value)
5375 return lp_int(data->value);
5377 return def;
5380 /* Return parametric option from a given service. Type is a part of option before ':' */
5381 /* Parametric option has following syntax: 'Type: option = value' */
5383 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5385 struct parmlist_entry *data = get_parametrics(snum, type, option);
5387 if (data && data->value && *data->value)
5388 return lp_ulong(data->value);
5390 return def;
5393 /* Return parametric option from a given service. Type is a part of option before ':' */
5394 /* Parametric option has following syntax: 'Type: option = value' */
5396 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5398 struct parmlist_entry *data = get_parametrics(snum, type, option);
5400 if (data && data->value && *data->value)
5401 return lp_bool(data->value);
5403 return def;
5406 /* Return parametric option from a given service. Type is a part of option before ':' */
5407 /* Parametric option has following syntax: 'Type: option = value' */
5409 int lp_parm_enum(int snum, const char *type, const char *option,
5410 const struct enum_list *_enum, int def)
5412 struct parmlist_entry *data = get_parametrics(snum, type, option);
5414 if (data && data->value && *data->value && _enum)
5415 return lp_enum(data->value, _enum);
5417 return def;
5421 /***************************************************************************
5422 Initialise a service to the defaults.
5423 ***************************************************************************/
5425 static void init_service(struct loadparm_service *pservice)
5427 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
5428 copy_service(pservice, &sDefault, NULL);
5433 * free a param_opts structure.
5434 * param_opts handling should be moved to talloc;
5435 * then this whole functions reduces to a TALLOC_FREE().
5438 static void free_param_opts(struct parmlist_entry **popts)
5440 struct parmlist_entry *opt, *next_opt;
5442 if (popts == NULL) {
5443 return;
5446 if (*popts != NULL) {
5447 DEBUG(5, ("Freeing parametrics:\n"));
5449 opt = *popts;
5450 while (opt != NULL) {
5451 string_free(&opt->key);
5452 string_free(&opt->value);
5453 TALLOC_FREE(opt->list);
5454 next_opt = opt->next;
5455 SAFE_FREE(opt);
5456 opt = next_opt;
5458 *popts = NULL;
5461 /***************************************************************************
5462 Free the dynamically allocated parts of a service struct.
5463 ***************************************************************************/
5465 static void free_service(struct loadparm_service *pservice)
5467 if (!pservice)
5468 return;
5470 if (pservice->szService)
5471 DEBUG(5, ("free_service: Freeing service %s\n",
5472 pservice->szService));
5474 free_parameters(pservice);
5476 string_free(&pservice->szService);
5477 TALLOC_FREE(pservice->copymap);
5479 free_param_opts(&pservice->param_opt);
5481 ZERO_STRUCTP(pservice);
5485 /***************************************************************************
5486 remove a service indexed in the ServicePtrs array from the ServiceHash
5487 and free the dynamically allocated parts
5488 ***************************************************************************/
5490 static void free_service_byindex(int idx)
5492 if ( !LP_SNUM_OK(idx) )
5493 return;
5495 ServicePtrs[idx]->valid = false;
5496 invalid_services[num_invalid_services++] = idx;
5498 /* we have to cleanup the hash record */
5500 if (ServicePtrs[idx]->szService) {
5501 char *canon_name = canonicalize_servicename(
5502 talloc_tos(),
5503 ServicePtrs[idx]->szService );
5505 dbwrap_delete_bystring(ServiceHash, canon_name );
5506 TALLOC_FREE(canon_name);
5509 free_service(ServicePtrs[idx]);
5512 /***************************************************************************
5513 Add a new service to the services array initialising it with the given
5514 service.
5515 ***************************************************************************/
5517 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5519 int i;
5520 struct loadparm_service tservice;
5521 int num_to_alloc = iNumServices + 1;
5523 tservice = *pservice;
5525 /* it might already exist */
5526 if (name) {
5527 i = getservicebyname(name, NULL);
5528 if (i >= 0) {
5529 return (i);
5533 /* find an invalid one */
5534 i = iNumServices;
5535 if (num_invalid_services > 0) {
5536 i = invalid_services[--num_invalid_services];
5539 /* if not, then create one */
5540 if (i == iNumServices) {
5541 struct loadparm_service **tsp;
5542 int *tinvalid;
5544 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5545 if (tsp == NULL) {
5546 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5547 return (-1);
5549 ServicePtrs = tsp;
5550 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5551 if (!ServicePtrs[iNumServices]) {
5552 DEBUG(0,("add_a_service: out of memory!\n"));
5553 return (-1);
5555 iNumServices++;
5557 /* enlarge invalid_services here for now... */
5558 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5559 num_to_alloc);
5560 if (tinvalid == NULL) {
5561 DEBUG(0,("add_a_service: failed to enlarge "
5562 "invalid_services!\n"));
5563 return (-1);
5565 invalid_services = tinvalid;
5566 } else {
5567 free_service_byindex(i);
5570 ServicePtrs[i]->valid = true;
5572 init_service(ServicePtrs[i]);
5573 copy_service(ServicePtrs[i], &tservice, NULL);
5574 if (name)
5575 string_set(&ServicePtrs[i]->szService, name);
5577 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5578 i, ServicePtrs[i]->szService));
5580 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5581 return (-1);
5584 return (i);
5587 /***************************************************************************
5588 Convert a string to uppercase and remove whitespaces.
5589 ***************************************************************************/
5591 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5593 char *result;
5595 if ( !src ) {
5596 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5597 return NULL;
5600 result = talloc_strdup(ctx, src);
5601 SMB_ASSERT(result != NULL);
5603 strlower_m(result);
5604 return result;
5607 /***************************************************************************
5608 Add a name/index pair for the services array to the hash table.
5609 ***************************************************************************/
5611 static bool hash_a_service(const char *name, int idx)
5613 char *canon_name;
5615 if ( !ServiceHash ) {
5616 DEBUG(10,("hash_a_service: creating servicehash\n"));
5617 ServiceHash = db_open_rbt(NULL);
5618 if ( !ServiceHash ) {
5619 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5620 return false;
5624 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5625 idx, name));
5627 canon_name = canonicalize_servicename(talloc_tos(), name );
5629 dbwrap_store_bystring(ServiceHash, canon_name,
5630 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5631 TDB_REPLACE);
5633 TALLOC_FREE(canon_name);
5635 return true;
5638 /***************************************************************************
5639 Add a new home service, with the specified home directory, defaults coming
5640 from service ifrom.
5641 ***************************************************************************/
5643 bool lp_add_home(const char *pszHomename, int iDefaultService,
5644 const char *user, const char *pszHomedir)
5646 int i;
5648 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5649 pszHomedir[0] == '\0') {
5650 return false;
5653 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5655 if (i < 0)
5656 return false;
5658 if (!(*(ServicePtrs[iDefaultService]->szPath))
5659 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5660 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5663 if (!(*(ServicePtrs[i]->comment))) {
5664 char *comment = NULL;
5665 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5666 return false;
5668 string_set(&ServicePtrs[i]->comment, comment);
5669 SAFE_FREE(comment);
5672 /* set the browseable flag from the global default */
5674 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5675 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
5677 ServicePtrs[i]->autoloaded = true;
5679 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5680 user, ServicePtrs[i]->szPath ));
5682 return true;
5685 /***************************************************************************
5686 Add a new service, based on an old one.
5687 ***************************************************************************/
5689 int lp_add_service(const char *pszService, int iDefaultService)
5691 if (iDefaultService < 0) {
5692 return add_a_service(&sDefault, pszService);
5695 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5698 /***************************************************************************
5699 Add the IPC service.
5700 ***************************************************************************/
5702 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5704 char *comment = NULL;
5705 int i = add_a_service(&sDefault, ipc_name);
5707 if (i < 0)
5708 return false;
5710 if (asprintf(&comment, "IPC Service (%s)",
5711 Globals.szServerString) < 0) {
5712 return false;
5715 string_set(&ServicePtrs[i]->szPath, tmpdir());
5716 string_set(&ServicePtrs[i]->szUsername, "");
5717 string_set(&ServicePtrs[i]->comment, comment);
5718 string_set(&ServicePtrs[i]->fstype, "IPC");
5719 ServicePtrs[i]->iMaxConnections = 0;
5720 ServicePtrs[i]->bAvailable = true;
5721 ServicePtrs[i]->bRead_only = true;
5722 ServicePtrs[i]->bGuest_only = false;
5723 ServicePtrs[i]->bAdministrative_share = true;
5724 ServicePtrs[i]->bGuest_ok = guest_ok;
5725 ServicePtrs[i]->bPrint_ok = false;
5726 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5728 DEBUG(3, ("adding IPC service\n"));
5730 SAFE_FREE(comment);
5731 return true;
5734 /***************************************************************************
5735 Add a new printer service, with defaults coming from service iFrom.
5736 ***************************************************************************/
5738 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5740 const char *comment = "From Printcap";
5741 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5743 if (i < 0)
5744 return false;
5746 /* note that we do NOT default the availability flag to true - */
5747 /* we take it from the default service passed. This allows all */
5748 /* dynamic printers to be disabled by disabling the [printers] */
5749 /* entry (if/when the 'available' keyword is implemented!). */
5751 /* the printer name is set to the service name. */
5752 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5753 string_set(&ServicePtrs[i]->comment, comment);
5755 /* set the browseable flag from the gloabl default */
5756 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5758 /* Printers cannot be read_only. */
5759 ServicePtrs[i]->bRead_only = false;
5760 /* No share modes on printer services. */
5761 ServicePtrs[i]->bShareModes = false;
5762 /* No oplocks on printer services. */
5763 ServicePtrs[i]->bOpLocks = false;
5764 /* Printer services must be printable. */
5765 ServicePtrs[i]->bPrint_ok = true;
5767 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5769 return true;
5773 /***************************************************************************
5774 Check whether the given parameter name is valid.
5775 Parametric options (names containing a colon) are considered valid.
5776 ***************************************************************************/
5778 bool lp_parameter_is_valid(const char *pszParmName)
5780 return ((map_parameter(pszParmName) != -1) ||
5781 (strchr(pszParmName, ':') != NULL));
5784 /***************************************************************************
5785 Check whether the given name is the name of a global parameter.
5786 Returns true for strings belonging to parameters of class
5787 P_GLOBAL, false for all other strings, also for parametric options
5788 and strings not belonging to any option.
5789 ***************************************************************************/
5791 bool lp_parameter_is_global(const char *pszParmName)
5793 int num = map_parameter(pszParmName);
5795 if (num >= 0) {
5796 return (parm_table[num].p_class == P_GLOBAL);
5799 return false;
5802 /**************************************************************************
5803 Check whether the given name is the canonical name of a parameter.
5804 Returns false if it is not a valid parameter Name.
5805 For parametric options, true is returned.
5806 **************************************************************************/
5808 bool lp_parameter_is_canonical(const char *parm_name)
5810 if (!lp_parameter_is_valid(parm_name)) {
5811 return false;
5814 return (map_parameter(parm_name) ==
5815 map_parameter_canonical(parm_name, NULL));
5818 /**************************************************************************
5819 Determine the canonical name for a parameter.
5820 Indicate when it is an inverse (boolean) synonym instead of a
5821 "usual" synonym.
5822 **************************************************************************/
5824 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5825 bool *inverse)
5827 int num;
5829 if (!lp_parameter_is_valid(parm_name)) {
5830 *canon_parm = NULL;
5831 return false;
5834 num = map_parameter_canonical(parm_name, inverse);
5835 if (num < 0) {
5836 /* parametric option */
5837 *canon_parm = parm_name;
5838 } else {
5839 *canon_parm = parm_table[num].label;
5842 return true;
5846 /**************************************************************************
5847 Determine the canonical name for a parameter.
5848 Turn the value given into the inverse boolean expression when
5849 the synonym is an invers boolean synonym.
5851 Return true if parm_name is a valid parameter name and
5852 in case it is an invers boolean synonym, if the val string could
5853 successfully be converted to the reverse bool.
5854 Return false in all other cases.
5855 **************************************************************************/
5857 bool lp_canonicalize_parameter_with_value(const char *parm_name,
5858 const char *val,
5859 const char **canon_parm,
5860 const char **canon_val)
5862 int num;
5863 bool inverse;
5865 if (!lp_parameter_is_valid(parm_name)) {
5866 *canon_parm = NULL;
5867 *canon_val = NULL;
5868 return false;
5871 num = map_parameter_canonical(parm_name, &inverse);
5872 if (num < 0) {
5873 /* parametric option */
5874 *canon_parm = parm_name;
5875 *canon_val = val;
5876 } else {
5877 *canon_parm = parm_table[num].label;
5878 if (inverse) {
5879 if (!lp_invert_boolean(val, canon_val)) {
5880 *canon_val = NULL;
5881 return false;
5883 } else {
5884 *canon_val = val;
5888 return true;
5891 /***************************************************************************
5892 Map a parameter's string representation to something we can use.
5893 Returns false if the parameter string is not recognised, else TRUE.
5894 ***************************************************************************/
5896 static int map_parameter(const char *pszParmName)
5898 int iIndex;
5900 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
5901 return (-1);
5903 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
5904 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
5905 return (iIndex);
5907 /* Warn only if it isn't parametric option */
5908 if (strchr(pszParmName, ':') == NULL)
5909 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
5910 /* We do return 'fail' for parametric options as well because they are
5911 stored in different storage
5913 return (-1);
5916 /***************************************************************************
5917 Map a parameter's string representation to the index of the canonical
5918 form of the parameter (it might be a synonym).
5919 Returns -1 if the parameter string is not recognised.
5920 ***************************************************************************/
5922 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
5924 int parm_num, canon_num;
5925 bool loc_inverse = false;
5927 parm_num = map_parameter(pszParmName);
5928 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
5929 /* invalid, parametric or no canidate for synonyms ... */
5930 goto done;
5933 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
5934 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
5935 parm_num = canon_num;
5936 goto done;
5940 done:
5941 if (inverse != NULL) {
5942 *inverse = loc_inverse;
5944 return parm_num;
5947 /***************************************************************************
5948 return true if parameter number parm1 is a synonym of parameter
5949 number parm2 (parm2 being the principal name).
5950 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
5951 false otherwise.
5952 ***************************************************************************/
5954 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
5956 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
5957 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
5958 (parm_table[parm1].flags & FLAG_HIDE) &&
5959 !(parm_table[parm2].flags & FLAG_HIDE))
5961 if (inverse != NULL) {
5962 if ((parm_table[parm1].type == P_BOOLREV) &&
5963 (parm_table[parm2].type == P_BOOL))
5965 *inverse = true;
5966 } else {
5967 *inverse = false;
5970 return true;
5972 return false;
5975 /***************************************************************************
5976 Show one parameter's name, type, [values,] and flags.
5977 (helper functions for show_parameter_list)
5978 ***************************************************************************/
5980 static void show_parameter(int parmIndex)
5982 int enumIndex, flagIndex;
5983 int parmIndex2;
5984 bool hadFlag;
5985 bool hadSyn;
5986 bool inverse;
5987 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
5988 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
5989 "P_ENUM", "P_SEP"};
5990 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
5991 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
5992 FLAG_HIDE};
5993 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
5994 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
5995 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
5997 printf("%s=%s", parm_table[parmIndex].label,
5998 type[parm_table[parmIndex].type]);
5999 if (parm_table[parmIndex].type == P_ENUM) {
6000 printf(",");
6001 for (enumIndex=0;
6002 parm_table[parmIndex].enum_list[enumIndex].name;
6003 enumIndex++)
6005 printf("%s%s",
6006 enumIndex ? "|" : "",
6007 parm_table[parmIndex].enum_list[enumIndex].name);
6010 printf(",");
6011 hadFlag = false;
6012 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6013 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6014 printf("%s%s",
6015 hadFlag ? "|" : "",
6016 flag_names[flagIndex]);
6017 hadFlag = true;
6021 /* output synonyms */
6022 hadSyn = false;
6023 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6024 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6025 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6026 parm_table[parmIndex2].label);
6027 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6028 if (!hadSyn) {
6029 printf(" (synonyms: ");
6030 hadSyn = true;
6031 } else {
6032 printf(", ");
6034 printf("%s%s", parm_table[parmIndex2].label,
6035 inverse ? "[i]" : "");
6038 if (hadSyn) {
6039 printf(")");
6042 printf("\n");
6045 /***************************************************************************
6046 Show all parameter's name, type, [values,] and flags.
6047 ***************************************************************************/
6049 void show_parameter_list(void)
6051 int classIndex, parmIndex;
6052 const char *section_names[] = { "local", "global", NULL};
6054 for (classIndex=0; section_names[classIndex]; classIndex++) {
6055 printf("[%s]\n", section_names[classIndex]);
6056 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6057 if (parm_table[parmIndex].p_class == classIndex) {
6058 show_parameter(parmIndex);
6064 /***************************************************************************
6065 Check if a given string correctly represents a boolean value.
6066 ***************************************************************************/
6068 bool lp_string_is_valid_boolean(const char *parm_value)
6070 return set_boolean(parm_value, NULL);
6073 /***************************************************************************
6074 Get the standard string representation of a boolean value ("yes" or "no")
6075 ***************************************************************************/
6077 static const char *get_boolean(bool bool_value)
6079 static const char *yes_str = "yes";
6080 static const char *no_str = "no";
6082 return (bool_value ? yes_str : no_str);
6085 /***************************************************************************
6086 Provide the string of the negated boolean value associated to the boolean
6087 given as a string. Returns false if the passed string does not correctly
6088 represent a boolean.
6089 ***************************************************************************/
6091 bool lp_invert_boolean(const char *str, const char **inverse_str)
6093 bool val;
6095 if (!set_boolean(str, &val)) {
6096 return false;
6099 *inverse_str = get_boolean(!val);
6100 return true;
6103 /***************************************************************************
6104 Provide the canonical string representation of a boolean value given
6105 as a string. Return true on success, false if the string given does
6106 not correctly represent a boolean.
6107 ***************************************************************************/
6109 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6111 bool val;
6113 if (!set_boolean(str, &val)) {
6114 return false;
6117 *canon_str = get_boolean(val);
6118 return true;
6121 /***************************************************************************
6122 Find a service by name. Otherwise works like get_service.
6123 ***************************************************************************/
6125 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6127 int iService = -1;
6128 char *canon_name;
6129 TDB_DATA data;
6130 NTSTATUS status;
6132 if (ServiceHash == NULL) {
6133 return -1;
6136 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6138 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
6139 &data);
6141 if (NT_STATUS_IS_OK(status) &&
6142 (data.dptr != NULL) &&
6143 (data.dsize == sizeof(iService)))
6145 iService = *(int *)data.dptr;
6148 TALLOC_FREE(canon_name);
6150 if ((iService != -1) && (LP_SNUM_OK(iService))
6151 && (pserviceDest != NULL)) {
6152 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6155 return (iService);
6158 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6159 struct loadparm_service *lp_service(const char *pszServiceName)
6161 int iService = getservicebyname(pszServiceName, NULL);
6162 if (iService == -1 || !LP_SNUM_OK(iService)) {
6163 return NULL;
6165 return ServicePtrs[iService];
6168 struct loadparm_service *lp_servicebynum(int snum)
6170 if ((snum == -1) || !LP_SNUM_OK(snum)) {
6171 return NULL;
6173 return ServicePtrs[snum];
6176 struct loadparm_service *lp_default_loadparm_service()
6178 return &sDefault;
6182 /***************************************************************************
6183 Copy a service structure to another.
6184 If pcopymapDest is NULL then copy all fields
6185 ***************************************************************************/
6188 * Add a parametric option to a parmlist_entry,
6189 * replacing old value, if already present.
6191 static void set_param_opt(struct parmlist_entry **opt_list,
6192 const char *opt_name,
6193 const char *opt_value,
6194 unsigned priority)
6196 struct parmlist_entry *new_opt, *opt;
6197 bool not_added;
6199 if (opt_list == NULL) {
6200 return;
6203 opt = *opt_list;
6204 not_added = true;
6206 /* Traverse destination */
6207 while (opt) {
6208 /* If we already have same option, override it */
6209 if (strwicmp(opt->key, opt_name) == 0) {
6210 if ((opt->priority & FLAG_CMDLINE) &&
6211 !(priority & FLAG_CMDLINE)) {
6212 /* it's been marked as not to be
6213 overridden */
6214 return;
6216 string_free(&opt->value);
6217 TALLOC_FREE(opt->list);
6218 opt->value = SMB_STRDUP(opt_value);
6219 opt->priority = priority;
6220 not_added = false;
6221 break;
6223 opt = opt->next;
6225 if (not_added) {
6226 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
6227 new_opt->key = SMB_STRDUP(opt_name);
6228 new_opt->value = SMB_STRDUP(opt_value);
6229 new_opt->list = NULL;
6230 new_opt->priority = priority;
6231 DLIST_ADD(*opt_list, new_opt);
6235 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6236 struct bitmap *pcopymapDest)
6238 int i;
6239 bool bcopyall = (pcopymapDest == NULL);
6240 struct parmlist_entry *data;
6242 for (i = 0; parm_table[i].label; i++)
6243 if (parm_table[i].p_class == P_LOCAL &&
6244 (bcopyall || bitmap_query(pcopymapDest,i))) {
6245 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6246 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6248 switch (parm_table[i].type) {
6249 case P_BOOL:
6250 case P_BOOLREV:
6251 *(bool *)dest_ptr = *(bool *)src_ptr;
6252 break;
6254 case P_INTEGER:
6255 case P_ENUM:
6256 case P_OCTAL:
6257 case P_BYTES:
6258 *(int *)dest_ptr = *(int *)src_ptr;
6259 break;
6261 case P_CHAR:
6262 *(char *)dest_ptr = *(char *)src_ptr;
6263 break;
6265 case P_STRING:
6266 string_set((char **)dest_ptr,
6267 *(char **)src_ptr);
6268 break;
6270 case P_USTRING:
6272 char *upper_string = strupper_talloc(talloc_tos(),
6273 *(char **)src_ptr);
6274 string_set((char **)dest_ptr,
6275 upper_string);
6276 TALLOC_FREE(upper_string);
6277 break;
6279 case P_LIST:
6280 TALLOC_FREE(*((char ***)dest_ptr));
6281 *((char ***)dest_ptr) = str_list_copy(NULL,
6282 *(const char ***)src_ptr);
6283 break;
6284 default:
6285 break;
6289 if (bcopyall) {
6290 init_copymap(pserviceDest);
6291 if (pserviceSource->copymap)
6292 bitmap_copy(pserviceDest->copymap,
6293 pserviceSource->copymap);
6296 data = pserviceSource->param_opt;
6297 while (data) {
6298 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6299 data = data->next;
6303 /***************************************************************************
6304 Check a service for consistency. Return false if the service is in any way
6305 incomplete or faulty, else true.
6306 ***************************************************************************/
6308 bool service_ok(int iService)
6310 bool bRetval;
6312 bRetval = true;
6313 if (ServicePtrs[iService]->szService[0] == '\0') {
6314 DEBUG(0, ("The following message indicates an internal error:\n"));
6315 DEBUG(0, ("No service name in service entry.\n"));
6316 bRetval = false;
6319 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6320 /* I can't see why you'd want a non-printable printer service... */
6321 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6322 if (!ServicePtrs[iService]->bPrint_ok) {
6323 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6324 ServicePtrs[iService]->szService));
6325 ServicePtrs[iService]->bPrint_ok = true;
6327 /* [printers] service must also be non-browsable. */
6328 if (ServicePtrs[iService]->bBrowseable)
6329 ServicePtrs[iService]->bBrowseable = false;
6332 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6333 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6334 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6336 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6337 ServicePtrs[iService]->szService));
6338 ServicePtrs[iService]->bAvailable = false;
6341 /* If a service is flagged unavailable, log the fact at level 1. */
6342 if (!ServicePtrs[iService]->bAvailable)
6343 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6344 ServicePtrs[iService]->szService));
6346 return (bRetval);
6349 static struct smbconf_ctx *lp_smbconf_ctx(void)
6351 sbcErr err;
6352 static struct smbconf_ctx *conf_ctx = NULL;
6354 if (conf_ctx == NULL) {
6355 err = smbconf_init(NULL, &conf_ctx, "registry:");
6356 if (!SBC_ERROR_IS_OK(err)) {
6357 DEBUG(1, ("error initializing registry configuration: "
6358 "%s\n", sbcErrorString(err)));
6359 conf_ctx = NULL;
6363 return conf_ctx;
6366 static bool process_smbconf_service(struct smbconf_service *service)
6368 uint32_t count;
6369 bool ret;
6371 if (service == NULL) {
6372 return false;
6375 ret = do_section(service->name, NULL);
6376 if (ret != true) {
6377 return false;
6379 for (count = 0; count < service->num_params; count++) {
6380 ret = do_parameter(service->param_names[count],
6381 service->param_values[count],
6382 NULL);
6383 if (ret != true) {
6384 return false;
6387 if (iServiceIndex >= 0) {
6388 return service_ok(iServiceIndex);
6390 return true;
6394 * load a service from registry and activate it
6396 bool process_registry_service(const char *service_name)
6398 sbcErr err;
6399 struct smbconf_service *service = NULL;
6400 TALLOC_CTX *mem_ctx = talloc_stackframe();
6401 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6402 bool ret = false;
6404 if (conf_ctx == NULL) {
6405 goto done;
6408 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6410 if (!smbconf_share_exists(conf_ctx, service_name)) {
6412 * Registry does not contain data for this service (yet),
6413 * but make sure lp_load doesn't return false.
6415 ret = true;
6416 goto done;
6419 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6420 if (!SBC_ERROR_IS_OK(err)) {
6421 goto done;
6424 ret = process_smbconf_service(service);
6425 if (!ret) {
6426 goto done;
6429 /* store the csn */
6430 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6432 done:
6433 TALLOC_FREE(mem_ctx);
6434 return ret;
6438 * process_registry_globals
6440 static bool process_registry_globals(void)
6442 bool ret;
6444 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6446 ret = do_parameter("registry shares", "yes", NULL);
6447 if (!ret) {
6448 return ret;
6451 return process_registry_service(GLOBAL_NAME);
6454 bool process_registry_shares(void)
6456 sbcErr err;
6457 uint32_t count;
6458 struct smbconf_service **service = NULL;
6459 uint32_t num_shares = 0;
6460 TALLOC_CTX *mem_ctx = talloc_stackframe();
6461 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6462 bool ret = false;
6464 if (conf_ctx == NULL) {
6465 goto done;
6468 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6469 if (!SBC_ERROR_IS_OK(err)) {
6470 goto done;
6473 ret = true;
6475 for (count = 0; count < num_shares; count++) {
6476 if (strequal(service[count]->name, GLOBAL_NAME)) {
6477 continue;
6479 ret = process_smbconf_service(service[count]);
6480 if (!ret) {
6481 goto done;
6485 /* store the csn */
6486 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6488 done:
6489 TALLOC_FREE(mem_ctx);
6490 return ret;
6494 * reload those shares from registry that are already
6495 * activated in the services array.
6497 static bool reload_registry_shares(void)
6499 int i;
6500 bool ret = true;
6502 for (i = 0; i < iNumServices; i++) {
6503 if (!VALID(i)) {
6504 continue;
6507 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
6508 continue;
6511 ret = process_registry_service(ServicePtrs[i]->szService);
6512 if (!ret) {
6513 goto done;
6517 done:
6518 return ret;
6522 #define MAX_INCLUDE_DEPTH 100
6524 static uint8_t include_depth;
6526 static struct file_lists {
6527 struct file_lists *next;
6528 char *name;
6529 char *subfname;
6530 time_t modtime;
6531 } *file_lists = NULL;
6533 /*******************************************************************
6534 Keep a linked list of all config files so we know when one has changed
6535 it's date and needs to be reloaded.
6536 ********************************************************************/
6538 static void add_to_file_list(const char *fname, const char *subfname)
6540 struct file_lists *f = file_lists;
6542 while (f) {
6543 if (f->name && !strcmp(f->name, fname))
6544 break;
6545 f = f->next;
6548 if (!f) {
6549 f = SMB_MALLOC_P(struct file_lists);
6550 if (!f)
6551 return;
6552 f->next = file_lists;
6553 f->name = SMB_STRDUP(fname);
6554 if (!f->name) {
6555 SAFE_FREE(f);
6556 return;
6558 f->subfname = SMB_STRDUP(subfname);
6559 if (!f->subfname) {
6560 SAFE_FREE(f->name);
6561 SAFE_FREE(f);
6562 return;
6564 file_lists = f;
6565 f->modtime = file_modtime(subfname);
6566 } else {
6567 time_t t = file_modtime(subfname);
6568 if (t)
6569 f->modtime = t;
6571 return;
6575 * Free the file lists
6577 static void free_file_list(void)
6579 struct file_lists *f;
6580 struct file_lists *next;
6582 f = file_lists;
6583 while( f ) {
6584 next = f->next;
6585 SAFE_FREE( f->name );
6586 SAFE_FREE( f->subfname );
6587 SAFE_FREE( f );
6588 f = next;
6590 file_lists = NULL;
6595 * Utility function for outsiders to check if we're running on registry.
6597 bool lp_config_backend_is_registry(void)
6599 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6603 * Utility function to check if the config backend is FILE.
6605 bool lp_config_backend_is_file(void)
6607 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6610 /*******************************************************************
6611 Check if a config file has changed date.
6612 ********************************************************************/
6614 bool lp_file_list_changed(void)
6616 struct file_lists *f = file_lists;
6618 DEBUG(6, ("lp_file_list_changed()\n"));
6620 while (f) {
6621 time_t mod_time;
6623 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6624 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6626 if (conf_ctx == NULL) {
6627 return false;
6629 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6630 NULL))
6632 DEBUGADD(6, ("registry config changed\n"));
6633 return true;
6635 } else {
6636 char *n2 = NULL;
6637 n2 = talloc_sub_basic(talloc_tos(),
6638 get_current_username(),
6639 current_user_info.domain,
6640 f->name);
6641 if (!n2) {
6642 return false;
6644 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6645 f->name, n2, ctime(&f->modtime)));
6647 mod_time = file_modtime(n2);
6649 if (mod_time &&
6650 ((f->modtime != mod_time) ||
6651 (f->subfname == NULL) ||
6652 (strcmp(n2, f->subfname) != 0)))
6654 DEBUGADD(6,
6655 ("file %s modified: %s\n", n2,
6656 ctime(&mod_time)));
6657 f->modtime = mod_time;
6658 SAFE_FREE(f->subfname);
6659 f->subfname = SMB_STRDUP(n2);
6660 TALLOC_FREE(n2);
6661 return true;
6663 TALLOC_FREE(n2);
6665 f = f->next;
6667 return false;
6672 * Initialize iconv conversion descriptors.
6674 * This is called the first time it is needed, and also called again
6675 * every time the configuration is reloaded, because the charset or
6676 * codepage might have changed.
6678 static void init_iconv(void)
6680 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
6681 lp_unix_charset(),
6682 true, global_iconv_handle);
6685 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6687 if (strcmp(*ptr, pszParmValue) != 0) {
6688 string_set(ptr, pszParmValue);
6689 init_iconv();
6691 return true;
6694 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6696 bool is_utf8 = false;
6697 size_t len = strlen(pszParmValue);
6699 if (len == 4 || len == 5) {
6700 /* Don't use StrCaseCmp here as we don't want to
6701 initialize iconv. */
6702 if ((toupper_m(pszParmValue[0]) == 'U') &&
6703 (toupper_m(pszParmValue[1]) == 'T') &&
6704 (toupper_m(pszParmValue[2]) == 'F')) {
6705 if (len == 4) {
6706 if (pszParmValue[3] == '8') {
6707 is_utf8 = true;
6709 } else {
6710 if (pszParmValue[3] == '-' &&
6711 pszParmValue[4] == '8') {
6712 is_utf8 = true;
6718 if (strcmp(*ptr, pszParmValue) != 0) {
6719 if (is_utf8) {
6720 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6721 "be UTF8, using (default value) %s instead.\n",
6722 DEFAULT_DOS_CHARSET));
6723 pszParmValue = DEFAULT_DOS_CHARSET;
6725 string_set(ptr, pszParmValue);
6726 init_iconv();
6728 return true;
6731 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6733 bool ret = true;
6734 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
6735 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
6737 ret &= string_set(&Globals.szRealm, pszParmValue);
6738 ret &= string_set(&Globals.szRealm_upper, realm);
6739 ret &= string_set(&Globals.szRealm_lower, dnsdomain);
6740 TALLOC_FREE(realm);
6741 TALLOC_FREE(dnsdomain);
6743 return ret;
6746 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6748 TALLOC_FREE(Globals.szNetbiosAliases);
6749 Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
6750 return set_netbios_aliases(Globals.szNetbiosAliases);
6753 /***************************************************************************
6754 Handle the include operation.
6755 ***************************************************************************/
6756 static bool bAllowIncludeRegistry = true;
6758 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6760 char *fname;
6762 if (include_depth >= MAX_INCLUDE_DEPTH) {
6763 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6764 include_depth));
6765 return false;
6768 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6769 if (!bAllowIncludeRegistry) {
6770 return true;
6772 if (bInGlobalSection) {
6773 bool ret;
6774 include_depth++;
6775 ret = process_registry_globals();
6776 include_depth--;
6777 return ret;
6778 } else {
6779 DEBUG(1, ("\"include = registry\" only effective "
6780 "in %s section\n", GLOBAL_NAME));
6781 return false;
6785 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
6786 current_user_info.domain,
6787 pszParmValue);
6789 add_to_file_list(pszParmValue, fname);
6791 string_set(ptr, fname);
6793 if (file_exist(fname)) {
6794 bool ret;
6795 include_depth++;
6796 ret = pm_process(fname, do_section, do_parameter, NULL);
6797 include_depth--;
6798 TALLOC_FREE(fname);
6799 return ret;
6802 DEBUG(2, ("Can't find include file %s\n", fname));
6803 TALLOC_FREE(fname);
6804 return true;
6807 /***************************************************************************
6808 Handle the interpretation of the copy parameter.
6809 ***************************************************************************/
6811 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6813 bool bRetval;
6814 int iTemp;
6815 struct loadparm_service serviceTemp;
6817 string_set(ptr, pszParmValue);
6819 init_service(&serviceTemp);
6821 bRetval = false;
6823 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6825 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6826 if (iTemp == iServiceIndex) {
6827 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6828 } else {
6829 copy_service(ServicePtrs[iServiceIndex],
6830 &serviceTemp,
6831 ServicePtrs[iServiceIndex]->copymap);
6832 bRetval = true;
6834 } else {
6835 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6836 bRetval = false;
6839 free_service(&serviceTemp);
6840 return (bRetval);
6843 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6845 Globals.ldap_debug_level = lp_int(pszParmValue);
6846 init_ldap_debugging();
6847 return true;
6850 /***************************************************************************
6851 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6852 parameters is:
6854 [global]
6856 idmap uid = 1000-1999
6857 idmap gid = 700-899
6859 We only do simple parsing checks here. The strings are parsed into useful
6860 structures in the idmap daemon code.
6862 ***************************************************************************/
6864 /* Some lp_ routines to return idmap [ug]id information */
6866 static uid_t idmap_uid_low, idmap_uid_high;
6867 static gid_t idmap_gid_low, idmap_gid_high;
6869 bool lp_idmap_uid(uid_t *low, uid_t *high)
6871 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6872 return false;
6874 if (low)
6875 *low = idmap_uid_low;
6877 if (high)
6878 *high = idmap_uid_high;
6880 return true;
6883 bool lp_idmap_gid(gid_t *low, gid_t *high)
6885 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6886 return false;
6888 if (low)
6889 *low = idmap_gid_low;
6891 if (high)
6892 *high = idmap_gid_high;
6894 return true;
6897 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6899 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
6901 return true;
6904 /* Do some simple checks on "idmap [ug]id" parameter values */
6906 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6908 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
6910 return true;
6913 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6915 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
6917 return true;
6920 /***************************************************************************
6921 Handle the DEBUG level list.
6922 ***************************************************************************/
6924 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
6926 string_set(ptr, pszParmValueIn);
6927 return debug_parse_levels(pszParmValueIn);
6930 /***************************************************************************
6931 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6932 ***************************************************************************/
6934 static const char *append_ldap_suffix( const char *str )
6936 const char *suffix_string;
6939 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6940 Globals.szLdapSuffix );
6941 if ( !suffix_string ) {
6942 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6943 return "";
6946 return suffix_string;
6949 const char *lp_ldap_machine_suffix(void)
6951 if (Globals.szLdapMachineSuffix[0])
6952 return append_ldap_suffix(Globals.szLdapMachineSuffix);
6954 return lp_string(Globals.szLdapSuffix);
6957 const char *lp_ldap_user_suffix(void)
6959 if (Globals.szLdapUserSuffix[0])
6960 return append_ldap_suffix(Globals.szLdapUserSuffix);
6962 return lp_string(Globals.szLdapSuffix);
6965 const char *lp_ldap_group_suffix(void)
6967 if (Globals.szLdapGroupSuffix[0])
6968 return append_ldap_suffix(Globals.szLdapGroupSuffix);
6970 return lp_string(Globals.szLdapSuffix);
6973 const char *lp_ldap_idmap_suffix(void)
6975 if (Globals.szLdapIdmapSuffix[0])
6976 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
6978 return lp_string(Globals.szLdapSuffix);
6981 /****************************************************************************
6982 set the value for a P_ENUM
6983 ***************************************************************************/
6985 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
6986 int *ptr )
6988 int i;
6990 for (i = 0; parm->enum_list[i].name; i++) {
6991 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
6992 *ptr = parm->enum_list[i].value;
6993 return;
6996 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
6997 pszParmValue, parm->label));
7000 /***************************************************************************
7001 ***************************************************************************/
7003 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7005 static int parm_num = -1;
7006 struct loadparm_service *s;
7008 if ( parm_num == -1 )
7009 parm_num = map_parameter( "printing" );
7011 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7013 if ( snum < 0 )
7014 s = &sDefault;
7015 else
7016 s = ServicePtrs[snum];
7018 init_printer_values( s );
7020 return true;
7024 /***************************************************************************
7025 Initialise a copymap.
7026 ***************************************************************************/
7028 static void init_copymap(struct loadparm_service *pservice)
7030 int i;
7032 TALLOC_FREE(pservice->copymap);
7034 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7035 if (!pservice->copymap)
7036 DEBUG(0,
7037 ("Couldn't allocate copymap!! (size %d)\n",
7038 (int)NUMPARAMETERS));
7039 else
7040 for (i = 0; i < NUMPARAMETERS; i++)
7041 bitmap_set(pservice->copymap, i);
7045 return the parameter pointer for a parameter
7047 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7049 if (service == NULL) {
7050 if (parm->p_class == P_LOCAL)
7051 return (void *)(((char *)&sDefault)+parm->offset);
7052 else if (parm->p_class == P_GLOBAL)
7053 return (void *)(((char *)&Globals)+parm->offset);
7054 else return NULL;
7055 } else {
7056 return (void *)(((char *)service) + parm->offset);
7060 /***************************************************************************
7061 Return the local pointer to a parameter given the service number and parameter
7062 ***************************************************************************/
7064 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7066 return lp_parm_ptr(ServicePtrs[snum], parm);
7069 /***************************************************************************
7070 Process a parameter for a particular service number. If snum < 0
7071 then assume we are in the globals.
7072 ***************************************************************************/
7074 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7076 int parmnum, i;
7077 void *parm_ptr = NULL; /* where we are going to store the result */
7078 struct parmlist_entry **opt_list;
7080 parmnum = map_parameter(pszParmName);
7082 if (parmnum < 0) {
7083 if (strchr(pszParmName, ':') == NULL) {
7084 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7085 pszParmName));
7086 return true;
7090 * We've got a parametric option
7093 opt_list = (snum < 0)
7094 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7095 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7097 return true;
7100 /* if it's already been set by the command line, then we don't
7101 override here */
7102 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7103 return true;
7106 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7107 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7108 pszParmName));
7111 /* we might point at a service, the default service or a global */
7112 if (snum < 0) {
7113 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7114 } else {
7115 if (parm_table[parmnum].p_class == P_GLOBAL) {
7116 DEBUG(0,
7117 ("Global parameter %s found in service section!\n",
7118 pszParmName));
7119 return true;
7121 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7124 if (snum >= 0) {
7125 if (!ServicePtrs[snum]->copymap)
7126 init_copymap(ServicePtrs[snum]);
7128 /* this handles the aliases - set the copymap for other entries with
7129 the same data pointer */
7130 for (i = 0; parm_table[i].label; i++) {
7131 if ((parm_table[i].offset == parm_table[parmnum].offset)
7132 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
7133 bitmap_clear(ServicePtrs[snum]->copymap, i);
7138 /* if it is a special case then go ahead */
7139 if (parm_table[parmnum].special) {
7140 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7141 (char **)parm_ptr);
7144 /* now switch on the type of variable it is */
7145 switch (parm_table[parmnum].type)
7147 case P_BOOL:
7148 *(bool *)parm_ptr = lp_bool(pszParmValue);
7149 break;
7151 case P_BOOLREV:
7152 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7153 break;
7155 case P_INTEGER:
7156 *(int *)parm_ptr = lp_int(pszParmValue);
7157 break;
7159 case P_CHAR:
7160 *(char *)parm_ptr = *pszParmValue;
7161 break;
7163 case P_OCTAL:
7164 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7165 if ( i != 1 ) {
7166 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7168 break;
7170 case P_BYTES:
7172 uint64_t val;
7173 if (conv_str_size_error(pszParmValue, &val)) {
7174 if (val <= INT_MAX) {
7175 *(int *)parm_ptr = (int)val;
7176 break;
7180 DEBUG(0,("lp_do_parameter(%s): value is not "
7181 "a valid size specifier!\n", pszParmValue));
7182 return false;
7185 case P_LIST:
7186 case P_CMDLIST:
7187 TALLOC_FREE(*((char ***)parm_ptr));
7188 *(char ***)parm_ptr = str_list_make_v3(
7189 NULL, pszParmValue, NULL);
7190 break;
7192 case P_STRING:
7193 string_set((char **)parm_ptr, pszParmValue);
7194 break;
7196 case P_USTRING:
7198 char *upper_string = strupper_talloc(talloc_tos(),
7199 pszParmValue);
7200 string_set((char **)parm_ptr, upper_string);
7201 TALLOC_FREE(upper_string);
7202 break;
7204 case P_ENUM:
7205 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7206 break;
7207 case P_SEP:
7208 break;
7211 return true;
7214 /***************************************************************************
7215 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7216 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7217 ***************************************************************************/
7219 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7221 int parmnum, i;
7222 parmnum = map_parameter(pszParmName);
7223 if (parmnum >= 0) {
7224 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7225 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7226 return false;
7228 parm_table[parmnum].flags |= FLAG_CMDLINE;
7230 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7231 * be grouped in the table, so we don't have to search the
7232 * whole table */
7233 for (i=parmnum-1;
7234 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7235 && parm_table[i].p_class == parm_table[parmnum].p_class;
7236 i--) {
7237 parm_table[i].flags |= FLAG_CMDLINE;
7239 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
7240 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
7241 parm_table[i].flags |= FLAG_CMDLINE;
7244 if (store_values) {
7245 store_lp_set_cmdline(pszParmName, pszParmValue);
7247 return true;
7250 /* it might be parametric */
7251 if (strchr(pszParmName, ':') != NULL) {
7252 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7253 if (store_values) {
7254 store_lp_set_cmdline(pszParmName, pszParmValue);
7256 return true;
7259 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7260 return true;
7263 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7265 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7268 /***************************************************************************
7269 Process a parameter.
7270 ***************************************************************************/
7272 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7273 void *userdata)
7275 if (!bInGlobalSection && bGlobalOnly)
7276 return true;
7278 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7280 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7281 pszParmName, pszParmValue));
7285 set a option from the commandline in 'a=b' format. Use to support --option
7287 bool lp_set_option(const char *option)
7289 char *p, *s;
7290 bool ret;
7292 s = talloc_strdup(NULL, option);
7293 if (!s) {
7294 return false;
7297 p = strchr(s, '=');
7298 if (!p) {
7299 talloc_free(s);
7300 return false;
7303 *p = 0;
7305 /* skip white spaces after the = sign */
7306 do {
7307 p++;
7308 } while (*p == ' ');
7310 ret = lp_set_cmdline(s, p);
7311 talloc_free(s);
7312 return ret;
7315 /**************************************************************************
7316 Print a parameter of the specified type.
7317 ***************************************************************************/
7319 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7321 /* For the seperation of lists values that we print below */
7322 const char *list_sep = ", ";
7323 int i;
7324 switch (p->type)
7326 case P_ENUM:
7327 for (i = 0; p->enum_list[i].name; i++) {
7328 if (*(int *)ptr == p->enum_list[i].value) {
7329 fprintf(f, "%s",
7330 p->enum_list[i].name);
7331 break;
7334 break;
7336 case P_BOOL:
7337 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7338 break;
7340 case P_BOOLREV:
7341 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7342 break;
7344 case P_INTEGER:
7345 case P_BYTES:
7346 fprintf(f, "%d", *(int *)ptr);
7347 break;
7349 case P_CHAR:
7350 fprintf(f, "%c", *(char *)ptr);
7351 break;
7353 case P_OCTAL: {
7354 int val = *(int *)ptr;
7355 if (val == -1) {
7356 fprintf(f, "-1");
7357 } else {
7358 fprintf(f, "0%o", val);
7360 break;
7363 case P_CMDLIST:
7364 list_sep = " ";
7365 /* fall through */
7366 case P_LIST:
7367 if ((char ***)ptr && *(char ***)ptr) {
7368 char **list = *(char ***)ptr;
7369 for (; *list; list++) {
7370 /* surround strings with whitespace in double quotes */
7371 if (*(list+1) == NULL) {
7372 /* last item, no extra separator */
7373 list_sep = "";
7375 if ( strchr_m( *list, ' ' ) ) {
7376 fprintf(f, "\"%s\"%s", *list, list_sep);
7377 } else {
7378 fprintf(f, "%s%s", *list, list_sep);
7382 break;
7384 case P_STRING:
7385 case P_USTRING:
7386 if (*(char **)ptr) {
7387 fprintf(f, "%s", *(char **)ptr);
7389 break;
7390 case P_SEP:
7391 break;
7395 /***************************************************************************
7396 Check if two parameters are equal.
7397 ***************************************************************************/
7399 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7401 switch (type) {
7402 case P_BOOL:
7403 case P_BOOLREV:
7404 return (*((bool *)ptr1) == *((bool *)ptr2));
7406 case P_INTEGER:
7407 case P_ENUM:
7408 case P_OCTAL:
7409 case P_BYTES:
7410 return (*((int *)ptr1) == *((int *)ptr2));
7412 case P_CHAR:
7413 return (*((char *)ptr1) == *((char *)ptr2));
7415 case P_LIST:
7416 case P_CMDLIST:
7417 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7419 case P_STRING:
7420 case P_USTRING:
7422 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7423 if (p1 && !*p1)
7424 p1 = NULL;
7425 if (p2 && !*p2)
7426 p2 = NULL;
7427 return (p1 == p2 || strequal(p1, p2));
7429 case P_SEP:
7430 break;
7432 return false;
7435 /***************************************************************************
7436 Initialize any local varients in the sDefault table.
7437 ***************************************************************************/
7439 void init_locals(void)
7441 /* None as yet. */
7444 /***************************************************************************
7445 Process a new section (service). At this stage all sections are services.
7446 Later we'll have special sections that permit server parameters to be set.
7447 Returns true on success, false on failure.
7448 ***************************************************************************/
7450 static bool do_section(const char *pszSectionName, void *userdata)
7452 bool bRetval;
7453 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7454 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7455 bRetval = false;
7457 /* if we were in a global section then do the local inits */
7458 if (bInGlobalSection && !isglobal)
7459 init_locals();
7461 /* if we've just struck a global section, note the fact. */
7462 bInGlobalSection = isglobal;
7464 /* check for multiple global sections */
7465 if (bInGlobalSection) {
7466 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7467 return true;
7470 if (!bInGlobalSection && bGlobalOnly)
7471 return true;
7473 /* if we have a current service, tidy it up before moving on */
7474 bRetval = true;
7476 if (iServiceIndex >= 0)
7477 bRetval = service_ok(iServiceIndex);
7479 /* if all is still well, move to the next record in the services array */
7480 if (bRetval) {
7481 /* We put this here to avoid an odd message order if messages are */
7482 /* issued by the post-processing of a previous section. */
7483 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7485 iServiceIndex = add_a_service(&sDefault, pszSectionName);
7486 if (iServiceIndex < 0) {
7487 DEBUG(0, ("Failed to add a new service\n"));
7488 return false;
7490 /* Clean all parametric options for service */
7491 /* They will be added during parsing again */
7492 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7495 return bRetval;
7499 /***************************************************************************
7500 Determine if a partcular base parameter is currentl set to the default value.
7501 ***************************************************************************/
7503 static bool is_default(int i)
7505 if (!defaults_saved)
7506 return false;
7507 switch (parm_table[i].type) {
7508 case P_LIST:
7509 case P_CMDLIST:
7510 return str_list_equal((const char **)parm_table[i].def.lvalue,
7511 *(const char ***)lp_parm_ptr(NULL,
7512 &parm_table[i]));
7513 case P_STRING:
7514 case P_USTRING:
7515 return strequal(parm_table[i].def.svalue,
7516 *(char **)lp_parm_ptr(NULL,
7517 &parm_table[i]));
7518 case P_BOOL:
7519 case P_BOOLREV:
7520 return parm_table[i].def.bvalue ==
7521 *(bool *)lp_parm_ptr(NULL,
7522 &parm_table[i]);
7523 case P_CHAR:
7524 return parm_table[i].def.cvalue ==
7525 *(char *)lp_parm_ptr(NULL,
7526 &parm_table[i]);
7527 case P_INTEGER:
7528 case P_OCTAL:
7529 case P_ENUM:
7530 case P_BYTES:
7531 return parm_table[i].def.ivalue ==
7532 *(int *)lp_parm_ptr(NULL,
7533 &parm_table[i]);
7534 case P_SEP:
7535 break;
7537 return false;
7540 /***************************************************************************
7541 Display the contents of the global structure.
7542 ***************************************************************************/
7544 static void dump_globals(FILE *f)
7546 int i;
7547 struct parmlist_entry *data;
7549 fprintf(f, "[global]\n");
7551 for (i = 0; parm_table[i].label; i++)
7552 if (parm_table[i].p_class == P_GLOBAL &&
7553 !(parm_table[i].flags & FLAG_META) &&
7554 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
7555 if (defaults_saved && is_default(i))
7556 continue;
7557 fprintf(f, "\t%s = ", parm_table[i].label);
7558 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7559 &parm_table[i]),
7561 fprintf(f, "\n");
7563 if (Globals.param_opt != NULL) {
7564 data = Globals.param_opt;
7565 while(data) {
7566 fprintf(f, "\t%s = %s\n", data->key, data->value);
7567 data = data->next;
7573 /***************************************************************************
7574 Return true if a local parameter is currently set to the global default.
7575 ***************************************************************************/
7577 bool lp_is_default(int snum, struct parm_struct *parm)
7579 return equal_parameter(parm->type,
7580 lp_parm_ptr(ServicePtrs[snum], parm),
7581 lp_parm_ptr(NULL, parm));
7584 /***************************************************************************
7585 Display the contents of a single services record.
7586 ***************************************************************************/
7588 static void dump_a_service(struct loadparm_service *pService, FILE * f)
7590 int i;
7591 struct parmlist_entry *data;
7593 if (pService != &sDefault)
7594 fprintf(f, "[%s]\n", pService->szService);
7596 for (i = 0; parm_table[i].label; i++) {
7598 if (parm_table[i].p_class == P_LOCAL &&
7599 !(parm_table[i].flags & FLAG_META) &&
7600 (*parm_table[i].label != '-') &&
7601 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7603 if (pService == &sDefault) {
7604 if (defaults_saved && is_default(i))
7605 continue;
7606 } else {
7607 if (equal_parameter(parm_table[i].type,
7608 lp_parm_ptr(pService, &parm_table[i]),
7609 lp_parm_ptr(NULL, &parm_table[i])))
7610 continue;
7613 fprintf(f, "\t%s = ", parm_table[i].label);
7614 print_parameter(&parm_table[i],
7615 lp_parm_ptr(pService, &parm_table[i]),
7617 fprintf(f, "\n");
7621 if (pService->param_opt != NULL) {
7622 data = pService->param_opt;
7623 while(data) {
7624 fprintf(f, "\t%s = %s\n", data->key, data->value);
7625 data = data->next;
7630 /***************************************************************************
7631 Display the contents of a parameter of a single services record.
7632 ***************************************************************************/
7634 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7636 int i;
7637 bool result = false;
7638 parm_class p_class;
7639 unsigned flag = 0;
7640 fstring local_parm_name;
7641 char *parm_opt;
7642 const char *parm_opt_value;
7644 /* check for parametrical option */
7645 fstrcpy( local_parm_name, parm_name);
7646 parm_opt = strchr( local_parm_name, ':');
7648 if (parm_opt) {
7649 *parm_opt = '\0';
7650 parm_opt++;
7651 if (strlen(parm_opt)) {
7652 parm_opt_value = lp_parm_const_string( snum,
7653 local_parm_name, parm_opt, NULL);
7654 if (parm_opt_value) {
7655 printf( "%s\n", parm_opt_value);
7656 result = true;
7659 return result;
7662 /* check for a key and print the value */
7663 if (isGlobal) {
7664 p_class = P_GLOBAL;
7665 flag = FLAG_GLOBAL;
7666 } else
7667 p_class = P_LOCAL;
7669 for (i = 0; parm_table[i].label; i++) {
7670 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7671 !(parm_table[i].flags & FLAG_META) &&
7672 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7673 (*parm_table[i].label != '-') &&
7674 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7676 void *ptr;
7678 if (isGlobal) {
7679 ptr = lp_parm_ptr(NULL,
7680 &parm_table[i]);
7681 } else {
7682 ptr = lp_parm_ptr(ServicePtrs[snum],
7683 &parm_table[i]);
7686 print_parameter(&parm_table[i],
7687 ptr, f);
7688 fprintf(f, "\n");
7689 result = true;
7690 break;
7694 return result;
7697 /***************************************************************************
7698 Return info about the requested parameter (given as a string).
7699 Return NULL when the string is not a valid parameter name.
7700 ***************************************************************************/
7702 struct parm_struct *lp_get_parameter(const char *param_name)
7704 int num = map_parameter(param_name);
7706 if (num < 0) {
7707 return NULL;
7710 return &parm_table[num];
7713 /***************************************************************************
7714 Return info about the next parameter in a service.
7715 snum==GLOBAL_SECTION_SNUM gives the globals.
7716 Return NULL when out of parameters.
7717 ***************************************************************************/
7719 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7721 if (snum < 0) {
7722 /* do the globals */
7723 for (; parm_table[*i].label; (*i)++) {
7724 if (parm_table[*i].p_class == P_SEPARATOR)
7725 return &parm_table[(*i)++];
7727 if ((*parm_table[*i].label == '-'))
7728 continue;
7730 if ((*i) > 0
7731 && (parm_table[*i].offset ==
7732 parm_table[(*i) - 1].offset)
7733 && (parm_table[*i].p_class ==
7734 parm_table[(*i) - 1].p_class))
7735 continue;
7737 if (is_default(*i) && !allparameters)
7738 continue;
7740 return &parm_table[(*i)++];
7742 } else {
7743 struct loadparm_service *pService = ServicePtrs[snum];
7745 for (; parm_table[*i].label; (*i)++) {
7746 if (parm_table[*i].p_class == P_SEPARATOR)
7747 return &parm_table[(*i)++];
7749 if (parm_table[*i].p_class == P_LOCAL &&
7750 (*parm_table[*i].label != '-') &&
7751 ((*i) == 0 ||
7752 (parm_table[*i].offset !=
7753 parm_table[(*i) - 1].offset)))
7755 if (allparameters ||
7756 !equal_parameter(parm_table[*i].type,
7757 lp_parm_ptr(pService,
7758 &parm_table[*i]),
7759 lp_parm_ptr(NULL,
7760 &parm_table[*i])))
7762 return &parm_table[(*i)++];
7768 return NULL;
7772 #if 0
7773 /***************************************************************************
7774 Display the contents of a single copy structure.
7775 ***************************************************************************/
7776 static void dump_copy_map(bool *pcopymap)
7778 int i;
7779 if (!pcopymap)
7780 return;
7782 printf("\n\tNon-Copied parameters:\n");
7784 for (i = 0; parm_table[i].label; i++)
7785 if (parm_table[i].p_class == P_LOCAL &&
7786 parm_table[i].ptr && !pcopymap[i] &&
7787 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7789 printf("\t\t%s\n", parm_table[i].label);
7792 #endif
7794 /***************************************************************************
7795 Return TRUE if the passed service number is within range.
7796 ***************************************************************************/
7798 bool lp_snum_ok(int iService)
7800 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7803 /***************************************************************************
7804 Auto-load some home services.
7805 ***************************************************************************/
7807 static void lp_add_auto_services(char *str)
7809 char *s;
7810 char *p;
7811 int homes;
7812 char *saveptr;
7814 if (!str)
7815 return;
7817 s = SMB_STRDUP(str);
7818 if (!s)
7819 return;
7821 homes = lp_servicenumber(HOMES_NAME);
7823 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7824 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7825 char *home;
7827 if (lp_servicenumber(p) >= 0)
7828 continue;
7830 home = get_user_home_dir(talloc_tos(), p);
7832 if (home && home[0] && homes >= 0)
7833 lp_add_home(p, homes, p, home);
7835 TALLOC_FREE(home);
7837 SAFE_FREE(s);
7840 /***************************************************************************
7841 Auto-load one printer.
7842 ***************************************************************************/
7844 void lp_add_one_printer(const char *name, const char *comment,
7845 const char *location, void *pdata)
7847 int printers = lp_servicenumber(PRINTERS_NAME);
7848 int i;
7850 if (lp_servicenumber(name) < 0) {
7851 lp_add_printer(name, printers);
7852 if ((i = lp_servicenumber(name)) >= 0) {
7853 string_set(&ServicePtrs[i]->comment, comment);
7854 ServicePtrs[i]->autoloaded = true;
7859 /***************************************************************************
7860 Have we loaded a services file yet?
7861 ***************************************************************************/
7863 bool lp_loaded(void)
7865 return (bLoaded);
7868 /***************************************************************************
7869 Unload unused services.
7870 ***************************************************************************/
7872 void lp_killunused(struct smbd_server_connection *sconn,
7873 bool (*snumused) (struct smbd_server_connection *, int))
7875 int i;
7876 for (i = 0; i < iNumServices; i++) {
7877 if (!VALID(i))
7878 continue;
7880 /* don't kill autoloaded or usershare services */
7881 if ( ServicePtrs[i]->autoloaded ||
7882 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7883 continue;
7886 if (!snumused || !snumused(sconn, i)) {
7887 free_service_byindex(i);
7893 * Kill all except autoloaded and usershare services - convenience wrapper
7895 void lp_kill_all_services(void)
7897 lp_killunused(NULL, NULL);
7900 /***************************************************************************
7901 Unload a service.
7902 ***************************************************************************/
7904 void lp_killservice(int iServiceIn)
7906 if (VALID(iServiceIn)) {
7907 free_service_byindex(iServiceIn);
7911 /***************************************************************************
7912 Save the curent values of all global and sDefault parameters into the
7913 defaults union. This allows swat and testparm to show only the
7914 changed (ie. non-default) parameters.
7915 ***************************************************************************/
7917 static void lp_save_defaults(void)
7919 int i;
7920 for (i = 0; parm_table[i].label; i++) {
7921 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
7922 && parm_table[i].p_class == parm_table[i - 1].p_class)
7923 continue;
7924 switch (parm_table[i].type) {
7925 case P_LIST:
7926 case P_CMDLIST:
7927 parm_table[i].def.lvalue = str_list_copy(
7928 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
7929 break;
7930 case P_STRING:
7931 case P_USTRING:
7932 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
7933 break;
7934 case P_BOOL:
7935 case P_BOOLREV:
7936 parm_table[i].def.bvalue =
7937 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
7938 break;
7939 case P_CHAR:
7940 parm_table[i].def.cvalue =
7941 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
7942 break;
7943 case P_INTEGER:
7944 case P_OCTAL:
7945 case P_ENUM:
7946 case P_BYTES:
7947 parm_table[i].def.ivalue =
7948 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
7949 break;
7950 case P_SEP:
7951 break;
7954 defaults_saved = true;
7957 /***********************************************************
7958 If we should send plaintext/LANMAN passwords in the clinet
7959 ************************************************************/
7961 static void set_allowed_client_auth(void)
7963 if (Globals.bClientNTLMv2Auth) {
7964 Globals.bClientLanManAuth = false;
7966 if (!Globals.bClientLanManAuth) {
7967 Globals.bClientPlaintextAuth = false;
7971 /***************************************************************************
7972 JRA.
7973 The following code allows smbd to read a user defined share file.
7974 Yes, this is my intent. Yes, I'm comfortable with that...
7976 THE FOLLOWING IS SECURITY CRITICAL CODE.
7978 It washes your clothes, it cleans your house, it guards you while you sleep...
7979 Do not f%^k with it....
7980 ***************************************************************************/
7982 #define MAX_USERSHARE_FILE_SIZE (10*1024)
7984 /***************************************************************************
7985 Check allowed stat state of a usershare file.
7986 Ensure we print out who is dicking with us so the admin can
7987 get their sorry ass fired.
7988 ***************************************************************************/
7990 static bool check_usershare_stat(const char *fname,
7991 const SMB_STRUCT_STAT *psbuf)
7993 if (!S_ISREG(psbuf->st_ex_mode)) {
7994 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7995 "not a regular file\n",
7996 fname, (unsigned int)psbuf->st_ex_uid ));
7997 return false;
8000 /* Ensure this doesn't have the other write bit set. */
8001 if (psbuf->st_ex_mode & S_IWOTH) {
8002 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8003 "public write. Refusing to allow as a usershare file.\n",
8004 fname, (unsigned int)psbuf->st_ex_uid ));
8005 return false;
8008 /* Should be 10k or less. */
8009 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8010 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8011 "too large (%u) to be a user share file.\n",
8012 fname, (unsigned int)psbuf->st_ex_uid,
8013 (unsigned int)psbuf->st_ex_size ));
8014 return false;
8017 return true;
8020 /***************************************************************************
8021 Parse the contents of a usershare file.
8022 ***************************************************************************/
8024 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8025 SMB_STRUCT_STAT *psbuf,
8026 const char *servicename,
8027 int snum,
8028 char **lines,
8029 int numlines,
8030 char **pp_sharepath,
8031 char **pp_comment,
8032 char **pp_cp_servicename,
8033 struct security_descriptor **ppsd,
8034 bool *pallow_guest)
8036 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8037 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8038 int us_vers;
8039 DIR *dp;
8040 SMB_STRUCT_STAT sbuf;
8041 char *sharepath = NULL;
8042 char *comment = NULL;
8044 *pp_sharepath = NULL;
8045 *pp_comment = NULL;
8047 *pallow_guest = false;
8049 if (numlines < 4) {
8050 return USERSHARE_MALFORMED_FILE;
8053 if (strcmp(lines[0], "#VERSION 1") == 0) {
8054 us_vers = 1;
8055 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8056 us_vers = 2;
8057 if (numlines < 5) {
8058 return USERSHARE_MALFORMED_FILE;
8060 } else {
8061 return USERSHARE_BAD_VERSION;
8064 if (strncmp(lines[1], "path=", 5) != 0) {
8065 return USERSHARE_MALFORMED_PATH;
8068 sharepath = talloc_strdup(ctx, &lines[1][5]);
8069 if (!sharepath) {
8070 return USERSHARE_POSIX_ERR;
8072 trim_string(sharepath, " ", " ");
8074 if (strncmp(lines[2], "comment=", 8) != 0) {
8075 return USERSHARE_MALFORMED_COMMENT_DEF;
8078 comment = talloc_strdup(ctx, &lines[2][8]);
8079 if (!comment) {
8080 return USERSHARE_POSIX_ERR;
8082 trim_string(comment, " ", " ");
8083 trim_char(comment, '"', '"');
8085 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8086 return USERSHARE_MALFORMED_ACL_DEF;
8089 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8090 return USERSHARE_ACL_ERR;
8093 if (us_vers == 2) {
8094 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8095 return USERSHARE_MALFORMED_ACL_DEF;
8097 if (lines[4][9] == 'y') {
8098 *pallow_guest = true;
8101 /* Backwards compatible extension to file version #2. */
8102 if (numlines > 5) {
8103 if (strncmp(lines[5], "sharename=", 10) != 0) {
8104 return USERSHARE_MALFORMED_SHARENAME_DEF;
8106 if (!strequal(&lines[5][10], servicename)) {
8107 return USERSHARE_BAD_SHARENAME;
8109 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8110 if (!*pp_cp_servicename) {
8111 return USERSHARE_POSIX_ERR;
8116 if (*pp_cp_servicename == NULL) {
8117 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8118 if (!*pp_cp_servicename) {
8119 return USERSHARE_POSIX_ERR;
8123 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8124 /* Path didn't change, no checks needed. */
8125 *pp_sharepath = sharepath;
8126 *pp_comment = comment;
8127 return USERSHARE_OK;
8130 /* The path *must* be absolute. */
8131 if (sharepath[0] != '/') {
8132 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8133 servicename, sharepath));
8134 return USERSHARE_PATH_NOT_ABSOLUTE;
8137 /* If there is a usershare prefix deny list ensure one of these paths
8138 doesn't match the start of the user given path. */
8139 if (prefixdenylist) {
8140 int i;
8141 for ( i=0; prefixdenylist[i]; i++ ) {
8142 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8143 servicename, i, prefixdenylist[i], sharepath ));
8144 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8145 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8146 "usershare prefix deny list entries.\n",
8147 servicename, sharepath));
8148 return USERSHARE_PATH_IS_DENIED;
8153 /* If there is a usershare prefix allow list ensure one of these paths
8154 does match the start of the user given path. */
8156 if (prefixallowlist) {
8157 int i;
8158 for ( i=0; prefixallowlist[i]; i++ ) {
8159 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8160 servicename, i, prefixallowlist[i], sharepath ));
8161 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8162 break;
8165 if (prefixallowlist[i] == NULL) {
8166 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8167 "usershare prefix allow list entries.\n",
8168 servicename, sharepath));
8169 return USERSHARE_PATH_NOT_ALLOWED;
8173 /* Ensure this is pointing to a directory. */
8174 dp = opendir(sharepath);
8176 if (!dp) {
8177 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8178 servicename, sharepath));
8179 return USERSHARE_PATH_NOT_DIRECTORY;
8182 /* Ensure the owner of the usershare file has permission to share
8183 this directory. */
8185 if (sys_stat(sharepath, &sbuf, false) == -1) {
8186 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8187 servicename, sharepath, strerror(errno) ));
8188 closedir(dp);
8189 return USERSHARE_POSIX_ERR;
8192 closedir(dp);
8194 if (!S_ISDIR(sbuf.st_ex_mode)) {
8195 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8196 servicename, sharepath ));
8197 return USERSHARE_PATH_NOT_DIRECTORY;
8200 /* Check if sharing is restricted to owner-only. */
8201 /* psbuf is the stat of the usershare definition file,
8202 sbuf is the stat of the target directory to be shared. */
8204 if (lp_usershare_owner_only()) {
8205 /* root can share anything. */
8206 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8207 return USERSHARE_PATH_NOT_ALLOWED;
8211 *pp_sharepath = sharepath;
8212 *pp_comment = comment;
8213 return USERSHARE_OK;
8216 /***************************************************************************
8217 Deal with a usershare file.
8218 Returns:
8219 >= 0 - snum
8220 -1 - Bad name, invalid contents.
8221 - service name already existed and not a usershare, problem
8222 with permissions to share directory etc.
8223 ***************************************************************************/
8225 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8227 SMB_STRUCT_STAT sbuf;
8228 SMB_STRUCT_STAT lsbuf;
8229 char *fname = NULL;
8230 char *sharepath = NULL;
8231 char *comment = NULL;
8232 char *cp_service_name = NULL;
8233 char **lines = NULL;
8234 int numlines = 0;
8235 int fd = -1;
8236 int iService = -1;
8237 TALLOC_CTX *ctx = talloc_stackframe();
8238 struct security_descriptor *psd = NULL;
8239 bool guest_ok = false;
8240 char *canon_name = NULL;
8241 bool added_service = false;
8242 int ret = -1;
8244 /* Ensure share name doesn't contain invalid characters. */
8245 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8246 DEBUG(0,("process_usershare_file: share name %s contains "
8247 "invalid characters (any of %s)\n",
8248 file_name, INVALID_SHARENAME_CHARS ));
8249 goto out;
8252 canon_name = canonicalize_servicename(ctx, file_name);
8253 if (!canon_name) {
8254 goto out;
8257 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8258 if (!fname) {
8259 goto out;
8262 /* Minimize the race condition by doing an lstat before we
8263 open and fstat. Ensure this isn't a symlink link. */
8265 if (sys_lstat(fname, &lsbuf, false) != 0) {
8266 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8267 fname, strerror(errno) ));
8268 goto out;
8271 /* This must be a regular file, not a symlink, directory or
8272 other strange filetype. */
8273 if (!check_usershare_stat(fname, &lsbuf)) {
8274 goto out;
8278 TDB_DATA data;
8279 NTSTATUS status;
8281 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
8282 canon_name, &data);
8284 iService = -1;
8286 if (NT_STATUS_IS_OK(status) &&
8287 (data.dptr != NULL) &&
8288 (data.dsize == sizeof(iService))) {
8289 memcpy(&iService, data.dptr, sizeof(iService));
8293 if (iService != -1 &&
8294 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8295 &lsbuf.st_ex_mtime) == 0) {
8296 /* Nothing changed - Mark valid and return. */
8297 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8298 canon_name ));
8299 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8300 ret = iService;
8301 goto out;
8304 /* Try and open the file read only - no symlinks allowed. */
8305 #ifdef O_NOFOLLOW
8306 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
8307 #else
8308 fd = open(fname, O_RDONLY, 0);
8309 #endif
8311 if (fd == -1) {
8312 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8313 fname, strerror(errno) ));
8314 goto out;
8317 /* Now fstat to be *SURE* it's a regular file. */
8318 if (sys_fstat(fd, &sbuf, false) != 0) {
8319 close(fd);
8320 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8321 fname, strerror(errno) ));
8322 goto out;
8325 /* Is it the same dev/inode as was lstated ? */
8326 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8327 close(fd);
8328 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8329 "Symlink spoofing going on ?\n", fname ));
8330 goto out;
8333 /* This must be a regular file, not a symlink, directory or
8334 other strange filetype. */
8335 if (!check_usershare_stat(fname, &sbuf)) {
8336 goto out;
8339 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8341 close(fd);
8342 if (lines == NULL) {
8343 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8344 fname, (unsigned int)sbuf.st_ex_uid ));
8345 goto out;
8348 if (parse_usershare_file(ctx, &sbuf, file_name,
8349 iService, lines, numlines, &sharepath,
8350 &comment, &cp_service_name,
8351 &psd, &guest_ok) != USERSHARE_OK) {
8352 goto out;
8355 /* Everything ok - add the service possibly using a template. */
8356 if (iService < 0) {
8357 const struct loadparm_service *sp = &sDefault;
8358 if (snum_template != -1) {
8359 sp = ServicePtrs[snum_template];
8362 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8363 DEBUG(0, ("process_usershare_file: Failed to add "
8364 "new service %s\n", cp_service_name));
8365 goto out;
8368 added_service = true;
8370 /* Read only is controlled by usershare ACL below. */
8371 ServicePtrs[iService]->bRead_only = false;
8374 /* Write the ACL of the new/modified share. */
8375 if (!set_share_security(canon_name, psd)) {
8376 DEBUG(0, ("process_usershare_file: Failed to set share "
8377 "security for user share %s\n",
8378 canon_name ));
8379 goto out;
8382 /* If from a template it may be marked invalid. */
8383 ServicePtrs[iService]->valid = true;
8385 /* Set the service as a valid usershare. */
8386 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8388 /* Set guest access. */
8389 if (lp_usershare_allow_guests()) {
8390 ServicePtrs[iService]->bGuest_ok = guest_ok;
8393 /* And note when it was loaded. */
8394 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8395 string_set(&ServicePtrs[iService]->szPath, sharepath);
8396 string_set(&ServicePtrs[iService]->comment, comment);
8398 ret = iService;
8400 out:
8402 if (ret == -1 && iService != -1 && added_service) {
8403 lp_remove_service(iService);
8406 TALLOC_FREE(lines);
8407 TALLOC_FREE(ctx);
8408 return ret;
8411 /***************************************************************************
8412 Checks if a usershare entry has been modified since last load.
8413 ***************************************************************************/
8415 static bool usershare_exists(int iService, struct timespec *last_mod)
8417 SMB_STRUCT_STAT lsbuf;
8418 const char *usersharepath = Globals.szUsersharePath;
8419 char *fname;
8421 if (asprintf(&fname, "%s/%s",
8422 usersharepath,
8423 ServicePtrs[iService]->szService) < 0) {
8424 return false;
8427 if (sys_lstat(fname, &lsbuf, false) != 0) {
8428 SAFE_FREE(fname);
8429 return false;
8432 if (!S_ISREG(lsbuf.st_ex_mode)) {
8433 SAFE_FREE(fname);
8434 return false;
8437 SAFE_FREE(fname);
8438 *last_mod = lsbuf.st_ex_mtime;
8439 return true;
8442 /***************************************************************************
8443 Load a usershare service by name. Returns a valid servicenumber or -1.
8444 ***************************************************************************/
8446 int load_usershare_service(const char *servicename)
8448 SMB_STRUCT_STAT sbuf;
8449 const char *usersharepath = Globals.szUsersharePath;
8450 int max_user_shares = Globals.iUsershareMaxShares;
8451 int snum_template = -1;
8453 if (*usersharepath == 0 || max_user_shares == 0) {
8454 return -1;
8457 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8458 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8459 usersharepath, strerror(errno) ));
8460 return -1;
8463 if (!S_ISDIR(sbuf.st_ex_mode)) {
8464 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8465 usersharepath ));
8466 return -1;
8470 * This directory must be owned by root, and have the 't' bit set.
8471 * It also must not be writable by "other".
8474 #ifdef S_ISVTX
8475 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8476 #else
8477 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8478 #endif
8479 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8480 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8481 usersharepath ));
8482 return -1;
8485 /* Ensure the template share exists if it's set. */
8486 if (Globals.szUsershareTemplateShare[0]) {
8487 /* We can't use lp_servicenumber here as we are recommending that
8488 template shares have -valid=false set. */
8489 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8490 if (ServicePtrs[snum_template]->szService &&
8491 strequal(ServicePtrs[snum_template]->szService,
8492 Globals.szUsershareTemplateShare)) {
8493 break;
8497 if (snum_template == -1) {
8498 DEBUG(0,("load_usershare_service: usershare template share %s "
8499 "does not exist.\n",
8500 Globals.szUsershareTemplateShare ));
8501 return -1;
8505 return process_usershare_file(usersharepath, servicename, snum_template);
8508 /***************************************************************************
8509 Load all user defined shares from the user share directory.
8510 We only do this if we're enumerating the share list.
8511 This is the function that can delete usershares that have
8512 been removed.
8513 ***************************************************************************/
8515 int load_usershare_shares(struct smbd_server_connection *sconn,
8516 bool (*snumused) (struct smbd_server_connection *, int))
8518 DIR *dp;
8519 SMB_STRUCT_STAT sbuf;
8520 struct dirent *de;
8521 int num_usershares = 0;
8522 int max_user_shares = Globals.iUsershareMaxShares;
8523 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8524 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8525 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8526 int iService;
8527 int snum_template = -1;
8528 const char *usersharepath = Globals.szUsersharePath;
8529 int ret = lp_numservices();
8531 if (max_user_shares == 0 || *usersharepath == '\0') {
8532 return lp_numservices();
8535 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8536 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8537 usersharepath, strerror(errno) ));
8538 return ret;
8542 * This directory must be owned by root, and have the 't' bit set.
8543 * It also must not be writable by "other".
8546 #ifdef S_ISVTX
8547 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8548 #else
8549 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8550 #endif
8551 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8552 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8553 usersharepath ));
8554 return ret;
8557 /* Ensure the template share exists if it's set. */
8558 if (Globals.szUsershareTemplateShare[0]) {
8559 /* We can't use lp_servicenumber here as we are recommending that
8560 template shares have -valid=false set. */
8561 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8562 if (ServicePtrs[snum_template]->szService &&
8563 strequal(ServicePtrs[snum_template]->szService,
8564 Globals.szUsershareTemplateShare)) {
8565 break;
8569 if (snum_template == -1) {
8570 DEBUG(0,("load_usershare_shares: usershare template share %s "
8571 "does not exist.\n",
8572 Globals.szUsershareTemplateShare ));
8573 return ret;
8577 /* Mark all existing usershares as pending delete. */
8578 for (iService = iNumServices - 1; iService >= 0; iService--) {
8579 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8580 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8584 dp = opendir(usersharepath);
8585 if (!dp) {
8586 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8587 usersharepath, strerror(errno) ));
8588 return ret;
8591 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8592 (de = readdir(dp));
8593 num_dir_entries++ ) {
8594 int r;
8595 const char *n = de->d_name;
8597 /* Ignore . and .. */
8598 if (*n == '.') {
8599 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8600 continue;
8604 if (n[0] == ':') {
8605 /* Temporary file used when creating a share. */
8606 num_tmp_dir_entries++;
8609 /* Allow 20% tmp entries. */
8610 if (num_tmp_dir_entries > allowed_tmp_entries) {
8611 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8612 "in directory %s\n",
8613 num_tmp_dir_entries, usersharepath));
8614 break;
8617 r = process_usershare_file(usersharepath, n, snum_template);
8618 if (r == 0) {
8619 /* Update the services count. */
8620 num_usershares++;
8621 if (num_usershares >= max_user_shares) {
8622 DEBUG(0,("load_usershare_shares: max user shares reached "
8623 "on file %s in directory %s\n",
8624 n, usersharepath ));
8625 break;
8627 } else if (r == -1) {
8628 num_bad_dir_entries++;
8631 /* Allow 20% bad entries. */
8632 if (num_bad_dir_entries > allowed_bad_entries) {
8633 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8634 "in directory %s\n",
8635 num_bad_dir_entries, usersharepath));
8636 break;
8639 /* Allow 20% bad entries. */
8640 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8641 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8642 "in directory %s\n",
8643 num_dir_entries, usersharepath));
8644 break;
8648 closedir(dp);
8650 /* Sweep through and delete any non-refreshed usershares that are
8651 not currently in use. */
8652 for (iService = iNumServices - 1; iService >= 0; iService--) {
8653 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8654 if (snumused && snumused(sconn, iService)) {
8655 continue;
8657 /* Remove from the share ACL db. */
8658 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8659 lp_servicename(iService) ));
8660 delete_share_security(lp_servicename(iService));
8661 free_service_byindex(iService);
8665 return lp_numservices();
8668 /********************************************************
8669 Destroy global resources allocated in this file
8670 ********************************************************/
8672 void gfree_loadparm(void)
8674 int i;
8676 free_file_list();
8678 /* Free resources allocated to services */
8680 for ( i = 0; i < iNumServices; i++ ) {
8681 if ( VALID(i) ) {
8682 free_service_byindex(i);
8686 SAFE_FREE( ServicePtrs );
8687 iNumServices = 0;
8689 /* Now release all resources allocated to global
8690 parameters and the default service */
8692 free_global_parameters();
8696 /***************************************************************************
8697 Allow client apps to specify that they are a client
8698 ***************************************************************************/
8699 static void lp_set_in_client(bool b)
8701 in_client = b;
8705 /***************************************************************************
8706 Determine if we're running in a client app
8707 ***************************************************************************/
8708 static bool lp_is_in_client(void)
8710 return in_client;
8713 /***************************************************************************
8714 Load the services array from the services file. Return true on success,
8715 false on failure.
8716 ***************************************************************************/
8718 static bool lp_load_ex(const char *pszFname,
8719 bool global_only,
8720 bool save_defaults,
8721 bool add_ipc,
8722 bool initialize_globals,
8723 bool allow_include_registry,
8724 bool load_all_shares)
8726 char *n2 = NULL;
8727 bool bRetval;
8729 bRetval = false;
8731 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8733 bInGlobalSection = true;
8734 bGlobalOnly = global_only;
8735 bAllowIncludeRegistry = allow_include_registry;
8737 init_globals(initialize_globals);
8739 free_file_list();
8741 if (save_defaults) {
8742 init_locals();
8743 lp_save_defaults();
8746 if (!initialize_globals) {
8747 free_param_opts(&Globals.param_opt);
8748 apply_lp_set_cmdline();
8751 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
8753 /* We get sections first, so have to start 'behind' to make up */
8754 iServiceIndex = -1;
8756 if (lp_config_backend_is_file()) {
8757 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
8758 current_user_info.domain,
8759 pszFname);
8760 if (!n2) {
8761 smb_panic("lp_load_ex: out of memory");
8764 add_to_file_list(pszFname, n2);
8766 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8767 TALLOC_FREE(n2);
8769 /* finish up the last section */
8770 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8771 if (bRetval) {
8772 if (iServiceIndex >= 0) {
8773 bRetval = service_ok(iServiceIndex);
8777 if (lp_config_backend_is_registry()) {
8778 /* config backend changed to registry in config file */
8780 * We need to use this extra global variable here to
8781 * survive restart: init_globals uses this as a default
8782 * for ConfigBackend. Otherwise, init_globals would
8783 * send us into an endless loop here.
8785 config_backend = CONFIG_BACKEND_REGISTRY;
8786 /* start over */
8787 DEBUG(1, ("lp_load_ex: changing to config backend "
8788 "registry\n"));
8789 init_globals(true);
8790 lp_kill_all_services();
8791 return lp_load_ex(pszFname, global_only, save_defaults,
8792 add_ipc, initialize_globals,
8793 allow_include_registry,
8794 load_all_shares);
8796 } else if (lp_config_backend_is_registry()) {
8797 bRetval = process_registry_globals();
8798 } else {
8799 DEBUG(0, ("Illegal config backend given: %d\n",
8800 lp_config_backend()));
8801 bRetval = false;
8804 if (bRetval && lp_registry_shares()) {
8805 if (load_all_shares) {
8806 bRetval = process_registry_shares();
8807 } else {
8808 bRetval = reload_registry_shares();
8813 char *serv = lp_auto_services();
8814 lp_add_auto_services(serv);
8815 TALLOC_FREE(serv);
8818 if (add_ipc) {
8819 /* When 'restrict anonymous = 2' guest connections to ipc$
8820 are denied */
8821 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8822 if ( lp_enable_asu_support() ) {
8823 lp_add_ipc("ADMIN$", false);
8827 set_allowed_client_auth();
8829 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
8830 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
8831 lp_passwordserver()));
8834 bLoaded = true;
8836 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8837 /* if bWINSsupport is true and we are in the client */
8838 if (lp_is_in_client() && Globals.bWINSsupport) {
8839 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8842 init_iconv();
8844 fault_configure(smb_panic_s3);
8846 bAllowIncludeRegistry = true;
8848 return (bRetval);
8851 bool lp_load(const char *pszFname,
8852 bool global_only,
8853 bool save_defaults,
8854 bool add_ipc,
8855 bool initialize_globals)
8857 return lp_load_ex(pszFname,
8858 global_only,
8859 save_defaults,
8860 add_ipc,
8861 initialize_globals,
8862 true, /* allow_include_registry */
8863 false); /* load_all_shares*/
8866 bool lp_load_initial_only(const char *pszFname)
8868 return lp_load_ex(pszFname,
8869 true, /* global only */
8870 false, /* save_defaults */
8871 false, /* add_ipc */
8872 true, /* initialize_globals */
8873 false, /* allow_include_registry */
8874 false); /* load_all_shares*/
8878 * most common lp_load wrapper, loading only the globals
8880 bool lp_load_global(const char *file_name)
8882 return lp_load_ex(file_name,
8883 true, /* global_only */
8884 false, /* save_defaults */
8885 false, /* add_ipc */
8886 true, /* initialize_globals */
8887 true, /* allow_include_registry */
8888 false); /* load_all_shares*/
8892 * lp_load wrapper, especially for clients
8894 bool lp_load_client(const char *file_name)
8896 lp_set_in_client(true);
8898 return lp_load_global(file_name);
8902 * lp_load wrapper, loading only globals, but intended
8903 * for subsequent calls, not reinitializing the globals
8904 * to default values
8906 bool lp_load_global_no_reinit(const char *file_name)
8908 return lp_load_ex(file_name,
8909 true, /* global_only */
8910 false, /* save_defaults */
8911 false, /* add_ipc */
8912 false, /* initialize_globals */
8913 true, /* allow_include_registry */
8914 false); /* load_all_shares*/
8918 * lp_load wrapper, especially for clients, no reinitialization
8920 bool lp_load_client_no_reinit(const char *file_name)
8922 lp_set_in_client(true);
8924 return lp_load_global_no_reinit(file_name);
8927 bool lp_load_with_registry_shares(const char *pszFname,
8928 bool global_only,
8929 bool save_defaults,
8930 bool add_ipc,
8931 bool initialize_globals)
8933 return lp_load_ex(pszFname,
8934 global_only,
8935 save_defaults,
8936 add_ipc,
8937 initialize_globals,
8938 true, /* allow_include_registry */
8939 true); /* load_all_shares*/
8942 /***************************************************************************
8943 Return the max number of services.
8944 ***************************************************************************/
8946 int lp_numservices(void)
8948 return (iNumServices);
8951 /***************************************************************************
8952 Display the contents of the services array in human-readable form.
8953 ***************************************************************************/
8955 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8957 int iService;
8959 if (show_defaults)
8960 defaults_saved = false;
8962 dump_globals(f);
8964 dump_a_service(&sDefault, f);
8966 for (iService = 0; iService < maxtoprint; iService++) {
8967 fprintf(f,"\n");
8968 lp_dump_one(f, show_defaults, iService);
8972 /***************************************************************************
8973 Display the contents of one service in human-readable form.
8974 ***************************************************************************/
8976 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8978 if (VALID(snum)) {
8979 if (ServicePtrs[snum]->szService[0] == '\0')
8980 return;
8981 dump_a_service(ServicePtrs[snum], f);
8985 /***************************************************************************
8986 Return the number of the service with the given name, or -1 if it doesn't
8987 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8988 getservicebyname()! This works ONLY if all services have been loaded, and
8989 does not copy the found service.
8990 ***************************************************************************/
8992 int lp_servicenumber(const char *pszServiceName)
8994 int iService;
8995 fstring serviceName;
8997 if (!pszServiceName) {
8998 return GLOBAL_SECTION_SNUM;
9001 for (iService = iNumServices - 1; iService >= 0; iService--) {
9002 if (VALID(iService) && ServicePtrs[iService]->szService) {
9004 * The substitution here is used to support %U is
9005 * service names
9007 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9008 standard_sub_basic(get_current_username(),
9009 current_user_info.domain,
9010 serviceName,sizeof(serviceName));
9011 if (strequal(serviceName, pszServiceName)) {
9012 break;
9017 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9018 struct timespec last_mod;
9020 if (!usershare_exists(iService, &last_mod)) {
9021 /* Remove the share security tdb entry for it. */
9022 delete_share_security(lp_servicename(iService));
9023 /* Remove it from the array. */
9024 free_service_byindex(iService);
9025 /* Doesn't exist anymore. */
9026 return GLOBAL_SECTION_SNUM;
9029 /* Has it been modified ? If so delete and reload. */
9030 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9031 &last_mod) < 0) {
9032 /* Remove it from the array. */
9033 free_service_byindex(iService);
9034 /* and now reload it. */
9035 iService = load_usershare_service(pszServiceName);
9039 if (iService < 0) {
9040 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9041 return GLOBAL_SECTION_SNUM;
9044 return (iService);
9047 /*******************************************************************
9048 A useful volume label function.
9049 ********************************************************************/
9051 const char *volume_label(int snum)
9053 char *ret;
9054 const char *label = lp_volume(snum);
9055 if (!*label) {
9056 label = lp_servicename(snum);
9059 /* This returns a 33 byte guarenteed null terminated string. */
9060 ret = talloc_strndup(talloc_tos(), label, 32);
9061 if (!ret) {
9062 return "";
9064 return ret;
9067 /*******************************************************************
9068 Get the default server type we will announce as via nmbd.
9069 ********************************************************************/
9071 int lp_default_server_announce(void)
9073 int default_server_announce = 0;
9074 default_server_announce |= SV_TYPE_WORKSTATION;
9075 default_server_announce |= SV_TYPE_SERVER;
9076 default_server_announce |= SV_TYPE_SERVER_UNIX;
9078 /* note that the flag should be set only if we have a
9079 printer service but nmbd doesn't actually load the
9080 services so we can't tell --jerry */
9082 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9084 default_server_announce |= SV_TYPE_SERVER_NT;
9085 default_server_announce |= SV_TYPE_NT;
9087 switch (lp_server_role()) {
9088 case ROLE_DOMAIN_MEMBER:
9089 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9090 break;
9091 case ROLE_DOMAIN_PDC:
9092 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9093 break;
9094 case ROLE_DOMAIN_BDC:
9095 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9096 break;
9097 case ROLE_STANDALONE:
9098 default:
9099 break;
9101 if (lp_time_server())
9102 default_server_announce |= SV_TYPE_TIME_SOURCE;
9104 if (lp_host_msdfs())
9105 default_server_announce |= SV_TYPE_DFS_SERVER;
9107 return default_server_announce;
9110 /***********************************************************
9111 If we are PDC then prefer us as DMB
9112 ************************************************************/
9114 bool lp_domain_master(void)
9116 if (Globals.iDomainMaster == Auto)
9117 return (lp_server_role() == ROLE_DOMAIN_PDC);
9119 return (bool)Globals.iDomainMaster;
9122 /***********************************************************
9123 If we are PDC then prefer us as DMB
9124 ************************************************************/
9126 static bool lp_domain_master_true_or_auto(void)
9128 if (Globals.iDomainMaster) /* auto or yes */
9129 return true;
9131 return false;
9134 /***********************************************************
9135 If we are DMB then prefer us as LMB
9136 ************************************************************/
9138 bool lp_preferred_master(void)
9140 if (Globals.iPreferredMaster == Auto)
9141 return (lp_local_master() && lp_domain_master());
9143 return (bool)Globals.iPreferredMaster;
9146 /*******************************************************************
9147 Remove a service.
9148 ********************************************************************/
9150 void lp_remove_service(int snum)
9152 ServicePtrs[snum]->valid = false;
9153 invalid_services[num_invalid_services++] = snum;
9156 /*******************************************************************
9157 Copy a service.
9158 ********************************************************************/
9160 void lp_copy_service(int snum, const char *new_name)
9162 do_section(new_name, NULL);
9163 if (snum >= 0) {
9164 snum = lp_servicenumber(new_name);
9165 if (snum >= 0)
9166 lp_do_parameter(snum, "copy", lp_servicename(snum));
9171 /***********************************************************
9172 Set the global name resolution order (used in smbclient).
9173 ************************************************************/
9175 void lp_set_name_resolve_order(const char *new_order)
9177 string_set(&Globals.szNameResolveOrder, new_order);
9180 const char *lp_printername(int snum)
9182 const char *ret = lp__printername(snum);
9183 if (ret == NULL || (ret != NULL && *ret == '\0'))
9184 ret = lp_const_servicename(snum);
9186 return ret;
9190 /***********************************************************
9191 Allow daemons such as winbindd to fix their logfile name.
9192 ************************************************************/
9194 void lp_set_logfile(const char *name)
9196 string_set(&Globals.logfile, name);
9197 debug_set_logfile(name);
9200 /*******************************************************************
9201 Return the max print jobs per queue.
9202 ********************************************************************/
9204 int lp_maxprintjobs(int snum)
9206 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9207 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9208 maxjobs = PRINT_MAX_JOBID - 1;
9210 return maxjobs;
9213 const char *lp_printcapname(void)
9215 if ((Globals.szPrintcapname != NULL) &&
9216 (Globals.szPrintcapname[0] != '\0'))
9217 return Globals.szPrintcapname;
9219 if (sDefault.iPrinting == PRINT_CUPS) {
9220 #ifdef HAVE_CUPS
9221 return "cups";
9222 #else
9223 return "lpstat";
9224 #endif
9227 if (sDefault.iPrinting == PRINT_BSD)
9228 return "/etc/printcap";
9230 return PRINTCAP_NAME;
9233 static uint32 spoolss_state;
9235 bool lp_disable_spoolss( void )
9237 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9238 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9240 return spoolss_state == SVCCTL_STOPPED ? true : false;
9243 void lp_set_spoolss_state( uint32 state )
9245 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9247 spoolss_state = state;
9250 uint32 lp_get_spoolss_state( void )
9252 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9255 /*******************************************************************
9256 Ensure we don't use sendfile if server smb signing is active.
9257 ********************************************************************/
9259 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9261 bool sign_active = false;
9263 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9264 if (get_Protocol() < PROTOCOL_NT1) {
9265 return false;
9267 if (signing_state) {
9268 sign_active = smb_signing_is_active(signing_state);
9270 return (lp__use_sendfile(snum) &&
9271 (get_remote_arch() != RA_WIN95) &&
9272 !sign_active);
9275 /*******************************************************************
9276 Turn off sendfile if we find the underlying OS doesn't support it.
9277 ********************************************************************/
9279 void set_use_sendfile(int snum, bool val)
9281 if (LP_SNUM_OK(snum))
9282 ServicePtrs[snum]->bUseSendfile = val;
9283 else
9284 sDefault.bUseSendfile = val;
9287 /*******************************************************************
9288 Turn off storing DOS attributes if this share doesn't support it.
9289 ********************************************************************/
9291 void set_store_dos_attributes(int snum, bool val)
9293 if (!LP_SNUM_OK(snum))
9294 return;
9295 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9298 void lp_set_mangling_method(const char *new_method)
9300 string_set(&Globals.szManglingMethod, new_method);
9303 /*******************************************************************
9304 Global state for POSIX pathname processing.
9305 ********************************************************************/
9307 static bool posix_pathnames;
9309 bool lp_posix_pathnames(void)
9311 return posix_pathnames;
9314 /*******************************************************************
9315 Change everything needed to ensure POSIX pathname processing (currently
9316 not much).
9317 ********************************************************************/
9319 void lp_set_posix_pathnames(void)
9321 posix_pathnames = true;
9324 /*******************************************************************
9325 Global state for POSIX lock processing - CIFS unix extensions.
9326 ********************************************************************/
9328 bool posix_default_lock_was_set;
9329 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9331 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9333 if (posix_default_lock_was_set) {
9334 return posix_cifsx_locktype;
9335 } else {
9336 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9340 /*******************************************************************
9341 ********************************************************************/
9343 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9345 posix_default_lock_was_set = true;
9346 posix_cifsx_locktype = val;
9349 int lp_min_receive_file_size(void)
9351 if (Globals.iminreceivefile < 0) {
9352 return 0;
9354 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9357 /*******************************************************************
9358 If socket address is an empty character string, it is necessary to
9359 define it as "0.0.0.0".
9360 ********************************************************************/
9362 const char *lp_socket_address(void)
9364 char *sock_addr = Globals.szSocketAddress;
9366 if (sock_addr[0] == '\0'){
9367 string_set(&Globals.szSocketAddress, "0.0.0.0");
9369 return Globals.szSocketAddress;
9372 /*******************************************************************
9373 Safe wide links checks.
9374 This helper function always verify the validity of wide links,
9375 even after a configuration file reload.
9376 ********************************************************************/
9378 static bool lp_widelinks_internal(int snum)
9380 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9381 sDefault.bWidelinks);
9384 void widelinks_warning(int snum)
9386 if (lp_allow_insecure_widelinks()) {
9387 return;
9390 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9391 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9392 "These parameters are incompatible. "
9393 "Wide links will be disabled for this share.\n",
9394 lp_servicename(snum) ));
9398 bool lp_widelinks(int snum)
9400 /* wide links is always incompatible with unix extensions */
9401 if (lp_unix_extensions()) {
9403 * Unless we have "allow insecure widelinks"
9404 * turned on.
9406 if (!lp_allow_insecure_widelinks()) {
9407 return false;
9411 return lp_widelinks_internal(snum);
9414 bool lp_writeraw(void)
9416 if (lp_async_smb_echo_handler()) {
9417 return false;
9419 return lp__writeraw();
9422 bool lp_readraw(void)
9424 if (lp_async_smb_echo_handler()) {
9425 return false;
9427 return lp__readraw();
9430 int lp_server_role(void)
9432 return lp_find_server_role(lp__server_role(),
9433 lp_security(),
9434 lp_domain_logons(),
9435 lp_domain_master_true_or_auto());
9438 const char *lp_ctdbd_socket(void)
9440 const char *result = lp__ctdbd_socket();
9442 #ifdef CLUSTER_SUPPORT
9443 if ((result == NULL) || (*result == '\0')) {
9444 return CTDB_PATH;
9446 #endif
9447 return result;