s3: Fix Coverity ID 242726 Uninitialized scalar variable
[Samba/gebeck_regimport.git] / source3 / param / loadparm.c
blobe781048d8ecf33c3aa129b55cf9c18f512e322d8
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 = "passdb backend",
727 .type = P_STRING,
728 .p_class = P_GLOBAL,
729 .offset = GLOBAL_VAR(szPassdbBackend),
730 .special = NULL,
731 .enum_list = NULL,
732 .flags = FLAG_ADVANCED | FLAG_WIZARD,
735 .label = "algorithmic rid base",
736 .type = P_INTEGER,
737 .p_class = P_GLOBAL,
738 .offset = GLOBAL_VAR(AlgorithmicRidBase),
739 .special = NULL,
740 .enum_list = NULL,
741 .flags = FLAG_ADVANCED,
744 .label = "root directory",
745 .type = P_STRING,
746 .p_class = P_GLOBAL,
747 .offset = GLOBAL_VAR(szRootdir),
748 .special = NULL,
749 .enum_list = NULL,
750 .flags = FLAG_ADVANCED,
753 .label = "root dir",
754 .type = P_STRING,
755 .p_class = P_GLOBAL,
756 .offset = GLOBAL_VAR(szRootdir),
757 .special = NULL,
758 .enum_list = NULL,
759 .flags = FLAG_HIDE,
762 .label = "root",
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 = "guest account",
772 .type = P_STRING,
773 .p_class = P_GLOBAL,
774 .offset = GLOBAL_VAR(szGuestaccount),
775 .special = NULL,
776 .enum_list = NULL,
777 .flags = FLAG_BASIC | FLAG_ADVANCED,
780 .label = "enable privileges",
781 .type = P_BOOL,
782 .p_class = P_GLOBAL,
783 .offset = GLOBAL_VAR(bEnablePrivileges),
784 .special = NULL,
785 .enum_list = NULL,
786 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
790 .label = "pam password change",
791 .type = P_BOOL,
792 .p_class = P_GLOBAL,
793 .offset = GLOBAL_VAR(bPamPasswordChange),
794 .special = NULL,
795 .enum_list = NULL,
796 .flags = FLAG_ADVANCED,
799 .label = "passwd program",
800 .type = P_STRING,
801 .p_class = P_GLOBAL,
802 .offset = GLOBAL_VAR(szPasswdProgram),
803 .special = NULL,
804 .enum_list = NULL,
805 .flags = FLAG_ADVANCED,
808 .label = "passwd chat",
809 .type = P_STRING,
810 .p_class = P_GLOBAL,
811 .offset = GLOBAL_VAR(szPasswdChat),
812 .special = NULL,
813 .enum_list = NULL,
814 .flags = FLAG_ADVANCED,
817 .label = "passwd chat debug",
818 .type = P_BOOL,
819 .p_class = P_GLOBAL,
820 .offset = GLOBAL_VAR(bPasswdChatDebug),
821 .special = NULL,
822 .enum_list = NULL,
823 .flags = FLAG_ADVANCED,
826 .label = "passwd chat timeout",
827 .type = P_INTEGER,
828 .p_class = P_GLOBAL,
829 .offset = GLOBAL_VAR(iPasswdChatTimeout),
830 .special = NULL,
831 .enum_list = NULL,
832 .flags = FLAG_ADVANCED,
835 .label = "check password script",
836 .type = P_STRING,
837 .p_class = P_GLOBAL,
838 .offset = GLOBAL_VAR(szCheckPasswordScript),
839 .special = NULL,
840 .enum_list = NULL,
841 .flags = FLAG_ADVANCED,
844 .label = "username map",
845 .type = P_STRING,
846 .p_class = P_GLOBAL,
847 .offset = GLOBAL_VAR(szUsernameMap),
848 .special = NULL,
849 .enum_list = NULL,
850 .flags = FLAG_ADVANCED,
853 .label = "password level",
854 .type = P_INTEGER,
855 .p_class = P_GLOBAL,
856 .offset = GLOBAL_VAR(pwordlevel),
857 .special = NULL,
858 .enum_list = NULL,
859 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
862 .label = "username level",
863 .type = P_INTEGER,
864 .p_class = P_GLOBAL,
865 .offset = GLOBAL_VAR(unamelevel),
866 .special = NULL,
867 .enum_list = NULL,
868 .flags = FLAG_ADVANCED,
871 .label = "unix password sync",
872 .type = P_BOOL,
873 .p_class = P_GLOBAL,
874 .offset = GLOBAL_VAR(bUnixPasswdSync),
875 .special = NULL,
876 .enum_list = NULL,
877 .flags = FLAG_ADVANCED,
880 .label = "restrict anonymous",
881 .type = P_INTEGER,
882 .p_class = P_GLOBAL,
883 .offset = GLOBAL_VAR(restrict_anonymous),
884 .special = NULL,
885 .enum_list = NULL,
886 .flags = FLAG_ADVANCED,
889 .label = "lanman auth",
890 .type = P_BOOL,
891 .p_class = P_GLOBAL,
892 .offset = GLOBAL_VAR(bLanmanAuth),
893 .special = NULL,
894 .enum_list = NULL,
895 .flags = FLAG_ADVANCED,
898 .label = "ntlm auth",
899 .type = P_BOOL,
900 .p_class = P_GLOBAL,
901 .offset = GLOBAL_VAR(bNTLMAuth),
902 .special = NULL,
903 .enum_list = NULL,
904 .flags = FLAG_ADVANCED,
907 .label = "client NTLMv2 auth",
908 .type = P_BOOL,
909 .p_class = P_GLOBAL,
910 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
911 .special = NULL,
912 .enum_list = NULL,
913 .flags = FLAG_ADVANCED,
916 .label = "client lanman auth",
917 .type = P_BOOL,
918 .p_class = P_GLOBAL,
919 .offset = GLOBAL_VAR(bClientLanManAuth),
920 .special = NULL,
921 .enum_list = NULL,
922 .flags = FLAG_ADVANCED,
925 .label = "client plaintext auth",
926 .type = P_BOOL,
927 .p_class = P_GLOBAL,
928 .offset = GLOBAL_VAR(bClientPlaintextAuth),
929 .special = NULL,
930 .enum_list = NULL,
931 .flags = FLAG_ADVANCED,
934 .label = "client use spnego principal",
935 .type = P_BOOL,
936 .p_class = P_GLOBAL,
937 .offset = GLOBAL_VAR(client_use_spnego_principal),
938 .special = NULL,
939 .enum_list = NULL,
940 .flags = FLAG_ADVANCED,
943 .label = "username",
944 .type = P_STRING,
945 .p_class = P_LOCAL,
946 .offset = LOCAL_VAR(szUsername),
947 .special = NULL,
948 .enum_list = NULL,
949 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
952 .label = "user",
953 .type = P_STRING,
954 .p_class = P_LOCAL,
955 .offset = LOCAL_VAR(szUsername),
956 .special = NULL,
957 .enum_list = NULL,
958 .flags = FLAG_HIDE,
961 .label = "users",
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 = "invalid users",
971 .type = P_LIST,
972 .p_class = P_LOCAL,
973 .offset = LOCAL_VAR(szInvalidUsers),
974 .special = NULL,
975 .enum_list = NULL,
976 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
979 .label = "valid users",
980 .type = P_LIST,
981 .p_class = P_LOCAL,
982 .offset = LOCAL_VAR(szValidUsers),
983 .special = NULL,
984 .enum_list = NULL,
985 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
988 .label = "admin users",
989 .type = P_LIST,
990 .p_class = P_LOCAL,
991 .offset = LOCAL_VAR(szAdminUsers),
992 .special = NULL,
993 .enum_list = NULL,
994 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
997 .label = "read list",
998 .type = P_LIST,
999 .p_class = P_LOCAL,
1000 .offset = LOCAL_VAR(readlist),
1001 .special = NULL,
1002 .enum_list = NULL,
1003 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1006 .label = "write list",
1007 .type = P_LIST,
1008 .p_class = P_LOCAL,
1009 .offset = LOCAL_VAR(writelist),
1010 .special = NULL,
1011 .enum_list = NULL,
1012 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1015 .label = "printer admin",
1016 .type = P_LIST,
1017 .p_class = P_LOCAL,
1018 .offset = LOCAL_VAR(printer_admin),
1019 .special = NULL,
1020 .enum_list = NULL,
1021 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1024 .label = "force user",
1025 .type = P_STRING,
1026 .p_class = P_LOCAL,
1027 .offset = LOCAL_VAR(force_user),
1028 .special = NULL,
1029 .enum_list = NULL,
1030 .flags = FLAG_ADVANCED | FLAG_SHARE,
1033 .label = "force group",
1034 .type = P_STRING,
1035 .p_class = P_LOCAL,
1036 .offset = LOCAL_VAR(force_group),
1037 .special = NULL,
1038 .enum_list = NULL,
1039 .flags = FLAG_ADVANCED | FLAG_SHARE,
1042 .label = "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,
1051 .label = "read only",
1052 .type = P_BOOL,
1053 .p_class = P_LOCAL,
1054 .offset = LOCAL_VAR(bRead_only),
1055 .special = NULL,
1056 .enum_list = NULL,
1057 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1060 .label = "write ok",
1061 .type = P_BOOLREV,
1062 .p_class = P_LOCAL,
1063 .offset = LOCAL_VAR(bRead_only),
1064 .special = NULL,
1065 .enum_list = NULL,
1066 .flags = FLAG_HIDE,
1069 .label = "writeable",
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 = "writable",
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 = "acl check permissions",
1088 .type = P_BOOL,
1089 .p_class = P_LOCAL,
1090 .offset = LOCAL_VAR(bAclCheckPermissions),
1091 .special = NULL,
1092 .enum_list = NULL,
1093 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1096 .label = "acl group control",
1097 .type = P_BOOL,
1098 .p_class = P_LOCAL,
1099 .offset = LOCAL_VAR(bAclGroupControl),
1100 .special = NULL,
1101 .enum_list = NULL,
1102 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1105 .label = "acl map full control",
1106 .type = P_BOOL,
1107 .p_class = P_LOCAL,
1108 .offset = LOCAL_VAR(bAclMapFullControl),
1109 .special = NULL,
1110 .enum_list = NULL,
1111 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1114 .label = "create mask",
1115 .type = P_OCTAL,
1116 .p_class = P_LOCAL,
1117 .offset = LOCAL_VAR(iCreate_mask),
1118 .special = NULL,
1119 .enum_list = NULL,
1120 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1123 .label = "create mode",
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_HIDE,
1132 .label = "force create mode",
1133 .type = P_OCTAL,
1134 .p_class = P_LOCAL,
1135 .offset = LOCAL_VAR(iCreate_force_mode),
1136 .special = NULL,
1137 .enum_list = NULL,
1138 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1141 .label = "security mask",
1142 .type = P_OCTAL,
1143 .p_class = P_LOCAL,
1144 .offset = LOCAL_VAR(iSecurity_mask),
1145 .special = NULL,
1146 .enum_list = NULL,
1147 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1150 .label = "force security mode",
1151 .type = P_OCTAL,
1152 .p_class = P_LOCAL,
1153 .offset = LOCAL_VAR(iSecurity_force_mode),
1154 .special = NULL,
1155 .enum_list = NULL,
1156 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1159 .label = "directory mask",
1160 .type = P_OCTAL,
1161 .p_class = P_LOCAL,
1162 .offset = LOCAL_VAR(iDir_mask),
1163 .special = NULL,
1164 .enum_list = NULL,
1165 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1168 .label = "directory mode",
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,
1177 .label = "force directory mode",
1178 .type = P_OCTAL,
1179 .p_class = P_LOCAL,
1180 .offset = LOCAL_VAR(iDir_force_mode),
1181 .special = NULL,
1182 .enum_list = NULL,
1183 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1186 .label = "directory security mask",
1187 .type = P_OCTAL,
1188 .p_class = P_LOCAL,
1189 .offset = LOCAL_VAR(iDir_Security_mask),
1190 .special = NULL,
1191 .enum_list = NULL,
1192 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1195 .label = "force directory security mode",
1196 .type = P_OCTAL,
1197 .p_class = P_LOCAL,
1198 .offset = LOCAL_VAR(iDir_Security_force_mode),
1199 .special = NULL,
1200 .enum_list = NULL,
1201 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1204 .label = "force unknown acl user",
1205 .type = P_BOOL,
1206 .p_class = P_LOCAL,
1207 .offset = LOCAL_VAR(bForceUnknownAclUser),
1208 .special = NULL,
1209 .enum_list = NULL,
1210 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1213 .label = "inherit permissions",
1214 .type = P_BOOL,
1215 .p_class = P_LOCAL,
1216 .offset = LOCAL_VAR(bInheritPerms),
1217 .special = NULL,
1218 .enum_list = NULL,
1219 .flags = FLAG_ADVANCED | FLAG_SHARE,
1222 .label = "inherit acls",
1223 .type = P_BOOL,
1224 .p_class = P_LOCAL,
1225 .offset = LOCAL_VAR(bInheritACLS),
1226 .special = NULL,
1227 .enum_list = NULL,
1228 .flags = FLAG_ADVANCED | FLAG_SHARE,
1231 .label = "inherit owner",
1232 .type = P_BOOL,
1233 .p_class = P_LOCAL,
1234 .offset = LOCAL_VAR(bInheritOwner),
1235 .special = NULL,
1236 .enum_list = NULL,
1237 .flags = FLAG_ADVANCED | FLAG_SHARE,
1240 .label = "guest only",
1241 .type = P_BOOL,
1242 .p_class = P_LOCAL,
1243 .offset = LOCAL_VAR(bGuest_only),
1244 .special = NULL,
1245 .enum_list = NULL,
1246 .flags = FLAG_ADVANCED | FLAG_SHARE,
1249 .label = "only guest",
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_HIDE,
1258 .label = "administrative share",
1259 .type = P_BOOL,
1260 .p_class = P_LOCAL,
1261 .offset = LOCAL_VAR(bAdministrative_share),
1262 .special = NULL,
1263 .enum_list = NULL,
1264 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1268 .label = "guest ok",
1269 .type = P_BOOL,
1270 .p_class = P_LOCAL,
1271 .offset = LOCAL_VAR(bGuest_ok),
1272 .special = NULL,
1273 .enum_list = NULL,
1274 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1277 .label = "public",
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_HIDE,
1286 .label = "only user",
1287 .type = P_BOOL,
1288 .p_class = P_LOCAL,
1289 .offset = LOCAL_VAR(bOnlyUser),
1290 .special = NULL,
1291 .enum_list = NULL,
1292 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1295 .label = "hosts allow",
1296 .type = P_LIST,
1297 .p_class = P_LOCAL,
1298 .offset = LOCAL_VAR(szHostsallow),
1299 .special = NULL,
1300 .enum_list = NULL,
1301 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1304 .label = "allow hosts",
1305 .type = P_LIST,
1306 .p_class = P_LOCAL,
1307 .offset = LOCAL_VAR(szHostsallow),
1308 .special = NULL,
1309 .enum_list = NULL,
1310 .flags = FLAG_HIDE,
1313 .label = "hosts deny",
1314 .type = P_LIST,
1315 .p_class = P_LOCAL,
1316 .offset = LOCAL_VAR(szHostsdeny),
1317 .special = NULL,
1318 .enum_list = NULL,
1319 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1322 .label = "deny hosts",
1323 .type = P_LIST,
1324 .p_class = P_LOCAL,
1325 .offset = LOCAL_VAR(szHostsdeny),
1326 .special = NULL,
1327 .enum_list = NULL,
1328 .flags = FLAG_HIDE,
1331 .label = "preload modules",
1332 .type = P_LIST,
1333 .p_class = P_GLOBAL,
1334 .offset = GLOBAL_VAR(szPreloadModules),
1335 .special = NULL,
1336 .enum_list = NULL,
1337 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1340 .label = "dedicated keytab file",
1341 .type = P_STRING,
1342 .p_class = P_GLOBAL,
1343 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1344 .special = NULL,
1345 .enum_list = NULL,
1346 .flags = FLAG_ADVANCED,
1349 .label = "kerberos method",
1350 .type = P_ENUM,
1351 .p_class = P_GLOBAL,
1352 .offset = GLOBAL_VAR(iKerberosMethod),
1353 .special = NULL,
1354 .enum_list = enum_kerberos_method,
1355 .flags = FLAG_ADVANCED,
1358 .label = "map untrusted to domain",
1359 .type = P_BOOL,
1360 .p_class = P_GLOBAL,
1361 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1362 .special = NULL,
1363 .enum_list = NULL,
1364 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1368 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1371 .label = "log level",
1372 .type = P_STRING,
1373 .p_class = P_GLOBAL,
1374 .offset = GLOBAL_VAR(szLogLevel),
1375 .special = handle_debug_list,
1376 .enum_list = NULL,
1377 .flags = FLAG_ADVANCED,
1380 .label = "debuglevel",
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_HIDE,
1389 .label = "syslog",
1390 .type = P_INTEGER,
1391 .p_class = P_GLOBAL,
1392 .offset = GLOBAL_VAR(syslog),
1393 .special = NULL,
1394 .enum_list = NULL,
1395 .flags = FLAG_ADVANCED,
1398 .label = "syslog only",
1399 .type = P_BOOL,
1400 .p_class = P_GLOBAL,
1401 .offset = GLOBAL_VAR(bSyslogOnly),
1402 .special = NULL,
1403 .enum_list = NULL,
1404 .flags = FLAG_ADVANCED,
1407 .label = "log file",
1408 .type = P_STRING,
1409 .p_class = P_GLOBAL,
1410 .offset = GLOBAL_VAR(logfile),
1411 .special = NULL,
1412 .enum_list = NULL,
1413 .flags = FLAG_ADVANCED,
1416 .label = "max log size",
1417 .type = P_BYTES,
1418 .p_class = P_GLOBAL,
1419 .offset = GLOBAL_VAR(max_log_size),
1420 .special = NULL,
1421 .enum_list = NULL,
1422 .flags = FLAG_ADVANCED,
1425 .label = "debug timestamp",
1426 .type = P_BOOL,
1427 .p_class = P_GLOBAL,
1428 .offset = GLOBAL_VAR(bTimestampLogs),
1429 .special = NULL,
1430 .enum_list = NULL,
1431 .flags = FLAG_ADVANCED,
1434 .label = "timestamp logs",
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 = "debug prefix timestamp",
1444 .type = P_BOOL,
1445 .p_class = P_GLOBAL,
1446 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1447 .special = NULL,
1448 .enum_list = NULL,
1449 .flags = FLAG_ADVANCED,
1452 .label = "debug hires timestamp",
1453 .type = P_BOOL,
1454 .p_class = P_GLOBAL,
1455 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1456 .special = NULL,
1457 .enum_list = NULL,
1458 .flags = FLAG_ADVANCED,
1461 .label = "debug pid",
1462 .type = P_BOOL,
1463 .p_class = P_GLOBAL,
1464 .offset = GLOBAL_VAR(bDebugPid),
1465 .special = NULL,
1466 .enum_list = NULL,
1467 .flags = FLAG_ADVANCED,
1470 .label = "debug uid",
1471 .type = P_BOOL,
1472 .p_class = P_GLOBAL,
1473 .offset = GLOBAL_VAR(bDebugUid),
1474 .special = NULL,
1475 .enum_list = NULL,
1476 .flags = FLAG_ADVANCED,
1479 .label = "debug class",
1480 .type = P_BOOL,
1481 .p_class = P_GLOBAL,
1482 .offset = GLOBAL_VAR(bDebugClass),
1483 .special = NULL,
1484 .enum_list = NULL,
1485 .flags = FLAG_ADVANCED,
1488 .label = "enable core files",
1489 .type = P_BOOL,
1490 .p_class = P_GLOBAL,
1491 .offset = GLOBAL_VAR(bEnableCoreFiles),
1492 .special = NULL,
1493 .enum_list = NULL,
1494 .flags = FLAG_ADVANCED,
1497 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1500 .label = "allocation roundup size",
1501 .type = P_BYTES,
1502 .p_class = P_LOCAL,
1503 .offset = LOCAL_VAR(iallocation_roundup_size),
1504 .special = NULL,
1505 .enum_list = NULL,
1506 .flags = FLAG_ADVANCED,
1509 .label = "aio read size",
1510 .type = P_BYTES,
1511 .p_class = P_LOCAL,
1512 .offset = LOCAL_VAR(iAioReadSize),
1513 .special = NULL,
1514 .enum_list = NULL,
1515 .flags = FLAG_ADVANCED,
1518 .label = "aio write size",
1519 .type = P_BYTES,
1520 .p_class = P_LOCAL,
1521 .offset = LOCAL_VAR(iAioWriteSize),
1522 .special = NULL,
1523 .enum_list = NULL,
1524 .flags = FLAG_ADVANCED,
1527 .label = "aio write behind",
1528 .type = P_STRING,
1529 .p_class = P_LOCAL,
1530 .offset = LOCAL_VAR(szAioWriteBehind),
1531 .special = NULL,
1532 .enum_list = NULL,
1533 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1536 .label = "smb ports",
1537 .type = P_STRING,
1538 .p_class = P_GLOBAL,
1539 .offset = GLOBAL_VAR(smb_ports),
1540 .special = NULL,
1541 .enum_list = NULL,
1542 .flags = FLAG_ADVANCED,
1545 .label = "large readwrite",
1546 .type = P_BOOL,
1547 .p_class = P_GLOBAL,
1548 .offset = GLOBAL_VAR(bLargeReadwrite),
1549 .special = NULL,
1550 .enum_list = NULL,
1551 .flags = FLAG_ADVANCED,
1554 .label = "max protocol",
1555 .type = P_ENUM,
1556 .p_class = P_GLOBAL,
1557 .offset = GLOBAL_VAR(srv_maxprotocol),
1558 .special = NULL,
1559 .enum_list = enum_protocol,
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 = "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 = "min protocol",
1582 .type = P_ENUM,
1583 .p_class = P_GLOBAL,
1584 .offset = GLOBAL_VAR(srv_minprotocol),
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 receivefile size",
1600 .type = P_BYTES,
1601 .p_class = P_GLOBAL,
1602 .offset = GLOBAL_VAR(iminreceivefile),
1603 .special = NULL,
1604 .enum_list = NULL,
1605 .flags = FLAG_ADVANCED,
1608 .label = "read raw",
1609 .type = P_BOOL,
1610 .p_class = P_GLOBAL,
1611 .offset = GLOBAL_VAR(bReadRaw),
1612 .special = NULL,
1613 .enum_list = NULL,
1614 .flags = FLAG_ADVANCED,
1617 .label = "write raw",
1618 .type = P_BOOL,
1619 .p_class = P_GLOBAL,
1620 .offset = GLOBAL_VAR(bWriteRaw),
1621 .special = NULL,
1622 .enum_list = NULL,
1623 .flags = FLAG_ADVANCED,
1626 .label = "disable netbios",
1627 .type = P_BOOL,
1628 .p_class = P_GLOBAL,
1629 .offset = GLOBAL_VAR(bDisableNetbios),
1630 .special = NULL,
1631 .enum_list = NULL,
1632 .flags = FLAG_ADVANCED,
1635 .label = "reset on zero vc",
1636 .type = P_BOOL,
1637 .p_class = P_GLOBAL,
1638 .offset = GLOBAL_VAR(bResetOnZeroVC),
1639 .special = NULL,
1640 .enum_list = NULL,
1641 .flags = FLAG_ADVANCED,
1644 .label = "log writeable files on exit",
1645 .type = P_BOOL,
1646 .p_class = P_GLOBAL,
1647 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1648 .special = NULL,
1649 .enum_list = NULL,
1650 .flags = FLAG_ADVANCED,
1653 .label = "acl compatibility",
1654 .type = P_ENUM,
1655 .p_class = P_GLOBAL,
1656 .offset = GLOBAL_VAR(iAclCompat),
1657 .special = NULL,
1658 .enum_list = enum_acl_compat_vals,
1659 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1662 .label = "defer sharing violations",
1663 .type = P_BOOL,
1664 .p_class = P_GLOBAL,
1665 .offset = GLOBAL_VAR(bDeferSharingViolations),
1666 .special = NULL,
1667 .enum_list = NULL,
1668 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1671 .label = "ea support",
1672 .type = P_BOOL,
1673 .p_class = P_LOCAL,
1674 .offset = LOCAL_VAR(bEASupport),
1675 .special = NULL,
1676 .enum_list = NULL,
1677 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1680 .label = "nt acl support",
1681 .type = P_BOOL,
1682 .p_class = P_LOCAL,
1683 .offset = LOCAL_VAR(bNTAclSupport),
1684 .special = NULL,
1685 .enum_list = NULL,
1686 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1689 .label = "nt pipe support",
1690 .type = P_BOOL,
1691 .p_class = P_GLOBAL,
1692 .offset = GLOBAL_VAR(bNTPipeSupport),
1693 .special = NULL,
1694 .enum_list = NULL,
1695 .flags = FLAG_ADVANCED,
1698 .label = "nt status support",
1699 .type = P_BOOL,
1700 .p_class = P_GLOBAL,
1701 .offset = GLOBAL_VAR(bNTStatusSupport),
1702 .special = NULL,
1703 .enum_list = NULL,
1704 .flags = FLAG_ADVANCED,
1707 .label = "profile acls",
1708 .type = P_BOOL,
1709 .p_class = P_LOCAL,
1710 .offset = LOCAL_VAR(bProfileAcls),
1711 .special = NULL,
1712 .enum_list = NULL,
1713 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1716 .label = "map acl inherit",
1717 .type = P_BOOL,
1718 .p_class = P_LOCAL,
1719 .offset = LOCAL_VAR(bMap_acl_inherit),
1720 .special = NULL,
1721 .enum_list = NULL,
1722 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1725 .label = "afs share",
1726 .type = P_BOOL,
1727 .p_class = P_LOCAL,
1728 .offset = LOCAL_VAR(bAfs_Share),
1729 .special = NULL,
1730 .enum_list = NULL,
1731 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1734 .label = "max mux",
1735 .type = P_INTEGER,
1736 .p_class = P_GLOBAL,
1737 .offset = GLOBAL_VAR(max_mux),
1738 .special = NULL,
1739 .enum_list = NULL,
1740 .flags = FLAG_ADVANCED,
1743 .label = "max xmit",
1744 .type = P_BYTES,
1745 .p_class = P_GLOBAL,
1746 .offset = GLOBAL_VAR(max_xmit),
1747 .special = NULL,
1748 .enum_list = NULL,
1749 .flags = FLAG_ADVANCED,
1752 .label = "name resolve order",
1753 .type = P_STRING,
1754 .p_class = P_GLOBAL,
1755 .offset = GLOBAL_VAR(szNameResolveOrder),
1756 .special = NULL,
1757 .enum_list = NULL,
1758 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1761 .label = "max ttl",
1762 .type = P_INTEGER,
1763 .p_class = P_GLOBAL,
1764 .offset = GLOBAL_VAR(max_ttl),
1765 .special = NULL,
1766 .enum_list = NULL,
1767 .flags = FLAG_ADVANCED,
1770 .label = "max wins ttl",
1771 .type = P_INTEGER,
1772 .p_class = P_GLOBAL,
1773 .offset = GLOBAL_VAR(max_wins_ttl),
1774 .special = NULL,
1775 .enum_list = NULL,
1776 .flags = FLAG_ADVANCED,
1779 .label = "min wins ttl",
1780 .type = P_INTEGER,
1781 .p_class = P_GLOBAL,
1782 .offset = GLOBAL_VAR(min_wins_ttl),
1783 .special = NULL,
1784 .enum_list = NULL,
1785 .flags = FLAG_ADVANCED,
1788 .label = "time server",
1789 .type = P_BOOL,
1790 .p_class = P_GLOBAL,
1791 .offset = GLOBAL_VAR(bTimeServer),
1792 .special = NULL,
1793 .enum_list = NULL,
1794 .flags = FLAG_ADVANCED,
1797 .label = "unix extensions",
1798 .type = P_BOOL,
1799 .p_class = P_GLOBAL,
1800 .offset = GLOBAL_VAR(bUnixExtensions),
1801 .special = NULL,
1802 .enum_list = NULL,
1803 .flags = FLAG_ADVANCED,
1806 .label = "use spnego",
1807 .type = P_BOOL,
1808 .p_class = P_GLOBAL,
1809 .offset = GLOBAL_VAR(bUseSpnego),
1810 .special = NULL,
1811 .enum_list = NULL,
1812 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1815 .label = "client signing",
1816 .type = P_ENUM,
1817 .p_class = P_GLOBAL,
1818 .offset = GLOBAL_VAR(client_signing),
1819 .special = NULL,
1820 .enum_list = enum_smb_signing_vals,
1821 .flags = FLAG_ADVANCED,
1824 .label = "server signing",
1825 .type = P_ENUM,
1826 .p_class = P_GLOBAL,
1827 .offset = GLOBAL_VAR(server_signing),
1828 .special = NULL,
1829 .enum_list = enum_smb_signing_vals,
1830 .flags = FLAG_ADVANCED,
1833 .label = "smb encrypt",
1834 .type = P_ENUM,
1835 .p_class = P_LOCAL,
1836 .offset = LOCAL_VAR(ismb_encrypt),
1837 .special = NULL,
1838 .enum_list = enum_smb_signing_vals,
1839 .flags = FLAG_ADVANCED,
1842 .label = "client use spnego",
1843 .type = P_BOOL,
1844 .p_class = P_GLOBAL,
1845 .offset = GLOBAL_VAR(bClientUseSpnego),
1846 .special = NULL,
1847 .enum_list = NULL,
1848 .flags = FLAG_ADVANCED,
1851 .label = "client ldap sasl wrapping",
1852 .type = P_ENUM,
1853 .p_class = P_GLOBAL,
1854 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1855 .special = NULL,
1856 .enum_list = enum_ldap_sasl_wrapping,
1857 .flags = FLAG_ADVANCED,
1860 .label = "enable asu support",
1861 .type = P_BOOL,
1862 .p_class = P_GLOBAL,
1863 .offset = GLOBAL_VAR(bASUSupport),
1864 .special = NULL,
1865 .enum_list = NULL,
1866 .flags = FLAG_ADVANCED,
1869 .label = "svcctl list",
1870 .type = P_LIST,
1871 .p_class = P_GLOBAL,
1872 .offset = GLOBAL_VAR(szServicesList),
1873 .special = NULL,
1874 .enum_list = NULL,
1875 .flags = FLAG_ADVANCED,
1878 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1881 .label = "block size",
1882 .type = P_BYTES,
1883 .p_class = P_LOCAL,
1884 .offset = LOCAL_VAR(iBlock_size),
1885 .special = NULL,
1886 .enum_list = NULL,
1887 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1890 .label = "deadtime",
1891 .type = P_INTEGER,
1892 .p_class = P_GLOBAL,
1893 .offset = GLOBAL_VAR(deadtime),
1894 .special = NULL,
1895 .enum_list = NULL,
1896 .flags = FLAG_ADVANCED,
1899 .label = "getwd cache",
1900 .type = P_BOOL,
1901 .p_class = P_GLOBAL,
1902 .offset = GLOBAL_VAR(getwd_cache),
1903 .special = NULL,
1904 .enum_list = NULL,
1905 .flags = FLAG_ADVANCED,
1908 .label = "keepalive",
1909 .type = P_INTEGER,
1910 .p_class = P_GLOBAL,
1911 .offset = GLOBAL_VAR(iKeepalive),
1912 .special = NULL,
1913 .enum_list = NULL,
1914 .flags = FLAG_ADVANCED,
1917 .label = "change notify",
1918 .type = P_BOOL,
1919 .p_class = P_LOCAL,
1920 .offset = LOCAL_VAR(bChangeNotify),
1921 .special = NULL,
1922 .enum_list = NULL,
1923 .flags = FLAG_ADVANCED | FLAG_SHARE,
1926 .label = "directory name cache size",
1927 .type = P_INTEGER,
1928 .p_class = P_LOCAL,
1929 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
1930 .special = NULL,
1931 .enum_list = NULL,
1932 .flags = FLAG_ADVANCED | FLAG_SHARE,
1935 .label = "kernel change notify",
1936 .type = P_BOOL,
1937 .p_class = P_LOCAL,
1938 .offset = LOCAL_VAR(bKernelChangeNotify),
1939 .special = NULL,
1940 .enum_list = NULL,
1941 .flags = FLAG_ADVANCED | FLAG_SHARE,
1944 .label = "lpq cache time",
1945 .type = P_INTEGER,
1946 .p_class = P_GLOBAL,
1947 .offset = GLOBAL_VAR(lpqcachetime),
1948 .special = NULL,
1949 .enum_list = NULL,
1950 .flags = FLAG_ADVANCED,
1953 .label = "max smbd processes",
1954 .type = P_INTEGER,
1955 .p_class = P_GLOBAL,
1956 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
1957 .special = NULL,
1958 .enum_list = NULL,
1959 .flags = FLAG_ADVANCED,
1962 .label = "max connections",
1963 .type = P_INTEGER,
1964 .p_class = P_LOCAL,
1965 .offset = LOCAL_VAR(iMaxConnections),
1966 .special = NULL,
1967 .enum_list = NULL,
1968 .flags = FLAG_ADVANCED | FLAG_SHARE,
1971 .label = "paranoid server security",
1972 .type = P_BOOL,
1973 .p_class = P_GLOBAL,
1974 .offset = GLOBAL_VAR(paranoid_server_security),
1975 .special = NULL,
1976 .enum_list = NULL,
1977 .flags = FLAG_ADVANCED,
1980 .label = "max disk size",
1981 .type = P_BYTES,
1982 .p_class = P_GLOBAL,
1983 .offset = GLOBAL_VAR(maxdisksize),
1984 .special = NULL,
1985 .enum_list = NULL,
1986 .flags = FLAG_ADVANCED,
1989 .label = "max open files",
1990 .type = P_INTEGER,
1991 .p_class = P_GLOBAL,
1992 .offset = GLOBAL_VAR(max_open_files),
1993 .special = NULL,
1994 .enum_list = NULL,
1995 .flags = FLAG_ADVANCED,
1998 .label = "min print space",
1999 .type = P_INTEGER,
2000 .p_class = P_LOCAL,
2001 .offset = LOCAL_VAR(iMinPrintSpace),
2002 .special = NULL,
2003 .enum_list = NULL,
2004 .flags = FLAG_ADVANCED | FLAG_PRINT,
2007 .label = "socket options",
2008 .type = P_STRING,
2009 .p_class = P_GLOBAL,
2010 .offset = GLOBAL_VAR(szSocketOptions),
2011 .special = NULL,
2012 .enum_list = NULL,
2013 .flags = FLAG_ADVANCED,
2016 .label = "strict allocate",
2017 .type = P_BOOL,
2018 .p_class = P_LOCAL,
2019 .offset = LOCAL_VAR(bStrictAllocate),
2020 .special = NULL,
2021 .enum_list = NULL,
2022 .flags = FLAG_ADVANCED | FLAG_SHARE,
2025 .label = "strict sync",
2026 .type = P_BOOL,
2027 .p_class = P_LOCAL,
2028 .offset = LOCAL_VAR(bStrictSync),
2029 .special = NULL,
2030 .enum_list = NULL,
2031 .flags = FLAG_ADVANCED | FLAG_SHARE,
2034 .label = "sync always",
2035 .type = P_BOOL,
2036 .p_class = P_LOCAL,
2037 .offset = LOCAL_VAR(bSyncAlways),
2038 .special = NULL,
2039 .enum_list = NULL,
2040 .flags = FLAG_ADVANCED | FLAG_SHARE,
2043 .label = "use mmap",
2044 .type = P_BOOL,
2045 .p_class = P_GLOBAL,
2046 .offset = GLOBAL_VAR(bUseMmap),
2047 .special = NULL,
2048 .enum_list = NULL,
2049 .flags = FLAG_ADVANCED,
2052 .label = "use sendfile",
2053 .type = P_BOOL,
2054 .p_class = P_LOCAL,
2055 .offset = LOCAL_VAR(bUseSendfile),
2056 .special = NULL,
2057 .enum_list = NULL,
2058 .flags = FLAG_ADVANCED | FLAG_SHARE,
2061 .label = "hostname lookups",
2062 .type = P_BOOL,
2063 .p_class = P_GLOBAL,
2064 .offset = GLOBAL_VAR(bHostnameLookups),
2065 .special = NULL,
2066 .enum_list = NULL,
2067 .flags = FLAG_ADVANCED,
2070 .label = "write cache size",
2071 .type = P_BYTES,
2072 .p_class = P_LOCAL,
2073 .offset = LOCAL_VAR(iWriteCacheSize),
2074 .special = NULL,
2075 .enum_list = NULL,
2076 .flags = FLAG_ADVANCED | FLAG_SHARE,
2079 .label = "name cache timeout",
2080 .type = P_INTEGER,
2081 .p_class = P_GLOBAL,
2082 .offset = GLOBAL_VAR(name_cache_timeout),
2083 .special = NULL,
2084 .enum_list = NULL,
2085 .flags = FLAG_ADVANCED,
2088 .label = "ctdbd socket",
2089 .type = P_STRING,
2090 .p_class = P_GLOBAL,
2091 .offset = GLOBAL_VAR(ctdbdSocket),
2092 .special = NULL,
2093 .enum_list = NULL,
2094 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2097 .label = "cluster addresses",
2098 .type = P_LIST,
2099 .p_class = P_GLOBAL,
2100 .offset = GLOBAL_VAR(szClusterAddresses),
2101 .special = NULL,
2102 .enum_list = NULL,
2103 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2106 .label = "clustering",
2107 .type = P_BOOL,
2108 .p_class = P_GLOBAL,
2109 .offset = GLOBAL_VAR(clustering),
2110 .special = NULL,
2111 .enum_list = NULL,
2112 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2115 .label = "ctdb timeout",
2116 .type = P_INTEGER,
2117 .p_class = P_GLOBAL,
2118 .offset = GLOBAL_VAR(ctdb_timeout),
2119 .special = NULL,
2120 .enum_list = NULL,
2121 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2124 .label = "ctdb locktime warn threshold",
2125 .type = P_INTEGER,
2126 .p_class = P_GLOBAL,
2127 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2128 .special = NULL,
2129 .enum_list = NULL,
2130 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2133 .label = "smb2 max read",
2134 .type = P_BYTES,
2135 .p_class = P_GLOBAL,
2136 .offset = GLOBAL_VAR(ismb2_max_read),
2137 .special = NULL,
2138 .enum_list = NULL,
2139 .flags = FLAG_ADVANCED,
2142 .label = "smb2 max write",
2143 .type = P_BYTES,
2144 .p_class = P_GLOBAL,
2145 .offset = GLOBAL_VAR(ismb2_max_write),
2146 .special = NULL,
2147 .enum_list = NULL,
2148 .flags = FLAG_ADVANCED,
2151 .label = "smb2 max trans",
2152 .type = P_BYTES,
2153 .p_class = P_GLOBAL,
2154 .offset = GLOBAL_VAR(ismb2_max_trans),
2155 .special = NULL,
2156 .enum_list = NULL,
2157 .flags = FLAG_ADVANCED,
2160 .label = "smb2 max credits",
2161 .type = P_INTEGER,
2162 .p_class = P_GLOBAL,
2163 .offset = GLOBAL_VAR(ismb2_max_credits),
2164 .special = NULL,
2165 .enum_list = NULL,
2166 .flags = FLAG_ADVANCED,
2169 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2172 .label = "max reported print jobs",
2173 .type = P_INTEGER,
2174 .p_class = P_LOCAL,
2175 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2176 .special = NULL,
2177 .enum_list = NULL,
2178 .flags = FLAG_ADVANCED | FLAG_PRINT,
2181 .label = "max print jobs",
2182 .type = P_INTEGER,
2183 .p_class = P_LOCAL,
2184 .offset = LOCAL_VAR(iMaxPrintJobs),
2185 .special = NULL,
2186 .enum_list = NULL,
2187 .flags = FLAG_ADVANCED | FLAG_PRINT,
2190 .label = "load printers",
2191 .type = P_BOOL,
2192 .p_class = P_GLOBAL,
2193 .offset = GLOBAL_VAR(bLoadPrinters),
2194 .special = NULL,
2195 .enum_list = NULL,
2196 .flags = FLAG_ADVANCED | FLAG_PRINT,
2199 .label = "printcap cache time",
2200 .type = P_INTEGER,
2201 .p_class = P_GLOBAL,
2202 .offset = GLOBAL_VAR(PrintcapCacheTime),
2203 .special = NULL,
2204 .enum_list = NULL,
2205 .flags = FLAG_ADVANCED | FLAG_PRINT,
2208 .label = "printcap name",
2209 .type = P_STRING,
2210 .p_class = P_GLOBAL,
2211 .offset = GLOBAL_VAR(szPrintcapname),
2212 .special = NULL,
2213 .enum_list = NULL,
2214 .flags = FLAG_ADVANCED | FLAG_PRINT,
2217 .label = "printcap",
2218 .type = P_STRING,
2219 .p_class = P_GLOBAL,
2220 .offset = GLOBAL_VAR(szPrintcapname),
2221 .special = NULL,
2222 .enum_list = NULL,
2223 .flags = FLAG_HIDE,
2226 .label = "printable",
2227 .type = P_BOOL,
2228 .p_class = P_LOCAL,
2229 .offset = LOCAL_VAR(bPrint_ok),
2230 .special = NULL,
2231 .enum_list = NULL,
2232 .flags = FLAG_ADVANCED | FLAG_PRINT,
2235 .label = "print notify backchannel",
2236 .type = P_BOOL,
2237 .p_class = P_LOCAL,
2238 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2239 .special = NULL,
2240 .enum_list = NULL,
2241 .flags = FLAG_ADVANCED,
2244 .label = "print ok",
2245 .type = P_BOOL,
2246 .p_class = P_LOCAL,
2247 .offset = LOCAL_VAR(bPrint_ok),
2248 .special = NULL,
2249 .enum_list = NULL,
2250 .flags = FLAG_HIDE,
2253 .label = "printing",
2254 .type = P_ENUM,
2255 .p_class = P_LOCAL,
2256 .offset = LOCAL_VAR(iPrinting),
2257 .special = handle_printing,
2258 .enum_list = enum_printing,
2259 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2262 .label = "cups options",
2263 .type = P_STRING,
2264 .p_class = P_LOCAL,
2265 .offset = LOCAL_VAR(szCupsOptions),
2266 .special = NULL,
2267 .enum_list = NULL,
2268 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2271 .label = "cups server",
2272 .type = P_STRING,
2273 .p_class = P_GLOBAL,
2274 .offset = GLOBAL_VAR(szCupsServer),
2275 .special = NULL,
2276 .enum_list = NULL,
2277 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2280 .label = "cups encrypt",
2281 .type = P_ENUM,
2282 .p_class = P_GLOBAL,
2283 .offset = GLOBAL_VAR(CupsEncrypt),
2284 .special = NULL,
2285 .enum_list = enum_bool_auto,
2286 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2290 .label = "cups connection timeout",
2291 .type = P_INTEGER,
2292 .p_class = P_GLOBAL,
2293 .offset = GLOBAL_VAR(cups_connection_timeout),
2294 .special = NULL,
2295 .enum_list = NULL,
2296 .flags = FLAG_ADVANCED,
2299 .label = "iprint server",
2300 .type = P_STRING,
2301 .p_class = P_GLOBAL,
2302 .offset = GLOBAL_VAR(szIPrintServer),
2303 .special = NULL,
2304 .enum_list = NULL,
2305 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2308 .label = "print command",
2309 .type = P_STRING,
2310 .p_class = P_LOCAL,
2311 .offset = LOCAL_VAR(szPrintcommand),
2312 .special = NULL,
2313 .enum_list = NULL,
2314 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2317 .label = "disable spoolss",
2318 .type = P_BOOL,
2319 .p_class = P_GLOBAL,
2320 .offset = GLOBAL_VAR(bDisableSpoolss),
2321 .special = NULL,
2322 .enum_list = NULL,
2323 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2326 .label = "enable spoolss",
2327 .type = P_BOOLREV,
2328 .p_class = P_GLOBAL,
2329 .offset = GLOBAL_VAR(bDisableSpoolss),
2330 .special = NULL,
2331 .enum_list = NULL,
2332 .flags = FLAG_HIDE,
2335 .label = "lpq command",
2336 .type = P_STRING,
2337 .p_class = P_LOCAL,
2338 .offset = LOCAL_VAR(szLpqcommand),
2339 .special = NULL,
2340 .enum_list = NULL,
2341 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2344 .label = "lprm command",
2345 .type = P_STRING,
2346 .p_class = P_LOCAL,
2347 .offset = LOCAL_VAR(szLprmcommand),
2348 .special = NULL,
2349 .enum_list = NULL,
2350 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2353 .label = "lppause command",
2354 .type = P_STRING,
2355 .p_class = P_LOCAL,
2356 .offset = LOCAL_VAR(szLppausecommand),
2357 .special = NULL,
2358 .enum_list = NULL,
2359 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2362 .label = "lpresume command",
2363 .type = P_STRING,
2364 .p_class = P_LOCAL,
2365 .offset = LOCAL_VAR(szLpresumecommand),
2366 .special = NULL,
2367 .enum_list = NULL,
2368 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2371 .label = "queuepause command",
2372 .type = P_STRING,
2373 .p_class = P_LOCAL,
2374 .offset = LOCAL_VAR(szQueuepausecommand),
2375 .special = NULL,
2376 .enum_list = NULL,
2377 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2380 .label = "queueresume command",
2381 .type = P_STRING,
2382 .p_class = P_LOCAL,
2383 .offset = LOCAL_VAR(szQueueresumecommand),
2384 .special = NULL,
2385 .enum_list = NULL,
2386 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2389 .label = "addport command",
2390 .type = P_STRING,
2391 .p_class = P_GLOBAL,
2392 .offset = GLOBAL_VAR(szAddPortCommand),
2393 .special = NULL,
2394 .enum_list = NULL,
2395 .flags = FLAG_ADVANCED,
2398 .label = "enumports command",
2399 .type = P_STRING,
2400 .p_class = P_GLOBAL,
2401 .offset = GLOBAL_VAR(szEnumPortsCommand),
2402 .special = NULL,
2403 .enum_list = NULL,
2404 .flags = FLAG_ADVANCED,
2407 .label = "addprinter command",
2408 .type = P_STRING,
2409 .p_class = P_GLOBAL,
2410 .offset = GLOBAL_VAR(szAddPrinterCommand),
2411 .special = NULL,
2412 .enum_list = NULL,
2413 .flags = FLAG_ADVANCED,
2416 .label = "deleteprinter command",
2417 .type = P_STRING,
2418 .p_class = P_GLOBAL,
2419 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2420 .special = NULL,
2421 .enum_list = NULL,
2422 .flags = FLAG_ADVANCED,
2425 .label = "show add printer wizard",
2426 .type = P_BOOL,
2427 .p_class = P_GLOBAL,
2428 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2429 .special = NULL,
2430 .enum_list = NULL,
2431 .flags = FLAG_ADVANCED,
2434 .label = "os2 driver map",
2435 .type = P_STRING,
2436 .p_class = P_GLOBAL,
2437 .offset = GLOBAL_VAR(szOs2DriverMap),
2438 .special = NULL,
2439 .enum_list = NULL,
2440 .flags = FLAG_ADVANCED,
2444 .label = "printer name",
2445 .type = P_STRING,
2446 .p_class = P_LOCAL,
2447 .offset = LOCAL_VAR(szPrintername),
2448 .special = NULL,
2449 .enum_list = NULL,
2450 .flags = FLAG_ADVANCED | FLAG_PRINT,
2453 .label = "printer",
2454 .type = P_STRING,
2455 .p_class = P_LOCAL,
2456 .offset = LOCAL_VAR(szPrintername),
2457 .special = NULL,
2458 .enum_list = NULL,
2459 .flags = FLAG_HIDE,
2462 .label = "use client driver",
2463 .type = P_BOOL,
2464 .p_class = P_LOCAL,
2465 .offset = LOCAL_VAR(bUseClientDriver),
2466 .special = NULL,
2467 .enum_list = NULL,
2468 .flags = FLAG_ADVANCED | FLAG_PRINT,
2471 .label = "default devmode",
2472 .type = P_BOOL,
2473 .p_class = P_LOCAL,
2474 .offset = LOCAL_VAR(bDefaultDevmode),
2475 .special = NULL,
2476 .enum_list = NULL,
2477 .flags = FLAG_ADVANCED | FLAG_PRINT,
2480 .label = "force printername",
2481 .type = P_BOOL,
2482 .p_class = P_LOCAL,
2483 .offset = LOCAL_VAR(bForcePrintername),
2484 .special = NULL,
2485 .enum_list = NULL,
2486 .flags = FLAG_ADVANCED | FLAG_PRINT,
2489 .label = "printjob username",
2490 .type = P_STRING,
2491 .p_class = P_LOCAL,
2492 .offset = LOCAL_VAR(szPrintjobUsername),
2493 .special = NULL,
2494 .enum_list = NULL,
2495 .flags = FLAG_ADVANCED | FLAG_PRINT,
2498 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2501 .label = "mangling method",
2502 .type = P_STRING,
2503 .p_class = P_GLOBAL,
2504 .offset = GLOBAL_VAR(szManglingMethod),
2505 .special = NULL,
2506 .enum_list = NULL,
2507 .flags = FLAG_ADVANCED,
2510 .label = "mangle prefix",
2511 .type = P_INTEGER,
2512 .p_class = P_GLOBAL,
2513 .offset = GLOBAL_VAR(mangle_prefix),
2514 .special = NULL,
2515 .enum_list = NULL,
2516 .flags = FLAG_ADVANCED,
2520 .label = "default case",
2521 .type = P_ENUM,
2522 .p_class = P_LOCAL,
2523 .offset = LOCAL_VAR(iDefaultCase),
2524 .special = NULL,
2525 .enum_list = enum_case,
2526 .flags = FLAG_ADVANCED | FLAG_SHARE,
2529 .label = "case sensitive",
2530 .type = P_ENUM,
2531 .p_class = P_LOCAL,
2532 .offset = LOCAL_VAR(iCaseSensitive),
2533 .special = NULL,
2534 .enum_list = enum_bool_auto,
2535 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2538 .label = "casesignames",
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 | FLAG_HIDE,
2547 .label = "preserve case",
2548 .type = P_BOOL,
2549 .p_class = P_LOCAL,
2550 .offset = LOCAL_VAR(bCasePreserve),
2551 .special = NULL,
2552 .enum_list = NULL,
2553 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2556 .label = "short preserve case",
2557 .type = P_BOOL,
2558 .p_class = P_LOCAL,
2559 .offset = LOCAL_VAR(bShortCasePreserve),
2560 .special = NULL,
2561 .enum_list = NULL,
2562 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2565 .label = "mangling char",
2566 .type = P_CHAR,
2567 .p_class = P_LOCAL,
2568 .offset = LOCAL_VAR(magic_char),
2569 .special = NULL,
2570 .enum_list = NULL,
2571 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2574 .label = "hide dot files",
2575 .type = P_BOOL,
2576 .p_class = P_LOCAL,
2577 .offset = LOCAL_VAR(bHideDotFiles),
2578 .special = NULL,
2579 .enum_list = NULL,
2580 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2583 .label = "hide special files",
2584 .type = P_BOOL,
2585 .p_class = P_LOCAL,
2586 .offset = LOCAL_VAR(bHideSpecialFiles),
2587 .special = NULL,
2588 .enum_list = NULL,
2589 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2592 .label = "hide unreadable",
2593 .type = P_BOOL,
2594 .p_class = P_LOCAL,
2595 .offset = LOCAL_VAR(bHideUnReadable),
2596 .special = NULL,
2597 .enum_list = NULL,
2598 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2601 .label = "hide unwriteable files",
2602 .type = P_BOOL,
2603 .p_class = P_LOCAL,
2604 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2605 .special = NULL,
2606 .enum_list = NULL,
2607 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2610 .label = "delete veto files",
2611 .type = P_BOOL,
2612 .p_class = P_LOCAL,
2613 .offset = LOCAL_VAR(bDeleteVetoFiles),
2614 .special = NULL,
2615 .enum_list = NULL,
2616 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2619 .label = "veto files",
2620 .type = P_STRING,
2621 .p_class = P_LOCAL,
2622 .offset = LOCAL_VAR(szVetoFiles),
2623 .special = NULL,
2624 .enum_list = NULL,
2625 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2628 .label = "hide files",
2629 .type = P_STRING,
2630 .p_class = P_LOCAL,
2631 .offset = LOCAL_VAR(szHideFiles),
2632 .special = NULL,
2633 .enum_list = NULL,
2634 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2637 .label = "veto oplock files",
2638 .type = P_STRING,
2639 .p_class = P_LOCAL,
2640 .offset = LOCAL_VAR(szVetoOplockFiles),
2641 .special = NULL,
2642 .enum_list = NULL,
2643 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2646 .label = "map archive",
2647 .type = P_BOOL,
2648 .p_class = P_LOCAL,
2649 .offset = LOCAL_VAR(bMap_archive),
2650 .special = NULL,
2651 .enum_list = NULL,
2652 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2655 .label = "map hidden",
2656 .type = P_BOOL,
2657 .p_class = P_LOCAL,
2658 .offset = LOCAL_VAR(bMap_hidden),
2659 .special = NULL,
2660 .enum_list = NULL,
2661 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2664 .label = "map system",
2665 .type = P_BOOL,
2666 .p_class = P_LOCAL,
2667 .offset = LOCAL_VAR(bMap_system),
2668 .special = NULL,
2669 .enum_list = NULL,
2670 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2673 .label = "map readonly",
2674 .type = P_ENUM,
2675 .p_class = P_LOCAL,
2676 .offset = LOCAL_VAR(iMap_readonly),
2677 .special = NULL,
2678 .enum_list = enum_map_readonly,
2679 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2682 .label = "mangled names",
2683 .type = P_BOOL,
2684 .p_class = P_LOCAL,
2685 .offset = LOCAL_VAR(bMangledNames),
2686 .special = NULL,
2687 .enum_list = NULL,
2688 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2691 .label = "max stat cache size",
2692 .type = P_INTEGER,
2693 .p_class = P_GLOBAL,
2694 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2695 .special = NULL,
2696 .enum_list = NULL,
2697 .flags = FLAG_ADVANCED,
2700 .label = "stat cache",
2701 .type = P_BOOL,
2702 .p_class = P_GLOBAL,
2703 .offset = GLOBAL_VAR(bStatCache),
2704 .special = NULL,
2705 .enum_list = NULL,
2706 .flags = FLAG_ADVANCED,
2709 .label = "store dos attributes",
2710 .type = P_BOOL,
2711 .p_class = P_LOCAL,
2712 .offset = LOCAL_VAR(bStoreDosAttributes),
2713 .special = NULL,
2714 .enum_list = NULL,
2715 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2718 .label = "dmapi support",
2719 .type = P_BOOL,
2720 .p_class = P_LOCAL,
2721 .offset = LOCAL_VAR(bDmapiSupport),
2722 .special = NULL,
2723 .enum_list = NULL,
2724 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2728 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2731 .label = "machine password timeout",
2732 .type = P_INTEGER,
2733 .p_class = P_GLOBAL,
2734 .offset = GLOBAL_VAR(machine_password_timeout),
2735 .special = NULL,
2736 .enum_list = NULL,
2737 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2740 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2743 .label = "add user script",
2744 .type = P_STRING,
2745 .p_class = P_GLOBAL,
2746 .offset = GLOBAL_VAR(szAddUserScript),
2747 .special = NULL,
2748 .enum_list = NULL,
2749 .flags = FLAG_ADVANCED,
2752 .label = "rename user script",
2753 .type = P_STRING,
2754 .p_class = P_GLOBAL,
2755 .offset = GLOBAL_VAR(szRenameUserScript),
2756 .special = NULL,
2757 .enum_list = NULL,
2758 .flags = FLAG_ADVANCED,
2761 .label = "delete user script",
2762 .type = P_STRING,
2763 .p_class = P_GLOBAL,
2764 .offset = GLOBAL_VAR(szDelUserScript),
2765 .special = NULL,
2766 .enum_list = NULL,
2767 .flags = FLAG_ADVANCED,
2770 .label = "add group script",
2771 .type = P_STRING,
2772 .p_class = P_GLOBAL,
2773 .offset = GLOBAL_VAR(szAddGroupScript),
2774 .special = NULL,
2775 .enum_list = NULL,
2776 .flags = FLAG_ADVANCED,
2779 .label = "delete group script",
2780 .type = P_STRING,
2781 .p_class = P_GLOBAL,
2782 .offset = GLOBAL_VAR(szDelGroupScript),
2783 .special = NULL,
2784 .enum_list = NULL,
2785 .flags = FLAG_ADVANCED,
2788 .label = "add user to group script",
2789 .type = P_STRING,
2790 .p_class = P_GLOBAL,
2791 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2792 .special = NULL,
2793 .enum_list = NULL,
2794 .flags = FLAG_ADVANCED,
2797 .label = "delete user from group script",
2798 .type = P_STRING,
2799 .p_class = P_GLOBAL,
2800 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2801 .special = NULL,
2802 .enum_list = NULL,
2803 .flags = FLAG_ADVANCED,
2806 .label = "set primary group script",
2807 .type = P_STRING,
2808 .p_class = P_GLOBAL,
2809 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2810 .special = NULL,
2811 .enum_list = NULL,
2812 .flags = FLAG_ADVANCED,
2815 .label = "add machine script",
2816 .type = P_STRING,
2817 .p_class = P_GLOBAL,
2818 .offset = GLOBAL_VAR(szAddMachineScript),
2819 .special = NULL,
2820 .enum_list = NULL,
2821 .flags = FLAG_ADVANCED,
2824 .label = "shutdown script",
2825 .type = P_STRING,
2826 .p_class = P_GLOBAL,
2827 .offset = GLOBAL_VAR(szShutdownScript),
2828 .special = NULL,
2829 .enum_list = NULL,
2830 .flags = FLAG_ADVANCED,
2833 .label = "abort shutdown script",
2834 .type = P_STRING,
2835 .p_class = P_GLOBAL,
2836 .offset = GLOBAL_VAR(szAbortShutdownScript),
2837 .special = NULL,
2838 .enum_list = NULL,
2839 .flags = FLAG_ADVANCED,
2842 .label = "username map script",
2843 .type = P_STRING,
2844 .p_class = P_GLOBAL,
2845 .offset = GLOBAL_VAR(szUsernameMapScript),
2846 .special = NULL,
2847 .enum_list = NULL,
2848 .flags = FLAG_ADVANCED,
2851 .label = "username map cache time",
2852 .type = P_INTEGER,
2853 .p_class = P_GLOBAL,
2854 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2855 .special = NULL,
2856 .enum_list = NULL,
2857 .flags = FLAG_ADVANCED,
2860 .label = "logon script",
2861 .type = P_STRING,
2862 .p_class = P_GLOBAL,
2863 .offset = GLOBAL_VAR(szLogonScript),
2864 .special = NULL,
2865 .enum_list = NULL,
2866 .flags = FLAG_ADVANCED,
2869 .label = "logon path",
2870 .type = P_STRING,
2871 .p_class = P_GLOBAL,
2872 .offset = GLOBAL_VAR(szLogonPath),
2873 .special = NULL,
2874 .enum_list = NULL,
2875 .flags = FLAG_ADVANCED,
2878 .label = "logon drive",
2879 .type = P_STRING,
2880 .p_class = P_GLOBAL,
2881 .offset = GLOBAL_VAR(szLogonDrive),
2882 .special = NULL,
2883 .enum_list = NULL,
2884 .flags = FLAG_ADVANCED,
2887 .label = "logon home",
2888 .type = P_STRING,
2889 .p_class = P_GLOBAL,
2890 .offset = GLOBAL_VAR(szLogonHome),
2891 .special = NULL,
2892 .enum_list = NULL,
2893 .flags = FLAG_ADVANCED,
2896 .label = "domain logons",
2897 .type = P_BOOL,
2898 .p_class = P_GLOBAL,
2899 .offset = GLOBAL_VAR(bDomainLogons),
2900 .special = NULL,
2901 .enum_list = NULL,
2902 .flags = FLAG_ADVANCED,
2906 .label = "init logon delayed hosts",
2907 .type = P_LIST,
2908 .p_class = P_GLOBAL,
2909 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2910 .special = NULL,
2911 .enum_list = NULL,
2912 .flags = FLAG_ADVANCED,
2916 .label = "init logon delay",
2917 .type = P_INTEGER,
2918 .p_class = P_GLOBAL,
2919 .offset = GLOBAL_VAR(InitLogonDelay),
2920 .special = NULL,
2921 .enum_list = NULL,
2922 .flags = FLAG_ADVANCED,
2926 {N_("Browse Options"), P_SEP, P_SEPARATOR},
2929 .label = "os level",
2930 .type = P_INTEGER,
2931 .p_class = P_GLOBAL,
2932 .offset = GLOBAL_VAR(os_level),
2933 .special = NULL,
2934 .enum_list = NULL,
2935 .flags = FLAG_BASIC | FLAG_ADVANCED,
2938 .label = "lm announce",
2939 .type = P_ENUM,
2940 .p_class = P_GLOBAL,
2941 .offset = GLOBAL_VAR(lm_announce),
2942 .special = NULL,
2943 .enum_list = enum_bool_auto,
2944 .flags = FLAG_ADVANCED,
2947 .label = "lm interval",
2948 .type = P_INTEGER,
2949 .p_class = P_GLOBAL,
2950 .offset = GLOBAL_VAR(lm_interval),
2951 .special = NULL,
2952 .enum_list = NULL,
2953 .flags = FLAG_ADVANCED,
2956 .label = "preferred master",
2957 .type = P_ENUM,
2958 .p_class = P_GLOBAL,
2959 .offset = GLOBAL_VAR(iPreferredMaster),
2960 .special = NULL,
2961 .enum_list = enum_bool_auto,
2962 .flags = FLAG_BASIC | FLAG_ADVANCED,
2965 .label = "prefered 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_HIDE,
2974 .label = "local master",
2975 .type = P_BOOL,
2976 .p_class = P_GLOBAL,
2977 .offset = GLOBAL_VAR(bLocalMaster),
2978 .special = NULL,
2979 .enum_list = NULL,
2980 .flags = FLAG_BASIC | FLAG_ADVANCED,
2983 .label = "domain master",
2984 .type = P_ENUM,
2985 .p_class = P_GLOBAL,
2986 .offset = GLOBAL_VAR(iDomainMaster),
2987 .special = NULL,
2988 .enum_list = enum_bool_auto,
2989 .flags = FLAG_BASIC | FLAG_ADVANCED,
2992 .label = "browse list",
2993 .type = P_BOOL,
2994 .p_class = P_GLOBAL,
2995 .offset = GLOBAL_VAR(bBrowseList),
2996 .special = NULL,
2997 .enum_list = NULL,
2998 .flags = FLAG_ADVANCED,
3001 .label = "browseable",
3002 .type = P_BOOL,
3003 .p_class = P_LOCAL,
3004 .offset = LOCAL_VAR(bBrowseable),
3005 .special = NULL,
3006 .enum_list = NULL,
3007 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3010 .label = "browsable",
3011 .type = P_BOOL,
3012 .p_class = P_LOCAL,
3013 .offset = LOCAL_VAR(bBrowseable),
3014 .special = NULL,
3015 .enum_list = NULL,
3016 .flags = FLAG_HIDE,
3019 .label = "access based share enum",
3020 .type = P_BOOL,
3021 .p_class = P_LOCAL,
3022 .offset = LOCAL_VAR(bAccessBasedShareEnum),
3023 .special = NULL,
3024 .enum_list = NULL,
3025 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3028 .label = "enhanced browsing",
3029 .type = P_BOOL,
3030 .p_class = P_GLOBAL,
3031 .offset = GLOBAL_VAR(enhanced_browsing),
3032 .special = NULL,
3033 .enum_list = NULL,
3034 .flags = FLAG_ADVANCED,
3037 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3040 .label = "dns proxy",
3041 .type = P_BOOL,
3042 .p_class = P_GLOBAL,
3043 .offset = GLOBAL_VAR(bWINSdnsProxy),
3044 .special = NULL,
3045 .enum_list = NULL,
3046 .flags = FLAG_ADVANCED,
3049 .label = "wins proxy",
3050 .type = P_BOOL,
3051 .p_class = P_GLOBAL,
3052 .offset = GLOBAL_VAR(bWINSproxy),
3053 .special = NULL,
3054 .enum_list = NULL,
3055 .flags = FLAG_ADVANCED,
3058 .label = "wins server",
3059 .type = P_LIST,
3060 .p_class = P_GLOBAL,
3061 .offset = GLOBAL_VAR(szWINSservers),
3062 .special = NULL,
3063 .enum_list = NULL,
3064 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3067 .label = "wins support",
3068 .type = P_BOOL,
3069 .p_class = P_GLOBAL,
3070 .offset = GLOBAL_VAR(bWINSsupport),
3071 .special = NULL,
3072 .enum_list = NULL,
3073 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3076 .label = "wins hook",
3077 .type = P_STRING,
3078 .p_class = P_GLOBAL,
3079 .offset = GLOBAL_VAR(szWINSHook),
3080 .special = NULL,
3081 .enum_list = NULL,
3082 .flags = FLAG_ADVANCED,
3085 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3088 .label = "blocking locks",
3089 .type = P_BOOL,
3090 .p_class = P_LOCAL,
3091 .offset = LOCAL_VAR(bBlockingLocks),
3092 .special = NULL,
3093 .enum_list = NULL,
3094 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3097 .label = "csc policy",
3098 .type = P_ENUM,
3099 .p_class = P_LOCAL,
3100 .offset = LOCAL_VAR(iCSCPolicy),
3101 .special = NULL,
3102 .enum_list = enum_csc_policy,
3103 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3106 .label = "fake oplocks",
3107 .type = P_BOOL,
3108 .p_class = P_LOCAL,
3109 .offset = LOCAL_VAR(bFakeOplocks),
3110 .special = NULL,
3111 .enum_list = NULL,
3112 .flags = FLAG_ADVANCED | FLAG_SHARE,
3115 .label = "kernel oplocks",
3116 .type = P_BOOL,
3117 .p_class = P_LOCAL,
3118 .offset = LOCAL_VAR(bKernelOplocks),
3119 .special = NULL,
3120 .enum_list = NULL,
3121 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3124 .label = "locking",
3125 .type = P_BOOL,
3126 .p_class = P_LOCAL,
3127 .offset = LOCAL_VAR(bLocking),
3128 .special = NULL,
3129 .enum_list = NULL,
3130 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3133 .label = "lock spin time",
3134 .type = P_INTEGER,
3135 .p_class = P_GLOBAL,
3136 .offset = GLOBAL_VAR(iLockSpinTime),
3137 .special = NULL,
3138 .enum_list = NULL,
3139 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3142 .label = "oplocks",
3143 .type = P_BOOL,
3144 .p_class = P_LOCAL,
3145 .offset = LOCAL_VAR(bOpLocks),
3146 .special = NULL,
3147 .enum_list = NULL,
3148 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3151 .label = "level2 oplocks",
3152 .type = P_BOOL,
3153 .p_class = P_LOCAL,
3154 .offset = LOCAL_VAR(bLevel2OpLocks),
3155 .special = NULL,
3156 .enum_list = NULL,
3157 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3160 .label = "oplock break wait time",
3161 .type = P_INTEGER,
3162 .p_class = P_GLOBAL,
3163 .offset = GLOBAL_VAR(oplock_break_wait_time),
3164 .special = NULL,
3165 .enum_list = NULL,
3166 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3169 .label = "oplock contention limit",
3170 .type = P_INTEGER,
3171 .p_class = P_LOCAL,
3172 .offset = LOCAL_VAR(iOplockContentionLimit),
3173 .special = NULL,
3174 .enum_list = NULL,
3175 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3178 .label = "posix locking",
3179 .type = P_BOOL,
3180 .p_class = P_LOCAL,
3181 .offset = LOCAL_VAR(bPosixLocking),
3182 .special = NULL,
3183 .enum_list = NULL,
3184 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3187 .label = "strict locking",
3188 .type = P_ENUM,
3189 .p_class = P_LOCAL,
3190 .offset = LOCAL_VAR(iStrictLocking),
3191 .special = NULL,
3192 .enum_list = enum_bool_auto,
3193 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3196 .label = "share modes",
3197 .type = P_BOOL,
3198 .p_class = P_LOCAL,
3199 .offset = LOCAL_VAR(bShareModes),
3200 .special = NULL,
3201 .enum_list = NULL,
3202 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3205 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3208 .label = "ldap admin dn",
3209 .type = P_STRING,
3210 .p_class = P_GLOBAL,
3211 .offset = GLOBAL_VAR(szLdapAdminDn),
3212 .special = NULL,
3213 .enum_list = NULL,
3214 .flags = FLAG_ADVANCED,
3217 .label = "ldap delete dn",
3218 .type = P_BOOL,
3219 .p_class = P_GLOBAL,
3220 .offset = GLOBAL_VAR(ldap_delete_dn),
3221 .special = NULL,
3222 .enum_list = NULL,
3223 .flags = FLAG_ADVANCED,
3226 .label = "ldap group suffix",
3227 .type = P_STRING,
3228 .p_class = P_GLOBAL,
3229 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3230 .special = NULL,
3231 .enum_list = NULL,
3232 .flags = FLAG_ADVANCED,
3235 .label = "ldap idmap suffix",
3236 .type = P_STRING,
3237 .p_class = P_GLOBAL,
3238 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3239 .special = NULL,
3240 .enum_list = NULL,
3241 .flags = FLAG_ADVANCED,
3244 .label = "ldap machine suffix",
3245 .type = P_STRING,
3246 .p_class = P_GLOBAL,
3247 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3248 .special = NULL,
3249 .enum_list = NULL,
3250 .flags = FLAG_ADVANCED,
3253 .label = "ldap passwd sync",
3254 .type = P_ENUM,
3255 .p_class = P_GLOBAL,
3256 .offset = GLOBAL_VAR(ldap_passwd_sync),
3257 .special = NULL,
3258 .enum_list = enum_ldap_passwd_sync,
3259 .flags = FLAG_ADVANCED,
3262 .label = "ldap password 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_HIDE,
3271 .label = "ldap replication sleep",
3272 .type = P_INTEGER,
3273 .p_class = P_GLOBAL,
3274 .offset = GLOBAL_VAR(ldap_replication_sleep),
3275 .special = NULL,
3276 .enum_list = NULL,
3277 .flags = FLAG_ADVANCED,
3280 .label = "ldap suffix",
3281 .type = P_STRING,
3282 .p_class = P_GLOBAL,
3283 .offset = GLOBAL_VAR(szLdapSuffix),
3284 .special = NULL,
3285 .enum_list = NULL,
3286 .flags = FLAG_ADVANCED,
3289 .label = "ldap ssl",
3290 .type = P_ENUM,
3291 .p_class = P_GLOBAL,
3292 .offset = GLOBAL_VAR(ldap_ssl),
3293 .special = NULL,
3294 .enum_list = enum_ldap_ssl,
3295 .flags = FLAG_ADVANCED,
3298 .label = "ldap ssl ads",
3299 .type = P_BOOL,
3300 .p_class = P_GLOBAL,
3301 .offset = GLOBAL_VAR(ldap_ssl_ads),
3302 .special = NULL,
3303 .enum_list = NULL,
3304 .flags = FLAG_ADVANCED,
3307 .label = "ldap deref",
3308 .type = P_ENUM,
3309 .p_class = P_GLOBAL,
3310 .offset = GLOBAL_VAR(ldap_deref),
3311 .special = NULL,
3312 .enum_list = enum_ldap_deref,
3313 .flags = FLAG_ADVANCED,
3316 .label = "ldap follow referral",
3317 .type = P_ENUM,
3318 .p_class = P_GLOBAL,
3319 .offset = GLOBAL_VAR(ldap_follow_referral),
3320 .special = NULL,
3321 .enum_list = enum_bool_auto,
3322 .flags = FLAG_ADVANCED,
3325 .label = "ldap timeout",
3326 .type = P_INTEGER,
3327 .p_class = P_GLOBAL,
3328 .offset = GLOBAL_VAR(ldap_timeout),
3329 .special = NULL,
3330 .enum_list = NULL,
3331 .flags = FLAG_ADVANCED,
3334 .label = "ldap connection timeout",
3335 .type = P_INTEGER,
3336 .p_class = P_GLOBAL,
3337 .offset = GLOBAL_VAR(ldap_connection_timeout),
3338 .special = NULL,
3339 .enum_list = NULL,
3340 .flags = FLAG_ADVANCED,
3343 .label = "ldap page size",
3344 .type = P_INTEGER,
3345 .p_class = P_GLOBAL,
3346 .offset = GLOBAL_VAR(ldap_page_size),
3347 .special = NULL,
3348 .enum_list = NULL,
3349 .flags = FLAG_ADVANCED,
3352 .label = "ldap user suffix",
3353 .type = P_STRING,
3354 .p_class = P_GLOBAL,
3355 .offset = GLOBAL_VAR(szLdapUserSuffix),
3356 .special = NULL,
3357 .enum_list = NULL,
3358 .flags = FLAG_ADVANCED,
3361 .label = "ldap debug level",
3362 .type = P_INTEGER,
3363 .p_class = P_GLOBAL,
3364 .offset = GLOBAL_VAR(ldap_debug_level),
3365 .special = handle_ldap_debug_level,
3366 .enum_list = NULL,
3367 .flags = FLAG_ADVANCED,
3370 .label = "ldap debug threshold",
3371 .type = P_INTEGER,
3372 .p_class = P_GLOBAL,
3373 .offset = GLOBAL_VAR(ldap_debug_threshold),
3374 .special = NULL,
3375 .enum_list = NULL,
3376 .flags = FLAG_ADVANCED,
3379 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3382 .label = "eventlog list",
3383 .type = P_LIST,
3384 .p_class = P_GLOBAL,
3385 .offset = GLOBAL_VAR(szEventLogs),
3386 .special = NULL,
3387 .enum_list = NULL,
3388 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3391 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3394 .label = "add share command",
3395 .type = P_STRING,
3396 .p_class = P_GLOBAL,
3397 .offset = GLOBAL_VAR(szAddShareCommand),
3398 .special = NULL,
3399 .enum_list = NULL,
3400 .flags = FLAG_ADVANCED,
3403 .label = "change share command",
3404 .type = P_STRING,
3405 .p_class = P_GLOBAL,
3406 .offset = GLOBAL_VAR(szChangeShareCommand),
3407 .special = NULL,
3408 .enum_list = NULL,
3409 .flags = FLAG_ADVANCED,
3412 .label = "delete share command",
3413 .type = P_STRING,
3414 .p_class = P_GLOBAL,
3415 .offset = GLOBAL_VAR(szDeleteShareCommand),
3416 .special = NULL,
3417 .enum_list = NULL,
3418 .flags = FLAG_ADVANCED,
3421 .label = "config file",
3422 .type = P_STRING,
3423 .p_class = P_GLOBAL,
3424 .offset = GLOBAL_VAR(szConfigFile),
3425 .special = NULL,
3426 .enum_list = NULL,
3427 .flags = FLAG_HIDE|FLAG_META,
3430 .label = "preload",
3431 .type = P_STRING,
3432 .p_class = P_GLOBAL,
3433 .offset = GLOBAL_VAR(szAutoServices),
3434 .special = NULL,
3435 .enum_list = NULL,
3436 .flags = FLAG_ADVANCED,
3439 .label = "auto services",
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 = "lock directory",
3449 .type = P_STRING,
3450 .p_class = P_GLOBAL,
3451 .offset = GLOBAL_VAR(szLockDir),
3452 .special = NULL,
3453 .enum_list = NULL,
3454 .flags = FLAG_ADVANCED,
3457 .label = "lock dir",
3458 .type = P_STRING,
3459 .p_class = P_GLOBAL,
3460 .offset = GLOBAL_VAR(szLockDir),
3461 .special = NULL,
3462 .enum_list = NULL,
3463 .flags = FLAG_HIDE,
3466 .label = "state directory",
3467 .type = P_STRING,
3468 .p_class = P_GLOBAL,
3469 .offset = GLOBAL_VAR(szStateDir),
3470 .special = NULL,
3471 .enum_list = NULL,
3472 .flags = FLAG_ADVANCED,
3475 .label = "cache directory",
3476 .type = P_STRING,
3477 .p_class = P_GLOBAL,
3478 .offset = GLOBAL_VAR(szCacheDir),
3479 .special = NULL,
3480 .enum_list = NULL,
3481 .flags = FLAG_ADVANCED,
3484 .label = "pid directory",
3485 .type = P_STRING,
3486 .p_class = P_GLOBAL,
3487 .offset = GLOBAL_VAR(szPidDir),
3488 .special = NULL,
3489 .enum_list = NULL,
3490 .flags = FLAG_ADVANCED,
3492 #ifdef WITH_UTMP
3494 .label = "utmp directory",
3495 .type = P_STRING,
3496 .p_class = P_GLOBAL,
3497 .offset = GLOBAL_VAR(szUtmpDir),
3498 .special = NULL,
3499 .enum_list = NULL,
3500 .flags = FLAG_ADVANCED,
3503 .label = "wtmp directory",
3504 .type = P_STRING,
3505 .p_class = P_GLOBAL,
3506 .offset = GLOBAL_VAR(szWtmpDir),
3507 .special = NULL,
3508 .enum_list = NULL,
3509 .flags = FLAG_ADVANCED,
3512 .label = "utmp",
3513 .type = P_BOOL,
3514 .p_class = P_GLOBAL,
3515 .offset = GLOBAL_VAR(bUtmp),
3516 .special = NULL,
3517 .enum_list = NULL,
3518 .flags = FLAG_ADVANCED,
3520 #endif
3522 .label = "default service",
3523 .type = P_STRING,
3524 .p_class = P_GLOBAL,
3525 .offset = GLOBAL_VAR(szDefaultService),
3526 .special = NULL,
3527 .enum_list = NULL,
3528 .flags = FLAG_ADVANCED,
3531 .label = "default",
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 = "message command",
3541 .type = P_STRING,
3542 .p_class = P_GLOBAL,
3543 .offset = GLOBAL_VAR(szMsgCommand),
3544 .special = NULL,
3545 .enum_list = NULL,
3546 .flags = FLAG_ADVANCED,
3549 .label = "dfree cache time",
3550 .type = P_INTEGER,
3551 .p_class = P_LOCAL,
3552 .offset = LOCAL_VAR(iDfreeCacheTime),
3553 .special = NULL,
3554 .enum_list = NULL,
3555 .flags = FLAG_ADVANCED,
3558 .label = "dfree command",
3559 .type = P_STRING,
3560 .p_class = P_LOCAL,
3561 .offset = LOCAL_VAR(szDfree),
3562 .special = NULL,
3563 .enum_list = NULL,
3564 .flags = FLAG_ADVANCED,
3567 .label = "get quota command",
3568 .type = P_STRING,
3569 .p_class = P_GLOBAL,
3570 .offset = GLOBAL_VAR(szGetQuota),
3571 .special = NULL,
3572 .enum_list = NULL,
3573 .flags = FLAG_ADVANCED,
3576 .label = "set quota command",
3577 .type = P_STRING,
3578 .p_class = P_GLOBAL,
3579 .offset = GLOBAL_VAR(szSetQuota),
3580 .special = NULL,
3581 .enum_list = NULL,
3582 .flags = FLAG_ADVANCED,
3585 .label = "remote announce",
3586 .type = P_STRING,
3587 .p_class = P_GLOBAL,
3588 .offset = GLOBAL_VAR(szRemoteAnnounce),
3589 .special = NULL,
3590 .enum_list = NULL,
3591 .flags = FLAG_ADVANCED,
3594 .label = "remote browse sync",
3595 .type = P_STRING,
3596 .p_class = P_GLOBAL,
3597 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3598 .special = NULL,
3599 .enum_list = NULL,
3600 .flags = FLAG_ADVANCED,
3603 .label = "socket address",
3604 .type = P_STRING,
3605 .p_class = P_GLOBAL,
3606 .offset = GLOBAL_VAR(szSocketAddress),
3607 .special = NULL,
3608 .enum_list = NULL,
3609 .flags = FLAG_ADVANCED,
3612 .label = "nmbd bind explicit broadcast",
3613 .type = P_BOOL,
3614 .p_class = P_GLOBAL,
3615 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3616 .special = NULL,
3617 .enum_list = NULL,
3618 .flags = FLAG_ADVANCED,
3621 .label = "homedir map",
3622 .type = P_STRING,
3623 .p_class = P_GLOBAL,
3624 .offset = GLOBAL_VAR(szNISHomeMapName),
3625 .special = NULL,
3626 .enum_list = NULL,
3627 .flags = FLAG_ADVANCED,
3630 .label = "afs username map",
3631 .type = P_STRING,
3632 .p_class = P_GLOBAL,
3633 .offset = GLOBAL_VAR(szAfsUsernameMap),
3634 .special = NULL,
3635 .enum_list = NULL,
3636 .flags = FLAG_ADVANCED,
3639 .label = "afs token lifetime",
3640 .type = P_INTEGER,
3641 .p_class = P_GLOBAL,
3642 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3643 .special = NULL,
3644 .enum_list = NULL,
3645 .flags = FLAG_ADVANCED,
3648 .label = "log nt token command",
3649 .type = P_STRING,
3650 .p_class = P_GLOBAL,
3651 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3652 .special = NULL,
3653 .enum_list = NULL,
3654 .flags = FLAG_ADVANCED,
3657 .label = "NIS homedir",
3658 .type = P_BOOL,
3659 .p_class = P_GLOBAL,
3660 .offset = GLOBAL_VAR(bNISHomeMap),
3661 .special = NULL,
3662 .enum_list = NULL,
3663 .flags = FLAG_ADVANCED,
3666 .label = "-valid",
3667 .type = P_BOOL,
3668 .p_class = P_LOCAL,
3669 .offset = LOCAL_VAR(valid),
3670 .special = NULL,
3671 .enum_list = NULL,
3672 .flags = FLAG_HIDE,
3675 .label = "copy",
3676 .type = P_STRING,
3677 .p_class = P_LOCAL,
3678 .offset = LOCAL_VAR(szCopy),
3679 .special = handle_copy,
3680 .enum_list = NULL,
3681 .flags = FLAG_HIDE,
3684 .label = "include",
3685 .type = P_STRING,
3686 .p_class = P_LOCAL,
3687 .offset = LOCAL_VAR(szInclude),
3688 .special = handle_include,
3689 .enum_list = NULL,
3690 .flags = FLAG_HIDE|FLAG_META,
3693 .label = "preexec",
3694 .type = P_STRING,
3695 .p_class = P_LOCAL,
3696 .offset = LOCAL_VAR(szPreExec),
3697 .special = NULL,
3698 .enum_list = NULL,
3699 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3702 .label = "exec",
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,
3711 .label = "preexec close",
3712 .type = P_BOOL,
3713 .p_class = P_LOCAL,
3714 .offset = LOCAL_VAR(bPreexecClose),
3715 .special = NULL,
3716 .enum_list = NULL,
3717 .flags = FLAG_ADVANCED | FLAG_SHARE,
3720 .label = "postexec",
3721 .type = P_STRING,
3722 .p_class = P_LOCAL,
3723 .offset = LOCAL_VAR(szPostExec),
3724 .special = NULL,
3725 .enum_list = NULL,
3726 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3729 .label = "root preexec",
3730 .type = P_STRING,
3731 .p_class = P_LOCAL,
3732 .offset = LOCAL_VAR(szRootPreExec),
3733 .special = NULL,
3734 .enum_list = NULL,
3735 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3738 .label = "root preexec close",
3739 .type = P_BOOL,
3740 .p_class = P_LOCAL,
3741 .offset = LOCAL_VAR(bRootpreexecClose),
3742 .special = NULL,
3743 .enum_list = NULL,
3744 .flags = FLAG_ADVANCED | FLAG_SHARE,
3747 .label = "root postexec",
3748 .type = P_STRING,
3749 .p_class = P_LOCAL,
3750 .offset = LOCAL_VAR(szRootPostExec),
3751 .special = NULL,
3752 .enum_list = NULL,
3753 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3756 .label = "available",
3757 .type = P_BOOL,
3758 .p_class = P_LOCAL,
3759 .offset = LOCAL_VAR(bAvailable),
3760 .special = NULL,
3761 .enum_list = NULL,
3762 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3765 .label = "registry shares",
3766 .type = P_BOOL,
3767 .p_class = P_GLOBAL,
3768 .offset = GLOBAL_VAR(bRegistryShares),
3769 .special = NULL,
3770 .enum_list = NULL,
3771 .flags = FLAG_ADVANCED,
3774 .label = "usershare allow guests",
3775 .type = P_BOOL,
3776 .p_class = P_GLOBAL,
3777 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3778 .special = NULL,
3779 .enum_list = NULL,
3780 .flags = FLAG_ADVANCED,
3783 .label = "usershare max shares",
3784 .type = P_INTEGER,
3785 .p_class = P_GLOBAL,
3786 .offset = GLOBAL_VAR(iUsershareMaxShares),
3787 .special = NULL,
3788 .enum_list = NULL,
3789 .flags = FLAG_ADVANCED,
3792 .label = "usershare owner only",
3793 .type = P_BOOL,
3794 .p_class = P_GLOBAL,
3795 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3796 .special = NULL,
3797 .enum_list = NULL,
3798 .flags = FLAG_ADVANCED,
3801 .label = "usershare path",
3802 .type = P_STRING,
3803 .p_class = P_GLOBAL,
3804 .offset = GLOBAL_VAR(szUsersharePath),
3805 .special = NULL,
3806 .enum_list = NULL,
3807 .flags = FLAG_ADVANCED,
3810 .label = "usershare prefix allow list",
3811 .type = P_LIST,
3812 .p_class = P_GLOBAL,
3813 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3814 .special = NULL,
3815 .enum_list = NULL,
3816 .flags = FLAG_ADVANCED,
3819 .label = "usershare prefix deny list",
3820 .type = P_LIST,
3821 .p_class = P_GLOBAL,
3822 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3823 .special = NULL,
3824 .enum_list = NULL,
3825 .flags = FLAG_ADVANCED,
3828 .label = "usershare template share",
3829 .type = P_STRING,
3830 .p_class = P_GLOBAL,
3831 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3832 .special = NULL,
3833 .enum_list = NULL,
3834 .flags = FLAG_ADVANCED,
3837 .label = "volume",
3838 .type = P_STRING,
3839 .p_class = P_LOCAL,
3840 .offset = LOCAL_VAR(volume),
3841 .special = NULL,
3842 .enum_list = NULL,
3843 .flags = FLAG_ADVANCED | FLAG_SHARE,
3846 .label = "fstype",
3847 .type = P_STRING,
3848 .p_class = P_LOCAL,
3849 .offset = LOCAL_VAR(fstype),
3850 .special = NULL,
3851 .enum_list = NULL,
3852 .flags = FLAG_ADVANCED | FLAG_SHARE,
3855 .label = "set directory",
3856 .type = P_BOOLREV,
3857 .p_class = P_LOCAL,
3858 .offset = LOCAL_VAR(bNo_set_dir),
3859 .special = NULL,
3860 .enum_list = NULL,
3861 .flags = FLAG_ADVANCED | FLAG_SHARE,
3864 .label = "allow insecure wide links",
3865 .type = P_BOOL,
3866 .p_class = P_GLOBAL,
3867 .offset = GLOBAL_VAR(bAllowInsecureWidelinks),
3868 .special = NULL,
3869 .enum_list = NULL,
3870 .flags = FLAG_ADVANCED,
3873 .label = "wide links",
3874 .type = P_BOOL,
3875 .p_class = P_LOCAL,
3876 .offset = LOCAL_VAR(bWidelinks),
3877 .special = NULL,
3878 .enum_list = NULL,
3879 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3882 .label = "follow symlinks",
3883 .type = P_BOOL,
3884 .p_class = P_LOCAL,
3885 .offset = LOCAL_VAR(bSymlinks),
3886 .special = NULL,
3887 .enum_list = NULL,
3888 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3891 .label = "dont descend",
3892 .type = P_STRING,
3893 .p_class = P_LOCAL,
3894 .offset = LOCAL_VAR(szDontdescend),
3895 .special = NULL,
3896 .enum_list = NULL,
3897 .flags = FLAG_ADVANCED | FLAG_SHARE,
3900 .label = "magic script",
3901 .type = P_STRING,
3902 .p_class = P_LOCAL,
3903 .offset = LOCAL_VAR(szMagicScript),
3904 .special = NULL,
3905 .enum_list = NULL,
3906 .flags = FLAG_ADVANCED | FLAG_SHARE,
3909 .label = "magic output",
3910 .type = P_STRING,
3911 .p_class = P_LOCAL,
3912 .offset = LOCAL_VAR(szMagicOutput),
3913 .special = NULL,
3914 .enum_list = NULL,
3915 .flags = FLAG_ADVANCED | FLAG_SHARE,
3918 .label = "delete readonly",
3919 .type = P_BOOL,
3920 .p_class = P_LOCAL,
3921 .offset = LOCAL_VAR(bDeleteReadonly),
3922 .special = NULL,
3923 .enum_list = NULL,
3924 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3927 .label = "dos filemode",
3928 .type = P_BOOL,
3929 .p_class = P_LOCAL,
3930 .offset = LOCAL_VAR(bDosFilemode),
3931 .special = NULL,
3932 .enum_list = NULL,
3933 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3936 .label = "dos filetimes",
3937 .type = P_BOOL,
3938 .p_class = P_LOCAL,
3939 .offset = LOCAL_VAR(bDosFiletimes),
3940 .special = NULL,
3941 .enum_list = NULL,
3942 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3945 .label = "dos filetime resolution",
3946 .type = P_BOOL,
3947 .p_class = P_LOCAL,
3948 .offset = LOCAL_VAR(bDosFiletimeResolution),
3949 .special = NULL,
3950 .enum_list = NULL,
3951 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3954 .label = "fake directory create times",
3955 .type = P_BOOL,
3956 .p_class = P_LOCAL,
3957 .offset = LOCAL_VAR(bFakeDirCreateTimes),
3958 .special = NULL,
3959 .enum_list = NULL,
3960 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3963 .label = "async smb echo handler",
3964 .type = P_BOOL,
3965 .p_class = P_GLOBAL,
3966 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
3967 .special = NULL,
3968 .enum_list = NULL,
3969 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3972 .label = "multicast dns register",
3973 .type = P_BOOL,
3974 .p_class = P_GLOBAL,
3975 .offset = GLOBAL_VAR(bMulticastDnsRegister),
3976 .special = NULL,
3977 .enum_list = NULL,
3978 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3981 .label = "panic action",
3982 .type = P_STRING,
3983 .p_class = P_GLOBAL,
3984 .offset = GLOBAL_VAR(szPanicAction),
3985 .special = NULL,
3986 .enum_list = NULL,
3987 .flags = FLAG_ADVANCED,
3990 .label = "perfcount module",
3991 .type = P_STRING,
3992 .p_class = P_GLOBAL,
3993 .offset = GLOBAL_VAR(szSMBPerfcountModule),
3994 .special = NULL,
3995 .enum_list = NULL,
3996 .flags = FLAG_ADVANCED,
3999 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4002 .label = "vfs objects",
4003 .type = P_LIST,
4004 .p_class = P_LOCAL,
4005 .offset = LOCAL_VAR(szVfsObjects),
4006 .special = NULL,
4007 .enum_list = NULL,
4008 .flags = FLAG_ADVANCED | FLAG_SHARE,
4011 .label = "vfs object",
4012 .type = P_LIST,
4013 .p_class = P_LOCAL,
4014 .offset = LOCAL_VAR(szVfsObjects),
4015 .special = NULL,
4016 .enum_list = NULL,
4017 .flags = FLAG_HIDE,
4021 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4024 .label = "msdfs root",
4025 .type = P_BOOL,
4026 .p_class = P_LOCAL,
4027 .offset = LOCAL_VAR(bMSDfsRoot),
4028 .special = NULL,
4029 .enum_list = NULL,
4030 .flags = FLAG_ADVANCED | FLAG_SHARE,
4033 .label = "msdfs proxy",
4034 .type = P_STRING,
4035 .p_class = P_LOCAL,
4036 .offset = LOCAL_VAR(szMSDfsProxy),
4037 .special = NULL,
4038 .enum_list = NULL,
4039 .flags = FLAG_ADVANCED | FLAG_SHARE,
4042 .label = "host msdfs",
4043 .type = P_BOOL,
4044 .p_class = P_GLOBAL,
4045 .offset = GLOBAL_VAR(bHostMSDfs),
4046 .special = NULL,
4047 .enum_list = NULL,
4048 .flags = FLAG_ADVANCED,
4051 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4054 .label = "passdb expand explicit",
4055 .type = P_BOOL,
4056 .p_class = P_GLOBAL,
4057 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4058 .special = NULL,
4059 .enum_list = NULL,
4060 .flags = FLAG_ADVANCED,
4063 .label = "idmap backend",
4064 .type = P_STRING,
4065 .p_class = P_GLOBAL,
4066 .offset = GLOBAL_VAR(szIdmapBackend),
4067 .special = handle_idmap_backend,
4068 .enum_list = NULL,
4069 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4072 .label = "idmap cache time",
4073 .type = P_INTEGER,
4074 .p_class = P_GLOBAL,
4075 .offset = GLOBAL_VAR(iIdmapCacheTime),
4076 .special = NULL,
4077 .enum_list = NULL,
4078 .flags = FLAG_ADVANCED,
4081 .label = "idmap negative cache time",
4082 .type = P_INTEGER,
4083 .p_class = P_GLOBAL,
4084 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4085 .special = NULL,
4086 .enum_list = NULL,
4087 .flags = FLAG_ADVANCED,
4090 .label = "idmap uid",
4091 .type = P_STRING,
4092 .p_class = P_GLOBAL,
4093 .offset = GLOBAL_VAR(szIdmapUID),
4094 .special = handle_idmap_uid,
4095 .enum_list = NULL,
4096 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4099 .label = "winbind 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_HIDE,
4108 .label = "idmap gid",
4109 .type = P_STRING,
4110 .p_class = P_GLOBAL,
4111 .offset = GLOBAL_VAR(szIdmapGID),
4112 .special = handle_idmap_gid,
4113 .enum_list = NULL,
4114 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4117 .label = "winbind 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_HIDE,
4126 .label = "template homedir",
4127 .type = P_STRING,
4128 .p_class = P_GLOBAL,
4129 .offset = GLOBAL_VAR(szTemplateHomedir),
4130 .special = NULL,
4131 .enum_list = NULL,
4132 .flags = FLAG_ADVANCED,
4135 .label = "template shell",
4136 .type = P_STRING,
4137 .p_class = P_GLOBAL,
4138 .offset = GLOBAL_VAR(szTemplateShell),
4139 .special = NULL,
4140 .enum_list = NULL,
4141 .flags = FLAG_ADVANCED,
4144 .label = "winbind separator",
4145 .type = P_STRING,
4146 .p_class = P_GLOBAL,
4147 .offset = GLOBAL_VAR(szWinbindSeparator),
4148 .special = NULL,
4149 .enum_list = NULL,
4150 .flags = FLAG_ADVANCED,
4153 .label = "winbind cache time",
4154 .type = P_INTEGER,
4155 .p_class = P_GLOBAL,
4156 .offset = GLOBAL_VAR(winbind_cache_time),
4157 .special = NULL,
4158 .enum_list = NULL,
4159 .flags = FLAG_ADVANCED,
4162 .label = "winbind reconnect delay",
4163 .type = P_INTEGER,
4164 .p_class = P_GLOBAL,
4165 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4166 .special = NULL,
4167 .enum_list = NULL,
4168 .flags = FLAG_ADVANCED,
4171 .label = "winbind max clients",
4172 .type = P_INTEGER,
4173 .p_class = P_GLOBAL,
4174 .offset = GLOBAL_VAR(winbind_max_clients),
4175 .special = NULL,
4176 .enum_list = NULL,
4177 .flags = FLAG_ADVANCED,
4180 .label = "winbind enum users",
4181 .type = P_BOOL,
4182 .p_class = P_GLOBAL,
4183 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4184 .special = NULL,
4185 .enum_list = NULL,
4186 .flags = FLAG_ADVANCED,
4189 .label = "winbind enum groups",
4190 .type = P_BOOL,
4191 .p_class = P_GLOBAL,
4192 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4193 .special = NULL,
4194 .enum_list = NULL,
4195 .flags = FLAG_ADVANCED,
4198 .label = "winbind use default domain",
4199 .type = P_BOOL,
4200 .p_class = P_GLOBAL,
4201 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4202 .special = NULL,
4203 .enum_list = NULL,
4204 .flags = FLAG_ADVANCED,
4207 .label = "winbind trusted domains only",
4208 .type = P_BOOL,
4209 .p_class = P_GLOBAL,
4210 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4211 .special = NULL,
4212 .enum_list = NULL,
4213 .flags = FLAG_ADVANCED,
4216 .label = "winbind nested groups",
4217 .type = P_BOOL,
4218 .p_class = P_GLOBAL,
4219 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4220 .special = NULL,
4221 .enum_list = NULL,
4222 .flags = FLAG_ADVANCED,
4225 .label = "winbind expand groups",
4226 .type = P_INTEGER,
4227 .p_class = P_GLOBAL,
4228 .offset = GLOBAL_VAR(winbind_expand_groups),
4229 .special = NULL,
4230 .enum_list = NULL,
4231 .flags = FLAG_ADVANCED,
4234 .label = "winbind nss info",
4235 .type = P_LIST,
4236 .p_class = P_GLOBAL,
4237 .offset = GLOBAL_VAR(szWinbindNssInfo),
4238 .special = NULL,
4239 .enum_list = NULL,
4240 .flags = FLAG_ADVANCED,
4243 .label = "winbind refresh tickets",
4244 .type = P_BOOL,
4245 .p_class = P_GLOBAL,
4246 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4247 .special = NULL,
4248 .enum_list = NULL,
4249 .flags = FLAG_ADVANCED,
4252 .label = "winbind offline logon",
4253 .type = P_BOOL,
4254 .p_class = P_GLOBAL,
4255 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4256 .special = NULL,
4257 .enum_list = NULL,
4258 .flags = FLAG_ADVANCED,
4261 .label = "winbind normalize names",
4262 .type = P_BOOL,
4263 .p_class = P_GLOBAL,
4264 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4265 .special = NULL,
4266 .enum_list = NULL,
4267 .flags = FLAG_ADVANCED,
4270 .label = "winbind rpc only",
4271 .type = P_BOOL,
4272 .p_class = P_GLOBAL,
4273 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4274 .special = NULL,
4275 .enum_list = NULL,
4276 .flags = FLAG_ADVANCED,
4279 .label = "create krb5 conf",
4280 .type = P_BOOL,
4281 .p_class = P_GLOBAL,
4282 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4283 .special = NULL,
4284 .enum_list = NULL,
4285 .flags = FLAG_ADVANCED,
4288 .label = "ncalrpc dir",
4289 .type = P_STRING,
4290 .p_class = P_GLOBAL,
4291 .offset = GLOBAL_VAR(ncalrpc_dir),
4292 .special = NULL,
4293 .enum_list = NULL,
4294 .flags = FLAG_ADVANCED,
4297 .label = "winbind max domain connections",
4298 .type = P_INTEGER,
4299 .p_class = P_GLOBAL,
4300 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4301 .special = NULL,
4302 .enum_list = NULL,
4303 .flags = FLAG_ADVANCED,
4306 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4309 /***************************************************************************
4310 Initialise the sDefault parameter structure for the printer values.
4311 ***************************************************************************/
4313 static void init_printer_values(struct loadparm_service *pService)
4315 /* choose defaults depending on the type of printing */
4316 switch (pService->iPrinting) {
4317 case PRINT_BSD:
4318 case PRINT_AIX:
4319 case PRINT_LPRNT:
4320 case PRINT_LPROS2:
4321 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4322 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4323 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4324 break;
4326 case PRINT_LPRNG:
4327 case PRINT_PLP:
4328 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4329 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4330 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4331 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4332 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4333 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4334 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4335 break;
4337 case PRINT_CUPS:
4338 case PRINT_IPRINT:
4339 #ifdef HAVE_CUPS
4340 /* set the lpq command to contain the destination printer
4341 name only. This is used by cups_queue_get() */
4342 string_set(&pService->szLpqcommand, "%p");
4343 string_set(&pService->szLprmcommand, "");
4344 string_set(&pService->szPrintcommand, "");
4345 string_set(&pService->szLppausecommand, "");
4346 string_set(&pService->szLpresumecommand, "");
4347 string_set(&pService->szQueuepausecommand, "");
4348 string_set(&pService->szQueueresumecommand, "");
4349 #else
4350 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4351 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4352 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4353 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4354 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4355 string_set(&pService->szQueuepausecommand, "disable '%p'");
4356 string_set(&pService->szQueueresumecommand, "enable '%p'");
4357 #endif /* HAVE_CUPS */
4358 break;
4360 case PRINT_SYSV:
4361 case PRINT_HPUX:
4362 string_set(&pService->szLpqcommand, "lpstat -o%p");
4363 string_set(&pService->szLprmcommand, "cancel %p-%j");
4364 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4365 string_set(&pService->szQueuepausecommand, "disable %p");
4366 string_set(&pService->szQueueresumecommand, "enable %p");
4367 #ifndef HPUX
4368 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4369 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4370 #endif /* HPUX */
4371 break;
4373 case PRINT_QNX:
4374 string_set(&pService->szLpqcommand, "lpq -P%p");
4375 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4376 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4377 break;
4379 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4381 case PRINT_TEST:
4382 case PRINT_VLP: {
4383 const char *tdbfile;
4384 char *tmp;
4386 tdbfile = talloc_asprintf(
4387 talloc_tos(), "tdbfile=%s",
4388 lp_parm_const_string(-1, "vlp", "tdbfile",
4389 "/tmp/vlp.tdb"));
4390 if (tdbfile == NULL) {
4391 tdbfile="tdbfile=/tmp/vlp.tdb";
4394 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4395 tdbfile);
4396 string_set(&pService->szPrintcommand,
4397 tmp ? tmp : "vlp print %p %s");
4398 TALLOC_FREE(tmp);
4400 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4401 tdbfile);
4402 string_set(&pService->szLpqcommand,
4403 tmp ? tmp : "vlp lpq %p");
4404 TALLOC_FREE(tmp);
4406 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4407 tdbfile);
4408 string_set(&pService->szLprmcommand,
4409 tmp ? tmp : "vlp lprm %p %j");
4410 TALLOC_FREE(tmp);
4412 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4413 tdbfile);
4414 string_set(&pService->szLppausecommand,
4415 tmp ? tmp : "vlp lppause %p %j");
4416 TALLOC_FREE(tmp);
4418 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4419 tdbfile);
4420 string_set(&pService->szLpresumecommand,
4421 tmp ? tmp : "vlp lpresume %p %j");
4422 TALLOC_FREE(tmp);
4424 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4425 tdbfile);
4426 string_set(&pService->szQueuepausecommand,
4427 tmp ? tmp : "vlp queuepause %p");
4428 TALLOC_FREE(tmp);
4430 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4431 tdbfile);
4432 string_set(&pService->szQueueresumecommand,
4433 tmp ? tmp : "vlp queueresume %p");
4434 TALLOC_FREE(tmp);
4436 break;
4438 #endif /* DEVELOPER */
4443 * Function to return the default value for the maximum number of open
4444 * file descriptors permitted. This function tries to consult the
4445 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4446 * the smaller of those.
4448 static int max_open_files(void)
4450 int sysctl_max = MAX_OPEN_FILES;
4451 int rlimit_max = MAX_OPEN_FILES;
4453 #ifdef HAVE_SYSCTLBYNAME
4455 size_t size = sizeof(sysctl_max);
4456 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4459 #endif
4461 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4463 struct rlimit rl;
4465 ZERO_STRUCT(rl);
4467 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4468 rlimit_max = rl.rlim_cur;
4470 #if defined(RLIM_INFINITY)
4471 if(rl.rlim_cur == RLIM_INFINITY)
4472 rlimit_max = MAX_OPEN_FILES;
4473 #endif
4475 #endif
4477 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4478 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4479 "minimum Windows limit (%d)\n",
4480 sysctl_max,
4481 MIN_OPEN_FILES_WINDOWS));
4482 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4485 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4486 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4487 "minimum Windows limit (%d)\n",
4488 rlimit_max,
4489 MIN_OPEN_FILES_WINDOWS));
4490 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4493 return MIN(sysctl_max, rlimit_max);
4497 * Common part of freeing allocated data for one parameter.
4499 static void free_one_parameter_common(void *parm_ptr,
4500 struct parm_struct parm)
4502 if ((parm.type == P_STRING) ||
4503 (parm.type == P_USTRING))
4505 string_free((char**)parm_ptr);
4506 } else if (parm.type == P_LIST) {
4507 TALLOC_FREE(*((char***)parm_ptr));
4512 * Free the allocated data for one parameter for a share
4513 * given as a service struct.
4515 static void free_one_parameter(struct loadparm_service *service,
4516 struct parm_struct parm)
4518 void *parm_ptr;
4520 if (parm.p_class != P_LOCAL) {
4521 return;
4524 parm_ptr = lp_parm_ptr(service, &parm);
4526 free_one_parameter_common(parm_ptr, parm);
4530 * Free the allocated parameter data of a share given
4531 * as a service struct.
4533 static void free_parameters(struct loadparm_service *service)
4535 uint32_t i;
4537 for (i=0; parm_table[i].label; i++) {
4538 free_one_parameter(service, parm_table[i]);
4543 * Free the allocated data for one parameter for a given share
4544 * specified by an snum.
4546 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4548 void *parm_ptr;
4550 if (snum < 0) {
4551 parm_ptr = lp_parm_ptr(NULL, &parm);
4552 } else if (parm.p_class != P_LOCAL) {
4553 return;
4554 } else {
4555 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4558 free_one_parameter_common(parm_ptr, parm);
4562 * Free the allocated parameter data for a share specified
4563 * by an snum.
4565 static void free_parameters_by_snum(int snum)
4567 uint32_t i;
4569 for (i=0; parm_table[i].label; i++) {
4570 free_one_parameter_by_snum(snum, parm_table[i]);
4575 * Free the allocated global parameters.
4577 static void free_global_parameters(void)
4579 free_param_opts(&Globals.param_opt);
4580 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4583 static int map_parameter(const char *pszParmName);
4585 struct lp_stored_option {
4586 struct lp_stored_option *prev, *next;
4587 const char *label;
4588 const char *value;
4591 static struct lp_stored_option *stored_options;
4594 save options set by lp_set_cmdline() into a list. This list is
4595 re-applied when we do a globals reset, so that cmdline set options
4596 are sticky across reloads of smb.conf
4598 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4600 struct lp_stored_option *entry, *entry_next;
4601 for (entry = stored_options; entry != NULL; entry = entry_next) {
4602 entry_next = entry->next;
4603 if (strcmp(pszParmName, entry->label) == 0) {
4604 DLIST_REMOVE(stored_options, entry);
4605 talloc_free(entry);
4606 break;
4610 entry = talloc(NULL, struct lp_stored_option);
4611 if (!entry) {
4612 return false;
4615 entry->label = talloc_strdup(entry, pszParmName);
4616 if (!entry->label) {
4617 talloc_free(entry);
4618 return false;
4621 entry->value = talloc_strdup(entry, pszParmValue);
4622 if (!entry->value) {
4623 talloc_free(entry);
4624 return false;
4627 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4629 return true;
4632 static bool apply_lp_set_cmdline(void)
4634 struct lp_stored_option *entry = NULL;
4635 for (entry = stored_options; entry != NULL; entry = entry->next) {
4636 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
4637 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4638 entry->label, entry->value));
4639 return false;
4642 return true;
4645 /***************************************************************************
4646 Initialise the global parameter structure.
4647 ***************************************************************************/
4649 static void init_globals(bool reinit_globals)
4651 static bool done_init = false;
4652 char *s = NULL;
4653 int i;
4655 /* If requested to initialize only once and we've already done it... */
4656 if (!reinit_globals && done_init) {
4657 /* ... then we have nothing more to do */
4658 return;
4661 if (!done_init) {
4662 /* The logfile can be set before this is invoked. Free it if so. */
4663 if (Globals.logfile != NULL) {
4664 string_free(&Globals.logfile);
4665 Globals.logfile = NULL;
4667 done_init = true;
4668 } else {
4669 free_global_parameters();
4672 /* This memset and the free_global_parameters() above will
4673 * wipe out smb.conf options set with lp_set_cmdline(). The
4674 * apply_lp_set_cmdline() call puts these values back in the
4675 * table once the defaults are set */
4676 ZERO_STRUCT(Globals);
4678 for (i = 0; parm_table[i].label; i++) {
4679 if ((parm_table[i].type == P_STRING ||
4680 parm_table[i].type == P_USTRING))
4682 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
4687 string_set(&sDefault.fstype, FSTYPE_STRING);
4688 string_set(&sDefault.szPrintjobUsername, "%U");
4690 init_printer_values(&sDefault);
4693 DEBUG(3, ("Initialising global parameters\n"));
4695 /* Must manually force to upper case here, as this does not go via the handler */
4696 string_set(&Globals.szNetbiosName, myhostname_upper());
4698 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4699 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4701 /* use the new 'hash2' method by default, with a prefix of 1 */
4702 string_set(&Globals.szManglingMethod, "hash2");
4703 Globals.mangle_prefix = 1;
4705 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4707 /* using UTF8 by default allows us to support all chars */
4708 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4710 /* Use codepage 850 as a default for the dos character set */
4711 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4714 * Allow the default PASSWD_CHAT to be overridden in local.h.
4716 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4718 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
4720 string_set(&Globals.szPasswdProgram, "");
4721 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4722 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4723 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4724 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4725 string_set(&Globals.szSocketAddress, "0.0.0.0");
4727 * By default support explicit binding to broadcast
4728 * addresses.
4730 Globals.bNmbdBindExplicitBroadcast = true;
4732 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4733 smb_panic("init_globals: ENOMEM");
4735 string_set(&Globals.szServerString, s);
4736 SAFE_FREE(s);
4737 #ifdef DEVELOPER
4738 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4739 #endif
4741 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4743 string_set(&Globals.szLogonDrive, "");
4744 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4745 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4746 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4748 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4749 string_set(&Globals.szPasswordServer, "*");
4751 Globals.AlgorithmicRidBase = BASE_RID;
4753 Globals.bLoadPrinters = true;
4754 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4756 Globals.ConfigBackend = config_backend;
4757 Globals.ServerRole = ROLE_AUTO;
4759 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4760 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4761 Globals.max_xmit = 0x4104;
4762 Globals.max_mux = 50; /* This is *needed* for profile support. */
4763 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4764 Globals.bDisableSpoolss = false;
4765 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4766 Globals.pwordlevel = 0;
4767 Globals.unamelevel = 0;
4768 Globals.deadtime = 0;
4769 Globals.getwd_cache = true;
4770 Globals.bLargeReadwrite = true;
4771 Globals.max_log_size = 5000;
4772 Globals.max_open_files = max_open_files();
4773 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4774 Globals.srv_maxprotocol = PROTOCOL_SMB2_02;
4775 Globals.srv_minprotocol = PROTOCOL_CORE;
4776 Globals.security = SEC_USER;
4777 Globals.paranoid_server_security = true;
4778 Globals.bEncryptPasswords = true;
4779 Globals.clientSchannel = Auto;
4780 Globals.serverSchannel = Auto;
4781 Globals.bReadRaw = true;
4782 Globals.bWriteRaw = true;
4783 Globals.bNullPasswords = false;
4784 Globals.bObeyPamRestrictions = false;
4785 Globals.syslog = 1;
4786 Globals.bSyslogOnly = false;
4787 Globals.bTimestampLogs = true;
4788 string_set(&Globals.szLogLevel, "0");
4789 Globals.bDebugPrefixTimestamp = false;
4790 Globals.bDebugHiresTimestamp = true;
4791 Globals.bDebugPid = false;
4792 Globals.bDebugUid = false;
4793 Globals.bDebugClass = false;
4794 Globals.bEnableCoreFiles = true;
4795 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4796 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4797 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4798 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4799 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
4800 Globals.lm_interval = 60;
4801 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4802 Globals.bNISHomeMap = false;
4803 #ifdef WITH_NISPLUS_HOME
4804 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4805 #else
4806 string_set(&Globals.szNISHomeMapName, "auto.home");
4807 #endif
4808 #endif
4809 Globals.bTimeServer = false;
4810 Globals.bBindInterfacesOnly = false;
4811 Globals.bUnixPasswdSync = false;
4812 Globals.bPamPasswordChange = false;
4813 Globals.bPasswdChatDebug = false;
4814 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4815 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
4816 Globals.bNTStatusSupport = true; /* Use NT status by default. */
4817 Globals.bStatCache = true; /* use stat cache by default */
4818 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4819 Globals.restrict_anonymous = 0;
4820 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
4821 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
4822 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
4823 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4824 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4825 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4827 Globals.map_to_guest = 0; /* By Default, "Never" */
4828 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4829 Globals.enhanced_browsing = true;
4830 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4831 #ifdef MMAP_BLACKLIST
4832 Globals.bUseMmap = false;
4833 #else
4834 Globals.bUseMmap = true;
4835 #endif
4836 Globals.bUnixExtensions = true;
4837 Globals.bResetOnZeroVC = false;
4838 Globals.bLogWriteableFilesOnExit = false;
4839 Globals.bCreateKrb5Conf = true;
4840 Globals.winbindMaxDomainConnections = 1;
4842 /* hostname lookups can be very expensive and are broken on
4843 a large number of sites (tridge) */
4844 Globals.bHostnameLookups = false;
4846 string_set(&Globals.szPassdbBackend, "tdbsam");
4847 string_set(&Globals.szLdapSuffix, "");
4848 string_set(&Globals.szLdapMachineSuffix, "");
4849 string_set(&Globals.szLdapUserSuffix, "");
4850 string_set(&Globals.szLdapGroupSuffix, "");
4851 string_set(&Globals.szLdapIdmapSuffix, "");
4853 string_set(&Globals.szLdapAdminDn, "");
4854 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4855 Globals.ldap_ssl_ads = false;
4856 Globals.ldap_deref = -1;
4857 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4858 Globals.ldap_delete_dn = false;
4859 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4860 Globals.ldap_follow_referral = Auto;
4861 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4862 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4863 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4865 Globals.ldap_debug_level = 0;
4866 Globals.ldap_debug_threshold = 10;
4868 /* This is what we tell the afs client. in reality we set the token
4869 * to never expire, though, when this runs out the afs client will
4870 * forget the token. Set to 0 to get NEVERDATE.*/
4871 Globals.iAfsTokenLifetime = 604800;
4872 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4874 /* these parameters are set to defaults that are more appropriate
4875 for the increasing samba install base:
4877 as a member of the workgroup, that will possibly become a
4878 _local_ master browser (lm = true). this is opposed to a forced
4879 local master browser startup (pm = true).
4881 doesn't provide WINS server service by default (wsupp = false),
4882 and doesn't provide domain master browser services by default, either.
4886 Globals.bMsAddPrinterWizard = true;
4887 Globals.os_level = 20;
4888 Globals.bLocalMaster = true;
4889 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4890 Globals.bDomainLogons = false;
4891 Globals.bBrowseList = true;
4892 Globals.bWINSsupport = false;
4893 Globals.bWINSproxy = false;
4895 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4896 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4898 Globals.bWINSdnsProxy = true;
4900 Globals.bAllowTrustedDomains = true;
4901 string_set(&Globals.szIdmapBackend, "tdb");
4903 string_set(&Globals.szTemplateShell, "/bin/false");
4904 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4905 string_set(&Globals.szWinbindSeparator, "\\");
4907 string_set(&Globals.szCupsServer, "");
4908 string_set(&Globals.szIPrintServer, "");
4910 string_set(&Globals.ctdbdSocket, "");
4911 Globals.szClusterAddresses = NULL;
4912 Globals.clustering = false;
4913 Globals.ctdb_timeout = 0;
4914 Globals.ctdb_locktime_warn_threshold = 0;
4916 Globals.winbind_cache_time = 300; /* 5 minutes */
4917 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4918 Globals.winbind_max_clients = 200;
4919 Globals.bWinbindEnumUsers = false;
4920 Globals.bWinbindEnumGroups = false;
4921 Globals.bWinbindUseDefaultDomain = false;
4922 Globals.bWinbindTrustedDomainsOnly = false;
4923 Globals.bWinbindNestedGroups = true;
4924 Globals.winbind_expand_groups = 1;
4925 Globals.szWinbindNssInfo = (const char **)str_list_make_v3(NULL, "template", NULL);
4926 Globals.bWinbindRefreshTickets = false;
4927 Globals.bWinbindOfflineLogon = false;
4929 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4930 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4932 Globals.bPassdbExpandExplicit = false;
4934 Globals.name_cache_timeout = 660; /* In seconds */
4936 Globals.bUseSpnego = true;
4937 Globals.bClientUseSpnego = true;
4939 Globals.client_signing = SMB_SIGNING_DEFAULT;
4940 Globals.server_signing = SMB_SIGNING_DEFAULT;
4942 Globals.bDeferSharingViolations = true;
4943 string_set(&Globals.smb_ports, SMB_PORTS);
4945 Globals.bEnablePrivileges = true;
4946 Globals.bHostMSDfs = true;
4947 Globals.bASUSupport = false;
4949 /* User defined shares. */
4950 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4951 smb_panic("init_globals: ENOMEM");
4953 string_set(&Globals.szUsersharePath, s);
4954 SAFE_FREE(s);
4955 string_set(&Globals.szUsershareTemplateShare, "");
4956 Globals.iUsershareMaxShares = 0;
4957 /* By default disallow sharing of directories not owned by the sharer. */
4958 Globals.bUsershareOwnerOnly = true;
4959 /* By default disallow guest access to usershares. */
4960 Globals.bUsershareAllowGuests = false;
4962 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4964 /* By default no shares out of the registry */
4965 Globals.bRegistryShares = false;
4967 Globals.iminreceivefile = 0;
4969 Globals.bMapUntrustedToDomain = false;
4970 Globals.bMulticastDnsRegister = true;
4972 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
4973 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
4974 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
4975 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
4977 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
4979 /* Now put back the settings that were set with lp_set_cmdline() */
4980 apply_lp_set_cmdline();
4983 /*******************************************************************
4984 Convenience routine to grab string parameters into temporary memory
4985 and run standard_sub_basic on them. The buffers can be written to by
4986 callers without affecting the source string.
4987 ********************************************************************/
4989 static char *lp_string(const char *s)
4991 char *ret;
4992 TALLOC_CTX *ctx = talloc_tos();
4994 /* The follow debug is useful for tracking down memory problems
4995 especially if you have an inner loop that is calling a lp_*()
4996 function that returns a string. Perhaps this debug should be
4997 present all the time? */
4999 #if 0
5000 DEBUG(10, ("lp_string(%s)\n", s));
5001 #endif
5002 if (!s) {
5003 return NULL;
5006 ret = talloc_sub_basic(ctx,
5007 get_current_username(),
5008 current_user_info.domain,
5010 if (trim_char(ret, '\"', '\"')) {
5011 if (strchr(ret,'\"') != NULL) {
5012 TALLOC_FREE(ret);
5013 ret = talloc_sub_basic(ctx,
5014 get_current_username(),
5015 current_user_info.domain,
5019 return ret;
5023 In this section all the functions that are used to access the
5024 parameters from the rest of the program are defined
5027 #define FN_GLOBAL_STRING(fn_name,ptr) \
5028 char *lp_ ## fn_name(void) {return(lp_string(*(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5029 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5030 const char *lp_ ## fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5031 #define FN_GLOBAL_LIST(fn_name,ptr) \
5032 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5033 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5034 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
5035 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5036 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
5037 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5038 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
5040 #define FN_LOCAL_STRING(fn_name,val) \
5041 char *lp_ ## fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5042 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5043 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5044 #define FN_LOCAL_LIST(fn_name,val) \
5045 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5046 #define FN_LOCAL_BOOL(fn_name,val) \
5047 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5048 #define FN_LOCAL_INTEGER(fn_name,val) \
5049 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5051 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5052 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5053 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5054 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5055 #define FN_LOCAL_CHAR(fn_name,val) \
5056 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5058 FN_GLOBAL_CONST_STRING(smb_ports, smb_ports)
5059 FN_GLOBAL_CONST_STRING(dos_charset, dos_charset)
5060 FN_GLOBAL_CONST_STRING(unix_charset, unix_charset)
5061 FN_GLOBAL_STRING(logfile, logfile)
5062 FN_GLOBAL_STRING(configfile, szConfigFile)
5063 FN_GLOBAL_CONST_STRING(smb_passwd_file, szSMBPasswdFile)
5064 FN_GLOBAL_CONST_STRING(private_dir, szPrivateDir)
5065 FN_GLOBAL_STRING(serverstring, szServerString)
5066 FN_GLOBAL_INTEGER(printcap_cache_time, PrintcapCacheTime)
5067 FN_GLOBAL_STRING(addport_cmd, szAddPortCommand)
5068 FN_GLOBAL_STRING(enumports_cmd, szEnumPortsCommand)
5069 FN_GLOBAL_STRING(addprinter_cmd, szAddPrinterCommand)
5070 FN_GLOBAL_STRING(deleteprinter_cmd, szDeletePrinterCommand)
5071 FN_GLOBAL_STRING(os2_driver_map, szOs2DriverMap)
5072 FN_GLOBAL_CONST_STRING(lockdir, szLockDir)
5073 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5074 * build process or in smb.conf, we use that value. Otherwise they
5075 * default to the value of lp_lockdir(). */
5076 const char *lp_statedir(void) {
5077 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5078 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5079 return(*(char **)(&Globals.szStateDir) ?
5080 *(char **)(&Globals.szStateDir) : "");
5081 else
5082 return(*(char **)(&Globals.szLockDir) ?
5083 *(char **)(&Globals.szLockDir) : "");
5085 const char *lp_cachedir(void) {
5086 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5087 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5088 return(*(char **)(&Globals.szCacheDir) ?
5089 *(char **)(&Globals.szCacheDir) : "");
5090 else
5091 return(*(char **)(&Globals.szLockDir) ?
5092 *(char **)(&Globals.szLockDir) : "");
5094 FN_GLOBAL_CONST_STRING(piddir, szPidDir)
5095 FN_GLOBAL_STRING(mangling_method, szManglingMethod)
5096 FN_GLOBAL_INTEGER(mangle_prefix, mangle_prefix)
5097 FN_GLOBAL_CONST_STRING(utmpdir, szUtmpDir)
5098 FN_GLOBAL_CONST_STRING(wtmpdir, szWtmpDir)
5099 FN_GLOBAL_BOOL(utmp, bUtmp)
5100 FN_GLOBAL_STRING(rootdir, szRootdir)
5101 FN_GLOBAL_STRING(perfcount_module, szSMBPerfcountModule)
5102 FN_GLOBAL_STRING(defaultservice, szDefaultService)
5103 FN_GLOBAL_STRING(msg_command, szMsgCommand)
5104 FN_GLOBAL_STRING(get_quota_command, szGetQuota)
5105 FN_GLOBAL_STRING(set_quota_command, szSetQuota)
5106 FN_GLOBAL_STRING(auto_services, szAutoServices)
5107 FN_GLOBAL_STRING(passwd_program, szPasswdProgram)
5108 FN_GLOBAL_STRING(passwd_chat, szPasswdChat)
5109 FN_GLOBAL_CONST_STRING(passwordserver, szPasswordServer)
5110 FN_GLOBAL_CONST_STRING(name_resolve_order, szNameResolveOrder)
5111 FN_GLOBAL_CONST_STRING(workgroup, szWorkgroup)
5112 FN_GLOBAL_CONST_STRING(netbios_name, szNetbiosName)
5113 FN_GLOBAL_CONST_STRING(netbios_scope, szNetbiosScope)
5114 FN_GLOBAL_CONST_STRING(realm, szRealmUpper)
5115 FN_GLOBAL_CONST_STRING(dnsdomain, szDnsDomain)
5116 FN_GLOBAL_CONST_STRING(afs_username_map, szAfsUsernameMap)
5117 FN_GLOBAL_INTEGER(afs_token_lifetime, iAfsTokenLifetime)
5118 FN_GLOBAL_STRING(log_nt_token_command, szLogNtTokenCommand)
5119 FN_GLOBAL_STRING(username_map, szUsernameMap)
5120 FN_GLOBAL_CONST_STRING(logon_script, szLogonScript)
5121 FN_GLOBAL_CONST_STRING(logon_path, szLogonPath)
5122 FN_GLOBAL_CONST_STRING(logon_drive, szLogonDrive)
5123 FN_GLOBAL_CONST_STRING(logon_home, szLogonHome)
5124 FN_GLOBAL_STRING(remote_announce, szRemoteAnnounce)
5125 FN_GLOBAL_STRING(remote_browse_sync, szRemoteBrowseSync)
5126 FN_GLOBAL_BOOL(nmbd_bind_explicit_broadcast, bNmbdBindExplicitBroadcast)
5127 FN_GLOBAL_LIST(wins_server_list, szWINSservers)
5128 FN_GLOBAL_LIST(interfaces, szInterfaces)
5129 FN_GLOBAL_STRING(nis_home_map_name, szNISHomeMapName)
5130 FN_GLOBAL_LIST(netbios_aliases, szNetbiosAliases)
5131 FN_GLOBAL_CONST_STRING(passdb_backend, szPassdbBackend)
5132 FN_GLOBAL_LIST(preload_modules, szPreloadModules)
5133 FN_GLOBAL_STRING(panic_action, szPanicAction)
5134 FN_GLOBAL_STRING(adduser_script, szAddUserScript)
5135 FN_GLOBAL_STRING(renameuser_script, szRenameUserScript)
5136 FN_GLOBAL_STRING(deluser_script, szDelUserScript)
5138 FN_GLOBAL_CONST_STRING(guestaccount, szGuestaccount)
5139 FN_GLOBAL_STRING(addgroup_script, szAddGroupScript)
5140 FN_GLOBAL_STRING(delgroup_script, szDelGroupScript)
5141 FN_GLOBAL_STRING(addusertogroup_script, szAddUserToGroupScript)
5142 FN_GLOBAL_STRING(deluserfromgroup_script, szDelUserFromGroupScript)
5143 FN_GLOBAL_STRING(setprimarygroup_script, szSetPrimaryGroupScript)
5145 FN_GLOBAL_STRING(addmachine_script, szAddMachineScript)
5147 FN_GLOBAL_STRING(shutdown_script, szShutdownScript)
5148 FN_GLOBAL_STRING(abort_shutdown_script, szAbortShutdownScript)
5149 FN_GLOBAL_STRING(username_map_script, szUsernameMapScript)
5150 FN_GLOBAL_INTEGER(username_map_cache_time, iUsernameMapCacheTime)
5152 FN_GLOBAL_STRING(check_password_script, szCheckPasswordScript)
5154 FN_GLOBAL_STRING(wins_hook, szWINSHook)
5155 FN_GLOBAL_CONST_STRING(template_homedir, szTemplateHomedir)
5156 FN_GLOBAL_CONST_STRING(template_shell, szTemplateShell)
5157 FN_GLOBAL_CONST_STRING(winbind_separator, szWinbindSeparator)
5158 FN_GLOBAL_INTEGER(acl_compatibility, iAclCompat)
5159 FN_GLOBAL_BOOL(winbind_enum_users, bWinbindEnumUsers)
5160 FN_GLOBAL_BOOL(winbind_enum_groups, bWinbindEnumGroups)
5161 FN_GLOBAL_BOOL(winbind_use_default_domain, bWinbindUseDefaultDomain)
5162 FN_GLOBAL_BOOL(winbind_trusted_domains_only, bWinbindTrustedDomainsOnly)
5163 FN_GLOBAL_BOOL(winbind_nested_groups, bWinbindNestedGroups)
5164 FN_GLOBAL_INTEGER(winbind_expand_groups, winbind_expand_groups)
5165 FN_GLOBAL_BOOL(winbind_refresh_tickets, bWinbindRefreshTickets)
5166 FN_GLOBAL_BOOL(winbind_offline_logon, bWinbindOfflineLogon)
5167 FN_GLOBAL_BOOL(winbind_normalize_names, bWinbindNormalizeNames)
5168 FN_GLOBAL_BOOL(winbind_rpc_only, bWinbindRpcOnly)
5169 FN_GLOBAL_BOOL(create_krb5_conf, bCreateKrb5Conf)
5170 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
5171 winbindMaxDomainConnections)
5173 int lp_winbind_max_domain_connections(void)
5175 if (lp_winbind_offline_logon() &&
5176 lp_winbind_max_domain_connections_int() > 1) {
5177 DEBUG(1, ("offline logons active, restricting max domain "
5178 "connections to 1\n"));
5179 return 1;
5181 return MAX(1, lp_winbind_max_domain_connections_int());
5184 FN_GLOBAL_CONST_STRING(idmap_backend, szIdmapBackend)
5185 FN_GLOBAL_INTEGER(idmap_cache_time, iIdmapCacheTime)
5186 FN_GLOBAL_INTEGER(idmap_negative_cache_time, iIdmapNegativeCacheTime)
5187 FN_GLOBAL_INTEGER(keepalive, iKeepalive)
5188 FN_GLOBAL_BOOL(passdb_expand_explicit, bPassdbExpandExplicit)
5190 FN_GLOBAL_STRING(ldap_suffix, szLdapSuffix)
5191 FN_GLOBAL_STRING(ldap_admin_dn, szLdapAdminDn)
5192 FN_GLOBAL_INTEGER(ldap_ssl, ldap_ssl)
5193 FN_GLOBAL_BOOL(ldap_ssl_ads, ldap_ssl_ads)
5194 FN_GLOBAL_INTEGER(ldap_deref, ldap_deref)
5195 FN_GLOBAL_INTEGER(ldap_follow_referral, ldap_follow_referral)
5196 FN_GLOBAL_INTEGER(ldap_passwd_sync, ldap_passwd_sync)
5197 FN_GLOBAL_BOOL(ldap_delete_dn, ldap_delete_dn)
5198 FN_GLOBAL_INTEGER(ldap_replication_sleep, ldap_replication_sleep)
5199 FN_GLOBAL_INTEGER(ldap_timeout, ldap_timeout)
5200 FN_GLOBAL_INTEGER(ldap_connection_timeout, ldap_connection_timeout)
5201 FN_GLOBAL_INTEGER(ldap_page_size, ldap_page_size)
5202 FN_GLOBAL_INTEGER(ldap_debug_level, ldap_debug_level)
5203 FN_GLOBAL_INTEGER(ldap_debug_threshold, ldap_debug_threshold)
5204 FN_GLOBAL_STRING(add_share_cmd, szAddShareCommand)
5205 FN_GLOBAL_STRING(change_share_cmd, szChangeShareCommand)
5206 FN_GLOBAL_STRING(delete_share_cmd, szDeleteShareCommand)
5207 FN_GLOBAL_STRING(usershare_path, szUsersharePath)
5208 FN_GLOBAL_LIST(usershare_prefix_allow_list, szUsersharePrefixAllowList)
5209 FN_GLOBAL_LIST(usershare_prefix_deny_list, szUsersharePrefixDenyList)
5211 FN_GLOBAL_LIST(eventlog_list, szEventLogs)
5213 FN_GLOBAL_BOOL(registry_shares, bRegistryShares)
5214 FN_GLOBAL_BOOL(usershare_allow_guests, bUsershareAllowGuests)
5215 FN_GLOBAL_BOOL(usershare_owner_only, bUsershareOwnerOnly)
5216 FN_GLOBAL_BOOL(disable_netbios, bDisableNetbios)
5217 FN_GLOBAL_BOOL(reset_on_zero_vc, bResetOnZeroVC)
5218 FN_GLOBAL_BOOL(log_writeable_files_on_exit, bLogWriteableFilesOnExit)
5219 FN_GLOBAL_BOOL(ms_add_printer_wizard, bMsAddPrinterWizard)
5220 FN_GLOBAL_BOOL(dns_proxy, bWINSdnsProxy)
5221 FN_GLOBAL_BOOL(we_are_a_wins_server, bWINSsupport)
5222 FN_GLOBAL_BOOL(wins_proxy, bWINSproxy)
5223 FN_GLOBAL_BOOL(local_master, bLocalMaster)
5224 static FN_GLOBAL_BOOL(domain_logons, bDomainLogons)
5225 FN_GLOBAL_LIST(init_logon_delayed_hosts, szInitLogonDelayedHosts)
5226 FN_GLOBAL_INTEGER(init_logon_delay, InitLogonDelay)
5227 FN_GLOBAL_BOOL(load_printers, bLoadPrinters)
5228 static FN_GLOBAL_BOOL(_readraw, bReadRaw)
5229 FN_GLOBAL_BOOL(large_readwrite, bLargeReadwrite)
5230 static FN_GLOBAL_BOOL(_writeraw, bWriteRaw)
5231 FN_GLOBAL_BOOL(null_passwords, bNullPasswords)
5232 FN_GLOBAL_BOOL(obey_pam_restrictions, bObeyPamRestrictions)
5233 FN_GLOBAL_BOOL(encrypted_passwords, bEncryptPasswords)
5234 FN_GLOBAL_INTEGER(client_schannel, clientSchannel)
5235 FN_GLOBAL_INTEGER(server_schannel, serverSchannel)
5236 FN_GLOBAL_BOOL(syslog_only, bSyslogOnly)
5237 FN_GLOBAL_BOOL(timestamp_logs, bTimestampLogs)
5238 FN_GLOBAL_BOOL(debug_prefix_timestamp, bDebugPrefixTimestamp)
5239 FN_GLOBAL_BOOL(debug_hires_timestamp, bDebugHiresTimestamp)
5240 FN_GLOBAL_BOOL(debug_pid, bDebugPid)
5241 FN_GLOBAL_BOOL(debug_uid, bDebugUid)
5242 FN_GLOBAL_BOOL(debug_class, bDebugClass)
5243 FN_GLOBAL_BOOL(enable_core_files, bEnableCoreFiles)
5244 FN_GLOBAL_BOOL(browse_list, bBrowseList)
5245 FN_GLOBAL_BOOL(nis_home_map, bNISHomeMap)
5246 static FN_GLOBAL_BOOL(time_server, bTimeServer)
5247 FN_GLOBAL_BOOL(bind_interfaces_only, bBindInterfacesOnly)
5248 FN_GLOBAL_BOOL(pam_password_change, bPamPasswordChange)
5249 FN_GLOBAL_BOOL(unix_password_sync, bUnixPasswdSync)
5250 FN_GLOBAL_BOOL(passwd_chat_debug, bPasswdChatDebug)
5251 FN_GLOBAL_INTEGER(passwd_chat_timeout, iPasswdChatTimeout)
5252 FN_GLOBAL_BOOL(nt_pipe_support, bNTPipeSupport)
5253 FN_GLOBAL_BOOL(nt_status_support, bNTStatusSupport)
5254 FN_GLOBAL_BOOL(stat_cache, bStatCache)
5255 FN_GLOBAL_INTEGER(max_stat_cache_size, iMaxStatCacheSize)
5256 FN_GLOBAL_BOOL(allow_trusted_domains, bAllowTrustedDomains)
5257 FN_GLOBAL_BOOL(map_untrusted_to_domain, bMapUntrustedToDomain)
5258 FN_GLOBAL_INTEGER(restrict_anonymous, restrict_anonymous)
5259 FN_GLOBAL_BOOL(lanman_auth, bLanmanAuth)
5260 FN_GLOBAL_BOOL(ntlm_auth, bNTLMAuth)
5261 FN_GLOBAL_BOOL(client_plaintext_auth, bClientPlaintextAuth)
5262 FN_GLOBAL_BOOL(client_lanman_auth, bClientLanManAuth)
5263 FN_GLOBAL_BOOL(client_ntlmv2_auth, bClientNTLMv2Auth)
5264 FN_GLOBAL_BOOL(host_msdfs, bHostMSDfs)
5265 FN_GLOBAL_BOOL(enhanced_browsing, enhanced_browsing)
5266 FN_GLOBAL_BOOL(use_mmap, bUseMmap)
5267 FN_GLOBAL_BOOL(unix_extensions, bUnixExtensions)
5268 FN_GLOBAL_BOOL(use_spnego, bUseSpnego)
5269 FN_GLOBAL_BOOL(client_use_spnego, bClientUseSpnego)
5270 FN_GLOBAL_BOOL(client_use_spnego_principal, client_use_spnego_principal)
5271 FN_GLOBAL_BOOL(hostname_lookups, bHostnameLookups)
5272 FN_GLOBAL_CONST_STRING(dedicated_keytab_file, szDedicatedKeytabFile)
5273 FN_GLOBAL_INTEGER(kerberos_method, iKerberosMethod)
5274 FN_GLOBAL_BOOL(defer_sharing_violations, bDeferSharingViolations)
5275 FN_GLOBAL_BOOL(enable_privileges, bEnablePrivileges)
5276 FN_GLOBAL_BOOL(enable_asu_support, bASUSupport)
5277 FN_GLOBAL_INTEGER(os_level, os_level)
5278 FN_GLOBAL_INTEGER(max_ttl, max_ttl)
5279 FN_GLOBAL_INTEGER(max_wins_ttl, max_wins_ttl)
5280 FN_GLOBAL_INTEGER(min_wins_ttl, min_wins_ttl)
5281 FN_GLOBAL_INTEGER(max_log_size, max_log_size)
5282 FN_GLOBAL_INTEGER(max_open_files, max_open_files)
5283 FN_GLOBAL_INTEGER(open_files_db_hash_size, open_files_db_hash_size)
5284 FN_GLOBAL_INTEGER(maxxmit, max_xmit)
5285 FN_GLOBAL_INTEGER(maxmux, max_mux)
5286 FN_GLOBAL_INTEGER(passwordlevel, pwordlevel)
5287 FN_GLOBAL_INTEGER(usernamelevel, unamelevel)
5288 FN_GLOBAL_INTEGER(deadtime, deadtime)
5289 FN_GLOBAL_BOOL(getwd_cache, getwd_cache)
5290 FN_GLOBAL_INTEGER(srv_maxprotocol, srv_maxprotocol)
5291 FN_GLOBAL_INTEGER(srv_minprotocol, srv_minprotocol)
5292 FN_GLOBAL_INTEGER(security, security)
5293 FN_GLOBAL_LIST(auth_methods, AuthMethods)
5294 FN_GLOBAL_BOOL(paranoid_server_security, paranoid_server_security)
5295 FN_GLOBAL_INTEGER(maxdisksize, maxdisksize)
5296 FN_GLOBAL_INTEGER(lpqcachetime, lpqcachetime)
5297 FN_GLOBAL_INTEGER(max_smbd_processes, iMaxSmbdProcesses)
5298 FN_GLOBAL_BOOL(_disable_spoolss, bDisableSpoolss)
5299 FN_GLOBAL_INTEGER(syslog, syslog)
5300 FN_GLOBAL_INTEGER(lm_announce, lm_announce)
5301 FN_GLOBAL_INTEGER(lm_interval, lm_interval)
5302 FN_GLOBAL_INTEGER(machine_password_timeout, machine_password_timeout)
5303 FN_GLOBAL_INTEGER(map_to_guest, map_to_guest)
5304 FN_GLOBAL_INTEGER(oplock_break_wait_time, oplock_break_wait_time)
5305 FN_GLOBAL_INTEGER(lock_spin_time, iLockSpinTime)
5306 FN_GLOBAL_INTEGER(usershare_max_shares, iUsershareMaxShares)
5307 FN_GLOBAL_CONST_STRING(socket_options, szSocketOptions)
5308 FN_GLOBAL_INTEGER(config_backend, ConfigBackend)
5309 static FN_GLOBAL_INTEGER(_server_role, ServerRole)
5310 FN_GLOBAL_INTEGER(smb2_max_read, ismb2_max_read)
5311 FN_GLOBAL_INTEGER(smb2_max_write, ismb2_max_write)
5312 FN_GLOBAL_INTEGER(smb2_max_trans, ismb2_max_trans)
5313 int lp_smb2_max_credits(void)
5315 if (Globals.ismb2_max_credits == 0) {
5316 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5318 return Globals.ismb2_max_credits;
5320 FN_GLOBAL_LIST(svcctl_list, szServicesList)
5321 FN_GLOBAL_STRING(cups_server, szCupsServer)
5322 int lp_cups_encrypt(void)
5324 int result = 0;
5325 #ifdef HAVE_HTTPCONNECTENCRYPT
5326 switch (Globals.CupsEncrypt) {
5327 case Auto:
5328 result = HTTP_ENCRYPT_REQUIRED;
5329 break;
5330 case true:
5331 result = HTTP_ENCRYPT_ALWAYS;
5332 break;
5333 case false:
5334 result = HTTP_ENCRYPT_NEVER;
5335 break;
5337 #endif
5338 return result;
5340 FN_GLOBAL_STRING(iprint_server, szIPrintServer)
5341 FN_GLOBAL_INTEGER(cups_connection_timeout, cups_connection_timeout)
5342 static FN_GLOBAL_CONST_STRING(_ctdbd_socket, ctdbdSocket)
5343 FN_GLOBAL_LIST(cluster_addresses, szClusterAddresses)
5344 FN_GLOBAL_BOOL(clustering, clustering)
5345 FN_GLOBAL_INTEGER(ctdb_timeout, ctdb_timeout)
5346 FN_GLOBAL_INTEGER(ctdb_locktime_warn_threshold, ctdb_locktime_warn_threshold)
5347 FN_GLOBAL_BOOL(async_smb_echo_handler, bAsyncSMBEchoHandler)
5348 FN_GLOBAL_BOOL(multicast_dns_register, bMulticastDnsRegister)
5349 FN_GLOBAL_BOOL(allow_insecure_widelinks, bAllowInsecureWidelinks)
5350 FN_GLOBAL_INTEGER(winbind_cache_time, winbind_cache_time)
5351 FN_GLOBAL_INTEGER(winbind_reconnect_delay, winbind_reconnect_delay)
5352 FN_GLOBAL_INTEGER(winbind_max_clients, winbind_max_clients)
5353 FN_GLOBAL_LIST(winbind_nss_info, szWinbindNssInfo)
5354 FN_GLOBAL_INTEGER(algorithmic_rid_base, AlgorithmicRidBase)
5355 FN_GLOBAL_INTEGER(name_cache_timeout, name_cache_timeout)
5356 FN_GLOBAL_INTEGER(client_signing, client_signing)
5357 FN_GLOBAL_INTEGER(server_signing, server_signing)
5358 FN_GLOBAL_INTEGER(client_ldap_sasl_wrapping, client_ldap_sasl_wrapping)
5360 FN_GLOBAL_CONST_STRING(ncalrpc_dir, ncalrpc_dir)
5362 #include "lib/param/param_functions.c"
5364 FN_LOCAL_STRING(servicename, szService)
5365 FN_LOCAL_CONST_STRING(const_servicename, szService)
5367 /* local prototypes */
5369 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5370 static const char *get_boolean(bool bool_value);
5371 static int getservicebyname(const char *pszServiceName,
5372 struct loadparm_service *pserviceDest);
5373 static void copy_service(struct loadparm_service *pserviceDest,
5374 struct loadparm_service *pserviceSource,
5375 struct bitmap *pcopymapDest);
5376 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5377 void *userdata);
5378 static bool do_section(const char *pszSectionName, void *userdata);
5379 static void init_copymap(struct loadparm_service *pservice);
5380 static bool hash_a_service(const char *name, int number);
5381 static void free_service_byindex(int iService);
5382 static void show_parameter(int parmIndex);
5383 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5386 * This is a helper function for parametrical options support. It returns a
5387 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5388 * parametrical functions are quite simple
5390 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
5391 const char *option)
5393 bool global_section = false;
5394 char* param_key;
5395 struct parmlist_entry *data;
5397 if (service == NULL) {
5398 data = Globals.param_opt;
5399 global_section = true;
5400 } else {
5401 data = service->param_opt;
5404 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5405 DEBUG(0,("asprintf failed!\n"));
5406 return NULL;
5409 while (data) {
5410 if (strwicmp(data->key, param_key) == 0) {
5411 string_free(&param_key);
5412 return data;
5414 data = data->next;
5417 if (!global_section) {
5418 /* Try to fetch the same option but from globals */
5419 /* but only if we are not already working with Globals */
5420 data = Globals.param_opt;
5421 while (data) {
5422 if (strwicmp(data->key, param_key) == 0) {
5423 string_free(&param_key);
5424 return data;
5426 data = data->next;
5430 string_free(&param_key);
5432 return NULL;
5436 * This is a helper function for parametrical options support. It returns a
5437 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5438 * parametrical functions are quite simple
5440 static struct parmlist_entry *get_parametrics(int snum, const char *type,
5441 const char *option)
5443 if (snum >= iNumServices) return NULL;
5445 if (snum < 0) {
5446 return get_parametrics_by_service(NULL, type, option);
5447 } else {
5448 return get_parametrics_by_service(ServicePtrs[snum], type, option);
5453 #define MISSING_PARAMETER(name) \
5454 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5456 /*******************************************************************
5457 convenience routine to return int parameters.
5458 ********************************************************************/
5459 static int lp_int(const char *s)
5462 if (!s || !*s) {
5463 MISSING_PARAMETER(lp_int);
5464 return (-1);
5467 return (int)strtol(s, NULL, 0);
5470 /*******************************************************************
5471 convenience routine to return unsigned long parameters.
5472 ********************************************************************/
5473 static unsigned long lp_ulong(const char *s)
5476 if (!s || !*s) {
5477 MISSING_PARAMETER(lp_ulong);
5478 return (0);
5481 return strtoul(s, NULL, 0);
5484 /*******************************************************************
5485 convenience routine to return boolean parameters.
5486 ********************************************************************/
5487 static bool lp_bool(const char *s)
5489 bool ret = false;
5491 if (!s || !*s) {
5492 MISSING_PARAMETER(lp_bool);
5493 return false;
5496 if (!set_boolean(s, &ret)) {
5497 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5498 return false;
5501 return ret;
5504 /*******************************************************************
5505 convenience routine to return enum parameters.
5506 ********************************************************************/
5507 static int lp_enum(const char *s,const struct enum_list *_enum)
5509 int i;
5511 if (!s || !*s || !_enum) {
5512 MISSING_PARAMETER(lp_enum);
5513 return (-1);
5516 for (i=0; _enum[i].name; i++) {
5517 if (strequal(_enum[i].name,s))
5518 return _enum[i].value;
5521 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5522 return (-1);
5525 #undef MISSING_PARAMETER
5527 /* Return parametric option from a given service. Type is a part of option before ':' */
5528 /* Parametric option has following syntax: 'Type: option = value' */
5529 /* the returned value is talloced on the talloc_tos() */
5530 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5532 struct parmlist_entry *data = get_parametrics(snum, type, option);
5534 if (data == NULL||data->value==NULL) {
5535 if (def) {
5536 return lp_string(def);
5537 } else {
5538 return NULL;
5542 return lp_string(data->value);
5545 /* Return parametric option from a given service. Type is a part of option before ':' */
5546 /* Parametric option has following syntax: 'Type: option = value' */
5547 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5549 struct parmlist_entry *data = get_parametrics(snum, type, option);
5551 if (data == NULL||data->value==NULL)
5552 return def;
5554 return data->value;
5557 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
5559 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
5561 if (data == NULL||data->value==NULL)
5562 return NULL;
5564 return data->value;
5568 /* Return parametric option from a given service. Type is a part of option before ':' */
5569 /* Parametric option has following syntax: 'Type: option = value' */
5571 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5573 struct parmlist_entry *data = get_parametrics(snum, type, option);
5575 if (data == NULL||data->value==NULL)
5576 return (const char **)def;
5578 if (data->list==NULL) {
5579 data->list = str_list_make_v3(NULL, data->value, NULL);
5582 return (const char **)data->list;
5585 /* Return parametric option from a given service. Type is a part of option before ':' */
5586 /* Parametric option has following syntax: 'Type: option = value' */
5588 int lp_parm_int(int snum, const char *type, const char *option, int def)
5590 struct parmlist_entry *data = get_parametrics(snum, type, option);
5592 if (data && data->value && *data->value)
5593 return lp_int(data->value);
5595 return def;
5598 /* Return parametric option from a given service. Type is a part of option before ':' */
5599 /* Parametric option has following syntax: 'Type: option = value' */
5601 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5603 struct parmlist_entry *data = get_parametrics(snum, type, option);
5605 if (data && data->value && *data->value)
5606 return lp_ulong(data->value);
5608 return def;
5611 /* Return parametric option from a given service. Type is a part of option before ':' */
5612 /* Parametric option has following syntax: 'Type: option = value' */
5614 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5616 struct parmlist_entry *data = get_parametrics(snum, type, option);
5618 if (data && data->value && *data->value)
5619 return lp_bool(data->value);
5621 return def;
5624 /* Return parametric option from a given service. Type is a part of option before ':' */
5625 /* Parametric option has following syntax: 'Type: option = value' */
5627 int lp_parm_enum(int snum, const char *type, const char *option,
5628 const struct enum_list *_enum, int def)
5630 struct parmlist_entry *data = get_parametrics(snum, type, option);
5632 if (data && data->value && *data->value && _enum)
5633 return lp_enum(data->value, _enum);
5635 return def;
5639 /***************************************************************************
5640 Initialise a service to the defaults.
5641 ***************************************************************************/
5643 static void init_service(struct loadparm_service *pservice)
5645 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
5646 copy_service(pservice, &sDefault, NULL);
5651 * free a param_opts structure.
5652 * param_opts handling should be moved to talloc;
5653 * then this whole functions reduces to a TALLOC_FREE().
5656 static void free_param_opts(struct parmlist_entry **popts)
5658 struct parmlist_entry *opt, *next_opt;
5660 if (popts == NULL) {
5661 return;
5664 if (*popts != NULL) {
5665 DEBUG(5, ("Freeing parametrics:\n"));
5667 opt = *popts;
5668 while (opt != NULL) {
5669 string_free(&opt->key);
5670 string_free(&opt->value);
5671 TALLOC_FREE(opt->list);
5672 next_opt = opt->next;
5673 SAFE_FREE(opt);
5674 opt = next_opt;
5676 *popts = NULL;
5679 /***************************************************************************
5680 Free the dynamically allocated parts of a service struct.
5681 ***************************************************************************/
5683 static void free_service(struct loadparm_service *pservice)
5685 if (!pservice)
5686 return;
5688 if (pservice->szService)
5689 DEBUG(5, ("free_service: Freeing service %s\n",
5690 pservice->szService));
5692 free_parameters(pservice);
5694 string_free(&pservice->szService);
5695 TALLOC_FREE(pservice->copymap);
5697 free_param_opts(&pservice->param_opt);
5699 ZERO_STRUCTP(pservice);
5703 /***************************************************************************
5704 remove a service indexed in the ServicePtrs array from the ServiceHash
5705 and free the dynamically allocated parts
5706 ***************************************************************************/
5708 static void free_service_byindex(int idx)
5710 if ( !LP_SNUM_OK(idx) )
5711 return;
5713 ServicePtrs[idx]->valid = false;
5714 invalid_services[num_invalid_services++] = idx;
5716 /* we have to cleanup the hash record */
5718 if (ServicePtrs[idx]->szService) {
5719 char *canon_name = canonicalize_servicename(
5720 talloc_tos(),
5721 ServicePtrs[idx]->szService );
5723 dbwrap_delete_bystring(ServiceHash, canon_name );
5724 TALLOC_FREE(canon_name);
5727 free_service(ServicePtrs[idx]);
5730 /***************************************************************************
5731 Add a new service to the services array initialising it with the given
5732 service.
5733 ***************************************************************************/
5735 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5737 int i;
5738 struct loadparm_service tservice;
5739 int num_to_alloc = iNumServices + 1;
5741 tservice = *pservice;
5743 /* it might already exist */
5744 if (name) {
5745 i = getservicebyname(name, NULL);
5746 if (i >= 0) {
5747 return (i);
5751 /* find an invalid one */
5752 i = iNumServices;
5753 if (num_invalid_services > 0) {
5754 i = invalid_services[--num_invalid_services];
5757 /* if not, then create one */
5758 if (i == iNumServices) {
5759 struct loadparm_service **tsp;
5760 int *tinvalid;
5762 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5763 if (tsp == NULL) {
5764 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5765 return (-1);
5767 ServicePtrs = tsp;
5768 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5769 if (!ServicePtrs[iNumServices]) {
5770 DEBUG(0,("add_a_service: out of memory!\n"));
5771 return (-1);
5773 iNumServices++;
5775 /* enlarge invalid_services here for now... */
5776 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5777 num_to_alloc);
5778 if (tinvalid == NULL) {
5779 DEBUG(0,("add_a_service: failed to enlarge "
5780 "invalid_services!\n"));
5781 return (-1);
5783 invalid_services = tinvalid;
5784 } else {
5785 free_service_byindex(i);
5788 ServicePtrs[i]->valid = true;
5790 init_service(ServicePtrs[i]);
5791 copy_service(ServicePtrs[i], &tservice, NULL);
5792 if (name)
5793 string_set(&ServicePtrs[i]->szService, name);
5795 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5796 i, ServicePtrs[i]->szService));
5798 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5799 return (-1);
5802 return (i);
5805 /***************************************************************************
5806 Convert a string to uppercase and remove whitespaces.
5807 ***************************************************************************/
5809 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5811 char *result;
5813 if ( !src ) {
5814 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5815 return NULL;
5818 result = talloc_strdup(ctx, src);
5819 SMB_ASSERT(result != NULL);
5821 strlower_m(result);
5822 return result;
5825 /***************************************************************************
5826 Add a name/index pair for the services array to the hash table.
5827 ***************************************************************************/
5829 static bool hash_a_service(const char *name, int idx)
5831 char *canon_name;
5833 if ( !ServiceHash ) {
5834 DEBUG(10,("hash_a_service: creating servicehash\n"));
5835 ServiceHash = db_open_rbt(NULL);
5836 if ( !ServiceHash ) {
5837 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5838 return false;
5842 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5843 idx, name));
5845 canon_name = canonicalize_servicename(talloc_tos(), name );
5847 dbwrap_store_bystring(ServiceHash, canon_name,
5848 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5849 TDB_REPLACE);
5851 TALLOC_FREE(canon_name);
5853 return true;
5856 /***************************************************************************
5857 Add a new home service, with the specified home directory, defaults coming
5858 from service ifrom.
5859 ***************************************************************************/
5861 bool lp_add_home(const char *pszHomename, int iDefaultService,
5862 const char *user, const char *pszHomedir)
5864 int i;
5866 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5867 pszHomedir[0] == '\0') {
5868 return false;
5871 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5873 if (i < 0)
5874 return false;
5876 if (!(*(ServicePtrs[iDefaultService]->szPath))
5877 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5878 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5881 if (!(*(ServicePtrs[i]->comment))) {
5882 char *comment = NULL;
5883 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5884 return false;
5886 string_set(&ServicePtrs[i]->comment, comment);
5887 SAFE_FREE(comment);
5890 /* set the browseable flag from the global default */
5892 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5893 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
5895 ServicePtrs[i]->autoloaded = true;
5897 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5898 user, ServicePtrs[i]->szPath ));
5900 return true;
5903 /***************************************************************************
5904 Add a new service, based on an old one.
5905 ***************************************************************************/
5907 int lp_add_service(const char *pszService, int iDefaultService)
5909 if (iDefaultService < 0) {
5910 return add_a_service(&sDefault, pszService);
5913 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5916 /***************************************************************************
5917 Add the IPC service.
5918 ***************************************************************************/
5920 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5922 char *comment = NULL;
5923 int i = add_a_service(&sDefault, ipc_name);
5925 if (i < 0)
5926 return false;
5928 if (asprintf(&comment, "IPC Service (%s)",
5929 Globals.szServerString) < 0) {
5930 return false;
5933 string_set(&ServicePtrs[i]->szPath, tmpdir());
5934 string_set(&ServicePtrs[i]->szUsername, "");
5935 string_set(&ServicePtrs[i]->comment, comment);
5936 string_set(&ServicePtrs[i]->fstype, "IPC");
5937 ServicePtrs[i]->iMaxConnections = 0;
5938 ServicePtrs[i]->bAvailable = true;
5939 ServicePtrs[i]->bRead_only = true;
5940 ServicePtrs[i]->bGuest_only = false;
5941 ServicePtrs[i]->bAdministrative_share = true;
5942 ServicePtrs[i]->bGuest_ok = guest_ok;
5943 ServicePtrs[i]->bPrint_ok = false;
5944 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5946 DEBUG(3, ("adding IPC service\n"));
5948 SAFE_FREE(comment);
5949 return true;
5952 /***************************************************************************
5953 Add a new printer service, with defaults coming from service iFrom.
5954 ***************************************************************************/
5956 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5958 const char *comment = "From Printcap";
5959 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5961 if (i < 0)
5962 return false;
5964 /* note that we do NOT default the availability flag to true - */
5965 /* we take it from the default service passed. This allows all */
5966 /* dynamic printers to be disabled by disabling the [printers] */
5967 /* entry (if/when the 'available' keyword is implemented!). */
5969 /* the printer name is set to the service name. */
5970 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5971 string_set(&ServicePtrs[i]->comment, comment);
5973 /* set the browseable flag from the gloabl default */
5974 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5976 /* Printers cannot be read_only. */
5977 ServicePtrs[i]->bRead_only = false;
5978 /* No share modes on printer services. */
5979 ServicePtrs[i]->bShareModes = false;
5980 /* No oplocks on printer services. */
5981 ServicePtrs[i]->bOpLocks = false;
5982 /* Printer services must be printable. */
5983 ServicePtrs[i]->bPrint_ok = true;
5985 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5987 return true;
5991 /***************************************************************************
5992 Check whether the given parameter name is valid.
5993 Parametric options (names containing a colon) are considered valid.
5994 ***************************************************************************/
5996 bool lp_parameter_is_valid(const char *pszParmName)
5998 return ((map_parameter(pszParmName) != -1) ||
5999 (strchr(pszParmName, ':') != NULL));
6002 /***************************************************************************
6003 Check whether the given name is the name of a global parameter.
6004 Returns true for strings belonging to parameters of class
6005 P_GLOBAL, false for all other strings, also for parametric options
6006 and strings not belonging to any option.
6007 ***************************************************************************/
6009 bool lp_parameter_is_global(const char *pszParmName)
6011 int num = map_parameter(pszParmName);
6013 if (num >= 0) {
6014 return (parm_table[num].p_class == P_GLOBAL);
6017 return false;
6020 /**************************************************************************
6021 Check whether the given name is the canonical name of a parameter.
6022 Returns false if it is not a valid parameter Name.
6023 For parametric options, true is returned.
6024 **************************************************************************/
6026 bool lp_parameter_is_canonical(const char *parm_name)
6028 if (!lp_parameter_is_valid(parm_name)) {
6029 return false;
6032 return (map_parameter(parm_name) ==
6033 map_parameter_canonical(parm_name, NULL));
6036 /**************************************************************************
6037 Determine the canonical name for a parameter.
6038 Indicate when it is an inverse (boolean) synonym instead of a
6039 "usual" synonym.
6040 **************************************************************************/
6042 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6043 bool *inverse)
6045 int num;
6047 if (!lp_parameter_is_valid(parm_name)) {
6048 *canon_parm = NULL;
6049 return false;
6052 num = map_parameter_canonical(parm_name, inverse);
6053 if (num < 0) {
6054 /* parametric option */
6055 *canon_parm = parm_name;
6056 } else {
6057 *canon_parm = parm_table[num].label;
6060 return true;
6064 /**************************************************************************
6065 Determine the canonical name for a parameter.
6066 Turn the value given into the inverse boolean expression when
6067 the synonym is an invers boolean synonym.
6069 Return true if parm_name is a valid parameter name and
6070 in case it is an invers boolean synonym, if the val string could
6071 successfully be converted to the reverse bool.
6072 Return false in all other cases.
6073 **************************************************************************/
6075 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6076 const char *val,
6077 const char **canon_parm,
6078 const char **canon_val)
6080 int num;
6081 bool inverse;
6083 if (!lp_parameter_is_valid(parm_name)) {
6084 *canon_parm = NULL;
6085 *canon_val = NULL;
6086 return false;
6089 num = map_parameter_canonical(parm_name, &inverse);
6090 if (num < 0) {
6091 /* parametric option */
6092 *canon_parm = parm_name;
6093 *canon_val = val;
6094 } else {
6095 *canon_parm = parm_table[num].label;
6096 if (inverse) {
6097 if (!lp_invert_boolean(val, canon_val)) {
6098 *canon_val = NULL;
6099 return false;
6101 } else {
6102 *canon_val = val;
6106 return true;
6109 /***************************************************************************
6110 Map a parameter's string representation to something we can use.
6111 Returns false if the parameter string is not recognised, else TRUE.
6112 ***************************************************************************/
6114 static int map_parameter(const char *pszParmName)
6116 int iIndex;
6118 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6119 return (-1);
6121 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6122 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6123 return (iIndex);
6125 /* Warn only if it isn't parametric option */
6126 if (strchr(pszParmName, ':') == NULL)
6127 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6128 /* We do return 'fail' for parametric options as well because they are
6129 stored in different storage
6131 return (-1);
6134 /***************************************************************************
6135 Map a parameter's string representation to the index of the canonical
6136 form of the parameter (it might be a synonym).
6137 Returns -1 if the parameter string is not recognised.
6138 ***************************************************************************/
6140 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6142 int parm_num, canon_num;
6143 bool loc_inverse = false;
6145 parm_num = map_parameter(pszParmName);
6146 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6147 /* invalid, parametric or no canidate for synonyms ... */
6148 goto done;
6151 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6152 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6153 parm_num = canon_num;
6154 goto done;
6158 done:
6159 if (inverse != NULL) {
6160 *inverse = loc_inverse;
6162 return parm_num;
6165 /***************************************************************************
6166 return true if parameter number parm1 is a synonym of parameter
6167 number parm2 (parm2 being the principal name).
6168 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6169 false otherwise.
6170 ***************************************************************************/
6172 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6174 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
6175 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
6176 (parm_table[parm1].flags & FLAG_HIDE) &&
6177 !(parm_table[parm2].flags & FLAG_HIDE))
6179 if (inverse != NULL) {
6180 if ((parm_table[parm1].type == P_BOOLREV) &&
6181 (parm_table[parm2].type == P_BOOL))
6183 *inverse = true;
6184 } else {
6185 *inverse = false;
6188 return true;
6190 return false;
6193 /***************************************************************************
6194 Show one parameter's name, type, [values,] and flags.
6195 (helper functions for show_parameter_list)
6196 ***************************************************************************/
6198 static void show_parameter(int parmIndex)
6200 int enumIndex, flagIndex;
6201 int parmIndex2;
6202 bool hadFlag;
6203 bool hadSyn;
6204 bool inverse;
6205 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6206 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6207 "P_ENUM", "P_SEP"};
6208 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6209 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6210 FLAG_HIDE};
6211 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6212 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6213 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
6215 printf("%s=%s", parm_table[parmIndex].label,
6216 type[parm_table[parmIndex].type]);
6217 if (parm_table[parmIndex].type == P_ENUM) {
6218 printf(",");
6219 for (enumIndex=0;
6220 parm_table[parmIndex].enum_list[enumIndex].name;
6221 enumIndex++)
6223 printf("%s%s",
6224 enumIndex ? "|" : "",
6225 parm_table[parmIndex].enum_list[enumIndex].name);
6228 printf(",");
6229 hadFlag = false;
6230 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6231 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6232 printf("%s%s",
6233 hadFlag ? "|" : "",
6234 flag_names[flagIndex]);
6235 hadFlag = true;
6239 /* output synonyms */
6240 hadSyn = false;
6241 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6242 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6243 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6244 parm_table[parmIndex2].label);
6245 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6246 if (!hadSyn) {
6247 printf(" (synonyms: ");
6248 hadSyn = true;
6249 } else {
6250 printf(", ");
6252 printf("%s%s", parm_table[parmIndex2].label,
6253 inverse ? "[i]" : "");
6256 if (hadSyn) {
6257 printf(")");
6260 printf("\n");
6263 /***************************************************************************
6264 Show all parameter's name, type, [values,] and flags.
6265 ***************************************************************************/
6267 void show_parameter_list(void)
6269 int classIndex, parmIndex;
6270 const char *section_names[] = { "local", "global", NULL};
6272 for (classIndex=0; section_names[classIndex]; classIndex++) {
6273 printf("[%s]\n", section_names[classIndex]);
6274 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6275 if (parm_table[parmIndex].p_class == classIndex) {
6276 show_parameter(parmIndex);
6282 /***************************************************************************
6283 Check if a given string correctly represents a boolean value.
6284 ***************************************************************************/
6286 bool lp_string_is_valid_boolean(const char *parm_value)
6288 return set_boolean(parm_value, NULL);
6291 /***************************************************************************
6292 Get the standard string representation of a boolean value ("yes" or "no")
6293 ***************************************************************************/
6295 static const char *get_boolean(bool bool_value)
6297 static const char *yes_str = "yes";
6298 static const char *no_str = "no";
6300 return (bool_value ? yes_str : no_str);
6303 /***************************************************************************
6304 Provide the string of the negated boolean value associated to the boolean
6305 given as a string. Returns false if the passed string does not correctly
6306 represent a boolean.
6307 ***************************************************************************/
6309 bool lp_invert_boolean(const char *str, const char **inverse_str)
6311 bool val;
6313 if (!set_boolean(str, &val)) {
6314 return false;
6317 *inverse_str = get_boolean(!val);
6318 return true;
6321 /***************************************************************************
6322 Provide the canonical string representation of a boolean value given
6323 as a string. Return true on success, false if the string given does
6324 not correctly represent a boolean.
6325 ***************************************************************************/
6327 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6329 bool val;
6331 if (!set_boolean(str, &val)) {
6332 return false;
6335 *canon_str = get_boolean(val);
6336 return true;
6339 /***************************************************************************
6340 Find a service by name. Otherwise works like get_service.
6341 ***************************************************************************/
6343 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6345 int iService = -1;
6346 char *canon_name;
6347 TDB_DATA data;
6348 NTSTATUS status;
6350 if (ServiceHash == NULL) {
6351 return -1;
6354 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6356 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
6357 &data);
6359 if (NT_STATUS_IS_OK(status) &&
6360 (data.dptr != NULL) &&
6361 (data.dsize == sizeof(iService)))
6363 iService = *(int *)data.dptr;
6366 TALLOC_FREE(canon_name);
6368 if ((iService != -1) && (LP_SNUM_OK(iService))
6369 && (pserviceDest != NULL)) {
6370 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6373 return (iService);
6376 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6377 struct loadparm_service *lp_service(const char *pszServiceName)
6379 int iService = getservicebyname(pszServiceName, NULL);
6380 if (iService == -1 || !LP_SNUM_OK(iService)) {
6381 return NULL;
6383 return ServicePtrs[iService];
6386 struct loadparm_service *lp_servicebynum(int snum)
6388 if ((snum == -1) || !LP_SNUM_OK(snum)) {
6389 return NULL;
6391 return ServicePtrs[snum];
6394 struct loadparm_service *lp_default_loadparm_service()
6396 return &sDefault;
6400 /***************************************************************************
6401 Copy a service structure to another.
6402 If pcopymapDest is NULL then copy all fields
6403 ***************************************************************************/
6406 * Add a parametric option to a parmlist_entry,
6407 * replacing old value, if already present.
6409 static void set_param_opt(struct parmlist_entry **opt_list,
6410 const char *opt_name,
6411 const char *opt_value,
6412 unsigned priority)
6414 struct parmlist_entry *new_opt, *opt;
6415 bool not_added;
6417 if (opt_list == NULL) {
6418 return;
6421 opt = *opt_list;
6422 not_added = true;
6424 /* Traverse destination */
6425 while (opt) {
6426 /* If we already have same option, override it */
6427 if (strwicmp(opt->key, opt_name) == 0) {
6428 if ((opt->priority & FLAG_CMDLINE) &&
6429 !(priority & FLAG_CMDLINE)) {
6430 /* it's been marked as not to be
6431 overridden */
6432 return;
6434 string_free(&opt->value);
6435 TALLOC_FREE(opt->list);
6436 opt->value = SMB_STRDUP(opt_value);
6437 opt->priority = priority;
6438 not_added = false;
6439 break;
6441 opt = opt->next;
6443 if (not_added) {
6444 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
6445 new_opt->key = SMB_STRDUP(opt_name);
6446 new_opt->value = SMB_STRDUP(opt_value);
6447 new_opt->list = NULL;
6448 new_opt->priority = priority;
6449 DLIST_ADD(*opt_list, new_opt);
6453 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6454 struct bitmap *pcopymapDest)
6456 int i;
6457 bool bcopyall = (pcopymapDest == NULL);
6458 struct parmlist_entry *data;
6460 for (i = 0; parm_table[i].label; i++)
6461 if (parm_table[i].p_class == P_LOCAL &&
6462 (bcopyall || bitmap_query(pcopymapDest,i))) {
6463 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6464 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6466 switch (parm_table[i].type) {
6467 case P_BOOL:
6468 case P_BOOLREV:
6469 *(bool *)dest_ptr = *(bool *)src_ptr;
6470 break;
6472 case P_INTEGER:
6473 case P_ENUM:
6474 case P_OCTAL:
6475 case P_BYTES:
6476 *(int *)dest_ptr = *(int *)src_ptr;
6477 break;
6479 case P_CHAR:
6480 *(char *)dest_ptr = *(char *)src_ptr;
6481 break;
6483 case P_STRING:
6484 string_set((char **)dest_ptr,
6485 *(char **)src_ptr);
6486 break;
6488 case P_USTRING:
6490 char *upper_string = strupper_talloc(talloc_tos(),
6491 *(char **)src_ptr);
6492 string_set((char **)dest_ptr,
6493 upper_string);
6494 TALLOC_FREE(upper_string);
6495 break;
6497 case P_LIST:
6498 TALLOC_FREE(*((char ***)dest_ptr));
6499 *((char ***)dest_ptr) = str_list_copy(NULL,
6500 *(const char ***)src_ptr);
6501 break;
6502 default:
6503 break;
6507 if (bcopyall) {
6508 init_copymap(pserviceDest);
6509 if (pserviceSource->copymap)
6510 bitmap_copy(pserviceDest->copymap,
6511 pserviceSource->copymap);
6514 data = pserviceSource->param_opt;
6515 while (data) {
6516 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6517 data = data->next;
6521 /***************************************************************************
6522 Check a service for consistency. Return false if the service is in any way
6523 incomplete or faulty, else true.
6524 ***************************************************************************/
6526 bool service_ok(int iService)
6528 bool bRetval;
6530 bRetval = true;
6531 if (ServicePtrs[iService]->szService[0] == '\0') {
6532 DEBUG(0, ("The following message indicates an internal error:\n"));
6533 DEBUG(0, ("No service name in service entry.\n"));
6534 bRetval = false;
6537 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6538 /* I can't see why you'd want a non-printable printer service... */
6539 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6540 if (!ServicePtrs[iService]->bPrint_ok) {
6541 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6542 ServicePtrs[iService]->szService));
6543 ServicePtrs[iService]->bPrint_ok = true;
6545 /* [printers] service must also be non-browsable. */
6546 if (ServicePtrs[iService]->bBrowseable)
6547 ServicePtrs[iService]->bBrowseable = false;
6550 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6551 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6552 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6554 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6555 ServicePtrs[iService]->szService));
6556 ServicePtrs[iService]->bAvailable = false;
6559 /* If a service is flagged unavailable, log the fact at level 1. */
6560 if (!ServicePtrs[iService]->bAvailable)
6561 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6562 ServicePtrs[iService]->szService));
6564 return (bRetval);
6567 static struct smbconf_ctx *lp_smbconf_ctx(void)
6569 sbcErr err;
6570 static struct smbconf_ctx *conf_ctx = NULL;
6572 if (conf_ctx == NULL) {
6573 err = smbconf_init(NULL, &conf_ctx, "registry:");
6574 if (!SBC_ERROR_IS_OK(err)) {
6575 DEBUG(1, ("error initializing registry configuration: "
6576 "%s\n", sbcErrorString(err)));
6577 conf_ctx = NULL;
6581 return conf_ctx;
6584 static bool process_smbconf_service(struct smbconf_service *service)
6586 uint32_t count;
6587 bool ret;
6589 if (service == NULL) {
6590 return false;
6593 ret = do_section(service->name, NULL);
6594 if (ret != true) {
6595 return false;
6597 for (count = 0; count < service->num_params; count++) {
6598 ret = do_parameter(service->param_names[count],
6599 service->param_values[count],
6600 NULL);
6601 if (ret != true) {
6602 return false;
6605 if (iServiceIndex >= 0) {
6606 return service_ok(iServiceIndex);
6608 return true;
6612 * load a service from registry and activate it
6614 bool process_registry_service(const char *service_name)
6616 sbcErr err;
6617 struct smbconf_service *service = NULL;
6618 TALLOC_CTX *mem_ctx = talloc_stackframe();
6619 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6620 bool ret = false;
6622 if (conf_ctx == NULL) {
6623 goto done;
6626 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6628 if (!smbconf_share_exists(conf_ctx, service_name)) {
6630 * Registry does not contain data for this service (yet),
6631 * but make sure lp_load doesn't return false.
6633 ret = true;
6634 goto done;
6637 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6638 if (!SBC_ERROR_IS_OK(err)) {
6639 goto done;
6642 ret = process_smbconf_service(service);
6643 if (!ret) {
6644 goto done;
6647 /* store the csn */
6648 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6650 done:
6651 TALLOC_FREE(mem_ctx);
6652 return ret;
6656 * process_registry_globals
6658 static bool process_registry_globals(void)
6660 bool ret;
6662 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6664 ret = do_parameter("registry shares", "yes", NULL);
6665 if (!ret) {
6666 return ret;
6669 return process_registry_service(GLOBAL_NAME);
6672 bool process_registry_shares(void)
6674 sbcErr err;
6675 uint32_t count;
6676 struct smbconf_service **service = NULL;
6677 uint32_t num_shares = 0;
6678 TALLOC_CTX *mem_ctx = talloc_stackframe();
6679 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6680 bool ret = false;
6682 if (conf_ctx == NULL) {
6683 goto done;
6686 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6687 if (!SBC_ERROR_IS_OK(err)) {
6688 goto done;
6691 ret = true;
6693 for (count = 0; count < num_shares; count++) {
6694 if (strequal(service[count]->name, GLOBAL_NAME)) {
6695 continue;
6697 ret = process_smbconf_service(service[count]);
6698 if (!ret) {
6699 goto done;
6703 /* store the csn */
6704 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6706 done:
6707 TALLOC_FREE(mem_ctx);
6708 return ret;
6712 * reload those shares from registry that are already
6713 * activated in the services array.
6715 static bool reload_registry_shares(void)
6717 int i;
6718 bool ret = true;
6720 for (i = 0; i < iNumServices; i++) {
6721 if (!VALID(i)) {
6722 continue;
6725 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
6726 continue;
6729 ret = process_registry_service(ServicePtrs[i]->szService);
6730 if (!ret) {
6731 goto done;
6735 done:
6736 return ret;
6740 #define MAX_INCLUDE_DEPTH 100
6742 static uint8_t include_depth;
6744 static struct file_lists {
6745 struct file_lists *next;
6746 char *name;
6747 char *subfname;
6748 time_t modtime;
6749 } *file_lists = NULL;
6751 /*******************************************************************
6752 Keep a linked list of all config files so we know when one has changed
6753 it's date and needs to be reloaded.
6754 ********************************************************************/
6756 static void add_to_file_list(const char *fname, const char *subfname)
6758 struct file_lists *f = file_lists;
6760 while (f) {
6761 if (f->name && !strcmp(f->name, fname))
6762 break;
6763 f = f->next;
6766 if (!f) {
6767 f = SMB_MALLOC_P(struct file_lists);
6768 if (!f)
6769 return;
6770 f->next = file_lists;
6771 f->name = SMB_STRDUP(fname);
6772 if (!f->name) {
6773 SAFE_FREE(f);
6774 return;
6776 f->subfname = SMB_STRDUP(subfname);
6777 if (!f->subfname) {
6778 SAFE_FREE(f->name);
6779 SAFE_FREE(f);
6780 return;
6782 file_lists = f;
6783 f->modtime = file_modtime(subfname);
6784 } else {
6785 time_t t = file_modtime(subfname);
6786 if (t)
6787 f->modtime = t;
6789 return;
6793 * Free the file lists
6795 static void free_file_list(void)
6797 struct file_lists *f;
6798 struct file_lists *next;
6800 f = file_lists;
6801 while( f ) {
6802 next = f->next;
6803 SAFE_FREE( f->name );
6804 SAFE_FREE( f->subfname );
6805 SAFE_FREE( f );
6806 f = next;
6808 file_lists = NULL;
6813 * Utility function for outsiders to check if we're running on registry.
6815 bool lp_config_backend_is_registry(void)
6817 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6821 * Utility function to check if the config backend is FILE.
6823 bool lp_config_backend_is_file(void)
6825 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6828 /*******************************************************************
6829 Check if a config file has changed date.
6830 ********************************************************************/
6832 bool lp_file_list_changed(void)
6834 struct file_lists *f = file_lists;
6836 DEBUG(6, ("lp_file_list_changed()\n"));
6838 while (f) {
6839 time_t mod_time;
6841 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6842 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6844 if (conf_ctx == NULL) {
6845 return false;
6847 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6848 NULL))
6850 DEBUGADD(6, ("registry config changed\n"));
6851 return true;
6853 } else {
6854 char *n2 = NULL;
6855 n2 = talloc_sub_basic(talloc_tos(),
6856 get_current_username(),
6857 current_user_info.domain,
6858 f->name);
6859 if (!n2) {
6860 return false;
6862 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6863 f->name, n2, ctime(&f->modtime)));
6865 mod_time = file_modtime(n2);
6867 if (mod_time &&
6868 ((f->modtime != mod_time) ||
6869 (f->subfname == NULL) ||
6870 (strcmp(n2, f->subfname) != 0)))
6872 DEBUGADD(6,
6873 ("file %s modified: %s\n", n2,
6874 ctime(&mod_time)));
6875 f->modtime = mod_time;
6876 SAFE_FREE(f->subfname);
6877 f->subfname = SMB_STRDUP(n2);
6878 TALLOC_FREE(n2);
6879 return true;
6881 TALLOC_FREE(n2);
6883 f = f->next;
6885 return false;
6890 * Initialize iconv conversion descriptors.
6892 * This is called the first time it is needed, and also called again
6893 * every time the configuration is reloaded, because the charset or
6894 * codepage might have changed.
6896 static void init_iconv(void)
6898 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
6899 lp_unix_charset(),
6900 true, global_iconv_handle);
6903 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6905 if (strcmp(*ptr, pszParmValue) != 0) {
6906 string_set(ptr, pszParmValue);
6907 init_iconv();
6909 return true;
6912 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6914 bool is_utf8 = false;
6915 size_t len = strlen(pszParmValue);
6917 if (len == 4 || len == 5) {
6918 /* Don't use StrCaseCmp here as we don't want to
6919 initialize iconv. */
6920 if ((toupper_m(pszParmValue[0]) == 'U') &&
6921 (toupper_m(pszParmValue[1]) == 'T') &&
6922 (toupper_m(pszParmValue[2]) == 'F')) {
6923 if (len == 4) {
6924 if (pszParmValue[3] == '8') {
6925 is_utf8 = true;
6927 } else {
6928 if (pszParmValue[3] == '-' &&
6929 pszParmValue[4] == '8') {
6930 is_utf8 = true;
6936 if (strcmp(*ptr, pszParmValue) != 0) {
6937 if (is_utf8) {
6938 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6939 "be UTF8, using (default value) %s instead.\n",
6940 DEFAULT_DOS_CHARSET));
6941 pszParmValue = DEFAULT_DOS_CHARSET;
6943 string_set(ptr, pszParmValue);
6944 init_iconv();
6946 return true;
6949 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6951 bool ret = true;
6952 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
6953 char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
6955 ret &= string_set(&Globals.szRealm, pszParmValue);
6956 ret &= string_set(&Globals.szRealmUpper, realm);
6957 ret &= string_set(&Globals.szDnsDomain, dnsdomain);
6958 TALLOC_FREE(realm);
6959 TALLOC_FREE(dnsdomain);
6961 return ret;
6964 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6966 TALLOC_FREE(Globals.szNetbiosAliases);
6967 Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
6968 return set_netbios_aliases(Globals.szNetbiosAliases);
6971 /***************************************************************************
6972 Handle the include operation.
6973 ***************************************************************************/
6974 static bool bAllowIncludeRegistry = true;
6976 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6978 char *fname;
6980 if (include_depth >= MAX_INCLUDE_DEPTH) {
6981 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6982 include_depth));
6983 return false;
6986 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6987 if (!bAllowIncludeRegistry) {
6988 return true;
6990 if (bInGlobalSection) {
6991 bool ret;
6992 include_depth++;
6993 ret = process_registry_globals();
6994 include_depth--;
6995 return ret;
6996 } else {
6997 DEBUG(1, ("\"include = registry\" only effective "
6998 "in %s section\n", GLOBAL_NAME));
6999 return false;
7003 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7004 current_user_info.domain,
7005 pszParmValue);
7007 add_to_file_list(pszParmValue, fname);
7009 string_set(ptr, fname);
7011 if (file_exist(fname)) {
7012 bool ret;
7013 include_depth++;
7014 ret = pm_process(fname, do_section, do_parameter, NULL);
7015 include_depth--;
7016 TALLOC_FREE(fname);
7017 return ret;
7020 DEBUG(2, ("Can't find include file %s\n", fname));
7021 TALLOC_FREE(fname);
7022 return true;
7025 /***************************************************************************
7026 Handle the interpretation of the copy parameter.
7027 ***************************************************************************/
7029 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7031 bool bRetval;
7032 int iTemp;
7033 struct loadparm_service serviceTemp;
7035 string_set(ptr, pszParmValue);
7037 init_service(&serviceTemp);
7039 bRetval = false;
7041 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7043 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7044 if (iTemp == iServiceIndex) {
7045 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7046 } else {
7047 copy_service(ServicePtrs[iServiceIndex],
7048 &serviceTemp,
7049 ServicePtrs[iServiceIndex]->copymap);
7050 bRetval = true;
7052 } else {
7053 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7054 bRetval = false;
7057 free_service(&serviceTemp);
7058 return (bRetval);
7061 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7063 Globals.ldap_debug_level = lp_int(pszParmValue);
7064 init_ldap_debugging();
7065 return true;
7068 /***************************************************************************
7069 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7070 parameters is:
7072 [global]
7074 idmap uid = 1000-1999
7075 idmap gid = 700-899
7077 We only do simple parsing checks here. The strings are parsed into useful
7078 structures in the idmap daemon code.
7080 ***************************************************************************/
7082 /* Some lp_ routines to return idmap [ug]id information */
7084 static uid_t idmap_uid_low, idmap_uid_high;
7085 static gid_t idmap_gid_low, idmap_gid_high;
7087 bool lp_idmap_uid(uid_t *low, uid_t *high)
7089 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7090 return false;
7092 if (low)
7093 *low = idmap_uid_low;
7095 if (high)
7096 *high = idmap_uid_high;
7098 return true;
7101 bool lp_idmap_gid(gid_t *low, gid_t *high)
7103 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7104 return false;
7106 if (low)
7107 *low = idmap_gid_low;
7109 if (high)
7110 *high = idmap_gid_high;
7112 return true;
7115 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7117 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7119 return true;
7122 /* Do some simple checks on "idmap [ug]id" parameter values */
7124 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7126 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7128 return true;
7131 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7133 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7135 return true;
7138 /***************************************************************************
7139 Handle the DEBUG level list.
7140 ***************************************************************************/
7142 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
7144 string_set(ptr, pszParmValueIn);
7145 return debug_parse_levels(pszParmValueIn);
7148 /***************************************************************************
7149 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7150 ***************************************************************************/
7152 static const char *append_ldap_suffix( const char *str )
7154 const char *suffix_string;
7157 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7158 Globals.szLdapSuffix );
7159 if ( !suffix_string ) {
7160 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7161 return "";
7164 return suffix_string;
7167 const char *lp_ldap_machine_suffix(void)
7169 if (Globals.szLdapMachineSuffix[0])
7170 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7172 return lp_string(Globals.szLdapSuffix);
7175 const char *lp_ldap_user_suffix(void)
7177 if (Globals.szLdapUserSuffix[0])
7178 return append_ldap_suffix(Globals.szLdapUserSuffix);
7180 return lp_string(Globals.szLdapSuffix);
7183 const char *lp_ldap_group_suffix(void)
7185 if (Globals.szLdapGroupSuffix[0])
7186 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7188 return lp_string(Globals.szLdapSuffix);
7191 const char *lp_ldap_idmap_suffix(void)
7193 if (Globals.szLdapIdmapSuffix[0])
7194 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7196 return lp_string(Globals.szLdapSuffix);
7199 /****************************************************************************
7200 set the value for a P_ENUM
7201 ***************************************************************************/
7203 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7204 int *ptr )
7206 int i;
7208 for (i = 0; parm->enum_list[i].name; i++) {
7209 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7210 *ptr = parm->enum_list[i].value;
7211 return;
7214 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7215 pszParmValue, parm->label));
7218 /***************************************************************************
7219 ***************************************************************************/
7221 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7223 static int parm_num = -1;
7224 struct loadparm_service *s;
7226 if ( parm_num == -1 )
7227 parm_num = map_parameter( "printing" );
7229 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7231 if ( snum < 0 )
7232 s = &sDefault;
7233 else
7234 s = ServicePtrs[snum];
7236 init_printer_values( s );
7238 return true;
7242 /***************************************************************************
7243 Initialise a copymap.
7244 ***************************************************************************/
7246 static void init_copymap(struct loadparm_service *pservice)
7248 int i;
7250 TALLOC_FREE(pservice->copymap);
7252 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7253 if (!pservice->copymap)
7254 DEBUG(0,
7255 ("Couldn't allocate copymap!! (size %d)\n",
7256 (int)NUMPARAMETERS));
7257 else
7258 for (i = 0; i < NUMPARAMETERS; i++)
7259 bitmap_set(pservice->copymap, i);
7263 return the parameter pointer for a parameter
7265 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7267 if (service == NULL) {
7268 if (parm->p_class == P_LOCAL)
7269 return (void *)(((char *)&sDefault)+parm->offset);
7270 else if (parm->p_class == P_GLOBAL)
7271 return (void *)(((char *)&Globals)+parm->offset);
7272 else return NULL;
7273 } else {
7274 return (void *)(((char *)service) + parm->offset);
7278 /***************************************************************************
7279 Return the local pointer to a parameter given the service number and parameter
7280 ***************************************************************************/
7282 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7284 return lp_parm_ptr(ServicePtrs[snum], parm);
7287 /***************************************************************************
7288 Process a parameter for a particular service number. If snum < 0
7289 then assume we are in the globals.
7290 ***************************************************************************/
7292 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7294 int parmnum, i;
7295 void *parm_ptr = NULL; /* where we are going to store the result */
7296 struct parmlist_entry **opt_list;
7298 parmnum = map_parameter(pszParmName);
7300 if (parmnum < 0) {
7301 if (strchr(pszParmName, ':') == NULL) {
7302 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7303 pszParmName));
7304 return true;
7308 * We've got a parametric option
7311 opt_list = (snum < 0)
7312 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7313 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7315 return true;
7318 /* if it's already been set by the command line, then we don't
7319 override here */
7320 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7321 return true;
7324 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7325 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7326 pszParmName));
7329 /* we might point at a service, the default service or a global */
7330 if (snum < 0) {
7331 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7332 } else {
7333 if (parm_table[parmnum].p_class == P_GLOBAL) {
7334 DEBUG(0,
7335 ("Global parameter %s found in service section!\n",
7336 pszParmName));
7337 return true;
7339 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7342 if (snum >= 0) {
7343 if (!ServicePtrs[snum]->copymap)
7344 init_copymap(ServicePtrs[snum]);
7346 /* this handles the aliases - set the copymap for other entries with
7347 the same data pointer */
7348 for (i = 0; parm_table[i].label; i++) {
7349 if ((parm_table[i].offset == parm_table[parmnum].offset)
7350 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
7351 bitmap_clear(ServicePtrs[snum]->copymap, i);
7356 /* if it is a special case then go ahead */
7357 if (parm_table[parmnum].special) {
7358 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7359 (char **)parm_ptr);
7362 /* now switch on the type of variable it is */
7363 switch (parm_table[parmnum].type)
7365 case P_BOOL:
7366 *(bool *)parm_ptr = lp_bool(pszParmValue);
7367 break;
7369 case P_BOOLREV:
7370 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7371 break;
7373 case P_INTEGER:
7374 *(int *)parm_ptr = lp_int(pszParmValue);
7375 break;
7377 case P_CHAR:
7378 *(char *)parm_ptr = *pszParmValue;
7379 break;
7381 case P_OCTAL:
7382 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7383 if ( i != 1 ) {
7384 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7386 break;
7388 case P_BYTES:
7390 uint64_t val;
7391 if (conv_str_size_error(pszParmValue, &val)) {
7392 if (val <= INT_MAX) {
7393 *(int *)parm_ptr = (int)val;
7394 break;
7398 DEBUG(0,("lp_do_parameter(%s): value is not "
7399 "a valid size specifier!\n", pszParmValue));
7400 return false;
7403 case P_LIST:
7404 case P_CMDLIST:
7405 TALLOC_FREE(*((char ***)parm_ptr));
7406 *(char ***)parm_ptr = str_list_make_v3(
7407 NULL, pszParmValue, NULL);
7408 break;
7410 case P_STRING:
7411 string_set((char **)parm_ptr, pszParmValue);
7412 break;
7414 case P_USTRING:
7416 char *upper_string = strupper_talloc(talloc_tos(),
7417 pszParmValue);
7418 string_set((char **)parm_ptr, upper_string);
7419 TALLOC_FREE(upper_string);
7420 break;
7422 case P_ENUM:
7423 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7424 break;
7425 case P_SEP:
7426 break;
7429 return true;
7432 /***************************************************************************
7433 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7434 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7435 ***************************************************************************/
7437 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7439 int parmnum, i;
7440 parmnum = map_parameter(pszParmName);
7441 if (parmnum >= 0) {
7442 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7443 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7444 return false;
7446 parm_table[parmnum].flags |= FLAG_CMDLINE;
7448 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7449 * be grouped in the table, so we don't have to search the
7450 * whole table */
7451 for (i=parmnum-1;
7452 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7453 && parm_table[i].p_class == parm_table[parmnum].p_class;
7454 i--) {
7455 parm_table[i].flags |= FLAG_CMDLINE;
7457 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
7458 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
7459 parm_table[i].flags |= FLAG_CMDLINE;
7462 if (store_values) {
7463 store_lp_set_cmdline(pszParmName, pszParmValue);
7465 return true;
7468 /* it might be parametric */
7469 if (strchr(pszParmName, ':') != NULL) {
7470 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7471 if (store_values) {
7472 store_lp_set_cmdline(pszParmName, pszParmValue);
7474 return true;
7477 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7478 return true;
7481 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7483 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7486 /***************************************************************************
7487 Process a parameter.
7488 ***************************************************************************/
7490 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7491 void *userdata)
7493 if (!bInGlobalSection && bGlobalOnly)
7494 return true;
7496 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7498 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7499 pszParmName, pszParmValue));
7503 set a option from the commandline in 'a=b' format. Use to support --option
7505 bool lp_set_option(const char *option)
7507 char *p, *s;
7508 bool ret;
7510 s = talloc_strdup(NULL, option);
7511 if (!s) {
7512 return false;
7515 p = strchr(s, '=');
7516 if (!p) {
7517 talloc_free(s);
7518 return false;
7521 *p = 0;
7523 /* skip white spaces after the = sign */
7524 do {
7525 p++;
7526 } while (*p == ' ');
7528 ret = lp_set_cmdline(s, p);
7529 talloc_free(s);
7530 return ret;
7533 /**************************************************************************
7534 Print a parameter of the specified type.
7535 ***************************************************************************/
7537 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7539 /* For the seperation of lists values that we print below */
7540 const char *list_sep = ", ";
7541 int i;
7542 switch (p->type)
7544 case P_ENUM:
7545 for (i = 0; p->enum_list[i].name; i++) {
7546 if (*(int *)ptr == p->enum_list[i].value) {
7547 fprintf(f, "%s",
7548 p->enum_list[i].name);
7549 break;
7552 break;
7554 case P_BOOL:
7555 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7556 break;
7558 case P_BOOLREV:
7559 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7560 break;
7562 case P_INTEGER:
7563 case P_BYTES:
7564 fprintf(f, "%d", *(int *)ptr);
7565 break;
7567 case P_CHAR:
7568 fprintf(f, "%c", *(char *)ptr);
7569 break;
7571 case P_OCTAL: {
7572 int val = *(int *)ptr;
7573 if (val == -1) {
7574 fprintf(f, "-1");
7575 } else {
7576 fprintf(f, "0%o", val);
7578 break;
7581 case P_CMDLIST:
7582 list_sep = " ";
7583 /* fall through */
7584 case P_LIST:
7585 if ((char ***)ptr && *(char ***)ptr) {
7586 char **list = *(char ***)ptr;
7587 for (; *list; list++) {
7588 /* surround strings with whitespace in double quotes */
7589 if (*(list+1) == NULL) {
7590 /* last item, no extra separator */
7591 list_sep = "";
7593 if ( strchr_m( *list, ' ' ) ) {
7594 fprintf(f, "\"%s\"%s", *list, list_sep);
7595 } else {
7596 fprintf(f, "%s%s", *list, list_sep);
7600 break;
7602 case P_STRING:
7603 case P_USTRING:
7604 if (*(char **)ptr) {
7605 fprintf(f, "%s", *(char **)ptr);
7607 break;
7608 case P_SEP:
7609 break;
7613 /***************************************************************************
7614 Check if two parameters are equal.
7615 ***************************************************************************/
7617 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7619 switch (type) {
7620 case P_BOOL:
7621 case P_BOOLREV:
7622 return (*((bool *)ptr1) == *((bool *)ptr2));
7624 case P_INTEGER:
7625 case P_ENUM:
7626 case P_OCTAL:
7627 case P_BYTES:
7628 return (*((int *)ptr1) == *((int *)ptr2));
7630 case P_CHAR:
7631 return (*((char *)ptr1) == *((char *)ptr2));
7633 case P_LIST:
7634 case P_CMDLIST:
7635 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7637 case P_STRING:
7638 case P_USTRING:
7640 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7641 if (p1 && !*p1)
7642 p1 = NULL;
7643 if (p2 && !*p2)
7644 p2 = NULL;
7645 return (p1 == p2 || strequal(p1, p2));
7647 case P_SEP:
7648 break;
7650 return false;
7653 /***************************************************************************
7654 Initialize any local varients in the sDefault table.
7655 ***************************************************************************/
7657 void init_locals(void)
7659 /* None as yet. */
7662 /***************************************************************************
7663 Process a new section (service). At this stage all sections are services.
7664 Later we'll have special sections that permit server parameters to be set.
7665 Returns true on success, false on failure.
7666 ***************************************************************************/
7668 static bool do_section(const char *pszSectionName, void *userdata)
7670 bool bRetval;
7671 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7672 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7673 bRetval = false;
7675 /* if we were in a global section then do the local inits */
7676 if (bInGlobalSection && !isglobal)
7677 init_locals();
7679 /* if we've just struck a global section, note the fact. */
7680 bInGlobalSection = isglobal;
7682 /* check for multiple global sections */
7683 if (bInGlobalSection) {
7684 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7685 return true;
7688 if (!bInGlobalSection && bGlobalOnly)
7689 return true;
7691 /* if we have a current service, tidy it up before moving on */
7692 bRetval = true;
7694 if (iServiceIndex >= 0)
7695 bRetval = service_ok(iServiceIndex);
7697 /* if all is still well, move to the next record in the services array */
7698 if (bRetval) {
7699 /* We put this here to avoid an odd message order if messages are */
7700 /* issued by the post-processing of a previous section. */
7701 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7703 iServiceIndex = add_a_service(&sDefault, pszSectionName);
7704 if (iServiceIndex < 0) {
7705 DEBUG(0, ("Failed to add a new service\n"));
7706 return false;
7708 /* Clean all parametric options for service */
7709 /* They will be added during parsing again */
7710 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7713 return bRetval;
7717 /***************************************************************************
7718 Determine if a partcular base parameter is currentl set to the default value.
7719 ***************************************************************************/
7721 static bool is_default(int i)
7723 if (!defaults_saved)
7724 return false;
7725 switch (parm_table[i].type) {
7726 case P_LIST:
7727 case P_CMDLIST:
7728 return str_list_equal((const char **)parm_table[i].def.lvalue,
7729 *(const char ***)lp_parm_ptr(NULL,
7730 &parm_table[i]));
7731 case P_STRING:
7732 case P_USTRING:
7733 return strequal(parm_table[i].def.svalue,
7734 *(char **)lp_parm_ptr(NULL,
7735 &parm_table[i]));
7736 case P_BOOL:
7737 case P_BOOLREV:
7738 return parm_table[i].def.bvalue ==
7739 *(bool *)lp_parm_ptr(NULL,
7740 &parm_table[i]);
7741 case P_CHAR:
7742 return parm_table[i].def.cvalue ==
7743 *(char *)lp_parm_ptr(NULL,
7744 &parm_table[i]);
7745 case P_INTEGER:
7746 case P_OCTAL:
7747 case P_ENUM:
7748 case P_BYTES:
7749 return parm_table[i].def.ivalue ==
7750 *(int *)lp_parm_ptr(NULL,
7751 &parm_table[i]);
7752 case P_SEP:
7753 break;
7755 return false;
7758 /***************************************************************************
7759 Display the contents of the global structure.
7760 ***************************************************************************/
7762 static void dump_globals(FILE *f)
7764 int i;
7765 struct parmlist_entry *data;
7767 fprintf(f, "[global]\n");
7769 for (i = 0; parm_table[i].label; i++)
7770 if (parm_table[i].p_class == P_GLOBAL &&
7771 !(parm_table[i].flags & FLAG_META) &&
7772 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
7773 if (defaults_saved && is_default(i))
7774 continue;
7775 fprintf(f, "\t%s = ", parm_table[i].label);
7776 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7777 &parm_table[i]),
7779 fprintf(f, "\n");
7781 if (Globals.param_opt != NULL) {
7782 data = Globals.param_opt;
7783 while(data) {
7784 fprintf(f, "\t%s = %s\n", data->key, data->value);
7785 data = data->next;
7791 /***************************************************************************
7792 Return true if a local parameter is currently set to the global default.
7793 ***************************************************************************/
7795 bool lp_is_default(int snum, struct parm_struct *parm)
7797 return equal_parameter(parm->type,
7798 lp_parm_ptr(ServicePtrs[snum], parm),
7799 lp_parm_ptr(NULL, parm));
7802 /***************************************************************************
7803 Display the contents of a single services record.
7804 ***************************************************************************/
7806 static void dump_a_service(struct loadparm_service *pService, FILE * f)
7808 int i;
7809 struct parmlist_entry *data;
7811 if (pService != &sDefault)
7812 fprintf(f, "[%s]\n", pService->szService);
7814 for (i = 0; parm_table[i].label; i++) {
7816 if (parm_table[i].p_class == P_LOCAL &&
7817 !(parm_table[i].flags & FLAG_META) &&
7818 (*parm_table[i].label != '-') &&
7819 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7821 if (pService == &sDefault) {
7822 if (defaults_saved && is_default(i))
7823 continue;
7824 } else {
7825 if (equal_parameter(parm_table[i].type,
7826 lp_parm_ptr(pService, &parm_table[i]),
7827 lp_parm_ptr(NULL, &parm_table[i])))
7828 continue;
7831 fprintf(f, "\t%s = ", parm_table[i].label);
7832 print_parameter(&parm_table[i],
7833 lp_parm_ptr(pService, &parm_table[i]),
7835 fprintf(f, "\n");
7839 if (pService->param_opt != NULL) {
7840 data = pService->param_opt;
7841 while(data) {
7842 fprintf(f, "\t%s = %s\n", data->key, data->value);
7843 data = data->next;
7848 /***************************************************************************
7849 Display the contents of a parameter of a single services record.
7850 ***************************************************************************/
7852 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7854 int i;
7855 bool result = false;
7856 parm_class p_class;
7857 unsigned flag = 0;
7858 fstring local_parm_name;
7859 char *parm_opt;
7860 const char *parm_opt_value;
7862 /* check for parametrical option */
7863 fstrcpy( local_parm_name, parm_name);
7864 parm_opt = strchr( local_parm_name, ':');
7866 if (parm_opt) {
7867 *parm_opt = '\0';
7868 parm_opt++;
7869 if (strlen(parm_opt)) {
7870 parm_opt_value = lp_parm_const_string( snum,
7871 local_parm_name, parm_opt, NULL);
7872 if (parm_opt_value) {
7873 printf( "%s\n", parm_opt_value);
7874 result = true;
7877 return result;
7880 /* check for a key and print the value */
7881 if (isGlobal) {
7882 p_class = P_GLOBAL;
7883 flag = FLAG_GLOBAL;
7884 } else
7885 p_class = P_LOCAL;
7887 for (i = 0; parm_table[i].label; i++) {
7888 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7889 !(parm_table[i].flags & FLAG_META) &&
7890 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7891 (*parm_table[i].label != '-') &&
7892 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7894 void *ptr;
7896 if (isGlobal) {
7897 ptr = lp_parm_ptr(NULL,
7898 &parm_table[i]);
7899 } else {
7900 ptr = lp_parm_ptr(ServicePtrs[snum],
7901 &parm_table[i]);
7904 print_parameter(&parm_table[i],
7905 ptr, f);
7906 fprintf(f, "\n");
7907 result = true;
7908 break;
7912 return result;
7915 /***************************************************************************
7916 Return info about the requested parameter (given as a string).
7917 Return NULL when the string is not a valid parameter name.
7918 ***************************************************************************/
7920 struct parm_struct *lp_get_parameter(const char *param_name)
7922 int num = map_parameter(param_name);
7924 if (num < 0) {
7925 return NULL;
7928 return &parm_table[num];
7931 /***************************************************************************
7932 Return info about the next parameter in a service.
7933 snum==GLOBAL_SECTION_SNUM gives the globals.
7934 Return NULL when out of parameters.
7935 ***************************************************************************/
7937 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7939 if (snum < 0) {
7940 /* do the globals */
7941 for (; parm_table[*i].label; (*i)++) {
7942 if (parm_table[*i].p_class == P_SEPARATOR)
7943 return &parm_table[(*i)++];
7945 if ((*parm_table[*i].label == '-'))
7946 continue;
7948 if ((*i) > 0
7949 && (parm_table[*i].offset ==
7950 parm_table[(*i) - 1].offset)
7951 && (parm_table[*i].p_class ==
7952 parm_table[(*i) - 1].p_class))
7953 continue;
7955 if (is_default(*i) && !allparameters)
7956 continue;
7958 return &parm_table[(*i)++];
7960 } else {
7961 struct loadparm_service *pService = ServicePtrs[snum];
7963 for (; parm_table[*i].label; (*i)++) {
7964 if (parm_table[*i].p_class == P_SEPARATOR)
7965 return &parm_table[(*i)++];
7967 if (parm_table[*i].p_class == P_LOCAL &&
7968 (*parm_table[*i].label != '-') &&
7969 ((*i) == 0 ||
7970 (parm_table[*i].offset !=
7971 parm_table[(*i) - 1].offset)))
7973 if (allparameters ||
7974 !equal_parameter(parm_table[*i].type,
7975 lp_parm_ptr(pService,
7976 &parm_table[*i]),
7977 lp_parm_ptr(NULL,
7978 &parm_table[*i])))
7980 return &parm_table[(*i)++];
7986 return NULL;
7990 #if 0
7991 /***************************************************************************
7992 Display the contents of a single copy structure.
7993 ***************************************************************************/
7994 static void dump_copy_map(bool *pcopymap)
7996 int i;
7997 if (!pcopymap)
7998 return;
8000 printf("\n\tNon-Copied parameters:\n");
8002 for (i = 0; parm_table[i].label; i++)
8003 if (parm_table[i].p_class == P_LOCAL &&
8004 parm_table[i].ptr && !pcopymap[i] &&
8005 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8007 printf("\t\t%s\n", parm_table[i].label);
8010 #endif
8012 /***************************************************************************
8013 Return TRUE if the passed service number is within range.
8014 ***************************************************************************/
8016 bool lp_snum_ok(int iService)
8018 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8021 /***************************************************************************
8022 Auto-load some home services.
8023 ***************************************************************************/
8025 static void lp_add_auto_services(char *str)
8027 char *s;
8028 char *p;
8029 int homes;
8030 char *saveptr;
8032 if (!str)
8033 return;
8035 s = SMB_STRDUP(str);
8036 if (!s)
8037 return;
8039 homes = lp_servicenumber(HOMES_NAME);
8041 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8042 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8043 char *home;
8045 if (lp_servicenumber(p) >= 0)
8046 continue;
8048 home = get_user_home_dir(talloc_tos(), p);
8050 if (home && home[0] && homes >= 0)
8051 lp_add_home(p, homes, p, home);
8053 TALLOC_FREE(home);
8055 SAFE_FREE(s);
8058 /***************************************************************************
8059 Auto-load one printer.
8060 ***************************************************************************/
8062 void lp_add_one_printer(const char *name, const char *comment,
8063 const char *location, void *pdata)
8065 int printers = lp_servicenumber(PRINTERS_NAME);
8066 int i;
8068 if (lp_servicenumber(name) < 0) {
8069 lp_add_printer(name, printers);
8070 if ((i = lp_servicenumber(name)) >= 0) {
8071 string_set(&ServicePtrs[i]->comment, comment);
8072 ServicePtrs[i]->autoloaded = true;
8077 /***************************************************************************
8078 Have we loaded a services file yet?
8079 ***************************************************************************/
8081 bool lp_loaded(void)
8083 return (bLoaded);
8086 /***************************************************************************
8087 Unload unused services.
8088 ***************************************************************************/
8090 void lp_killunused(struct smbd_server_connection *sconn,
8091 bool (*snumused) (struct smbd_server_connection *, int))
8093 int i;
8094 for (i = 0; i < iNumServices; i++) {
8095 if (!VALID(i))
8096 continue;
8098 /* don't kill autoloaded or usershare services */
8099 if ( ServicePtrs[i]->autoloaded ||
8100 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8101 continue;
8104 if (!snumused || !snumused(sconn, i)) {
8105 free_service_byindex(i);
8111 * Kill all except autoloaded and usershare services - convenience wrapper
8113 void lp_kill_all_services(void)
8115 lp_killunused(NULL, NULL);
8118 /***************************************************************************
8119 Unload a service.
8120 ***************************************************************************/
8122 void lp_killservice(int iServiceIn)
8124 if (VALID(iServiceIn)) {
8125 free_service_byindex(iServiceIn);
8129 /***************************************************************************
8130 Save the curent values of all global and sDefault parameters into the
8131 defaults union. This allows swat and testparm to show only the
8132 changed (ie. non-default) parameters.
8133 ***************************************************************************/
8135 static void lp_save_defaults(void)
8137 int i;
8138 for (i = 0; parm_table[i].label; i++) {
8139 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
8140 && parm_table[i].p_class == parm_table[i - 1].p_class)
8141 continue;
8142 switch (parm_table[i].type) {
8143 case P_LIST:
8144 case P_CMDLIST:
8145 parm_table[i].def.lvalue = str_list_copy(
8146 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8147 break;
8148 case P_STRING:
8149 case P_USTRING:
8150 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8151 break;
8152 case P_BOOL:
8153 case P_BOOLREV:
8154 parm_table[i].def.bvalue =
8155 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8156 break;
8157 case P_CHAR:
8158 parm_table[i].def.cvalue =
8159 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8160 break;
8161 case P_INTEGER:
8162 case P_OCTAL:
8163 case P_ENUM:
8164 case P_BYTES:
8165 parm_table[i].def.ivalue =
8166 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8167 break;
8168 case P_SEP:
8169 break;
8172 defaults_saved = true;
8175 /***********************************************************
8176 If we should send plaintext/LANMAN passwords in the clinet
8177 ************************************************************/
8179 static void set_allowed_client_auth(void)
8181 if (Globals.bClientNTLMv2Auth) {
8182 Globals.bClientLanManAuth = false;
8184 if (!Globals.bClientLanManAuth) {
8185 Globals.bClientPlaintextAuth = false;
8189 /***************************************************************************
8190 JRA.
8191 The following code allows smbd to read a user defined share file.
8192 Yes, this is my intent. Yes, I'm comfortable with that...
8194 THE FOLLOWING IS SECURITY CRITICAL CODE.
8196 It washes your clothes, it cleans your house, it guards you while you sleep...
8197 Do not f%^k with it....
8198 ***************************************************************************/
8200 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8202 /***************************************************************************
8203 Check allowed stat state of a usershare file.
8204 Ensure we print out who is dicking with us so the admin can
8205 get their sorry ass fired.
8206 ***************************************************************************/
8208 static bool check_usershare_stat(const char *fname,
8209 const SMB_STRUCT_STAT *psbuf)
8211 if (!S_ISREG(psbuf->st_ex_mode)) {
8212 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8213 "not a regular file\n",
8214 fname, (unsigned int)psbuf->st_ex_uid ));
8215 return false;
8218 /* Ensure this doesn't have the other write bit set. */
8219 if (psbuf->st_ex_mode & S_IWOTH) {
8220 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8221 "public write. Refusing to allow as a usershare file.\n",
8222 fname, (unsigned int)psbuf->st_ex_uid ));
8223 return false;
8226 /* Should be 10k or less. */
8227 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8228 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8229 "too large (%u) to be a user share file.\n",
8230 fname, (unsigned int)psbuf->st_ex_uid,
8231 (unsigned int)psbuf->st_ex_size ));
8232 return false;
8235 return true;
8238 /***************************************************************************
8239 Parse the contents of a usershare file.
8240 ***************************************************************************/
8242 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8243 SMB_STRUCT_STAT *psbuf,
8244 const char *servicename,
8245 int snum,
8246 char **lines,
8247 int numlines,
8248 char **pp_sharepath,
8249 char **pp_comment,
8250 char **pp_cp_servicename,
8251 struct security_descriptor **ppsd,
8252 bool *pallow_guest)
8254 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8255 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8256 int us_vers;
8257 DIR *dp;
8258 SMB_STRUCT_STAT sbuf;
8259 char *sharepath = NULL;
8260 char *comment = NULL;
8262 *pp_sharepath = NULL;
8263 *pp_comment = NULL;
8265 *pallow_guest = false;
8267 if (numlines < 4) {
8268 return USERSHARE_MALFORMED_FILE;
8271 if (strcmp(lines[0], "#VERSION 1") == 0) {
8272 us_vers = 1;
8273 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8274 us_vers = 2;
8275 if (numlines < 5) {
8276 return USERSHARE_MALFORMED_FILE;
8278 } else {
8279 return USERSHARE_BAD_VERSION;
8282 if (strncmp(lines[1], "path=", 5) != 0) {
8283 return USERSHARE_MALFORMED_PATH;
8286 sharepath = talloc_strdup(ctx, &lines[1][5]);
8287 if (!sharepath) {
8288 return USERSHARE_POSIX_ERR;
8290 trim_string(sharepath, " ", " ");
8292 if (strncmp(lines[2], "comment=", 8) != 0) {
8293 return USERSHARE_MALFORMED_COMMENT_DEF;
8296 comment = talloc_strdup(ctx, &lines[2][8]);
8297 if (!comment) {
8298 return USERSHARE_POSIX_ERR;
8300 trim_string(comment, " ", " ");
8301 trim_char(comment, '"', '"');
8303 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8304 return USERSHARE_MALFORMED_ACL_DEF;
8307 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8308 return USERSHARE_ACL_ERR;
8311 if (us_vers == 2) {
8312 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8313 return USERSHARE_MALFORMED_ACL_DEF;
8315 if (lines[4][9] == 'y') {
8316 *pallow_guest = true;
8319 /* Backwards compatible extension to file version #2. */
8320 if (numlines > 5) {
8321 if (strncmp(lines[5], "sharename=", 10) != 0) {
8322 return USERSHARE_MALFORMED_SHARENAME_DEF;
8324 if (!strequal(&lines[5][10], servicename)) {
8325 return USERSHARE_BAD_SHARENAME;
8327 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8328 if (!*pp_cp_servicename) {
8329 return USERSHARE_POSIX_ERR;
8334 if (*pp_cp_servicename == NULL) {
8335 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8336 if (!*pp_cp_servicename) {
8337 return USERSHARE_POSIX_ERR;
8341 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8342 /* Path didn't change, no checks needed. */
8343 *pp_sharepath = sharepath;
8344 *pp_comment = comment;
8345 return USERSHARE_OK;
8348 /* The path *must* be absolute. */
8349 if (sharepath[0] != '/') {
8350 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8351 servicename, sharepath));
8352 return USERSHARE_PATH_NOT_ABSOLUTE;
8355 /* If there is a usershare prefix deny list ensure one of these paths
8356 doesn't match the start of the user given path. */
8357 if (prefixdenylist) {
8358 int i;
8359 for ( i=0; prefixdenylist[i]; i++ ) {
8360 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8361 servicename, i, prefixdenylist[i], sharepath ));
8362 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8363 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8364 "usershare prefix deny list entries.\n",
8365 servicename, sharepath));
8366 return USERSHARE_PATH_IS_DENIED;
8371 /* If there is a usershare prefix allow list ensure one of these paths
8372 does match the start of the user given path. */
8374 if (prefixallowlist) {
8375 int i;
8376 for ( i=0; prefixallowlist[i]; i++ ) {
8377 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8378 servicename, i, prefixallowlist[i], sharepath ));
8379 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8380 break;
8383 if (prefixallowlist[i] == NULL) {
8384 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8385 "usershare prefix allow list entries.\n",
8386 servicename, sharepath));
8387 return USERSHARE_PATH_NOT_ALLOWED;
8391 /* Ensure this is pointing to a directory. */
8392 dp = opendir(sharepath);
8394 if (!dp) {
8395 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8396 servicename, sharepath));
8397 return USERSHARE_PATH_NOT_DIRECTORY;
8400 /* Ensure the owner of the usershare file has permission to share
8401 this directory. */
8403 if (sys_stat(sharepath, &sbuf, false) == -1) {
8404 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8405 servicename, sharepath, strerror(errno) ));
8406 closedir(dp);
8407 return USERSHARE_POSIX_ERR;
8410 closedir(dp);
8412 if (!S_ISDIR(sbuf.st_ex_mode)) {
8413 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8414 servicename, sharepath ));
8415 return USERSHARE_PATH_NOT_DIRECTORY;
8418 /* Check if sharing is restricted to owner-only. */
8419 /* psbuf is the stat of the usershare definition file,
8420 sbuf is the stat of the target directory to be shared. */
8422 if (lp_usershare_owner_only()) {
8423 /* root can share anything. */
8424 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8425 return USERSHARE_PATH_NOT_ALLOWED;
8429 *pp_sharepath = sharepath;
8430 *pp_comment = comment;
8431 return USERSHARE_OK;
8434 /***************************************************************************
8435 Deal with a usershare file.
8436 Returns:
8437 >= 0 - snum
8438 -1 - Bad name, invalid contents.
8439 - service name already existed and not a usershare, problem
8440 with permissions to share directory etc.
8441 ***************************************************************************/
8443 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8445 SMB_STRUCT_STAT sbuf;
8446 SMB_STRUCT_STAT lsbuf;
8447 char *fname = NULL;
8448 char *sharepath = NULL;
8449 char *comment = NULL;
8450 char *cp_service_name = NULL;
8451 char **lines = NULL;
8452 int numlines = 0;
8453 int fd = -1;
8454 int iService = -1;
8455 TALLOC_CTX *ctx = talloc_stackframe();
8456 struct security_descriptor *psd = NULL;
8457 bool guest_ok = false;
8458 char *canon_name = NULL;
8459 bool added_service = false;
8460 int ret = -1;
8462 /* Ensure share name doesn't contain invalid characters. */
8463 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8464 DEBUG(0,("process_usershare_file: share name %s contains "
8465 "invalid characters (any of %s)\n",
8466 file_name, INVALID_SHARENAME_CHARS ));
8467 goto out;
8470 canon_name = canonicalize_servicename(ctx, file_name);
8471 if (!canon_name) {
8472 goto out;
8475 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8476 if (!fname) {
8477 goto out;
8480 /* Minimize the race condition by doing an lstat before we
8481 open and fstat. Ensure this isn't a symlink link. */
8483 if (sys_lstat(fname, &lsbuf, false) != 0) {
8484 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8485 fname, strerror(errno) ));
8486 goto out;
8489 /* This must be a regular file, not a symlink, directory or
8490 other strange filetype. */
8491 if (!check_usershare_stat(fname, &lsbuf)) {
8492 goto out;
8496 TDB_DATA data;
8497 NTSTATUS status;
8499 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
8500 canon_name, &data);
8502 iService = -1;
8504 if (NT_STATUS_IS_OK(status) &&
8505 (data.dptr != NULL) &&
8506 (data.dsize == sizeof(iService))) {
8507 memcpy(&iService, data.dptr, sizeof(iService));
8511 if (iService != -1 &&
8512 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8513 &lsbuf.st_ex_mtime) == 0) {
8514 /* Nothing changed - Mark valid and return. */
8515 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8516 canon_name ));
8517 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8518 ret = iService;
8519 goto out;
8522 /* Try and open the file read only - no symlinks allowed. */
8523 #ifdef O_NOFOLLOW
8524 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
8525 #else
8526 fd = open(fname, O_RDONLY, 0);
8527 #endif
8529 if (fd == -1) {
8530 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8531 fname, strerror(errno) ));
8532 goto out;
8535 /* Now fstat to be *SURE* it's a regular file. */
8536 if (sys_fstat(fd, &sbuf, false) != 0) {
8537 close(fd);
8538 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8539 fname, strerror(errno) ));
8540 goto out;
8543 /* Is it the same dev/inode as was lstated ? */
8544 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8545 close(fd);
8546 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8547 "Symlink spoofing going on ?\n", fname ));
8548 goto out;
8551 /* This must be a regular file, not a symlink, directory or
8552 other strange filetype. */
8553 if (!check_usershare_stat(fname, &sbuf)) {
8554 goto out;
8557 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8559 close(fd);
8560 if (lines == NULL) {
8561 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8562 fname, (unsigned int)sbuf.st_ex_uid ));
8563 goto out;
8566 if (parse_usershare_file(ctx, &sbuf, file_name,
8567 iService, lines, numlines, &sharepath,
8568 &comment, &cp_service_name,
8569 &psd, &guest_ok) != USERSHARE_OK) {
8570 goto out;
8573 /* Everything ok - add the service possibly using a template. */
8574 if (iService < 0) {
8575 const struct loadparm_service *sp = &sDefault;
8576 if (snum_template != -1) {
8577 sp = ServicePtrs[snum_template];
8580 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8581 DEBUG(0, ("process_usershare_file: Failed to add "
8582 "new service %s\n", cp_service_name));
8583 goto out;
8586 added_service = true;
8588 /* Read only is controlled by usershare ACL below. */
8589 ServicePtrs[iService]->bRead_only = false;
8592 /* Write the ACL of the new/modified share. */
8593 if (!set_share_security(canon_name, psd)) {
8594 DEBUG(0, ("process_usershare_file: Failed to set share "
8595 "security for user share %s\n",
8596 canon_name ));
8597 goto out;
8600 /* If from a template it may be marked invalid. */
8601 ServicePtrs[iService]->valid = true;
8603 /* Set the service as a valid usershare. */
8604 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8606 /* Set guest access. */
8607 if (lp_usershare_allow_guests()) {
8608 ServicePtrs[iService]->bGuest_ok = guest_ok;
8611 /* And note when it was loaded. */
8612 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8613 string_set(&ServicePtrs[iService]->szPath, sharepath);
8614 string_set(&ServicePtrs[iService]->comment, comment);
8616 ret = iService;
8618 out:
8620 if (ret == -1 && iService != -1 && added_service) {
8621 lp_remove_service(iService);
8624 TALLOC_FREE(lines);
8625 TALLOC_FREE(ctx);
8626 return ret;
8629 /***************************************************************************
8630 Checks if a usershare entry has been modified since last load.
8631 ***************************************************************************/
8633 static bool usershare_exists(int iService, struct timespec *last_mod)
8635 SMB_STRUCT_STAT lsbuf;
8636 const char *usersharepath = Globals.szUsersharePath;
8637 char *fname;
8639 if (asprintf(&fname, "%s/%s",
8640 usersharepath,
8641 ServicePtrs[iService]->szService) < 0) {
8642 return false;
8645 if (sys_lstat(fname, &lsbuf, false) != 0) {
8646 SAFE_FREE(fname);
8647 return false;
8650 if (!S_ISREG(lsbuf.st_ex_mode)) {
8651 SAFE_FREE(fname);
8652 return false;
8655 SAFE_FREE(fname);
8656 *last_mod = lsbuf.st_ex_mtime;
8657 return true;
8660 /***************************************************************************
8661 Load a usershare service by name. Returns a valid servicenumber or -1.
8662 ***************************************************************************/
8664 int load_usershare_service(const char *servicename)
8666 SMB_STRUCT_STAT sbuf;
8667 const char *usersharepath = Globals.szUsersharePath;
8668 int max_user_shares = Globals.iUsershareMaxShares;
8669 int snum_template = -1;
8671 if (*usersharepath == 0 || max_user_shares == 0) {
8672 return -1;
8675 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8676 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8677 usersharepath, strerror(errno) ));
8678 return -1;
8681 if (!S_ISDIR(sbuf.st_ex_mode)) {
8682 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8683 usersharepath ));
8684 return -1;
8688 * This directory must be owned by root, and have the 't' bit set.
8689 * It also must not be writable by "other".
8692 #ifdef S_ISVTX
8693 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8694 #else
8695 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8696 #endif
8697 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8698 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8699 usersharepath ));
8700 return -1;
8703 /* Ensure the template share exists if it's set. */
8704 if (Globals.szUsershareTemplateShare[0]) {
8705 /* We can't use lp_servicenumber here as we are recommending that
8706 template shares have -valid=false set. */
8707 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8708 if (ServicePtrs[snum_template]->szService &&
8709 strequal(ServicePtrs[snum_template]->szService,
8710 Globals.szUsershareTemplateShare)) {
8711 break;
8715 if (snum_template == -1) {
8716 DEBUG(0,("load_usershare_service: usershare template share %s "
8717 "does not exist.\n",
8718 Globals.szUsershareTemplateShare ));
8719 return -1;
8723 return process_usershare_file(usersharepath, servicename, snum_template);
8726 /***************************************************************************
8727 Load all user defined shares from the user share directory.
8728 We only do this if we're enumerating the share list.
8729 This is the function that can delete usershares that have
8730 been removed.
8731 ***************************************************************************/
8733 int load_usershare_shares(struct smbd_server_connection *sconn,
8734 bool (*snumused) (struct smbd_server_connection *, int))
8736 DIR *dp;
8737 SMB_STRUCT_STAT sbuf;
8738 struct dirent *de;
8739 int num_usershares = 0;
8740 int max_user_shares = Globals.iUsershareMaxShares;
8741 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8742 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8743 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8744 int iService;
8745 int snum_template = -1;
8746 const char *usersharepath = Globals.szUsersharePath;
8747 int ret = lp_numservices();
8749 if (max_user_shares == 0 || *usersharepath == '\0') {
8750 return lp_numservices();
8753 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8754 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8755 usersharepath, strerror(errno) ));
8756 return ret;
8760 * This directory must be owned by root, and have the 't' bit set.
8761 * It also must not be writable by "other".
8764 #ifdef S_ISVTX
8765 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8766 #else
8767 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8768 #endif
8769 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8770 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8771 usersharepath ));
8772 return ret;
8775 /* Ensure the template share exists if it's set. */
8776 if (Globals.szUsershareTemplateShare[0]) {
8777 /* We can't use lp_servicenumber here as we are recommending that
8778 template shares have -valid=false set. */
8779 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8780 if (ServicePtrs[snum_template]->szService &&
8781 strequal(ServicePtrs[snum_template]->szService,
8782 Globals.szUsershareTemplateShare)) {
8783 break;
8787 if (snum_template == -1) {
8788 DEBUG(0,("load_usershare_shares: usershare template share %s "
8789 "does not exist.\n",
8790 Globals.szUsershareTemplateShare ));
8791 return ret;
8795 /* Mark all existing usershares as pending delete. */
8796 for (iService = iNumServices - 1; iService >= 0; iService--) {
8797 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8798 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8802 dp = opendir(usersharepath);
8803 if (!dp) {
8804 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8805 usersharepath, strerror(errno) ));
8806 return ret;
8809 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8810 (de = readdir(dp));
8811 num_dir_entries++ ) {
8812 int r;
8813 const char *n = de->d_name;
8815 /* Ignore . and .. */
8816 if (*n == '.') {
8817 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8818 continue;
8822 if (n[0] == ':') {
8823 /* Temporary file used when creating a share. */
8824 num_tmp_dir_entries++;
8827 /* Allow 20% tmp entries. */
8828 if (num_tmp_dir_entries > allowed_tmp_entries) {
8829 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8830 "in directory %s\n",
8831 num_tmp_dir_entries, usersharepath));
8832 break;
8835 r = process_usershare_file(usersharepath, n, snum_template);
8836 if (r == 0) {
8837 /* Update the services count. */
8838 num_usershares++;
8839 if (num_usershares >= max_user_shares) {
8840 DEBUG(0,("load_usershare_shares: max user shares reached "
8841 "on file %s in directory %s\n",
8842 n, usersharepath ));
8843 break;
8845 } else if (r == -1) {
8846 num_bad_dir_entries++;
8849 /* Allow 20% bad entries. */
8850 if (num_bad_dir_entries > allowed_bad_entries) {
8851 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8852 "in directory %s\n",
8853 num_bad_dir_entries, usersharepath));
8854 break;
8857 /* Allow 20% bad entries. */
8858 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8859 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8860 "in directory %s\n",
8861 num_dir_entries, usersharepath));
8862 break;
8866 closedir(dp);
8868 /* Sweep through and delete any non-refreshed usershares that are
8869 not currently in use. */
8870 for (iService = iNumServices - 1; iService >= 0; iService--) {
8871 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8872 if (snumused && snumused(sconn, iService)) {
8873 continue;
8875 /* Remove from the share ACL db. */
8876 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8877 lp_servicename(iService) ));
8878 delete_share_security(lp_servicename(iService));
8879 free_service_byindex(iService);
8883 return lp_numservices();
8886 /********************************************************
8887 Destroy global resources allocated in this file
8888 ********************************************************/
8890 void gfree_loadparm(void)
8892 int i;
8894 free_file_list();
8896 /* Free resources allocated to services */
8898 for ( i = 0; i < iNumServices; i++ ) {
8899 if ( VALID(i) ) {
8900 free_service_byindex(i);
8904 SAFE_FREE( ServicePtrs );
8905 iNumServices = 0;
8907 /* Now release all resources allocated to global
8908 parameters and the default service */
8910 free_global_parameters();
8914 /***************************************************************************
8915 Allow client apps to specify that they are a client
8916 ***************************************************************************/
8917 static void lp_set_in_client(bool b)
8919 in_client = b;
8923 /***************************************************************************
8924 Determine if we're running in a client app
8925 ***************************************************************************/
8926 static bool lp_is_in_client(void)
8928 return in_client;
8931 /***************************************************************************
8932 Load the services array from the services file. Return true on success,
8933 false on failure.
8934 ***************************************************************************/
8936 static bool lp_load_ex(const char *pszFname,
8937 bool global_only,
8938 bool save_defaults,
8939 bool add_ipc,
8940 bool initialize_globals,
8941 bool allow_include_registry,
8942 bool load_all_shares)
8944 char *n2 = NULL;
8945 bool bRetval;
8947 bRetval = false;
8949 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8951 bInGlobalSection = true;
8952 bGlobalOnly = global_only;
8953 bAllowIncludeRegistry = allow_include_registry;
8955 init_globals(initialize_globals);
8957 free_file_list();
8959 if (save_defaults) {
8960 init_locals();
8961 lp_save_defaults();
8964 if (!initialize_globals) {
8965 free_param_opts(&Globals.param_opt);
8966 apply_lp_set_cmdline();
8969 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
8971 /* We get sections first, so have to start 'behind' to make up */
8972 iServiceIndex = -1;
8974 if (lp_config_backend_is_file()) {
8975 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
8976 current_user_info.domain,
8977 pszFname);
8978 if (!n2) {
8979 smb_panic("lp_load_ex: out of memory");
8982 add_to_file_list(pszFname, n2);
8984 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8985 TALLOC_FREE(n2);
8987 /* finish up the last section */
8988 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8989 if (bRetval) {
8990 if (iServiceIndex >= 0) {
8991 bRetval = service_ok(iServiceIndex);
8995 if (lp_config_backend_is_registry()) {
8996 /* config backend changed to registry in config file */
8998 * We need to use this extra global variable here to
8999 * survive restart: init_globals uses this as a default
9000 * for ConfigBackend. Otherwise, init_globals would
9001 * send us into an endless loop here.
9003 config_backend = CONFIG_BACKEND_REGISTRY;
9004 /* start over */
9005 DEBUG(1, ("lp_load_ex: changing to config backend "
9006 "registry\n"));
9007 init_globals(true);
9008 lp_kill_all_services();
9009 return lp_load_ex(pszFname, global_only, save_defaults,
9010 add_ipc, initialize_globals,
9011 allow_include_registry,
9012 load_all_shares);
9014 } else if (lp_config_backend_is_registry()) {
9015 bRetval = process_registry_globals();
9016 } else {
9017 DEBUG(0, ("Illegal config backend given: %d\n",
9018 lp_config_backend()));
9019 bRetval = false;
9022 if (bRetval && lp_registry_shares()) {
9023 if (load_all_shares) {
9024 bRetval = process_registry_shares();
9025 } else {
9026 bRetval = reload_registry_shares();
9030 lp_add_auto_services(lp_auto_services());
9032 if (add_ipc) {
9033 /* When 'restrict anonymous = 2' guest connections to ipc$
9034 are denied */
9035 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9036 if ( lp_enable_asu_support() ) {
9037 lp_add_ipc("ADMIN$", false);
9041 set_allowed_client_auth();
9043 if (lp_security() == SEC_SERVER) {
9044 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9047 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9048 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9049 lp_passwordserver()));
9052 bLoaded = true;
9054 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9055 /* if bWINSsupport is true and we are in the client */
9056 if (lp_is_in_client() && Globals.bWINSsupport) {
9057 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9060 init_iconv();
9062 fault_configure(smb_panic_s3);
9064 bAllowIncludeRegistry = true;
9066 return (bRetval);
9069 bool lp_load(const char *pszFname,
9070 bool global_only,
9071 bool save_defaults,
9072 bool add_ipc,
9073 bool initialize_globals)
9075 return lp_load_ex(pszFname,
9076 global_only,
9077 save_defaults,
9078 add_ipc,
9079 initialize_globals,
9080 true, /* allow_include_registry */
9081 false); /* load_all_shares*/
9084 bool lp_load_initial_only(const char *pszFname)
9086 return lp_load_ex(pszFname,
9087 true, /* global only */
9088 false, /* save_defaults */
9089 false, /* add_ipc */
9090 true, /* initialize_globals */
9091 false, /* allow_include_registry */
9092 false); /* load_all_shares*/
9096 * most common lp_load wrapper, loading only the globals
9098 bool lp_load_global(const char *file_name)
9100 return lp_load_ex(file_name,
9101 true, /* global_only */
9102 false, /* save_defaults */
9103 false, /* add_ipc */
9104 true, /* initialize_globals */
9105 true, /* allow_include_registry */
9106 false); /* load_all_shares*/
9110 * lp_load wrapper, especially for clients
9112 bool lp_load_client(const char *file_name)
9114 lp_set_in_client(true);
9116 return lp_load_global(file_name);
9120 * lp_load wrapper, loading only globals, but intended
9121 * for subsequent calls, not reinitializing the globals
9122 * to default values
9124 bool lp_load_global_no_reinit(const char *file_name)
9126 return lp_load_ex(file_name,
9127 true, /* global_only */
9128 false, /* save_defaults */
9129 false, /* add_ipc */
9130 false, /* initialize_globals */
9131 true, /* allow_include_registry */
9132 false); /* load_all_shares*/
9136 * lp_load wrapper, especially for clients, no reinitialization
9138 bool lp_load_client_no_reinit(const char *file_name)
9140 lp_set_in_client(true);
9142 return lp_load_global_no_reinit(file_name);
9145 bool lp_load_with_registry_shares(const char *pszFname,
9146 bool global_only,
9147 bool save_defaults,
9148 bool add_ipc,
9149 bool initialize_globals)
9151 return lp_load_ex(pszFname,
9152 global_only,
9153 save_defaults,
9154 add_ipc,
9155 initialize_globals,
9156 true, /* allow_include_registry */
9157 true); /* load_all_shares*/
9160 /***************************************************************************
9161 Return the max number of services.
9162 ***************************************************************************/
9164 int lp_numservices(void)
9166 return (iNumServices);
9169 /***************************************************************************
9170 Display the contents of the services array in human-readable form.
9171 ***************************************************************************/
9173 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9175 int iService;
9177 if (show_defaults)
9178 defaults_saved = false;
9180 dump_globals(f);
9182 dump_a_service(&sDefault, f);
9184 for (iService = 0; iService < maxtoprint; iService++) {
9185 fprintf(f,"\n");
9186 lp_dump_one(f, show_defaults, iService);
9190 /***************************************************************************
9191 Display the contents of one service in human-readable form.
9192 ***************************************************************************/
9194 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9196 if (VALID(snum)) {
9197 if (ServicePtrs[snum]->szService[0] == '\0')
9198 return;
9199 dump_a_service(ServicePtrs[snum], f);
9203 /***************************************************************************
9204 Return the number of the service with the given name, or -1 if it doesn't
9205 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9206 getservicebyname()! This works ONLY if all services have been loaded, and
9207 does not copy the found service.
9208 ***************************************************************************/
9210 int lp_servicenumber(const char *pszServiceName)
9212 int iService;
9213 fstring serviceName;
9215 if (!pszServiceName) {
9216 return GLOBAL_SECTION_SNUM;
9219 for (iService = iNumServices - 1; iService >= 0; iService--) {
9220 if (VALID(iService) && ServicePtrs[iService]->szService) {
9222 * The substitution here is used to support %U is
9223 * service names
9225 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9226 standard_sub_basic(get_current_username(),
9227 current_user_info.domain,
9228 serviceName,sizeof(serviceName));
9229 if (strequal(serviceName, pszServiceName)) {
9230 break;
9235 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9236 struct timespec last_mod;
9238 if (!usershare_exists(iService, &last_mod)) {
9239 /* Remove the share security tdb entry for it. */
9240 delete_share_security(lp_servicename(iService));
9241 /* Remove it from the array. */
9242 free_service_byindex(iService);
9243 /* Doesn't exist anymore. */
9244 return GLOBAL_SECTION_SNUM;
9247 /* Has it been modified ? If so delete and reload. */
9248 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9249 &last_mod) < 0) {
9250 /* Remove it from the array. */
9251 free_service_byindex(iService);
9252 /* and now reload it. */
9253 iService = load_usershare_service(pszServiceName);
9257 if (iService < 0) {
9258 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9259 return GLOBAL_SECTION_SNUM;
9262 return (iService);
9265 /*******************************************************************
9266 A useful volume label function.
9267 ********************************************************************/
9269 const char *volume_label(int snum)
9271 char *ret;
9272 const char *label = lp_volume(snum);
9273 if (!*label) {
9274 label = lp_servicename(snum);
9277 /* This returns a 33 byte guarenteed null terminated string. */
9278 ret = talloc_strndup(talloc_tos(), label, 32);
9279 if (!ret) {
9280 return "";
9282 return ret;
9285 /*******************************************************************
9286 Get the default server type we will announce as via nmbd.
9287 ********************************************************************/
9289 int lp_default_server_announce(void)
9291 int default_server_announce = 0;
9292 default_server_announce |= SV_TYPE_WORKSTATION;
9293 default_server_announce |= SV_TYPE_SERVER;
9294 default_server_announce |= SV_TYPE_SERVER_UNIX;
9296 /* note that the flag should be set only if we have a
9297 printer service but nmbd doesn't actually load the
9298 services so we can't tell --jerry */
9300 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9302 default_server_announce |= SV_TYPE_SERVER_NT;
9303 default_server_announce |= SV_TYPE_NT;
9305 switch (lp_server_role()) {
9306 case ROLE_DOMAIN_MEMBER:
9307 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9308 break;
9309 case ROLE_DOMAIN_PDC:
9310 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9311 break;
9312 case ROLE_DOMAIN_BDC:
9313 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9314 break;
9315 case ROLE_STANDALONE:
9316 default:
9317 break;
9319 if (lp_time_server())
9320 default_server_announce |= SV_TYPE_TIME_SOURCE;
9322 if (lp_host_msdfs())
9323 default_server_announce |= SV_TYPE_DFS_SERVER;
9325 return default_server_announce;
9328 /***********************************************************
9329 If we are PDC then prefer us as DMB
9330 ************************************************************/
9332 bool lp_domain_master(void)
9334 if (Globals.iDomainMaster == Auto)
9335 return (lp_server_role() == ROLE_DOMAIN_PDC);
9337 return (bool)Globals.iDomainMaster;
9340 /***********************************************************
9341 If we are PDC then prefer us as DMB
9342 ************************************************************/
9344 static bool lp_domain_master_true_or_auto(void)
9346 if (Globals.iDomainMaster) /* auto or yes */
9347 return true;
9349 return false;
9352 /***********************************************************
9353 If we are DMB then prefer us as LMB
9354 ************************************************************/
9356 bool lp_preferred_master(void)
9358 if (Globals.iPreferredMaster == Auto)
9359 return (lp_local_master() && lp_domain_master());
9361 return (bool)Globals.iPreferredMaster;
9364 /*******************************************************************
9365 Remove a service.
9366 ********************************************************************/
9368 void lp_remove_service(int snum)
9370 ServicePtrs[snum]->valid = false;
9371 invalid_services[num_invalid_services++] = snum;
9374 /*******************************************************************
9375 Copy a service.
9376 ********************************************************************/
9378 void lp_copy_service(int snum, const char *new_name)
9380 do_section(new_name, NULL);
9381 if (snum >= 0) {
9382 snum = lp_servicenumber(new_name);
9383 if (snum >= 0)
9384 lp_do_parameter(snum, "copy", lp_servicename(snum));
9389 /***********************************************************
9390 Set the global name resolution order (used in smbclient).
9391 ************************************************************/
9393 void lp_set_name_resolve_order(const char *new_order)
9395 string_set(&Globals.szNameResolveOrder, new_order);
9398 const char *lp_printername(int snum)
9400 const char *ret = lp__printername(snum);
9401 if (ret == NULL || (ret != NULL && *ret == '\0'))
9402 ret = lp_const_servicename(snum);
9404 return ret;
9408 /***********************************************************
9409 Allow daemons such as winbindd to fix their logfile name.
9410 ************************************************************/
9412 void lp_set_logfile(const char *name)
9414 string_set(&Globals.logfile, name);
9415 debug_set_logfile(name);
9418 /*******************************************************************
9419 Return the max print jobs per queue.
9420 ********************************************************************/
9422 int lp_maxprintjobs(int snum)
9424 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9425 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9426 maxjobs = PRINT_MAX_JOBID - 1;
9428 return maxjobs;
9431 const char *lp_printcapname(void)
9433 if ((Globals.szPrintcapname != NULL) &&
9434 (Globals.szPrintcapname[0] != '\0'))
9435 return Globals.szPrintcapname;
9437 if (sDefault.iPrinting == PRINT_CUPS) {
9438 #ifdef HAVE_CUPS
9439 return "cups";
9440 #else
9441 return "lpstat";
9442 #endif
9445 if (sDefault.iPrinting == PRINT_BSD)
9446 return "/etc/printcap";
9448 return PRINTCAP_NAME;
9451 static uint32 spoolss_state;
9453 bool lp_disable_spoolss( void )
9455 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9456 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9458 return spoolss_state == SVCCTL_STOPPED ? true : false;
9461 void lp_set_spoolss_state( uint32 state )
9463 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9465 spoolss_state = state;
9468 uint32 lp_get_spoolss_state( void )
9470 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9473 /*******************************************************************
9474 Ensure we don't use sendfile if server smb signing is active.
9475 ********************************************************************/
9477 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9479 bool sign_active = false;
9481 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9482 if (get_Protocol() < PROTOCOL_NT1) {
9483 return false;
9485 if (signing_state) {
9486 sign_active = smb_signing_is_active(signing_state);
9488 return (lp__use_sendfile(snum) &&
9489 (get_remote_arch() != RA_WIN95) &&
9490 !sign_active);
9493 /*******************************************************************
9494 Turn off sendfile if we find the underlying OS doesn't support it.
9495 ********************************************************************/
9497 void set_use_sendfile(int snum, bool val)
9499 if (LP_SNUM_OK(snum))
9500 ServicePtrs[snum]->bUseSendfile = val;
9501 else
9502 sDefault.bUseSendfile = val;
9505 /*******************************************************************
9506 Turn off storing DOS attributes if this share doesn't support it.
9507 ********************************************************************/
9509 void set_store_dos_attributes(int snum, bool val)
9511 if (!LP_SNUM_OK(snum))
9512 return;
9513 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9516 void lp_set_mangling_method(const char *new_method)
9518 string_set(&Globals.szManglingMethod, new_method);
9521 /*******************************************************************
9522 Global state for POSIX pathname processing.
9523 ********************************************************************/
9525 static bool posix_pathnames;
9527 bool lp_posix_pathnames(void)
9529 return posix_pathnames;
9532 /*******************************************************************
9533 Change everything needed to ensure POSIX pathname processing (currently
9534 not much).
9535 ********************************************************************/
9537 void lp_set_posix_pathnames(void)
9539 posix_pathnames = true;
9542 /*******************************************************************
9543 Global state for POSIX lock processing - CIFS unix extensions.
9544 ********************************************************************/
9546 bool posix_default_lock_was_set;
9547 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9549 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9551 if (posix_default_lock_was_set) {
9552 return posix_cifsx_locktype;
9553 } else {
9554 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9558 /*******************************************************************
9559 ********************************************************************/
9561 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9563 posix_default_lock_was_set = true;
9564 posix_cifsx_locktype = val;
9567 int lp_min_receive_file_size(void)
9569 if (Globals.iminreceivefile < 0) {
9570 return 0;
9572 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9575 /*******************************************************************
9576 If socket address is an empty character string, it is necessary to
9577 define it as "0.0.0.0".
9578 ********************************************************************/
9580 const char *lp_socket_address(void)
9582 char *sock_addr = Globals.szSocketAddress;
9584 if (sock_addr[0] == '\0'){
9585 string_set(&Globals.szSocketAddress, "0.0.0.0");
9587 return Globals.szSocketAddress;
9590 /*******************************************************************
9591 Safe wide links checks.
9592 This helper function always verify the validity of wide links,
9593 even after a configuration file reload.
9594 ********************************************************************/
9596 static bool lp_widelinks_internal(int snum)
9598 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9599 sDefault.bWidelinks);
9602 void widelinks_warning(int snum)
9604 if (lp_allow_insecure_widelinks()) {
9605 return;
9608 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9609 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9610 "These parameters are incompatible. "
9611 "Wide links will be disabled for this share.\n",
9612 lp_servicename(snum) ));
9616 bool lp_widelinks(int snum)
9618 /* wide links is always incompatible with unix extensions */
9619 if (lp_unix_extensions()) {
9621 * Unless we have "allow insecure widelinks"
9622 * turned on.
9624 if (!lp_allow_insecure_widelinks()) {
9625 return false;
9629 return lp_widelinks_internal(snum);
9632 bool lp_writeraw(void)
9634 if (lp_async_smb_echo_handler()) {
9635 return false;
9637 return lp__writeraw();
9640 bool lp_readraw(void)
9642 if (lp_async_smb_echo_handler()) {
9643 return false;
9645 return lp__readraw();
9648 int lp_server_role(void)
9650 return lp_find_server_role(lp__server_role(),
9651 lp_security(),
9652 lp_domain_logons(),
9653 lp_domain_master_true_or_auto());
9656 const char *lp_ctdbd_socket(void)
9658 const char *result = lp__ctdbd_socket();
9660 #ifdef CLUSTER_SUPPORT
9661 if ((result == NULL) || (*result == '\0')) {
9662 return CTDB_PATH;
9664 #endif
9665 return result;