s3-param: Merge "log file" parameter with lib/param
[Samba.git] / source3 / param / loadparm.c
blob0891eeb40a7ffd64305916d72afd9718e5aafa51
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 "lib/param/loadparm.h"
60 #include "printing.h"
61 #include "lib/smbconf/smbconf.h"
62 #include "lib/smbconf/smbconf_init.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 static int config_backend = CONFIG_BACKEND_FILE;
102 /* some helpful bits */
103 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
104 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
106 #define USERSHARE_VALID 1
107 #define USERSHARE_PENDING_DELETE 2
109 static bool defaults_saved = false;
111 #define LOADPARM_EXTRA_GLOBALS \
112 struct parmlist_entry *param_opt; \
113 char *szRealm; \
114 char *loglevel; \
115 int iminreceivefile; \
116 char *szPrintcapname; \
117 int CupsEncrypt; \
118 int iPreferredMaster; \
119 char *szLdapMachineSuffix; \
120 char *szLdapUserSuffix; \
121 char *szLdapIdmapSuffix; \
122 char *szLdapGroupSuffix; \
123 char *szStateDir; \
124 char *szCacheDir; \
125 char *szSocketAddress; \
126 char *szUsershareTemplateShare; \
127 char *szIdmapUID; \
128 char *szIdmapGID; \
129 int winbindMaxDomainConnections; \
130 int ismb2_max_credits; \
131 char *tls_keyfile; \
132 char *tls_certfile; \
133 char *tls_cafile; \
134 char *tls_crlfile; \
135 char *tls_dhpfile; \
136 char *panic_action; \
137 int bPreferredMaster;
139 #include "param/param_global.h"
141 static struct loadparm_global Globals;
143 /* This is a default service used to prime a services structure */
144 static struct loadparm_service sDefault =
146 .valid = true,
147 .autoloaded = false,
148 .usershare = 0,
149 .usershare_last_mod = {0, 0},
150 .szService = NULL,
151 .szPath = NULL,
152 .szUsername = NULL,
153 .szInvalidUsers = NULL,
154 .szValidUsers = NULL,
155 .szAdminUsers = NULL,
156 .szCopy = NULL,
157 .szInclude = NULL,
158 .szPreExec = NULL,
159 .szPostExec = NULL,
160 .szRootPreExec = NULL,
161 .szRootPostExec = NULL,
162 .szCupsOptions = NULL,
163 .szPrintcommand = NULL,
164 .szLpqcommand = NULL,
165 .szLprmcommand = NULL,
166 .szLppausecommand = NULL,
167 .szLpresumecommand = NULL,
168 .szQueuepausecommand = NULL,
169 .szQueueresumecommand = NULL,
170 .szPrintername = NULL,
171 .szPrintjobUsername = NULL,
172 .szDontdescend = NULL,
173 .szHostsallow = NULL,
174 .szHostsdeny = NULL,
175 .szMagicScript = NULL,
176 .szMagicOutput = NULL,
177 .szVetoFiles = NULL,
178 .szHideFiles = NULL,
179 .szVetoOplockFiles = NULL,
180 .comment = NULL,
181 .force_user = NULL,
182 .force_group = NULL,
183 .readlist = NULL,
184 .writelist = NULL,
185 .volume = NULL,
186 .fstype = NULL,
187 .szVfsObjects = NULL,
188 .szMSDfsProxy = NULL,
189 .szAioWriteBehind = NULL,
190 .szDfree = NULL,
191 .iMinPrintSpace = 0,
192 .iMaxPrintJobs = 1000,
193 .iMaxReportedPrintJobs = 0,
194 .iWriteCacheSize = 0,
195 .iCreate_mask = 0744,
196 .iCreate_force_mode = 0,
197 .iSecurity_mask = 0777,
198 .iSecurity_force_mode = 0,
199 .iDir_mask = 0755,
200 .iDir_force_mode = 0,
201 .iDir_Security_mask = 0777,
202 .iDir_Security_force_mode = 0,
203 .iMaxConnections = 0,
204 .iDefaultCase = CASE_LOWER,
205 .iPrinting = DEFAULT_PRINTING,
206 .iOplockContentionLimit = 2,
207 .iCSCPolicy = 0,
208 .iBlock_size = 1024,
209 .iDfreeCacheTime = 0,
210 .bPreexecClose = false,
211 .bRootpreexecClose = false,
212 .iCaseSensitive = Auto,
213 .bCasePreserve = true,
214 .bShortCasePreserve = true,
215 .bHideDotFiles = true,
216 .bHideSpecialFiles = false,
217 .bHideUnReadable = false,
218 .bHideUnWriteableFiles = false,
219 .bBrowseable = true,
220 .bAccessBasedShareEnum = false,
221 .bAvailable = true,
222 .bRead_only = true,
223 .bNo_set_dir = true,
224 .bGuest_only = false,
225 .bAdministrative_share = false,
226 .bGuest_ok = false,
227 .bPrint_ok = false,
228 .bPrintNotifyBackchannel = true,
229 .bMap_system = false,
230 .bMap_hidden = false,
231 .bMap_archive = true,
232 .bStoreDosAttributes = false,
233 .bDmapiSupport = false,
234 .bLocking = true,
235 .iStrictLocking = Auto,
236 .bPosixLocking = true,
237 .bShareModes = true,
238 .bOpLocks = true,
239 .bKernelOplocks = false,
240 .bLevel2OpLocks = true,
241 .bOnlyUser = false,
242 .bMangledNames = true,
243 .bWidelinks = false,
244 .bSymlinks = true,
245 .bSyncAlways = false,
246 .bStrictAllocate = false,
247 .bStrictSync = false,
248 .magic_char = '~',
249 .copymap = NULL,
250 .bDeleteReadonly = false,
251 .bFakeOplocks = false,
252 .bDeleteVetoFiles = false,
253 .bDosFilemode = false,
254 .bDosFiletimes = true,
255 .bDosFiletimeResolution = false,
256 .bFakeDirCreateTimes = false,
257 .bBlockingLocks = true,
258 .bInheritPerms = false,
259 .bInheritACLS = false,
260 .bInheritOwner = false,
261 .bMSDfsRoot = false,
262 .bUseClientDriver = false,
263 .bDefaultDevmode = true,
264 .bForcePrintername = false,
265 .bNTAclSupport = true,
266 .bForceUnknownAclUser = false,
267 .bUseSendfile = false,
268 .bProfileAcls = false,
269 .bMap_acl_inherit = false,
270 .bAfs_Share = false,
271 .bEASupport = false,
272 .bAclCheckPermissions = true,
273 .bAclMapFullControl = true,
274 .bAclGroupControl = false,
275 .bChangeNotify = true,
276 .bKernelChangeNotify = true,
277 .iallocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
278 .iAioReadSize = 0,
279 .iAioWriteSize = 0,
280 .iMap_readonly = MAP_READONLY_YES,
281 #ifdef BROKEN_DIRECTORY_HANDLING
282 .iDirectoryNameCacheSize = 0,
283 #else
284 .iDirectoryNameCacheSize = 100,
285 #endif
286 .ismb_encrypt = Auto,
287 .param_opt = NULL,
288 .dummy = ""
291 /* local variables */
292 static struct loadparm_service **ServicePtrs = NULL;
293 static int iNumServices = 0;
294 static int iServiceIndex = 0;
295 static struct db_context *ServiceHash;
296 static int *invalid_services = NULL;
297 static int num_invalid_services = 0;
298 static bool bInGlobalSection = true;
299 static bool bGlobalOnly = false;
301 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
303 /* prototypes for the special type handlers */
304 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
305 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
306 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
307 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
308 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
309 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
310 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
311 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
312 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
313 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
314 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
315 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
317 /* these are parameter handlers which are not needed in the
318 * source3 code
321 #define handle_logfile NULL
323 static void set_allowed_client_auth(void);
325 static void add_to_file_list(const char *fname, const char *subfname);
326 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
327 static void free_param_opts(struct parmlist_entry **popts);
329 #include "lib/param/param_table.c"
331 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
333 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
334 * screen in SWAT. This is used to exclude parameters as well as to squash all
335 * parameters that have been duplicated by pseudonyms.
337 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
338 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
339 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
340 * respective views.
342 * NOTE2: Handling of duplicated (synonym) parameters:
343 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
344 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
345 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
346 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
349 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
350 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
353 static struct parm_struct parm_table[] = {
354 {N_("Base Options"), P_SEP, P_SEPARATOR},
357 .label = "dos charset",
358 .type = P_STRING,
359 .p_class = P_GLOBAL,
360 .offset = GLOBAL_VAR(dos_charset),
361 .special = handle_dos_charset,
362 .enum_list = NULL,
363 .flags = FLAG_ADVANCED
366 .label = "unix charset",
367 .type = P_STRING,
368 .p_class = P_GLOBAL,
369 .offset = GLOBAL_VAR(unix_charset),
370 .special = handle_charset,
371 .enum_list = NULL,
372 .flags = FLAG_ADVANCED
375 .label = "comment",
376 .type = P_STRING,
377 .p_class = P_LOCAL,
378 .offset = LOCAL_VAR(comment),
379 .special = NULL,
380 .enum_list = NULL,
381 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
384 .label = "path",
385 .type = P_STRING,
386 .p_class = P_LOCAL,
387 .offset = LOCAL_VAR(szPath),
388 .special = NULL,
389 .enum_list = NULL,
390 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
393 .label = "directory",
394 .type = P_STRING,
395 .p_class = P_LOCAL,
396 .offset = LOCAL_VAR(szPath),
397 .special = NULL,
398 .enum_list = NULL,
399 .flags = FLAG_HIDE,
402 .label = "workgroup",
403 .type = P_USTRING,
404 .p_class = P_GLOBAL,
405 .offset = GLOBAL_VAR(szWorkgroup),
406 .special = NULL,
407 .enum_list = NULL,
408 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
411 .label = "realm",
412 .type = P_STRING,
413 .p_class = P_GLOBAL,
414 .offset = GLOBAL_VAR(szRealm),
415 .special = handle_realm,
416 .enum_list = NULL,
417 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
420 .label = "netbios name",
421 .type = P_USTRING,
422 .p_class = P_GLOBAL,
423 .offset = GLOBAL_VAR(szNetbiosName),
424 .special = NULL,
425 .enum_list = NULL,
426 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
429 .label = "netbios aliases",
430 .type = P_LIST,
431 .p_class = P_GLOBAL,
432 .offset = GLOBAL_VAR(szNetbiosAliases),
433 .special = handle_netbios_aliases,
434 .enum_list = NULL,
435 .flags = FLAG_ADVANCED,
438 .label = "netbios scope",
439 .type = P_USTRING,
440 .p_class = P_GLOBAL,
441 .offset = GLOBAL_VAR(szNetbiosScope),
442 .special = NULL,
443 .enum_list = NULL,
444 .flags = FLAG_ADVANCED,
447 .label = "server string",
448 .type = P_STRING,
449 .p_class = P_GLOBAL,
450 .offset = GLOBAL_VAR(szServerString),
451 .special = NULL,
452 .enum_list = NULL,
453 .flags = FLAG_BASIC | FLAG_ADVANCED,
456 .label = "interfaces",
457 .type = P_LIST,
458 .p_class = P_GLOBAL,
459 .offset = GLOBAL_VAR(szInterfaces),
460 .special = NULL,
461 .enum_list = NULL,
462 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
465 .label = "bind interfaces only",
466 .type = P_BOOL,
467 .p_class = P_GLOBAL,
468 .offset = GLOBAL_VAR(bBindInterfacesOnly),
469 .special = NULL,
470 .enum_list = NULL,
471 .flags = FLAG_ADVANCED | FLAG_WIZARD,
474 .label = "config backend",
475 .type = P_ENUM,
476 .p_class = P_GLOBAL,
477 .offset = GLOBAL_VAR(ConfigBackend),
478 .special = NULL,
479 .enum_list = enum_config_backend,
480 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
483 .label = "server role",
484 .type = P_ENUM,
485 .p_class = P_GLOBAL,
486 .offset = GLOBAL_VAR(server_role),
487 .special = NULL,
488 .enum_list = enum_server_role,
489 .flags = FLAG_BASIC | FLAG_ADVANCED,
492 {N_("Security Options"), P_SEP, P_SEPARATOR},
495 .label = "security",
496 .type = P_ENUM,
497 .p_class = P_GLOBAL,
498 .offset = GLOBAL_VAR(security),
499 .special = NULL,
500 .enum_list = enum_security,
501 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
504 .label = "auth methods",
505 .type = P_LIST,
506 .p_class = P_GLOBAL,
507 .offset = GLOBAL_VAR(AuthMethods),
508 .special = NULL,
509 .enum_list = NULL,
510 .flags = FLAG_ADVANCED,
513 .label = "encrypt passwords",
514 .type = P_BOOL,
515 .p_class = P_GLOBAL,
516 .offset = GLOBAL_VAR(bEncryptPasswords),
517 .special = NULL,
518 .enum_list = NULL,
519 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
522 .label = "client schannel",
523 .type = P_ENUM,
524 .p_class = P_GLOBAL,
525 .offset = GLOBAL_VAR(clientSchannel),
526 .special = NULL,
527 .enum_list = enum_bool_auto,
528 .flags = FLAG_BASIC | FLAG_ADVANCED,
531 .label = "server schannel",
532 .type = P_ENUM,
533 .p_class = P_GLOBAL,
534 .offset = GLOBAL_VAR(serverSchannel),
535 .special = NULL,
536 .enum_list = enum_bool_auto,
537 .flags = FLAG_BASIC | FLAG_ADVANCED,
540 .label = "allow trusted domains",
541 .type = P_BOOL,
542 .p_class = P_GLOBAL,
543 .offset = GLOBAL_VAR(bAllowTrustedDomains),
544 .special = NULL,
545 .enum_list = NULL,
546 .flags = FLAG_ADVANCED,
549 .label = "map to guest",
550 .type = P_ENUM,
551 .p_class = P_GLOBAL,
552 .offset = GLOBAL_VAR(map_to_guest),
553 .special = NULL,
554 .enum_list = enum_map_to_guest,
555 .flags = FLAG_ADVANCED,
558 .label = "null passwords",
559 .type = P_BOOL,
560 .p_class = P_GLOBAL,
561 .offset = GLOBAL_VAR(bNullPasswords),
562 .special = NULL,
563 .enum_list = NULL,
564 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
567 .label = "obey pam restrictions",
568 .type = P_BOOL,
569 .p_class = P_GLOBAL,
570 .offset = GLOBAL_VAR(bObeyPamRestrictions),
571 .special = NULL,
572 .enum_list = NULL,
573 .flags = FLAG_ADVANCED,
576 .label = "password server",
577 .type = P_STRING,
578 .p_class = P_GLOBAL,
579 .offset = GLOBAL_VAR(szPasswordServer),
580 .special = NULL,
581 .enum_list = NULL,
582 .flags = FLAG_ADVANCED | FLAG_WIZARD,
585 .label = "smb passwd file",
586 .type = P_STRING,
587 .p_class = P_GLOBAL,
588 .offset = GLOBAL_VAR(szSMBPasswdFile),
589 .special = NULL,
590 .enum_list = NULL,
591 .flags = FLAG_ADVANCED,
594 .label = "private dir",
595 .type = P_STRING,
596 .p_class = P_GLOBAL,
597 .offset = GLOBAL_VAR(szPrivateDir),
598 .special = NULL,
599 .enum_list = NULL,
600 .flags = FLAG_ADVANCED,
603 .label = "private directory",
604 .type = P_STRING,
605 .p_class = P_GLOBAL,
606 .offset = GLOBAL_VAR(szPrivateDir),
607 .special = NULL,
608 .enum_list = NULL,
609 .flags = FLAG_HIDE,
612 .label = "passdb backend",
613 .type = P_STRING,
614 .p_class = P_GLOBAL,
615 .offset = GLOBAL_VAR(passdb_backend),
616 .special = NULL,
617 .enum_list = NULL,
618 .flags = FLAG_ADVANCED | FLAG_WIZARD,
621 .label = "algorithmic rid base",
622 .type = P_INTEGER,
623 .p_class = P_GLOBAL,
624 .offset = GLOBAL_VAR(AlgorithmicRidBase),
625 .special = NULL,
626 .enum_list = NULL,
627 .flags = FLAG_ADVANCED,
630 .label = "root directory",
631 .type = P_STRING,
632 .p_class = P_GLOBAL,
633 .offset = GLOBAL_VAR(szRootdir),
634 .special = NULL,
635 .enum_list = NULL,
636 .flags = FLAG_ADVANCED,
639 .label = "root dir",
640 .type = P_STRING,
641 .p_class = P_GLOBAL,
642 .offset = GLOBAL_VAR(szRootdir),
643 .special = NULL,
644 .enum_list = NULL,
645 .flags = FLAG_HIDE,
648 .label = "root",
649 .type = P_STRING,
650 .p_class = P_GLOBAL,
651 .offset = GLOBAL_VAR(szRootdir),
652 .special = NULL,
653 .enum_list = NULL,
654 .flags = FLAG_HIDE,
657 .label = "guest account",
658 .type = P_STRING,
659 .p_class = P_GLOBAL,
660 .offset = GLOBAL_VAR(szGuestaccount),
661 .special = NULL,
662 .enum_list = NULL,
663 .flags = FLAG_BASIC | FLAG_ADVANCED,
666 .label = "enable privileges",
667 .type = P_BOOL,
668 .p_class = P_GLOBAL,
669 .offset = GLOBAL_VAR(bEnablePrivileges),
670 .special = NULL,
671 .enum_list = NULL,
672 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
676 .label = "pam password change",
677 .type = P_BOOL,
678 .p_class = P_GLOBAL,
679 .offset = GLOBAL_VAR(bPamPasswordChange),
680 .special = NULL,
681 .enum_list = NULL,
682 .flags = FLAG_ADVANCED,
685 .label = "passwd program",
686 .type = P_STRING,
687 .p_class = P_GLOBAL,
688 .offset = GLOBAL_VAR(szPasswdProgram),
689 .special = NULL,
690 .enum_list = NULL,
691 .flags = FLAG_ADVANCED,
694 .label = "passwd chat",
695 .type = P_STRING,
696 .p_class = P_GLOBAL,
697 .offset = GLOBAL_VAR(szPasswdChat),
698 .special = NULL,
699 .enum_list = NULL,
700 .flags = FLAG_ADVANCED,
703 .label = "passwd chat debug",
704 .type = P_BOOL,
705 .p_class = P_GLOBAL,
706 .offset = GLOBAL_VAR(bPasswdChatDebug),
707 .special = NULL,
708 .enum_list = NULL,
709 .flags = FLAG_ADVANCED,
712 .label = "passwd chat timeout",
713 .type = P_INTEGER,
714 .p_class = P_GLOBAL,
715 .offset = GLOBAL_VAR(iPasswdChatTimeout),
716 .special = NULL,
717 .enum_list = NULL,
718 .flags = FLAG_ADVANCED,
721 .label = "check password script",
722 .type = P_STRING,
723 .p_class = P_GLOBAL,
724 .offset = GLOBAL_VAR(szCheckPasswordScript),
725 .special = NULL,
726 .enum_list = NULL,
727 .flags = FLAG_ADVANCED,
730 .label = "username map",
731 .type = P_STRING,
732 .p_class = P_GLOBAL,
733 .offset = GLOBAL_VAR(szUsernameMap),
734 .special = NULL,
735 .enum_list = NULL,
736 .flags = FLAG_ADVANCED,
739 .label = "password level",
740 .type = P_INTEGER,
741 .p_class = P_GLOBAL,
742 .offset = GLOBAL_VAR(pwordlevel),
743 .special = NULL,
744 .enum_list = NULL,
745 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
748 .label = "username level",
749 .type = P_INTEGER,
750 .p_class = P_GLOBAL,
751 .offset = GLOBAL_VAR(unamelevel),
752 .special = NULL,
753 .enum_list = NULL,
754 .flags = FLAG_ADVANCED,
757 .label = "unix password sync",
758 .type = P_BOOL,
759 .p_class = P_GLOBAL,
760 .offset = GLOBAL_VAR(bUnixPasswdSync),
761 .special = NULL,
762 .enum_list = NULL,
763 .flags = FLAG_ADVANCED,
766 .label = "restrict anonymous",
767 .type = P_INTEGER,
768 .p_class = P_GLOBAL,
769 .offset = GLOBAL_VAR(restrict_anonymous),
770 .special = NULL,
771 .enum_list = NULL,
772 .flags = FLAG_ADVANCED,
775 .label = "lanman auth",
776 .type = P_BOOL,
777 .p_class = P_GLOBAL,
778 .offset = GLOBAL_VAR(bLanmanAuth),
779 .special = NULL,
780 .enum_list = NULL,
781 .flags = FLAG_ADVANCED,
784 .label = "ntlm auth",
785 .type = P_BOOL,
786 .p_class = P_GLOBAL,
787 .offset = GLOBAL_VAR(bNTLMAuth),
788 .special = NULL,
789 .enum_list = NULL,
790 .flags = FLAG_ADVANCED,
793 .label = "client NTLMv2 auth",
794 .type = P_BOOL,
795 .p_class = P_GLOBAL,
796 .offset = GLOBAL_VAR(bClientNTLMv2Auth),
797 .special = NULL,
798 .enum_list = NULL,
799 .flags = FLAG_ADVANCED,
802 .label = "client lanman auth",
803 .type = P_BOOL,
804 .p_class = P_GLOBAL,
805 .offset = GLOBAL_VAR(bClientLanManAuth),
806 .special = NULL,
807 .enum_list = NULL,
808 .flags = FLAG_ADVANCED,
811 .label = "client plaintext auth",
812 .type = P_BOOL,
813 .p_class = P_GLOBAL,
814 .offset = GLOBAL_VAR(bClientPlaintextAuth),
815 .special = NULL,
816 .enum_list = NULL,
817 .flags = FLAG_ADVANCED,
820 .label = "client use spnego principal",
821 .type = P_BOOL,
822 .p_class = P_GLOBAL,
823 .offset = GLOBAL_VAR(client_use_spnego_principal),
824 .special = NULL,
825 .enum_list = NULL,
826 .flags = FLAG_ADVANCED,
829 .label = "username",
830 .type = P_STRING,
831 .p_class = P_LOCAL,
832 .offset = LOCAL_VAR(szUsername),
833 .special = NULL,
834 .enum_list = NULL,
835 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
838 .label = "user",
839 .type = P_STRING,
840 .p_class = P_LOCAL,
841 .offset = LOCAL_VAR(szUsername),
842 .special = NULL,
843 .enum_list = NULL,
844 .flags = FLAG_HIDE,
847 .label = "users",
848 .type = P_STRING,
849 .p_class = P_LOCAL,
850 .offset = LOCAL_VAR(szUsername),
851 .special = NULL,
852 .enum_list = NULL,
853 .flags = FLAG_HIDE,
856 .label = "invalid users",
857 .type = P_LIST,
858 .p_class = P_LOCAL,
859 .offset = LOCAL_VAR(szInvalidUsers),
860 .special = NULL,
861 .enum_list = NULL,
862 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
865 .label = "valid users",
866 .type = P_LIST,
867 .p_class = P_LOCAL,
868 .offset = LOCAL_VAR(szValidUsers),
869 .special = NULL,
870 .enum_list = NULL,
871 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
874 .label = "admin users",
875 .type = P_LIST,
876 .p_class = P_LOCAL,
877 .offset = LOCAL_VAR(szAdminUsers),
878 .special = NULL,
879 .enum_list = NULL,
880 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
883 .label = "read list",
884 .type = P_LIST,
885 .p_class = P_LOCAL,
886 .offset = LOCAL_VAR(readlist),
887 .special = NULL,
888 .enum_list = NULL,
889 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
892 .label = "write list",
893 .type = P_LIST,
894 .p_class = P_LOCAL,
895 .offset = LOCAL_VAR(writelist),
896 .special = NULL,
897 .enum_list = NULL,
898 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
901 .label = "force user",
902 .type = P_STRING,
903 .p_class = P_LOCAL,
904 .offset = LOCAL_VAR(force_user),
905 .special = NULL,
906 .enum_list = NULL,
907 .flags = FLAG_ADVANCED | FLAG_SHARE,
910 .label = "force group",
911 .type = P_STRING,
912 .p_class = P_LOCAL,
913 .offset = LOCAL_VAR(force_group),
914 .special = NULL,
915 .enum_list = NULL,
916 .flags = FLAG_ADVANCED | FLAG_SHARE,
919 .label = "group",
920 .type = P_STRING,
921 .p_class = P_LOCAL,
922 .offset = LOCAL_VAR(force_group),
923 .special = NULL,
924 .enum_list = NULL,
925 .flags = FLAG_ADVANCED,
928 .label = "read only",
929 .type = P_BOOL,
930 .p_class = P_LOCAL,
931 .offset = LOCAL_VAR(bRead_only),
932 .special = NULL,
933 .enum_list = NULL,
934 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
937 .label = "write ok",
938 .type = P_BOOLREV,
939 .p_class = P_LOCAL,
940 .offset = LOCAL_VAR(bRead_only),
941 .special = NULL,
942 .enum_list = NULL,
943 .flags = FLAG_HIDE,
946 .label = "writeable",
947 .type = P_BOOLREV,
948 .p_class = P_LOCAL,
949 .offset = LOCAL_VAR(bRead_only),
950 .special = NULL,
951 .enum_list = NULL,
952 .flags = FLAG_HIDE,
955 .label = "writable",
956 .type = P_BOOLREV,
957 .p_class = P_LOCAL,
958 .offset = LOCAL_VAR(bRead_only),
959 .special = NULL,
960 .enum_list = NULL,
961 .flags = FLAG_HIDE,
964 .label = "acl check permissions",
965 .type = P_BOOL,
966 .p_class = P_LOCAL,
967 .offset = LOCAL_VAR(bAclCheckPermissions),
968 .special = NULL,
969 .enum_list = NULL,
970 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
973 .label = "acl group control",
974 .type = P_BOOL,
975 .p_class = P_LOCAL,
976 .offset = LOCAL_VAR(bAclGroupControl),
977 .special = NULL,
978 .enum_list = NULL,
979 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
982 .label = "acl map full control",
983 .type = P_BOOL,
984 .p_class = P_LOCAL,
985 .offset = LOCAL_VAR(bAclMapFullControl),
986 .special = NULL,
987 .enum_list = NULL,
988 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
991 .label = "create mask",
992 .type = P_OCTAL,
993 .p_class = P_LOCAL,
994 .offset = LOCAL_VAR(iCreate_mask),
995 .special = NULL,
996 .enum_list = NULL,
997 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1000 .label = "create mode",
1001 .type = P_OCTAL,
1002 .p_class = P_LOCAL,
1003 .offset = LOCAL_VAR(iCreate_mask),
1004 .special = NULL,
1005 .enum_list = NULL,
1006 .flags = FLAG_HIDE,
1009 .label = "force create mode",
1010 .type = P_OCTAL,
1011 .p_class = P_LOCAL,
1012 .offset = LOCAL_VAR(iCreate_force_mode),
1013 .special = NULL,
1014 .enum_list = NULL,
1015 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1018 .label = "security mask",
1019 .type = P_OCTAL,
1020 .p_class = P_LOCAL,
1021 .offset = LOCAL_VAR(iSecurity_mask),
1022 .special = NULL,
1023 .enum_list = NULL,
1024 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1027 .label = "force security mode",
1028 .type = P_OCTAL,
1029 .p_class = P_LOCAL,
1030 .offset = LOCAL_VAR(iSecurity_force_mode),
1031 .special = NULL,
1032 .enum_list = NULL,
1033 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1036 .label = "directory mask",
1037 .type = P_OCTAL,
1038 .p_class = P_LOCAL,
1039 .offset = LOCAL_VAR(iDir_mask),
1040 .special = NULL,
1041 .enum_list = NULL,
1042 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1045 .label = "directory mode",
1046 .type = P_OCTAL,
1047 .p_class = P_LOCAL,
1048 .offset = LOCAL_VAR(iDir_mask),
1049 .special = NULL,
1050 .enum_list = NULL,
1051 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1054 .label = "force directory mode",
1055 .type = P_OCTAL,
1056 .p_class = P_LOCAL,
1057 .offset = LOCAL_VAR(iDir_force_mode),
1058 .special = NULL,
1059 .enum_list = NULL,
1060 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1063 .label = "directory security mask",
1064 .type = P_OCTAL,
1065 .p_class = P_LOCAL,
1066 .offset = LOCAL_VAR(iDir_Security_mask),
1067 .special = NULL,
1068 .enum_list = NULL,
1069 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1072 .label = "force directory security mode",
1073 .type = P_OCTAL,
1074 .p_class = P_LOCAL,
1075 .offset = LOCAL_VAR(iDir_Security_force_mode),
1076 .special = NULL,
1077 .enum_list = NULL,
1078 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1081 .label = "force unknown acl user",
1082 .type = P_BOOL,
1083 .p_class = P_LOCAL,
1084 .offset = LOCAL_VAR(bForceUnknownAclUser),
1085 .special = NULL,
1086 .enum_list = NULL,
1087 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1090 .label = "inherit permissions",
1091 .type = P_BOOL,
1092 .p_class = P_LOCAL,
1093 .offset = LOCAL_VAR(bInheritPerms),
1094 .special = NULL,
1095 .enum_list = NULL,
1096 .flags = FLAG_ADVANCED | FLAG_SHARE,
1099 .label = "inherit acls",
1100 .type = P_BOOL,
1101 .p_class = P_LOCAL,
1102 .offset = LOCAL_VAR(bInheritACLS),
1103 .special = NULL,
1104 .enum_list = NULL,
1105 .flags = FLAG_ADVANCED | FLAG_SHARE,
1108 .label = "inherit owner",
1109 .type = P_BOOL,
1110 .p_class = P_LOCAL,
1111 .offset = LOCAL_VAR(bInheritOwner),
1112 .special = NULL,
1113 .enum_list = NULL,
1114 .flags = FLAG_ADVANCED | FLAG_SHARE,
1117 .label = "guest only",
1118 .type = P_BOOL,
1119 .p_class = P_LOCAL,
1120 .offset = LOCAL_VAR(bGuest_only),
1121 .special = NULL,
1122 .enum_list = NULL,
1123 .flags = FLAG_ADVANCED | FLAG_SHARE,
1126 .label = "only guest",
1127 .type = P_BOOL,
1128 .p_class = P_LOCAL,
1129 .offset = LOCAL_VAR(bGuest_only),
1130 .special = NULL,
1131 .enum_list = NULL,
1132 .flags = FLAG_HIDE,
1135 .label = "administrative share",
1136 .type = P_BOOL,
1137 .p_class = P_LOCAL,
1138 .offset = LOCAL_VAR(bAdministrative_share),
1139 .special = NULL,
1140 .enum_list = NULL,
1141 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1145 .label = "guest ok",
1146 .type = P_BOOL,
1147 .p_class = P_LOCAL,
1148 .offset = LOCAL_VAR(bGuest_ok),
1149 .special = NULL,
1150 .enum_list = NULL,
1151 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1154 .label = "public",
1155 .type = P_BOOL,
1156 .p_class = P_LOCAL,
1157 .offset = LOCAL_VAR(bGuest_ok),
1158 .special = NULL,
1159 .enum_list = NULL,
1160 .flags = FLAG_HIDE,
1163 .label = "only user",
1164 .type = P_BOOL,
1165 .p_class = P_LOCAL,
1166 .offset = LOCAL_VAR(bOnlyUser),
1167 .special = NULL,
1168 .enum_list = NULL,
1169 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1172 .label = "hosts allow",
1173 .type = P_LIST,
1174 .p_class = P_LOCAL,
1175 .offset = LOCAL_VAR(szHostsallow),
1176 .special = NULL,
1177 .enum_list = NULL,
1178 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1181 .label = "allow hosts",
1182 .type = P_LIST,
1183 .p_class = P_LOCAL,
1184 .offset = LOCAL_VAR(szHostsallow),
1185 .special = NULL,
1186 .enum_list = NULL,
1187 .flags = FLAG_HIDE,
1190 .label = "hosts deny",
1191 .type = P_LIST,
1192 .p_class = P_LOCAL,
1193 .offset = LOCAL_VAR(szHostsdeny),
1194 .special = NULL,
1195 .enum_list = NULL,
1196 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1199 .label = "deny hosts",
1200 .type = P_LIST,
1201 .p_class = P_LOCAL,
1202 .offset = LOCAL_VAR(szHostsdeny),
1203 .special = NULL,
1204 .enum_list = NULL,
1205 .flags = FLAG_HIDE,
1208 .label = "preload modules",
1209 .type = P_LIST,
1210 .p_class = P_GLOBAL,
1211 .offset = GLOBAL_VAR(szPreloadModules),
1212 .special = NULL,
1213 .enum_list = NULL,
1214 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1217 .label = "dedicated keytab file",
1218 .type = P_STRING,
1219 .p_class = P_GLOBAL,
1220 .offset = GLOBAL_VAR(szDedicatedKeytabFile),
1221 .special = NULL,
1222 .enum_list = NULL,
1223 .flags = FLAG_ADVANCED,
1226 .label = "kerberos method",
1227 .type = P_ENUM,
1228 .p_class = P_GLOBAL,
1229 .offset = GLOBAL_VAR(iKerberosMethod),
1230 .special = NULL,
1231 .enum_list = enum_kerberos_method,
1232 .flags = FLAG_ADVANCED,
1235 .label = "map untrusted to domain",
1236 .type = P_BOOL,
1237 .p_class = P_GLOBAL,
1238 .offset = GLOBAL_VAR(bMapUntrustedToDomain),
1239 .special = NULL,
1240 .enum_list = NULL,
1241 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1245 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1248 .label = "log level",
1249 .type = P_STRING,
1250 .p_class = P_GLOBAL,
1251 .offset = GLOBAL_VAR(loglevel),
1252 .special = handle_debug_list,
1253 .enum_list = NULL,
1254 .flags = FLAG_ADVANCED,
1257 .label = "debuglevel",
1258 .type = P_STRING,
1259 .p_class = P_GLOBAL,
1260 .offset = GLOBAL_VAR(loglevel),
1261 .special = handle_debug_list,
1262 .enum_list = NULL,
1263 .flags = FLAG_HIDE,
1266 .label = "syslog",
1267 .type = P_INTEGER,
1268 .p_class = P_GLOBAL,
1269 .offset = GLOBAL_VAR(syslog),
1270 .special = NULL,
1271 .enum_list = NULL,
1272 .flags = FLAG_ADVANCED,
1275 .label = "syslog only",
1276 .type = P_BOOL,
1277 .p_class = P_GLOBAL,
1278 .offset = GLOBAL_VAR(bSyslogOnly),
1279 .special = NULL,
1280 .enum_list = NULL,
1281 .flags = FLAG_ADVANCED,
1284 .label = "log file",
1285 .type = P_STRING,
1286 .p_class = P_GLOBAL,
1287 .offset = GLOBAL_VAR(logfile),
1288 .special = handle_logfile,
1289 .enum_list = NULL,
1290 .flags = FLAG_ADVANCED,
1293 .label = "max log size",
1294 .type = P_BYTES,
1295 .p_class = P_GLOBAL,
1296 .offset = GLOBAL_VAR(max_log_size),
1297 .special = NULL,
1298 .enum_list = NULL,
1299 .flags = FLAG_ADVANCED,
1302 .label = "debug timestamp",
1303 .type = P_BOOL,
1304 .p_class = P_GLOBAL,
1305 .offset = GLOBAL_VAR(bTimestampLogs),
1306 .special = NULL,
1307 .enum_list = NULL,
1308 .flags = FLAG_ADVANCED,
1311 .label = "timestamp logs",
1312 .type = P_BOOL,
1313 .p_class = P_GLOBAL,
1314 .offset = GLOBAL_VAR(bTimestampLogs),
1315 .special = NULL,
1316 .enum_list = NULL,
1317 .flags = FLAG_ADVANCED,
1320 .label = "debug prefix timestamp",
1321 .type = P_BOOL,
1322 .p_class = P_GLOBAL,
1323 .offset = GLOBAL_VAR(bDebugPrefixTimestamp),
1324 .special = NULL,
1325 .enum_list = NULL,
1326 .flags = FLAG_ADVANCED,
1329 .label = "debug hires timestamp",
1330 .type = P_BOOL,
1331 .p_class = P_GLOBAL,
1332 .offset = GLOBAL_VAR(bDebugHiresTimestamp),
1333 .special = NULL,
1334 .enum_list = NULL,
1335 .flags = FLAG_ADVANCED,
1338 .label = "debug pid",
1339 .type = P_BOOL,
1340 .p_class = P_GLOBAL,
1341 .offset = GLOBAL_VAR(bDebugPid),
1342 .special = NULL,
1343 .enum_list = NULL,
1344 .flags = FLAG_ADVANCED,
1347 .label = "debug uid",
1348 .type = P_BOOL,
1349 .p_class = P_GLOBAL,
1350 .offset = GLOBAL_VAR(bDebugUid),
1351 .special = NULL,
1352 .enum_list = NULL,
1353 .flags = FLAG_ADVANCED,
1356 .label = "debug class",
1357 .type = P_BOOL,
1358 .p_class = P_GLOBAL,
1359 .offset = GLOBAL_VAR(bDebugClass),
1360 .special = NULL,
1361 .enum_list = NULL,
1362 .flags = FLAG_ADVANCED,
1365 .label = "enable core files",
1366 .type = P_BOOL,
1367 .p_class = P_GLOBAL,
1368 .offset = GLOBAL_VAR(bEnableCoreFiles),
1369 .special = NULL,
1370 .enum_list = NULL,
1371 .flags = FLAG_ADVANCED,
1374 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1377 .label = "allocation roundup size",
1378 .type = P_BYTES,
1379 .p_class = P_LOCAL,
1380 .offset = LOCAL_VAR(iallocation_roundup_size),
1381 .special = NULL,
1382 .enum_list = NULL,
1383 .flags = FLAG_ADVANCED,
1386 .label = "aio read size",
1387 .type = P_BYTES,
1388 .p_class = P_LOCAL,
1389 .offset = LOCAL_VAR(iAioReadSize),
1390 .special = NULL,
1391 .enum_list = NULL,
1392 .flags = FLAG_ADVANCED,
1395 .label = "aio write size",
1396 .type = P_BYTES,
1397 .p_class = P_LOCAL,
1398 .offset = LOCAL_VAR(iAioWriteSize),
1399 .special = NULL,
1400 .enum_list = NULL,
1401 .flags = FLAG_ADVANCED,
1404 .label = "aio write behind",
1405 .type = P_STRING,
1406 .p_class = P_LOCAL,
1407 .offset = LOCAL_VAR(szAioWriteBehind),
1408 .special = NULL,
1409 .enum_list = NULL,
1410 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1413 .label = "smb ports",
1414 .type = P_LIST,
1415 .p_class = P_GLOBAL,
1416 .offset = GLOBAL_VAR(smb_ports),
1417 .special = NULL,
1418 .enum_list = NULL,
1419 .flags = FLAG_ADVANCED,
1422 .label = "large readwrite",
1423 .type = P_BOOL,
1424 .p_class = P_GLOBAL,
1425 .offset = GLOBAL_VAR(bLargeReadwrite),
1426 .special = NULL,
1427 .enum_list = NULL,
1428 .flags = FLAG_ADVANCED,
1431 .label = "server max protocol",
1432 .type = P_ENUM,
1433 .p_class = P_GLOBAL,
1434 .offset = GLOBAL_VAR(srv_maxprotocol),
1435 .special = NULL,
1436 .enum_list = enum_protocol,
1437 .flags = FLAG_ADVANCED,
1440 .label = "max protocol",
1441 .type = P_ENUM,
1442 .p_class = P_GLOBAL,
1443 .offset = GLOBAL_VAR(srv_maxprotocol),
1444 .special = NULL,
1445 .enum_list = enum_protocol,
1446 .flags = FLAG_ADVANCED,
1449 .label = "protocol",
1450 .type = P_ENUM,
1451 .p_class = P_GLOBAL,
1452 .offset = GLOBAL_VAR(srv_maxprotocol),
1453 .special = NULL,
1454 .enum_list = enum_protocol,
1455 .flags = FLAG_ADVANCED,
1458 .label = "server min protocol",
1459 .type = P_ENUM,
1460 .p_class = P_GLOBAL,
1461 .offset = GLOBAL_VAR(srv_minprotocol),
1462 .special = NULL,
1463 .enum_list = enum_protocol,
1464 .flags = FLAG_ADVANCED,
1467 .label = "min protocol",
1468 .type = P_ENUM,
1469 .p_class = P_GLOBAL,
1470 .offset = GLOBAL_VAR(srv_minprotocol),
1471 .special = NULL,
1472 .enum_list = enum_protocol,
1473 .flags = FLAG_ADVANCED,
1476 .label = "client max protocol",
1477 .type = P_ENUM,
1478 .p_class = P_GLOBAL,
1479 .offset = GLOBAL_VAR(cli_maxprotocol),
1480 .special = NULL,
1481 .enum_list = enum_protocol,
1482 .flags = FLAG_ADVANCED,
1485 .label = "client min protocol",
1486 .type = P_ENUM,
1487 .p_class = P_GLOBAL,
1488 .offset = GLOBAL_VAR(cli_minprotocol),
1489 .special = NULL,
1490 .enum_list = enum_protocol,
1491 .flags = FLAG_ADVANCED,
1494 .label = "unicode",
1495 .type = P_BOOL,
1496 .p_class = P_GLOBAL,
1497 .offset = GLOBAL_VAR(bUnicode),
1498 .special = NULL,
1499 .enum_list = NULL
1502 .label = "min receivefile size",
1503 .type = P_BYTES,
1504 .p_class = P_GLOBAL,
1505 .offset = GLOBAL_VAR(iminreceivefile),
1506 .special = NULL,
1507 .enum_list = NULL,
1508 .flags = FLAG_ADVANCED,
1511 .label = "read raw",
1512 .type = P_BOOL,
1513 .p_class = P_GLOBAL,
1514 .offset = GLOBAL_VAR(bReadRaw),
1515 .special = NULL,
1516 .enum_list = NULL,
1517 .flags = FLAG_ADVANCED,
1520 .label = "write raw",
1521 .type = P_BOOL,
1522 .p_class = P_GLOBAL,
1523 .offset = GLOBAL_VAR(bWriteRaw),
1524 .special = NULL,
1525 .enum_list = NULL,
1526 .flags = FLAG_ADVANCED,
1529 .label = "disable netbios",
1530 .type = P_BOOL,
1531 .p_class = P_GLOBAL,
1532 .offset = GLOBAL_VAR(bDisableNetbios),
1533 .special = NULL,
1534 .enum_list = NULL,
1535 .flags = FLAG_ADVANCED,
1538 .label = "reset on zero vc",
1539 .type = P_BOOL,
1540 .p_class = P_GLOBAL,
1541 .offset = GLOBAL_VAR(bResetOnZeroVC),
1542 .special = NULL,
1543 .enum_list = NULL,
1544 .flags = FLAG_ADVANCED,
1547 .label = "log writeable files on exit",
1548 .type = P_BOOL,
1549 .p_class = P_GLOBAL,
1550 .offset = GLOBAL_VAR(bLogWriteableFilesOnExit),
1551 .special = NULL,
1552 .enum_list = NULL,
1553 .flags = FLAG_ADVANCED,
1556 .label = "acl compatibility",
1557 .type = P_ENUM,
1558 .p_class = P_GLOBAL,
1559 .offset = GLOBAL_VAR(iAclCompat),
1560 .special = NULL,
1561 .enum_list = enum_acl_compat_vals,
1562 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1565 .label = "defer sharing violations",
1566 .type = P_BOOL,
1567 .p_class = P_GLOBAL,
1568 .offset = GLOBAL_VAR(bDeferSharingViolations),
1569 .special = NULL,
1570 .enum_list = NULL,
1571 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1574 .label = "ea support",
1575 .type = P_BOOL,
1576 .p_class = P_LOCAL,
1577 .offset = LOCAL_VAR(bEASupport),
1578 .special = NULL,
1579 .enum_list = NULL,
1580 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1583 .label = "nt acl support",
1584 .type = P_BOOL,
1585 .p_class = P_LOCAL,
1586 .offset = LOCAL_VAR(bNTAclSupport),
1587 .special = NULL,
1588 .enum_list = NULL,
1589 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1592 .label = "nt pipe support",
1593 .type = P_BOOL,
1594 .p_class = P_GLOBAL,
1595 .offset = GLOBAL_VAR(bNTPipeSupport),
1596 .special = NULL,
1597 .enum_list = NULL,
1598 .flags = FLAG_ADVANCED,
1601 .label = "nt status support",
1602 .type = P_BOOL,
1603 .p_class = P_GLOBAL,
1604 .offset = GLOBAL_VAR(bNTStatusSupport),
1605 .special = NULL,
1606 .enum_list = NULL,
1607 .flags = FLAG_ADVANCED,
1610 .label = "profile acls",
1611 .type = P_BOOL,
1612 .p_class = P_LOCAL,
1613 .offset = LOCAL_VAR(bProfileAcls),
1614 .special = NULL,
1615 .enum_list = NULL,
1616 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1619 .label = "map acl inherit",
1620 .type = P_BOOL,
1621 .p_class = P_LOCAL,
1622 .offset = LOCAL_VAR(bMap_acl_inherit),
1623 .special = NULL,
1624 .enum_list = NULL,
1625 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1628 .label = "afs share",
1629 .type = P_BOOL,
1630 .p_class = P_LOCAL,
1631 .offset = LOCAL_VAR(bAfs_Share),
1632 .special = NULL,
1633 .enum_list = NULL,
1634 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1637 .label = "max mux",
1638 .type = P_INTEGER,
1639 .p_class = P_GLOBAL,
1640 .offset = GLOBAL_VAR(max_mux),
1641 .special = NULL,
1642 .enum_list = NULL,
1643 .flags = FLAG_ADVANCED,
1646 .label = "max xmit",
1647 .type = P_BYTES,
1648 .p_class = P_GLOBAL,
1649 .offset = GLOBAL_VAR(max_xmit),
1650 .special = NULL,
1651 .enum_list = NULL,
1652 .flags = FLAG_ADVANCED,
1655 .label = "name resolve order",
1656 .type = P_LIST,
1657 .p_class = P_GLOBAL,
1658 .offset = GLOBAL_VAR(szNameResolveOrder),
1659 .special = NULL,
1660 .enum_list = NULL,
1661 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1664 .label = "max ttl",
1665 .type = P_INTEGER,
1666 .p_class = P_GLOBAL,
1667 .offset = GLOBAL_VAR(max_ttl),
1668 .special = NULL,
1669 .enum_list = NULL,
1670 .flags = FLAG_ADVANCED,
1673 .label = "max wins ttl",
1674 .type = P_INTEGER,
1675 .p_class = P_GLOBAL,
1676 .offset = GLOBAL_VAR(max_wins_ttl),
1677 .special = NULL,
1678 .enum_list = NULL,
1679 .flags = FLAG_ADVANCED,
1682 .label = "min wins ttl",
1683 .type = P_INTEGER,
1684 .p_class = P_GLOBAL,
1685 .offset = GLOBAL_VAR(min_wins_ttl),
1686 .special = NULL,
1687 .enum_list = NULL,
1688 .flags = FLAG_ADVANCED,
1691 .label = "time server",
1692 .type = P_BOOL,
1693 .p_class = P_GLOBAL,
1694 .offset = GLOBAL_VAR(bTimeServer),
1695 .special = NULL,
1696 .enum_list = NULL,
1697 .flags = FLAG_ADVANCED,
1700 .label = "unix extensions",
1701 .type = P_BOOL,
1702 .p_class = P_GLOBAL,
1703 .offset = GLOBAL_VAR(bUnixExtensions),
1704 .special = NULL,
1705 .enum_list = NULL,
1706 .flags = FLAG_ADVANCED,
1709 .label = "use spnego",
1710 .type = P_BOOL,
1711 .p_class = P_GLOBAL,
1712 .offset = GLOBAL_VAR(bUseSpnego),
1713 .special = NULL,
1714 .enum_list = NULL,
1715 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1718 .label = "client signing",
1719 .type = P_ENUM,
1720 .p_class = P_GLOBAL,
1721 .offset = GLOBAL_VAR(client_signing),
1722 .special = NULL,
1723 .enum_list = enum_smb_signing_vals,
1724 .flags = FLAG_ADVANCED,
1727 .label = "server signing",
1728 .type = P_ENUM,
1729 .p_class = P_GLOBAL,
1730 .offset = GLOBAL_VAR(server_signing),
1731 .special = NULL,
1732 .enum_list = enum_smb_signing_vals,
1733 .flags = FLAG_ADVANCED,
1736 .label = "smb encrypt",
1737 .type = P_ENUM,
1738 .p_class = P_LOCAL,
1739 .offset = LOCAL_VAR(ismb_encrypt),
1740 .special = NULL,
1741 .enum_list = enum_smb_signing_vals,
1742 .flags = FLAG_ADVANCED,
1745 .label = "client use spnego",
1746 .type = P_BOOL,
1747 .p_class = P_GLOBAL,
1748 .offset = GLOBAL_VAR(bClientUseSpnego),
1749 .special = NULL,
1750 .enum_list = NULL,
1751 .flags = FLAG_ADVANCED,
1754 .label = "client ldap sasl wrapping",
1755 .type = P_ENUM,
1756 .p_class = P_GLOBAL,
1757 .offset = GLOBAL_VAR(client_ldap_sasl_wrapping),
1758 .special = NULL,
1759 .enum_list = enum_ldap_sasl_wrapping,
1760 .flags = FLAG_ADVANCED,
1763 .label = "enable asu support",
1764 .type = P_BOOL,
1765 .p_class = P_GLOBAL,
1766 .offset = GLOBAL_VAR(bASUSupport),
1767 .special = NULL,
1768 .enum_list = NULL,
1769 .flags = FLAG_ADVANCED,
1772 .label = "svcctl list",
1773 .type = P_LIST,
1774 .p_class = P_GLOBAL,
1775 .offset = GLOBAL_VAR(szServicesList),
1776 .special = NULL,
1777 .enum_list = NULL,
1778 .flags = FLAG_ADVANCED,
1781 .label = "cldap port",
1782 .type = P_INTEGER,
1783 .p_class = P_GLOBAL,
1784 .offset = GLOBAL_VAR(cldap_port),
1785 .special = NULL,
1786 .enum_list = NULL
1789 .label = "dgram port",
1790 .type = P_INTEGER,
1791 .p_class = P_GLOBAL,
1792 .offset = GLOBAL_VAR(dgram_port),
1793 .special = NULL,
1794 .enum_list = NULL
1797 .label = "nbt port",
1798 .type = P_INTEGER,
1799 .p_class = P_GLOBAL,
1800 .offset = GLOBAL_VAR(nbt_port),
1801 .special = NULL,
1802 .enum_list = NULL
1805 .label = "krb5 port",
1806 .type = P_INTEGER,
1807 .p_class = P_GLOBAL,
1808 .offset = GLOBAL_VAR(krb5_port),
1809 .special = NULL,
1810 .enum_list = NULL
1813 .label = "kpasswd port",
1814 .type = P_INTEGER,
1815 .p_class = P_GLOBAL,
1816 .offset = GLOBAL_VAR(kpasswd_port),
1817 .special = NULL,
1818 .enum_list = NULL
1821 .label = "web port",
1822 .type = P_INTEGER,
1823 .p_class = P_GLOBAL,
1824 .offset = GLOBAL_VAR(web_port),
1825 .special = NULL,
1826 .enum_list = NULL
1829 .label = "rpc big endian",
1830 .type = P_BOOL,
1831 .p_class = P_GLOBAL,
1832 .offset = GLOBAL_VAR(bRpcBigEndian),
1833 .special = NULL,
1834 .enum_list = NULL
1837 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1840 .label = "block size",
1841 .type = P_BYTES,
1842 .p_class = P_LOCAL,
1843 .offset = LOCAL_VAR(iBlock_size),
1844 .special = NULL,
1845 .enum_list = NULL,
1846 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1849 .label = "deadtime",
1850 .type = P_INTEGER,
1851 .p_class = P_GLOBAL,
1852 .offset = GLOBAL_VAR(deadtime),
1853 .special = NULL,
1854 .enum_list = NULL,
1855 .flags = FLAG_ADVANCED,
1858 .label = "getwd cache",
1859 .type = P_BOOL,
1860 .p_class = P_GLOBAL,
1861 .offset = GLOBAL_VAR(getwd_cache),
1862 .special = NULL,
1863 .enum_list = NULL,
1864 .flags = FLAG_ADVANCED,
1867 .label = "keepalive",
1868 .type = P_INTEGER,
1869 .p_class = P_GLOBAL,
1870 .offset = GLOBAL_VAR(iKeepalive),
1871 .special = NULL,
1872 .enum_list = NULL,
1873 .flags = FLAG_ADVANCED,
1876 .label = "change notify",
1877 .type = P_BOOL,
1878 .p_class = P_LOCAL,
1879 .offset = LOCAL_VAR(bChangeNotify),
1880 .special = NULL,
1881 .enum_list = NULL,
1882 .flags = FLAG_ADVANCED | FLAG_SHARE,
1885 .label = "directory name cache size",
1886 .type = P_INTEGER,
1887 .p_class = P_LOCAL,
1888 .offset = LOCAL_VAR(iDirectoryNameCacheSize),
1889 .special = NULL,
1890 .enum_list = NULL,
1891 .flags = FLAG_ADVANCED | FLAG_SHARE,
1894 .label = "kernel change notify",
1895 .type = P_BOOL,
1896 .p_class = P_LOCAL,
1897 .offset = LOCAL_VAR(bKernelChangeNotify),
1898 .special = NULL,
1899 .enum_list = NULL,
1900 .flags = FLAG_ADVANCED | FLAG_SHARE,
1903 .label = "lpq cache time",
1904 .type = P_INTEGER,
1905 .p_class = P_GLOBAL,
1906 .offset = GLOBAL_VAR(lpqcachetime),
1907 .special = NULL,
1908 .enum_list = NULL,
1909 .flags = FLAG_ADVANCED,
1912 .label = "max smbd processes",
1913 .type = P_INTEGER,
1914 .p_class = P_GLOBAL,
1915 .offset = GLOBAL_VAR(iMaxSmbdProcesses),
1916 .special = NULL,
1917 .enum_list = NULL,
1918 .flags = FLAG_ADVANCED,
1921 .label = "max connections",
1922 .type = P_INTEGER,
1923 .p_class = P_LOCAL,
1924 .offset = LOCAL_VAR(iMaxConnections),
1925 .special = NULL,
1926 .enum_list = NULL,
1927 .flags = FLAG_ADVANCED | FLAG_SHARE,
1930 .label = "paranoid server security",
1931 .type = P_BOOL,
1932 .p_class = P_GLOBAL,
1933 .offset = GLOBAL_VAR(paranoid_server_security),
1934 .special = NULL,
1935 .enum_list = NULL,
1936 .flags = FLAG_ADVANCED,
1939 .label = "max disk size",
1940 .type = P_BYTES,
1941 .p_class = P_GLOBAL,
1942 .offset = GLOBAL_VAR(maxdisksize),
1943 .special = NULL,
1944 .enum_list = NULL,
1945 .flags = FLAG_ADVANCED,
1948 .label = "max open files",
1949 .type = P_INTEGER,
1950 .p_class = P_GLOBAL,
1951 .offset = GLOBAL_VAR(max_open_files),
1952 .special = NULL,
1953 .enum_list = NULL,
1954 .flags = FLAG_ADVANCED,
1957 .label = "min print space",
1958 .type = P_INTEGER,
1959 .p_class = P_LOCAL,
1960 .offset = LOCAL_VAR(iMinPrintSpace),
1961 .special = NULL,
1962 .enum_list = NULL,
1963 .flags = FLAG_ADVANCED | FLAG_PRINT,
1966 .label = "socket options",
1967 .type = P_STRING,
1968 .p_class = P_GLOBAL,
1969 .offset = GLOBAL_VAR(socket_options),
1970 .special = NULL,
1971 .enum_list = NULL,
1972 .flags = FLAG_ADVANCED,
1975 .label = "strict allocate",
1976 .type = P_BOOL,
1977 .p_class = P_LOCAL,
1978 .offset = LOCAL_VAR(bStrictAllocate),
1979 .special = NULL,
1980 .enum_list = NULL,
1981 .flags = FLAG_ADVANCED | FLAG_SHARE,
1984 .label = "strict sync",
1985 .type = P_BOOL,
1986 .p_class = P_LOCAL,
1987 .offset = LOCAL_VAR(bStrictSync),
1988 .special = NULL,
1989 .enum_list = NULL,
1990 .flags = FLAG_ADVANCED | FLAG_SHARE,
1993 .label = "sync always",
1994 .type = P_BOOL,
1995 .p_class = P_LOCAL,
1996 .offset = LOCAL_VAR(bSyncAlways),
1997 .special = NULL,
1998 .enum_list = NULL,
1999 .flags = FLAG_ADVANCED | FLAG_SHARE,
2002 .label = "use mmap",
2003 .type = P_BOOL,
2004 .p_class = P_GLOBAL,
2005 .offset = GLOBAL_VAR(bUseMmap),
2006 .special = NULL,
2007 .enum_list = NULL,
2008 .flags = FLAG_ADVANCED,
2011 .label = "use sendfile",
2012 .type = P_BOOL,
2013 .p_class = P_LOCAL,
2014 .offset = LOCAL_VAR(bUseSendfile),
2015 .special = NULL,
2016 .enum_list = NULL,
2017 .flags = FLAG_ADVANCED | FLAG_SHARE,
2020 .label = "hostname lookups",
2021 .type = P_BOOL,
2022 .p_class = P_GLOBAL,
2023 .offset = GLOBAL_VAR(bHostnameLookups),
2024 .special = NULL,
2025 .enum_list = NULL,
2026 .flags = FLAG_ADVANCED,
2029 .label = "write cache size",
2030 .type = P_BYTES,
2031 .p_class = P_LOCAL,
2032 .offset = LOCAL_VAR(iWriteCacheSize),
2033 .special = NULL,
2034 .enum_list = NULL,
2035 .flags = FLAG_ADVANCED | FLAG_SHARE,
2038 .label = "name cache timeout",
2039 .type = P_INTEGER,
2040 .p_class = P_GLOBAL,
2041 .offset = GLOBAL_VAR(name_cache_timeout),
2042 .special = NULL,
2043 .enum_list = NULL,
2044 .flags = FLAG_ADVANCED,
2047 .label = "ctdbd socket",
2048 .type = P_STRING,
2049 .p_class = P_GLOBAL,
2050 .offset = GLOBAL_VAR(ctdbdSocket),
2051 .special = NULL,
2052 .enum_list = NULL,
2053 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2056 .label = "cluster addresses",
2057 .type = P_LIST,
2058 .p_class = P_GLOBAL,
2059 .offset = GLOBAL_VAR(szClusterAddresses),
2060 .special = NULL,
2061 .enum_list = NULL,
2062 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2065 .label = "clustering",
2066 .type = P_BOOL,
2067 .p_class = P_GLOBAL,
2068 .offset = GLOBAL_VAR(clustering),
2069 .special = NULL,
2070 .enum_list = NULL,
2071 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2074 .label = "ctdb timeout",
2075 .type = P_INTEGER,
2076 .p_class = P_GLOBAL,
2077 .offset = GLOBAL_VAR(ctdb_timeout),
2078 .special = NULL,
2079 .enum_list = NULL,
2080 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2083 .label = "ctdb locktime warn threshold",
2084 .type = P_INTEGER,
2085 .p_class = P_GLOBAL,
2086 .offset = GLOBAL_VAR(ctdb_locktime_warn_threshold),
2087 .special = NULL,
2088 .enum_list = NULL,
2089 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2092 .label = "smb2 max read",
2093 .type = P_BYTES,
2094 .p_class = P_GLOBAL,
2095 .offset = GLOBAL_VAR(ismb2_max_read),
2096 .special = NULL,
2097 .enum_list = NULL,
2098 .flags = FLAG_ADVANCED,
2101 .label = "smb2 max write",
2102 .type = P_BYTES,
2103 .p_class = P_GLOBAL,
2104 .offset = GLOBAL_VAR(ismb2_max_write),
2105 .special = NULL,
2106 .enum_list = NULL,
2107 .flags = FLAG_ADVANCED,
2110 .label = "smb2 max trans",
2111 .type = P_BYTES,
2112 .p_class = P_GLOBAL,
2113 .offset = GLOBAL_VAR(ismb2_max_trans),
2114 .special = NULL,
2115 .enum_list = NULL,
2116 .flags = FLAG_ADVANCED,
2119 .label = "smb2 max credits",
2120 .type = P_INTEGER,
2121 .p_class = P_GLOBAL,
2122 .offset = GLOBAL_VAR(ismb2_max_credits),
2123 .special = NULL,
2124 .enum_list = NULL,
2125 .flags = FLAG_ADVANCED,
2128 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2131 .label = "max reported print jobs",
2132 .type = P_INTEGER,
2133 .p_class = P_LOCAL,
2134 .offset = LOCAL_VAR(iMaxReportedPrintJobs),
2135 .special = NULL,
2136 .enum_list = NULL,
2137 .flags = FLAG_ADVANCED | FLAG_PRINT,
2140 .label = "max print jobs",
2141 .type = P_INTEGER,
2142 .p_class = P_LOCAL,
2143 .offset = LOCAL_VAR(iMaxPrintJobs),
2144 .special = NULL,
2145 .enum_list = NULL,
2146 .flags = FLAG_ADVANCED | FLAG_PRINT,
2149 .label = "load printers",
2150 .type = P_BOOL,
2151 .p_class = P_GLOBAL,
2152 .offset = GLOBAL_VAR(bLoadPrinters),
2153 .special = NULL,
2154 .enum_list = NULL,
2155 .flags = FLAG_ADVANCED | FLAG_PRINT,
2158 .label = "printcap cache time",
2159 .type = P_INTEGER,
2160 .p_class = P_GLOBAL,
2161 .offset = GLOBAL_VAR(PrintcapCacheTime),
2162 .special = NULL,
2163 .enum_list = NULL,
2164 .flags = FLAG_ADVANCED | FLAG_PRINT,
2167 .label = "printcap name",
2168 .type = P_STRING,
2169 .p_class = P_GLOBAL,
2170 .offset = GLOBAL_VAR(szPrintcapname),
2171 .special = NULL,
2172 .enum_list = NULL,
2173 .flags = FLAG_ADVANCED | FLAG_PRINT,
2176 .label = "printcap",
2177 .type = P_STRING,
2178 .p_class = P_GLOBAL,
2179 .offset = GLOBAL_VAR(szPrintcapname),
2180 .special = NULL,
2181 .enum_list = NULL,
2182 .flags = FLAG_HIDE,
2185 .label = "printable",
2186 .type = P_BOOL,
2187 .p_class = P_LOCAL,
2188 .offset = LOCAL_VAR(bPrint_ok),
2189 .special = NULL,
2190 .enum_list = NULL,
2191 .flags = FLAG_ADVANCED | FLAG_PRINT,
2194 .label = "print notify backchannel",
2195 .type = P_BOOL,
2196 .p_class = P_LOCAL,
2197 .offset = LOCAL_VAR(bPrintNotifyBackchannel),
2198 .special = NULL,
2199 .enum_list = NULL,
2200 .flags = FLAG_ADVANCED,
2203 .label = "print ok",
2204 .type = P_BOOL,
2205 .p_class = P_LOCAL,
2206 .offset = LOCAL_VAR(bPrint_ok),
2207 .special = NULL,
2208 .enum_list = NULL,
2209 .flags = FLAG_HIDE,
2212 .label = "printing",
2213 .type = P_ENUM,
2214 .p_class = P_LOCAL,
2215 .offset = LOCAL_VAR(iPrinting),
2216 .special = handle_printing,
2217 .enum_list = enum_printing,
2218 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2221 .label = "cups options",
2222 .type = P_STRING,
2223 .p_class = P_LOCAL,
2224 .offset = LOCAL_VAR(szCupsOptions),
2225 .special = NULL,
2226 .enum_list = NULL,
2227 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2230 .label = "cups server",
2231 .type = P_STRING,
2232 .p_class = P_GLOBAL,
2233 .offset = GLOBAL_VAR(szCupsServer),
2234 .special = NULL,
2235 .enum_list = NULL,
2236 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2239 .label = "cups encrypt",
2240 .type = P_ENUM,
2241 .p_class = P_GLOBAL,
2242 .offset = GLOBAL_VAR(CupsEncrypt),
2243 .special = NULL,
2244 .enum_list = enum_bool_auto,
2245 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2249 .label = "cups connection timeout",
2250 .type = P_INTEGER,
2251 .p_class = P_GLOBAL,
2252 .offset = GLOBAL_VAR(cups_connection_timeout),
2253 .special = NULL,
2254 .enum_list = NULL,
2255 .flags = FLAG_ADVANCED,
2258 .label = "iprint server",
2259 .type = P_STRING,
2260 .p_class = P_GLOBAL,
2261 .offset = GLOBAL_VAR(szIPrintServer),
2262 .special = NULL,
2263 .enum_list = NULL,
2264 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2267 .label = "print command",
2268 .type = P_STRING,
2269 .p_class = P_LOCAL,
2270 .offset = LOCAL_VAR(szPrintcommand),
2271 .special = NULL,
2272 .enum_list = NULL,
2273 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2276 .label = "disable spoolss",
2277 .type = P_BOOL,
2278 .p_class = P_GLOBAL,
2279 .offset = GLOBAL_VAR(bDisableSpoolss),
2280 .special = NULL,
2281 .enum_list = NULL,
2282 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2285 .label = "enable spoolss",
2286 .type = P_BOOLREV,
2287 .p_class = P_GLOBAL,
2288 .offset = GLOBAL_VAR(bDisableSpoolss),
2289 .special = NULL,
2290 .enum_list = NULL,
2291 .flags = FLAG_HIDE,
2294 .label = "lpq command",
2295 .type = P_STRING,
2296 .p_class = P_LOCAL,
2297 .offset = LOCAL_VAR(szLpqcommand),
2298 .special = NULL,
2299 .enum_list = NULL,
2300 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2303 .label = "lprm command",
2304 .type = P_STRING,
2305 .p_class = P_LOCAL,
2306 .offset = LOCAL_VAR(szLprmcommand),
2307 .special = NULL,
2308 .enum_list = NULL,
2309 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2312 .label = "lppause command",
2313 .type = P_STRING,
2314 .p_class = P_LOCAL,
2315 .offset = LOCAL_VAR(szLppausecommand),
2316 .special = NULL,
2317 .enum_list = NULL,
2318 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2321 .label = "lpresume command",
2322 .type = P_STRING,
2323 .p_class = P_LOCAL,
2324 .offset = LOCAL_VAR(szLpresumecommand),
2325 .special = NULL,
2326 .enum_list = NULL,
2327 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2330 .label = "queuepause command",
2331 .type = P_STRING,
2332 .p_class = P_LOCAL,
2333 .offset = LOCAL_VAR(szQueuepausecommand),
2334 .special = NULL,
2335 .enum_list = NULL,
2336 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2339 .label = "queueresume command",
2340 .type = P_STRING,
2341 .p_class = P_LOCAL,
2342 .offset = LOCAL_VAR(szQueueresumecommand),
2343 .special = NULL,
2344 .enum_list = NULL,
2345 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2348 .label = "addport command",
2349 .type = P_STRING,
2350 .p_class = P_GLOBAL,
2351 .offset = GLOBAL_VAR(szAddPortCommand),
2352 .special = NULL,
2353 .enum_list = NULL,
2354 .flags = FLAG_ADVANCED,
2357 .label = "enumports command",
2358 .type = P_STRING,
2359 .p_class = P_GLOBAL,
2360 .offset = GLOBAL_VAR(szEnumPortsCommand),
2361 .special = NULL,
2362 .enum_list = NULL,
2363 .flags = FLAG_ADVANCED,
2366 .label = "addprinter command",
2367 .type = P_STRING,
2368 .p_class = P_GLOBAL,
2369 .offset = GLOBAL_VAR(szAddPrinterCommand),
2370 .special = NULL,
2371 .enum_list = NULL,
2372 .flags = FLAG_ADVANCED,
2375 .label = "deleteprinter command",
2376 .type = P_STRING,
2377 .p_class = P_GLOBAL,
2378 .offset = GLOBAL_VAR(szDeletePrinterCommand),
2379 .special = NULL,
2380 .enum_list = NULL,
2381 .flags = FLAG_ADVANCED,
2384 .label = "show add printer wizard",
2385 .type = P_BOOL,
2386 .p_class = P_GLOBAL,
2387 .offset = GLOBAL_VAR(bMsAddPrinterWizard),
2388 .special = NULL,
2389 .enum_list = NULL,
2390 .flags = FLAG_ADVANCED,
2393 .label = "os2 driver map",
2394 .type = P_STRING,
2395 .p_class = P_GLOBAL,
2396 .offset = GLOBAL_VAR(szOs2DriverMap),
2397 .special = NULL,
2398 .enum_list = NULL,
2399 .flags = FLAG_ADVANCED,
2403 .label = "printer name",
2404 .type = P_STRING,
2405 .p_class = P_LOCAL,
2406 .offset = LOCAL_VAR(szPrintername),
2407 .special = NULL,
2408 .enum_list = NULL,
2409 .flags = FLAG_ADVANCED | FLAG_PRINT,
2412 .label = "printer",
2413 .type = P_STRING,
2414 .p_class = P_LOCAL,
2415 .offset = LOCAL_VAR(szPrintername),
2416 .special = NULL,
2417 .enum_list = NULL,
2418 .flags = FLAG_HIDE,
2421 .label = "use client driver",
2422 .type = P_BOOL,
2423 .p_class = P_LOCAL,
2424 .offset = LOCAL_VAR(bUseClientDriver),
2425 .special = NULL,
2426 .enum_list = NULL,
2427 .flags = FLAG_ADVANCED | FLAG_PRINT,
2430 .label = "default devmode",
2431 .type = P_BOOL,
2432 .p_class = P_LOCAL,
2433 .offset = LOCAL_VAR(bDefaultDevmode),
2434 .special = NULL,
2435 .enum_list = NULL,
2436 .flags = FLAG_ADVANCED | FLAG_PRINT,
2439 .label = "force printername",
2440 .type = P_BOOL,
2441 .p_class = P_LOCAL,
2442 .offset = LOCAL_VAR(bForcePrintername),
2443 .special = NULL,
2444 .enum_list = NULL,
2445 .flags = FLAG_ADVANCED | FLAG_PRINT,
2448 .label = "printjob username",
2449 .type = P_STRING,
2450 .p_class = P_LOCAL,
2451 .offset = LOCAL_VAR(szPrintjobUsername),
2452 .special = NULL,
2453 .enum_list = NULL,
2454 .flags = FLAG_ADVANCED | FLAG_PRINT,
2457 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2460 .label = "mangling method",
2461 .type = P_STRING,
2462 .p_class = P_GLOBAL,
2463 .offset = GLOBAL_VAR(szManglingMethod),
2464 .special = NULL,
2465 .enum_list = NULL,
2466 .flags = FLAG_ADVANCED,
2469 .label = "mangle prefix",
2470 .type = P_INTEGER,
2471 .p_class = P_GLOBAL,
2472 .offset = GLOBAL_VAR(mangle_prefix),
2473 .special = NULL,
2474 .enum_list = NULL,
2475 .flags = FLAG_ADVANCED,
2479 .label = "default case",
2480 .type = P_ENUM,
2481 .p_class = P_LOCAL,
2482 .offset = LOCAL_VAR(iDefaultCase),
2483 .special = NULL,
2484 .enum_list = enum_case,
2485 .flags = FLAG_ADVANCED | FLAG_SHARE,
2488 .label = "case sensitive",
2489 .type = P_ENUM,
2490 .p_class = P_LOCAL,
2491 .offset = LOCAL_VAR(iCaseSensitive),
2492 .special = NULL,
2493 .enum_list = enum_bool_auto,
2494 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2497 .label = "casesignames",
2498 .type = P_ENUM,
2499 .p_class = P_LOCAL,
2500 .offset = LOCAL_VAR(iCaseSensitive),
2501 .special = NULL,
2502 .enum_list = enum_bool_auto,
2503 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2506 .label = "preserve case",
2507 .type = P_BOOL,
2508 .p_class = P_LOCAL,
2509 .offset = LOCAL_VAR(bCasePreserve),
2510 .special = NULL,
2511 .enum_list = NULL,
2512 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2515 .label = "short preserve case",
2516 .type = P_BOOL,
2517 .p_class = P_LOCAL,
2518 .offset = LOCAL_VAR(bShortCasePreserve),
2519 .special = NULL,
2520 .enum_list = NULL,
2521 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2524 .label = "mangling char",
2525 .type = P_CHAR,
2526 .p_class = P_LOCAL,
2527 .offset = LOCAL_VAR(magic_char),
2528 .special = NULL,
2529 .enum_list = NULL,
2530 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2533 .label = "hide dot files",
2534 .type = P_BOOL,
2535 .p_class = P_LOCAL,
2536 .offset = LOCAL_VAR(bHideDotFiles),
2537 .special = NULL,
2538 .enum_list = NULL,
2539 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2542 .label = "hide special files",
2543 .type = P_BOOL,
2544 .p_class = P_LOCAL,
2545 .offset = LOCAL_VAR(bHideSpecialFiles),
2546 .special = NULL,
2547 .enum_list = NULL,
2548 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2551 .label = "hide unreadable",
2552 .type = P_BOOL,
2553 .p_class = P_LOCAL,
2554 .offset = LOCAL_VAR(bHideUnReadable),
2555 .special = NULL,
2556 .enum_list = NULL,
2557 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2560 .label = "hide unwriteable files",
2561 .type = P_BOOL,
2562 .p_class = P_LOCAL,
2563 .offset = LOCAL_VAR(bHideUnWriteableFiles),
2564 .special = NULL,
2565 .enum_list = NULL,
2566 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2569 .label = "delete veto files",
2570 .type = P_BOOL,
2571 .p_class = P_LOCAL,
2572 .offset = LOCAL_VAR(bDeleteVetoFiles),
2573 .special = NULL,
2574 .enum_list = NULL,
2575 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2578 .label = "veto files",
2579 .type = P_STRING,
2580 .p_class = P_LOCAL,
2581 .offset = LOCAL_VAR(szVetoFiles),
2582 .special = NULL,
2583 .enum_list = NULL,
2584 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2587 .label = "hide files",
2588 .type = P_STRING,
2589 .p_class = P_LOCAL,
2590 .offset = LOCAL_VAR(szHideFiles),
2591 .special = NULL,
2592 .enum_list = NULL,
2593 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2596 .label = "veto oplock files",
2597 .type = P_STRING,
2598 .p_class = P_LOCAL,
2599 .offset = LOCAL_VAR(szVetoOplockFiles),
2600 .special = NULL,
2601 .enum_list = NULL,
2602 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2605 .label = "map archive",
2606 .type = P_BOOL,
2607 .p_class = P_LOCAL,
2608 .offset = LOCAL_VAR(bMap_archive),
2609 .special = NULL,
2610 .enum_list = NULL,
2611 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2614 .label = "map hidden",
2615 .type = P_BOOL,
2616 .p_class = P_LOCAL,
2617 .offset = LOCAL_VAR(bMap_hidden),
2618 .special = NULL,
2619 .enum_list = NULL,
2620 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2623 .label = "map system",
2624 .type = P_BOOL,
2625 .p_class = P_LOCAL,
2626 .offset = LOCAL_VAR(bMap_system),
2627 .special = NULL,
2628 .enum_list = NULL,
2629 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2632 .label = "map readonly",
2633 .type = P_ENUM,
2634 .p_class = P_LOCAL,
2635 .offset = LOCAL_VAR(iMap_readonly),
2636 .special = NULL,
2637 .enum_list = enum_map_readonly,
2638 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2641 .label = "mangled names",
2642 .type = P_BOOL,
2643 .p_class = P_LOCAL,
2644 .offset = LOCAL_VAR(bMangledNames),
2645 .special = NULL,
2646 .enum_list = NULL,
2647 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2650 .label = "max stat cache size",
2651 .type = P_INTEGER,
2652 .p_class = P_GLOBAL,
2653 .offset = GLOBAL_VAR(iMaxStatCacheSize),
2654 .special = NULL,
2655 .enum_list = NULL,
2656 .flags = FLAG_ADVANCED,
2659 .label = "stat cache",
2660 .type = P_BOOL,
2661 .p_class = P_GLOBAL,
2662 .offset = GLOBAL_VAR(bStatCache),
2663 .special = NULL,
2664 .enum_list = NULL,
2665 .flags = FLAG_ADVANCED,
2668 .label = "store dos attributes",
2669 .type = P_BOOL,
2670 .p_class = P_LOCAL,
2671 .offset = LOCAL_VAR(bStoreDosAttributes),
2672 .special = NULL,
2673 .enum_list = NULL,
2674 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2677 .label = "dmapi support",
2678 .type = P_BOOL,
2679 .p_class = P_LOCAL,
2680 .offset = LOCAL_VAR(bDmapiSupport),
2681 .special = NULL,
2682 .enum_list = NULL,
2683 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2687 {N_("Domain Options"), P_SEP, P_SEPARATOR},
2690 .label = "machine password timeout",
2691 .type = P_INTEGER,
2692 .p_class = P_GLOBAL,
2693 .offset = GLOBAL_VAR(machine_password_timeout),
2694 .special = NULL,
2695 .enum_list = NULL,
2696 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2699 {N_("Logon Options"), P_SEP, P_SEPARATOR},
2702 .label = "add user script",
2703 .type = P_STRING,
2704 .p_class = P_GLOBAL,
2705 .offset = GLOBAL_VAR(szAddUserScript),
2706 .special = NULL,
2707 .enum_list = NULL,
2708 .flags = FLAG_ADVANCED,
2711 .label = "rename user script",
2712 .type = P_STRING,
2713 .p_class = P_GLOBAL,
2714 .offset = GLOBAL_VAR(szRenameUserScript),
2715 .special = NULL,
2716 .enum_list = NULL,
2717 .flags = FLAG_ADVANCED,
2720 .label = "delete user script",
2721 .type = P_STRING,
2722 .p_class = P_GLOBAL,
2723 .offset = GLOBAL_VAR(szDelUserScript),
2724 .special = NULL,
2725 .enum_list = NULL,
2726 .flags = FLAG_ADVANCED,
2729 .label = "add group script",
2730 .type = P_STRING,
2731 .p_class = P_GLOBAL,
2732 .offset = GLOBAL_VAR(szAddGroupScript),
2733 .special = NULL,
2734 .enum_list = NULL,
2735 .flags = FLAG_ADVANCED,
2738 .label = "delete group script",
2739 .type = P_STRING,
2740 .p_class = P_GLOBAL,
2741 .offset = GLOBAL_VAR(szDelGroupScript),
2742 .special = NULL,
2743 .enum_list = NULL,
2744 .flags = FLAG_ADVANCED,
2747 .label = "add user to group script",
2748 .type = P_STRING,
2749 .p_class = P_GLOBAL,
2750 .offset = GLOBAL_VAR(szAddUserToGroupScript),
2751 .special = NULL,
2752 .enum_list = NULL,
2753 .flags = FLAG_ADVANCED,
2756 .label = "delete user from group script",
2757 .type = P_STRING,
2758 .p_class = P_GLOBAL,
2759 .offset = GLOBAL_VAR(szDelUserFromGroupScript),
2760 .special = NULL,
2761 .enum_list = NULL,
2762 .flags = FLAG_ADVANCED,
2765 .label = "set primary group script",
2766 .type = P_STRING,
2767 .p_class = P_GLOBAL,
2768 .offset = GLOBAL_VAR(szSetPrimaryGroupScript),
2769 .special = NULL,
2770 .enum_list = NULL,
2771 .flags = FLAG_ADVANCED,
2774 .label = "add machine script",
2775 .type = P_STRING,
2776 .p_class = P_GLOBAL,
2777 .offset = GLOBAL_VAR(szAddMachineScript),
2778 .special = NULL,
2779 .enum_list = NULL,
2780 .flags = FLAG_ADVANCED,
2783 .label = "shutdown script",
2784 .type = P_STRING,
2785 .p_class = P_GLOBAL,
2786 .offset = GLOBAL_VAR(szShutdownScript),
2787 .special = NULL,
2788 .enum_list = NULL,
2789 .flags = FLAG_ADVANCED,
2792 .label = "abort shutdown script",
2793 .type = P_STRING,
2794 .p_class = P_GLOBAL,
2795 .offset = GLOBAL_VAR(szAbortShutdownScript),
2796 .special = NULL,
2797 .enum_list = NULL,
2798 .flags = FLAG_ADVANCED,
2801 .label = "username map script",
2802 .type = P_STRING,
2803 .p_class = P_GLOBAL,
2804 .offset = GLOBAL_VAR(szUsernameMapScript),
2805 .special = NULL,
2806 .enum_list = NULL,
2807 .flags = FLAG_ADVANCED,
2810 .label = "username map cache time",
2811 .type = P_INTEGER,
2812 .p_class = P_GLOBAL,
2813 .offset = GLOBAL_VAR(iUsernameMapCacheTime),
2814 .special = NULL,
2815 .enum_list = NULL,
2816 .flags = FLAG_ADVANCED,
2819 .label = "logon script",
2820 .type = P_STRING,
2821 .p_class = P_GLOBAL,
2822 .offset = GLOBAL_VAR(szLogonScript),
2823 .special = NULL,
2824 .enum_list = NULL,
2825 .flags = FLAG_ADVANCED,
2828 .label = "logon path",
2829 .type = P_STRING,
2830 .p_class = P_GLOBAL,
2831 .offset = GLOBAL_VAR(szLogonPath),
2832 .special = NULL,
2833 .enum_list = NULL,
2834 .flags = FLAG_ADVANCED,
2837 .label = "logon drive",
2838 .type = P_STRING,
2839 .p_class = P_GLOBAL,
2840 .offset = GLOBAL_VAR(szLogonDrive),
2841 .special = NULL,
2842 .enum_list = NULL,
2843 .flags = FLAG_ADVANCED,
2846 .label = "logon home",
2847 .type = P_STRING,
2848 .p_class = P_GLOBAL,
2849 .offset = GLOBAL_VAR(szLogonHome),
2850 .special = NULL,
2851 .enum_list = NULL,
2852 .flags = FLAG_ADVANCED,
2855 .label = "domain logons",
2856 .type = P_BOOL,
2857 .p_class = P_GLOBAL,
2858 .offset = GLOBAL_VAR(bDomainLogons),
2859 .special = NULL,
2860 .enum_list = NULL,
2861 .flags = FLAG_ADVANCED,
2865 .label = "init logon delayed hosts",
2866 .type = P_LIST,
2867 .p_class = P_GLOBAL,
2868 .offset = GLOBAL_VAR(szInitLogonDelayedHosts),
2869 .special = NULL,
2870 .enum_list = NULL,
2871 .flags = FLAG_ADVANCED,
2875 .label = "init logon delay",
2876 .type = P_INTEGER,
2877 .p_class = P_GLOBAL,
2878 .offset = GLOBAL_VAR(InitLogonDelay),
2879 .special = NULL,
2880 .enum_list = NULL,
2881 .flags = FLAG_ADVANCED,
2885 {N_("Browse Options"), P_SEP, P_SEPARATOR},
2888 .label = "os level",
2889 .type = P_INTEGER,
2890 .p_class = P_GLOBAL,
2891 .offset = GLOBAL_VAR(os_level),
2892 .special = NULL,
2893 .enum_list = NULL,
2894 .flags = FLAG_BASIC | FLAG_ADVANCED,
2897 .label = "lm announce",
2898 .type = P_ENUM,
2899 .p_class = P_GLOBAL,
2900 .offset = GLOBAL_VAR(lm_announce),
2901 .special = NULL,
2902 .enum_list = enum_bool_auto,
2903 .flags = FLAG_ADVANCED,
2906 .label = "lm interval",
2907 .type = P_INTEGER,
2908 .p_class = P_GLOBAL,
2909 .offset = GLOBAL_VAR(lm_interval),
2910 .special = NULL,
2911 .enum_list = NULL,
2912 .flags = FLAG_ADVANCED,
2915 .label = "preferred master",
2916 .type = P_ENUM,
2917 .p_class = P_GLOBAL,
2918 .offset = GLOBAL_VAR(iPreferredMaster),
2919 .special = NULL,
2920 .enum_list = enum_bool_auto,
2921 .flags = FLAG_BASIC | FLAG_ADVANCED,
2924 .label = "prefered master",
2925 .type = P_ENUM,
2926 .p_class = P_GLOBAL,
2927 .offset = GLOBAL_VAR(iPreferredMaster),
2928 .special = NULL,
2929 .enum_list = enum_bool_auto,
2930 .flags = FLAG_HIDE,
2933 .label = "local master",
2934 .type = P_BOOL,
2935 .p_class = P_GLOBAL,
2936 .offset = GLOBAL_VAR(bLocalMaster),
2937 .special = NULL,
2938 .enum_list = NULL,
2939 .flags = FLAG_BASIC | FLAG_ADVANCED,
2942 .label = "domain master",
2943 .type = P_ENUM,
2944 .p_class = P_GLOBAL,
2945 .offset = GLOBAL_VAR(domain_master),
2946 .special = NULL,
2947 .enum_list = enum_bool_auto,
2948 .flags = FLAG_BASIC | FLAG_ADVANCED,
2951 .label = "browse list",
2952 .type = P_BOOL,
2953 .p_class = P_GLOBAL,
2954 .offset = GLOBAL_VAR(bBrowseList),
2955 .special = NULL,
2956 .enum_list = NULL,
2957 .flags = FLAG_ADVANCED,
2960 .label = "browseable",
2961 .type = P_BOOL,
2962 .p_class = P_LOCAL,
2963 .offset = LOCAL_VAR(bBrowseable),
2964 .special = NULL,
2965 .enum_list = NULL,
2966 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
2969 .label = "browsable",
2970 .type = P_BOOL,
2971 .p_class = P_LOCAL,
2972 .offset = LOCAL_VAR(bBrowseable),
2973 .special = NULL,
2974 .enum_list = NULL,
2975 .flags = FLAG_HIDE,
2978 .label = "access based share enum",
2979 .type = P_BOOL,
2980 .p_class = P_LOCAL,
2981 .offset = LOCAL_VAR(bAccessBasedShareEnum),
2982 .special = NULL,
2983 .enum_list = NULL,
2984 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
2987 .label = "enhanced browsing",
2988 .type = P_BOOL,
2989 .p_class = P_GLOBAL,
2990 .offset = GLOBAL_VAR(enhanced_browsing),
2991 .special = NULL,
2992 .enum_list = NULL,
2993 .flags = FLAG_ADVANCED,
2996 {N_("WINS Options"), P_SEP, P_SEPARATOR},
2999 .label = "dns proxy",
3000 .type = P_BOOL,
3001 .p_class = P_GLOBAL,
3002 .offset = GLOBAL_VAR(bWINSdnsProxy),
3003 .special = NULL,
3004 .enum_list = NULL,
3005 .flags = FLAG_ADVANCED,
3008 .label = "wins proxy",
3009 .type = P_BOOL,
3010 .p_class = P_GLOBAL,
3011 .offset = GLOBAL_VAR(bWINSproxy),
3012 .special = NULL,
3013 .enum_list = NULL,
3014 .flags = FLAG_ADVANCED,
3017 .label = "wins server",
3018 .type = P_LIST,
3019 .p_class = P_GLOBAL,
3020 .offset = GLOBAL_VAR(szWINSservers),
3021 .special = NULL,
3022 .enum_list = NULL,
3023 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3026 .label = "wins support",
3027 .type = P_BOOL,
3028 .p_class = P_GLOBAL,
3029 .offset = GLOBAL_VAR(bWINSsupport),
3030 .special = NULL,
3031 .enum_list = NULL,
3032 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3035 .label = "wins hook",
3036 .type = P_STRING,
3037 .p_class = P_GLOBAL,
3038 .offset = GLOBAL_VAR(szWINSHook),
3039 .special = NULL,
3040 .enum_list = NULL,
3041 .flags = FLAG_ADVANCED,
3044 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3047 .label = "blocking locks",
3048 .type = P_BOOL,
3049 .p_class = P_LOCAL,
3050 .offset = LOCAL_VAR(bBlockingLocks),
3051 .special = NULL,
3052 .enum_list = NULL,
3053 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3056 .label = "csc policy",
3057 .type = P_ENUM,
3058 .p_class = P_LOCAL,
3059 .offset = LOCAL_VAR(iCSCPolicy),
3060 .special = NULL,
3061 .enum_list = enum_csc_policy,
3062 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3065 .label = "fake oplocks",
3066 .type = P_BOOL,
3067 .p_class = P_LOCAL,
3068 .offset = LOCAL_VAR(bFakeOplocks),
3069 .special = NULL,
3070 .enum_list = NULL,
3071 .flags = FLAG_ADVANCED | FLAG_SHARE,
3074 .label = "kernel oplocks",
3075 .type = P_BOOL,
3076 .p_class = P_LOCAL,
3077 .offset = LOCAL_VAR(bKernelOplocks),
3078 .special = NULL,
3079 .enum_list = NULL,
3080 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3083 .label = "locking",
3084 .type = P_BOOL,
3085 .p_class = P_LOCAL,
3086 .offset = LOCAL_VAR(bLocking),
3087 .special = NULL,
3088 .enum_list = NULL,
3089 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3092 .label = "lock spin time",
3093 .type = P_INTEGER,
3094 .p_class = P_GLOBAL,
3095 .offset = GLOBAL_VAR(iLockSpinTime),
3096 .special = NULL,
3097 .enum_list = NULL,
3098 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3101 .label = "oplocks",
3102 .type = P_BOOL,
3103 .p_class = P_LOCAL,
3104 .offset = LOCAL_VAR(bOpLocks),
3105 .special = NULL,
3106 .enum_list = NULL,
3107 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3110 .label = "level2 oplocks",
3111 .type = P_BOOL,
3112 .p_class = P_LOCAL,
3113 .offset = LOCAL_VAR(bLevel2OpLocks),
3114 .special = NULL,
3115 .enum_list = NULL,
3116 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3119 .label = "oplock break wait time",
3120 .type = P_INTEGER,
3121 .p_class = P_GLOBAL,
3122 .offset = GLOBAL_VAR(oplock_break_wait_time),
3123 .special = NULL,
3124 .enum_list = NULL,
3125 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3128 .label = "oplock contention limit",
3129 .type = P_INTEGER,
3130 .p_class = P_LOCAL,
3131 .offset = LOCAL_VAR(iOplockContentionLimit),
3132 .special = NULL,
3133 .enum_list = NULL,
3134 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3137 .label = "posix locking",
3138 .type = P_BOOL,
3139 .p_class = P_LOCAL,
3140 .offset = LOCAL_VAR(bPosixLocking),
3141 .special = NULL,
3142 .enum_list = NULL,
3143 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3146 .label = "strict locking",
3147 .type = P_ENUM,
3148 .p_class = P_LOCAL,
3149 .offset = LOCAL_VAR(iStrictLocking),
3150 .special = NULL,
3151 .enum_list = enum_bool_auto,
3152 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3155 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3158 .label = "ldap admin dn",
3159 .type = P_STRING,
3160 .p_class = P_GLOBAL,
3161 .offset = GLOBAL_VAR(szLdapAdminDn),
3162 .special = NULL,
3163 .enum_list = NULL,
3164 .flags = FLAG_ADVANCED,
3167 .label = "ldap delete dn",
3168 .type = P_BOOL,
3169 .p_class = P_GLOBAL,
3170 .offset = GLOBAL_VAR(ldap_delete_dn),
3171 .special = NULL,
3172 .enum_list = NULL,
3173 .flags = FLAG_ADVANCED,
3176 .label = "ldap group suffix",
3177 .type = P_STRING,
3178 .p_class = P_GLOBAL,
3179 .offset = GLOBAL_VAR(szLdapGroupSuffix),
3180 .special = NULL,
3181 .enum_list = NULL,
3182 .flags = FLAG_ADVANCED,
3185 .label = "ldap idmap suffix",
3186 .type = P_STRING,
3187 .p_class = P_GLOBAL,
3188 .offset = GLOBAL_VAR(szLdapIdmapSuffix),
3189 .special = NULL,
3190 .enum_list = NULL,
3191 .flags = FLAG_ADVANCED,
3194 .label = "ldap machine suffix",
3195 .type = P_STRING,
3196 .p_class = P_GLOBAL,
3197 .offset = GLOBAL_VAR(szLdapMachineSuffix),
3198 .special = NULL,
3199 .enum_list = NULL,
3200 .flags = FLAG_ADVANCED,
3203 .label = "ldap passwd sync",
3204 .type = P_ENUM,
3205 .p_class = P_GLOBAL,
3206 .offset = GLOBAL_VAR(ldap_passwd_sync),
3207 .special = NULL,
3208 .enum_list = enum_ldap_passwd_sync,
3209 .flags = FLAG_ADVANCED,
3212 .label = "ldap password sync",
3213 .type = P_ENUM,
3214 .p_class = P_GLOBAL,
3215 .offset = GLOBAL_VAR(ldap_passwd_sync),
3216 .special = NULL,
3217 .enum_list = enum_ldap_passwd_sync,
3218 .flags = FLAG_HIDE,
3221 .label = "ldap replication sleep",
3222 .type = P_INTEGER,
3223 .p_class = P_GLOBAL,
3224 .offset = GLOBAL_VAR(ldap_replication_sleep),
3225 .special = NULL,
3226 .enum_list = NULL,
3227 .flags = FLAG_ADVANCED,
3230 .label = "ldap suffix",
3231 .type = P_STRING,
3232 .p_class = P_GLOBAL,
3233 .offset = GLOBAL_VAR(szLdapSuffix),
3234 .special = NULL,
3235 .enum_list = NULL,
3236 .flags = FLAG_ADVANCED,
3239 .label = "ldap ssl",
3240 .type = P_ENUM,
3241 .p_class = P_GLOBAL,
3242 .offset = GLOBAL_VAR(ldap_ssl),
3243 .special = NULL,
3244 .enum_list = enum_ldap_ssl,
3245 .flags = FLAG_ADVANCED,
3248 .label = "ldap ssl ads",
3249 .type = P_BOOL,
3250 .p_class = P_GLOBAL,
3251 .offset = GLOBAL_VAR(ldap_ssl_ads),
3252 .special = NULL,
3253 .enum_list = NULL,
3254 .flags = FLAG_ADVANCED,
3257 .label = "ldap deref",
3258 .type = P_ENUM,
3259 .p_class = P_GLOBAL,
3260 .offset = GLOBAL_VAR(ldap_deref),
3261 .special = NULL,
3262 .enum_list = enum_ldap_deref,
3263 .flags = FLAG_ADVANCED,
3266 .label = "ldap follow referral",
3267 .type = P_ENUM,
3268 .p_class = P_GLOBAL,
3269 .offset = GLOBAL_VAR(ldap_follow_referral),
3270 .special = NULL,
3271 .enum_list = enum_bool_auto,
3272 .flags = FLAG_ADVANCED,
3275 .label = "ldap timeout",
3276 .type = P_INTEGER,
3277 .p_class = P_GLOBAL,
3278 .offset = GLOBAL_VAR(ldap_timeout),
3279 .special = NULL,
3280 .enum_list = NULL,
3281 .flags = FLAG_ADVANCED,
3284 .label = "ldap connection timeout",
3285 .type = P_INTEGER,
3286 .p_class = P_GLOBAL,
3287 .offset = GLOBAL_VAR(ldap_connection_timeout),
3288 .special = NULL,
3289 .enum_list = NULL,
3290 .flags = FLAG_ADVANCED,
3293 .label = "ldap page size",
3294 .type = P_INTEGER,
3295 .p_class = P_GLOBAL,
3296 .offset = GLOBAL_VAR(ldap_page_size),
3297 .special = NULL,
3298 .enum_list = NULL,
3299 .flags = FLAG_ADVANCED,
3302 .label = "ldap user suffix",
3303 .type = P_STRING,
3304 .p_class = P_GLOBAL,
3305 .offset = GLOBAL_VAR(szLdapUserSuffix),
3306 .special = NULL,
3307 .enum_list = NULL,
3308 .flags = FLAG_ADVANCED,
3311 .label = "ldap debug level",
3312 .type = P_INTEGER,
3313 .p_class = P_GLOBAL,
3314 .offset = GLOBAL_VAR(ldap_debug_level),
3315 .special = handle_ldap_debug_level,
3316 .enum_list = NULL,
3317 .flags = FLAG_ADVANCED,
3320 .label = "ldap debug threshold",
3321 .type = P_INTEGER,
3322 .p_class = P_GLOBAL,
3323 .offset = GLOBAL_VAR(ldap_debug_threshold),
3324 .special = NULL,
3325 .enum_list = NULL,
3326 .flags = FLAG_ADVANCED,
3329 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3332 .label = "eventlog list",
3333 .type = P_LIST,
3334 .p_class = P_GLOBAL,
3335 .offset = GLOBAL_VAR(szEventLogs),
3336 .special = NULL,
3337 .enum_list = NULL,
3338 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3341 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3344 .label = "add share command",
3345 .type = P_STRING,
3346 .p_class = P_GLOBAL,
3347 .offset = GLOBAL_VAR(szAddShareCommand),
3348 .special = NULL,
3349 .enum_list = NULL,
3350 .flags = FLAG_ADVANCED,
3353 .label = "change share command",
3354 .type = P_STRING,
3355 .p_class = P_GLOBAL,
3356 .offset = GLOBAL_VAR(szChangeShareCommand),
3357 .special = NULL,
3358 .enum_list = NULL,
3359 .flags = FLAG_ADVANCED,
3362 .label = "delete share command",
3363 .type = P_STRING,
3364 .p_class = P_GLOBAL,
3365 .offset = GLOBAL_VAR(szDeleteShareCommand),
3366 .special = NULL,
3367 .enum_list = NULL,
3368 .flags = FLAG_ADVANCED,
3371 .label = "config file",
3372 .type = P_STRING,
3373 .p_class = P_GLOBAL,
3374 .offset = GLOBAL_VAR(szConfigFile),
3375 .special = NULL,
3376 .enum_list = NULL,
3377 .flags = FLAG_HIDE|FLAG_META,
3380 .label = "preload",
3381 .type = P_STRING,
3382 .p_class = P_GLOBAL,
3383 .offset = GLOBAL_VAR(szAutoServices),
3384 .special = NULL,
3385 .enum_list = NULL,
3386 .flags = FLAG_ADVANCED,
3389 .label = "auto services",
3390 .type = P_STRING,
3391 .p_class = P_GLOBAL,
3392 .offset = GLOBAL_VAR(szAutoServices),
3393 .special = NULL,
3394 .enum_list = NULL,
3395 .flags = FLAG_ADVANCED,
3398 .label = "lock directory",
3399 .type = P_STRING,
3400 .p_class = P_GLOBAL,
3401 .offset = GLOBAL_VAR(szLockDir),
3402 .special = NULL,
3403 .enum_list = NULL,
3404 .flags = FLAG_ADVANCED,
3407 .label = "lock dir",
3408 .type = P_STRING,
3409 .p_class = P_GLOBAL,
3410 .offset = GLOBAL_VAR(szLockDir),
3411 .special = NULL,
3412 .enum_list = NULL,
3413 .flags = FLAG_HIDE,
3416 .label = "state directory",
3417 .type = P_STRING,
3418 .p_class = P_GLOBAL,
3419 .offset = GLOBAL_VAR(szStateDir),
3420 .special = NULL,
3421 .enum_list = NULL,
3422 .flags = FLAG_ADVANCED,
3425 .label = "cache directory",
3426 .type = P_STRING,
3427 .p_class = P_GLOBAL,
3428 .offset = GLOBAL_VAR(szCacheDir),
3429 .special = NULL,
3430 .enum_list = NULL,
3431 .flags = FLAG_ADVANCED,
3434 .label = "pid directory",
3435 .type = P_STRING,
3436 .p_class = P_GLOBAL,
3437 .offset = GLOBAL_VAR(szPidDir),
3438 .special = NULL,
3439 .enum_list = NULL,
3440 .flags = FLAG_ADVANCED,
3443 .label = "ntp signd socket directory",
3444 .type = P_STRING,
3445 .p_class = P_GLOBAL,
3446 .offset = GLOBAL_VAR(szNTPSignDSocketDirectory),
3447 .special = NULL,
3448 .enum_list = NULL,
3449 .flags = FLAG_ADVANCED,
3452 #ifdef WITH_UTMP
3454 .label = "utmp directory",
3455 .type = P_STRING,
3456 .p_class = P_GLOBAL,
3457 .offset = GLOBAL_VAR(szUtmpDir),
3458 .special = NULL,
3459 .enum_list = NULL,
3460 .flags = FLAG_ADVANCED,
3463 .label = "wtmp directory",
3464 .type = P_STRING,
3465 .p_class = P_GLOBAL,
3466 .offset = GLOBAL_VAR(szWtmpDir),
3467 .special = NULL,
3468 .enum_list = NULL,
3469 .flags = FLAG_ADVANCED,
3472 .label = "utmp",
3473 .type = P_BOOL,
3474 .p_class = P_GLOBAL,
3475 .offset = GLOBAL_VAR(bUtmp),
3476 .special = NULL,
3477 .enum_list = NULL,
3478 .flags = FLAG_ADVANCED,
3480 #endif
3482 .label = "default service",
3483 .type = P_STRING,
3484 .p_class = P_GLOBAL,
3485 .offset = GLOBAL_VAR(szDefaultService),
3486 .special = NULL,
3487 .enum_list = NULL,
3488 .flags = FLAG_ADVANCED,
3491 .label = "default",
3492 .type = P_STRING,
3493 .p_class = P_GLOBAL,
3494 .offset = GLOBAL_VAR(szDefaultService),
3495 .special = NULL,
3496 .enum_list = NULL,
3497 .flags = FLAG_ADVANCED,
3500 .label = "message command",
3501 .type = P_STRING,
3502 .p_class = P_GLOBAL,
3503 .offset = GLOBAL_VAR(szMsgCommand),
3504 .special = NULL,
3505 .enum_list = NULL,
3506 .flags = FLAG_ADVANCED,
3509 .label = "dfree cache time",
3510 .type = P_INTEGER,
3511 .p_class = P_LOCAL,
3512 .offset = LOCAL_VAR(iDfreeCacheTime),
3513 .special = NULL,
3514 .enum_list = NULL,
3515 .flags = FLAG_ADVANCED,
3518 .label = "dfree command",
3519 .type = P_STRING,
3520 .p_class = P_LOCAL,
3521 .offset = LOCAL_VAR(szDfree),
3522 .special = NULL,
3523 .enum_list = NULL,
3524 .flags = FLAG_ADVANCED,
3527 .label = "get quota command",
3528 .type = P_STRING,
3529 .p_class = P_GLOBAL,
3530 .offset = GLOBAL_VAR(szGetQuota),
3531 .special = NULL,
3532 .enum_list = NULL,
3533 .flags = FLAG_ADVANCED,
3536 .label = "set quota command",
3537 .type = P_STRING,
3538 .p_class = P_GLOBAL,
3539 .offset = GLOBAL_VAR(szSetQuota),
3540 .special = NULL,
3541 .enum_list = NULL,
3542 .flags = FLAG_ADVANCED,
3545 .label = "remote announce",
3546 .type = P_STRING,
3547 .p_class = P_GLOBAL,
3548 .offset = GLOBAL_VAR(szRemoteAnnounce),
3549 .special = NULL,
3550 .enum_list = NULL,
3551 .flags = FLAG_ADVANCED,
3554 .label = "remote browse sync",
3555 .type = P_STRING,
3556 .p_class = P_GLOBAL,
3557 .offset = GLOBAL_VAR(szRemoteBrowseSync),
3558 .special = NULL,
3559 .enum_list = NULL,
3560 .flags = FLAG_ADVANCED,
3563 .label = "socket address",
3564 .type = P_STRING,
3565 .p_class = P_GLOBAL,
3566 .offset = GLOBAL_VAR(szSocketAddress),
3567 .special = NULL,
3568 .enum_list = NULL,
3569 .flags = FLAG_ADVANCED,
3572 .label = "nmbd bind explicit broadcast",
3573 .type = P_BOOL,
3574 .p_class = P_GLOBAL,
3575 .offset = GLOBAL_VAR(bNmbdBindExplicitBroadcast),
3576 .special = NULL,
3577 .enum_list = NULL,
3578 .flags = FLAG_ADVANCED,
3581 .label = "homedir map",
3582 .type = P_STRING,
3583 .p_class = P_GLOBAL,
3584 .offset = GLOBAL_VAR(szNISHomeMapName),
3585 .special = NULL,
3586 .enum_list = NULL,
3587 .flags = FLAG_ADVANCED,
3590 .label = "afs username map",
3591 .type = P_STRING,
3592 .p_class = P_GLOBAL,
3593 .offset = GLOBAL_VAR(szAfsUsernameMap),
3594 .special = NULL,
3595 .enum_list = NULL,
3596 .flags = FLAG_ADVANCED,
3599 .label = "afs token lifetime",
3600 .type = P_INTEGER,
3601 .p_class = P_GLOBAL,
3602 .offset = GLOBAL_VAR(iAfsTokenLifetime),
3603 .special = NULL,
3604 .enum_list = NULL,
3605 .flags = FLAG_ADVANCED,
3608 .label = "log nt token command",
3609 .type = P_STRING,
3610 .p_class = P_GLOBAL,
3611 .offset = GLOBAL_VAR(szLogNtTokenCommand),
3612 .special = NULL,
3613 .enum_list = NULL,
3614 .flags = FLAG_ADVANCED,
3617 .label = "NIS homedir",
3618 .type = P_BOOL,
3619 .p_class = P_GLOBAL,
3620 .offset = GLOBAL_VAR(bNISHomeMap),
3621 .special = NULL,
3622 .enum_list = NULL,
3623 .flags = FLAG_ADVANCED,
3626 .label = "-valid",
3627 .type = P_BOOL,
3628 .p_class = P_LOCAL,
3629 .offset = LOCAL_VAR(valid),
3630 .special = NULL,
3631 .enum_list = NULL,
3632 .flags = FLAG_HIDE,
3635 .label = "copy",
3636 .type = P_STRING,
3637 .p_class = P_LOCAL,
3638 .offset = LOCAL_VAR(szCopy),
3639 .special = handle_copy,
3640 .enum_list = NULL,
3641 .flags = FLAG_HIDE,
3644 .label = "include",
3645 .type = P_STRING,
3646 .p_class = P_LOCAL,
3647 .offset = LOCAL_VAR(szInclude),
3648 .special = handle_include,
3649 .enum_list = NULL,
3650 .flags = FLAG_HIDE|FLAG_META,
3653 .label = "preexec",
3654 .type = P_STRING,
3655 .p_class = P_LOCAL,
3656 .offset = LOCAL_VAR(szPreExec),
3657 .special = NULL,
3658 .enum_list = NULL,
3659 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3662 .label = "exec",
3663 .type = P_STRING,
3664 .p_class = P_LOCAL,
3665 .offset = LOCAL_VAR(szPreExec),
3666 .special = NULL,
3667 .enum_list = NULL,
3668 .flags = FLAG_ADVANCED,
3671 .label = "preexec close",
3672 .type = P_BOOL,
3673 .p_class = P_LOCAL,
3674 .offset = LOCAL_VAR(bPreexecClose),
3675 .special = NULL,
3676 .enum_list = NULL,
3677 .flags = FLAG_ADVANCED | FLAG_SHARE,
3680 .label = "postexec",
3681 .type = P_STRING,
3682 .p_class = P_LOCAL,
3683 .offset = LOCAL_VAR(szPostExec),
3684 .special = NULL,
3685 .enum_list = NULL,
3686 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3689 .label = "root preexec",
3690 .type = P_STRING,
3691 .p_class = P_LOCAL,
3692 .offset = LOCAL_VAR(szRootPreExec),
3693 .special = NULL,
3694 .enum_list = NULL,
3695 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3698 .label = "root preexec close",
3699 .type = P_BOOL,
3700 .p_class = P_LOCAL,
3701 .offset = LOCAL_VAR(bRootpreexecClose),
3702 .special = NULL,
3703 .enum_list = NULL,
3704 .flags = FLAG_ADVANCED | FLAG_SHARE,
3707 .label = "root postexec",
3708 .type = P_STRING,
3709 .p_class = P_LOCAL,
3710 .offset = LOCAL_VAR(szRootPostExec),
3711 .special = NULL,
3712 .enum_list = NULL,
3713 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3716 .label = "available",
3717 .type = P_BOOL,
3718 .p_class = P_LOCAL,
3719 .offset = LOCAL_VAR(bAvailable),
3720 .special = NULL,
3721 .enum_list = NULL,
3722 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3725 .label = "registry shares",
3726 .type = P_BOOL,
3727 .p_class = P_GLOBAL,
3728 .offset = GLOBAL_VAR(bRegistryShares),
3729 .special = NULL,
3730 .enum_list = NULL,
3731 .flags = FLAG_ADVANCED,
3734 .label = "usershare allow guests",
3735 .type = P_BOOL,
3736 .p_class = P_GLOBAL,
3737 .offset = GLOBAL_VAR(bUsershareAllowGuests),
3738 .special = NULL,
3739 .enum_list = NULL,
3740 .flags = FLAG_ADVANCED,
3743 .label = "usershare max shares",
3744 .type = P_INTEGER,
3745 .p_class = P_GLOBAL,
3746 .offset = GLOBAL_VAR(iUsershareMaxShares),
3747 .special = NULL,
3748 .enum_list = NULL,
3749 .flags = FLAG_ADVANCED,
3752 .label = "usershare owner only",
3753 .type = P_BOOL,
3754 .p_class = P_GLOBAL,
3755 .offset = GLOBAL_VAR(bUsershareOwnerOnly),
3756 .special = NULL,
3757 .enum_list = NULL,
3758 .flags = FLAG_ADVANCED,
3761 .label = "usershare path",
3762 .type = P_STRING,
3763 .p_class = P_GLOBAL,
3764 .offset = GLOBAL_VAR(szUsersharePath),
3765 .special = NULL,
3766 .enum_list = NULL,
3767 .flags = FLAG_ADVANCED,
3770 .label = "usershare prefix allow list",
3771 .type = P_LIST,
3772 .p_class = P_GLOBAL,
3773 .offset = GLOBAL_VAR(szUsersharePrefixAllowList),
3774 .special = NULL,
3775 .enum_list = NULL,
3776 .flags = FLAG_ADVANCED,
3779 .label = "usershare prefix deny list",
3780 .type = P_LIST,
3781 .p_class = P_GLOBAL,
3782 .offset = GLOBAL_VAR(szUsersharePrefixDenyList),
3783 .special = NULL,
3784 .enum_list = NULL,
3785 .flags = FLAG_ADVANCED,
3788 .label = "usershare template share",
3789 .type = P_STRING,
3790 .p_class = P_GLOBAL,
3791 .offset = GLOBAL_VAR(szUsershareTemplateShare),
3792 .special = NULL,
3793 .enum_list = NULL,
3794 .flags = FLAG_ADVANCED,
3797 .label = "volume",
3798 .type = P_STRING,
3799 .p_class = P_LOCAL,
3800 .offset = LOCAL_VAR(volume),
3801 .special = NULL,
3802 .enum_list = NULL,
3803 .flags = FLAG_ADVANCED | FLAG_SHARE,
3806 .label = "fstype",
3807 .type = P_STRING,
3808 .p_class = P_LOCAL,
3809 .offset = LOCAL_VAR(fstype),
3810 .special = NULL,
3811 .enum_list = NULL,
3812 .flags = FLAG_ADVANCED | FLAG_SHARE,
3815 .label = "set directory",
3816 .type = P_BOOLREV,
3817 .p_class = P_LOCAL,
3818 .offset = LOCAL_VAR(bNo_set_dir),
3819 .special = NULL,
3820 .enum_list = NULL,
3821 .flags = FLAG_ADVANCED | FLAG_SHARE,
3824 .label = "allow insecure wide links",
3825 .type = P_BOOL,
3826 .p_class = P_GLOBAL,
3827 .offset = GLOBAL_VAR(bAllowInsecureWidelinks),
3828 .special = NULL,
3829 .enum_list = NULL,
3830 .flags = FLAG_ADVANCED,
3833 .label = "wide links",
3834 .type = P_BOOL,
3835 .p_class = P_LOCAL,
3836 .offset = LOCAL_VAR(bWidelinks),
3837 .special = NULL,
3838 .enum_list = NULL,
3839 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3842 .label = "follow symlinks",
3843 .type = P_BOOL,
3844 .p_class = P_LOCAL,
3845 .offset = LOCAL_VAR(bSymlinks),
3846 .special = NULL,
3847 .enum_list = NULL,
3848 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3851 .label = "dont descend",
3852 .type = P_STRING,
3853 .p_class = P_LOCAL,
3854 .offset = LOCAL_VAR(szDontdescend),
3855 .special = NULL,
3856 .enum_list = NULL,
3857 .flags = FLAG_ADVANCED | FLAG_SHARE,
3860 .label = "magic script",
3861 .type = P_STRING,
3862 .p_class = P_LOCAL,
3863 .offset = LOCAL_VAR(szMagicScript),
3864 .special = NULL,
3865 .enum_list = NULL,
3866 .flags = FLAG_ADVANCED | FLAG_SHARE,
3869 .label = "magic output",
3870 .type = P_STRING,
3871 .p_class = P_LOCAL,
3872 .offset = LOCAL_VAR(szMagicOutput),
3873 .special = NULL,
3874 .enum_list = NULL,
3875 .flags = FLAG_ADVANCED | FLAG_SHARE,
3878 .label = "delete readonly",
3879 .type = P_BOOL,
3880 .p_class = P_LOCAL,
3881 .offset = LOCAL_VAR(bDeleteReadonly),
3882 .special = NULL,
3883 .enum_list = NULL,
3884 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3887 .label = "dos filemode",
3888 .type = P_BOOL,
3889 .p_class = P_LOCAL,
3890 .offset = LOCAL_VAR(bDosFilemode),
3891 .special = NULL,
3892 .enum_list = NULL,
3893 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3896 .label = "dos filetimes",
3897 .type = P_BOOL,
3898 .p_class = P_LOCAL,
3899 .offset = LOCAL_VAR(bDosFiletimes),
3900 .special = NULL,
3901 .enum_list = NULL,
3902 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3905 .label = "dos filetime resolution",
3906 .type = P_BOOL,
3907 .p_class = P_LOCAL,
3908 .offset = LOCAL_VAR(bDosFiletimeResolution),
3909 .special = NULL,
3910 .enum_list = NULL,
3911 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3914 .label = "fake directory create times",
3915 .type = P_BOOL,
3916 .p_class = P_LOCAL,
3917 .offset = LOCAL_VAR(bFakeDirCreateTimes),
3918 .special = NULL,
3919 .enum_list = NULL,
3920 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3923 .label = "async smb echo handler",
3924 .type = P_BOOL,
3925 .p_class = P_GLOBAL,
3926 .offset = GLOBAL_VAR(bAsyncSMBEchoHandler),
3927 .special = NULL,
3928 .enum_list = NULL,
3929 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3932 .label = "panic action",
3933 .type = P_STRING,
3934 .p_class = P_GLOBAL,
3935 .offset = GLOBAL_VAR(szPanicAction),
3936 .special = NULL,
3937 .enum_list = NULL,
3938 .flags = FLAG_ADVANCED,
3941 .label = "perfcount module",
3942 .type = P_STRING,
3943 .p_class = P_GLOBAL,
3944 .offset = GLOBAL_VAR(szSMBPerfcountModule),
3945 .special = NULL,
3946 .enum_list = NULL,
3947 .flags = FLAG_ADVANCED,
3950 {N_("VFS module options"), P_SEP, P_SEPARATOR},
3953 .label = "vfs objects",
3954 .type = P_LIST,
3955 .p_class = P_LOCAL,
3956 .offset = LOCAL_VAR(szVfsObjects),
3957 .special = NULL,
3958 .enum_list = NULL,
3959 .flags = FLAG_ADVANCED | FLAG_SHARE,
3962 .label = "vfs object",
3963 .type = P_LIST,
3964 .p_class = P_LOCAL,
3965 .offset = LOCAL_VAR(szVfsObjects),
3966 .special = NULL,
3967 .enum_list = NULL,
3968 .flags = FLAG_HIDE,
3972 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
3975 .label = "msdfs root",
3976 .type = P_BOOL,
3977 .p_class = P_LOCAL,
3978 .offset = LOCAL_VAR(bMSDfsRoot),
3979 .special = NULL,
3980 .enum_list = NULL,
3981 .flags = FLAG_ADVANCED | FLAG_SHARE,
3984 .label = "msdfs proxy",
3985 .type = P_STRING,
3986 .p_class = P_LOCAL,
3987 .offset = LOCAL_VAR(szMSDfsProxy),
3988 .special = NULL,
3989 .enum_list = NULL,
3990 .flags = FLAG_ADVANCED | FLAG_SHARE,
3993 .label = "host msdfs",
3994 .type = P_BOOL,
3995 .p_class = P_GLOBAL,
3996 .offset = GLOBAL_VAR(bHostMSDfs),
3997 .special = NULL,
3998 .enum_list = NULL,
3999 .flags = FLAG_ADVANCED,
4002 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4005 .label = "passdb expand explicit",
4006 .type = P_BOOL,
4007 .p_class = P_GLOBAL,
4008 .offset = GLOBAL_VAR(bPassdbExpandExplicit),
4009 .special = NULL,
4010 .enum_list = NULL,
4011 .flags = FLAG_ADVANCED,
4014 .label = "idmap backend",
4015 .type = P_STRING,
4016 .p_class = P_GLOBAL,
4017 .offset = GLOBAL_VAR(szIdmapBackend),
4018 .special = handle_idmap_backend,
4019 .enum_list = NULL,
4020 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4023 .label = "idmap cache time",
4024 .type = P_INTEGER,
4025 .p_class = P_GLOBAL,
4026 .offset = GLOBAL_VAR(iIdmapCacheTime),
4027 .special = NULL,
4028 .enum_list = NULL,
4029 .flags = FLAG_ADVANCED,
4032 .label = "idmap negative cache time",
4033 .type = P_INTEGER,
4034 .p_class = P_GLOBAL,
4035 .offset = GLOBAL_VAR(iIdmapNegativeCacheTime),
4036 .special = NULL,
4037 .enum_list = NULL,
4038 .flags = FLAG_ADVANCED,
4041 .label = "idmap uid",
4042 .type = P_STRING,
4043 .p_class = P_GLOBAL,
4044 .offset = GLOBAL_VAR(szIdmapUID),
4045 .special = handle_idmap_uid,
4046 .enum_list = NULL,
4047 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4050 .label = "winbind uid",
4051 .type = P_STRING,
4052 .p_class = P_GLOBAL,
4053 .offset = GLOBAL_VAR(szIdmapUID),
4054 .special = handle_idmap_uid,
4055 .enum_list = NULL,
4056 .flags = FLAG_HIDE,
4059 .label = "idmap gid",
4060 .type = P_STRING,
4061 .p_class = P_GLOBAL,
4062 .offset = GLOBAL_VAR(szIdmapGID),
4063 .special = handle_idmap_gid,
4064 .enum_list = NULL,
4065 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4068 .label = "winbind gid",
4069 .type = P_STRING,
4070 .p_class = P_GLOBAL,
4071 .offset = GLOBAL_VAR(szIdmapGID),
4072 .special = handle_idmap_gid,
4073 .enum_list = NULL,
4074 .flags = FLAG_HIDE,
4077 .label = "template homedir",
4078 .type = P_STRING,
4079 .p_class = P_GLOBAL,
4080 .offset = GLOBAL_VAR(szTemplateHomedir),
4081 .special = NULL,
4082 .enum_list = NULL,
4083 .flags = FLAG_ADVANCED,
4086 .label = "template shell",
4087 .type = P_STRING,
4088 .p_class = P_GLOBAL,
4089 .offset = GLOBAL_VAR(szTemplateShell),
4090 .special = NULL,
4091 .enum_list = NULL,
4092 .flags = FLAG_ADVANCED,
4095 .label = "winbind separator",
4096 .type = P_STRING,
4097 .p_class = P_GLOBAL,
4098 .offset = GLOBAL_VAR(szWinbindSeparator),
4099 .special = NULL,
4100 .enum_list = NULL,
4101 .flags = FLAG_ADVANCED,
4104 .label = "winbind cache time",
4105 .type = P_INTEGER,
4106 .p_class = P_GLOBAL,
4107 .offset = GLOBAL_VAR(winbind_cache_time),
4108 .special = NULL,
4109 .enum_list = NULL,
4110 .flags = FLAG_ADVANCED,
4113 .label = "winbind reconnect delay",
4114 .type = P_INTEGER,
4115 .p_class = P_GLOBAL,
4116 .offset = GLOBAL_VAR(winbind_reconnect_delay),
4117 .special = NULL,
4118 .enum_list = NULL,
4119 .flags = FLAG_ADVANCED,
4122 .label = "winbind max clients",
4123 .type = P_INTEGER,
4124 .p_class = P_GLOBAL,
4125 .offset = GLOBAL_VAR(winbind_max_clients),
4126 .special = NULL,
4127 .enum_list = NULL,
4128 .flags = FLAG_ADVANCED,
4131 .label = "winbind enum users",
4132 .type = P_BOOL,
4133 .p_class = P_GLOBAL,
4134 .offset = GLOBAL_VAR(bWinbindEnumUsers),
4135 .special = NULL,
4136 .enum_list = NULL,
4137 .flags = FLAG_ADVANCED,
4140 .label = "winbind enum groups",
4141 .type = P_BOOL,
4142 .p_class = P_GLOBAL,
4143 .offset = GLOBAL_VAR(bWinbindEnumGroups),
4144 .special = NULL,
4145 .enum_list = NULL,
4146 .flags = FLAG_ADVANCED,
4149 .label = "winbind use default domain",
4150 .type = P_BOOL,
4151 .p_class = P_GLOBAL,
4152 .offset = GLOBAL_VAR(bWinbindUseDefaultDomain),
4153 .special = NULL,
4154 .enum_list = NULL,
4155 .flags = FLAG_ADVANCED,
4158 .label = "winbind trusted domains only",
4159 .type = P_BOOL,
4160 .p_class = P_GLOBAL,
4161 .offset = GLOBAL_VAR(bWinbindTrustedDomainsOnly),
4162 .special = NULL,
4163 .enum_list = NULL,
4164 .flags = FLAG_ADVANCED,
4167 .label = "winbind nested groups",
4168 .type = P_BOOL,
4169 .p_class = P_GLOBAL,
4170 .offset = GLOBAL_VAR(bWinbindNestedGroups),
4171 .special = NULL,
4172 .enum_list = NULL,
4173 .flags = FLAG_ADVANCED,
4176 .label = "winbind expand groups",
4177 .type = P_INTEGER,
4178 .p_class = P_GLOBAL,
4179 .offset = GLOBAL_VAR(winbind_expand_groups),
4180 .special = NULL,
4181 .enum_list = NULL,
4182 .flags = FLAG_ADVANCED,
4185 .label = "winbind nss info",
4186 .type = P_LIST,
4187 .p_class = P_GLOBAL,
4188 .offset = GLOBAL_VAR(szWinbindNssInfo),
4189 .special = NULL,
4190 .enum_list = NULL,
4191 .flags = FLAG_ADVANCED,
4194 .label = "winbind refresh tickets",
4195 .type = P_BOOL,
4196 .p_class = P_GLOBAL,
4197 .offset = GLOBAL_VAR(bWinbindRefreshTickets),
4198 .special = NULL,
4199 .enum_list = NULL,
4200 .flags = FLAG_ADVANCED,
4203 .label = "winbind offline logon",
4204 .type = P_BOOL,
4205 .p_class = P_GLOBAL,
4206 .offset = GLOBAL_VAR(bWinbindOfflineLogon),
4207 .special = NULL,
4208 .enum_list = NULL,
4209 .flags = FLAG_ADVANCED,
4212 .label = "winbind normalize names",
4213 .type = P_BOOL,
4214 .p_class = P_GLOBAL,
4215 .offset = GLOBAL_VAR(bWinbindNormalizeNames),
4216 .special = NULL,
4217 .enum_list = NULL,
4218 .flags = FLAG_ADVANCED,
4221 .label = "winbind rpc only",
4222 .type = P_BOOL,
4223 .p_class = P_GLOBAL,
4224 .offset = GLOBAL_VAR(bWinbindRpcOnly),
4225 .special = NULL,
4226 .enum_list = NULL,
4227 .flags = FLAG_ADVANCED,
4230 .label = "create krb5 conf",
4231 .type = P_BOOL,
4232 .p_class = P_GLOBAL,
4233 .offset = GLOBAL_VAR(bCreateKrb5Conf),
4234 .special = NULL,
4235 .enum_list = NULL,
4236 .flags = FLAG_ADVANCED,
4239 .label = "ncalrpc dir",
4240 .type = P_STRING,
4241 .p_class = P_GLOBAL,
4242 .offset = GLOBAL_VAR(ncalrpc_dir),
4243 .special = NULL,
4244 .enum_list = NULL,
4245 .flags = FLAG_ADVANCED,
4248 .label = "winbind max domain connections",
4249 .type = P_INTEGER,
4250 .p_class = P_GLOBAL,
4251 .offset = GLOBAL_VAR(winbindMaxDomainConnections),
4252 .special = NULL,
4253 .enum_list = NULL,
4254 .flags = FLAG_ADVANCED,
4257 .label = "winbindd socket directory",
4258 .type = P_STRING,
4259 .p_class = P_GLOBAL,
4260 .offset = GLOBAL_VAR(szWinbinddSocketDirectory),
4261 .special = NULL,
4262 .enum_list = NULL,
4263 .flags = FLAG_ADVANCED,
4266 .label = "winbindd privileged socket directory",
4267 .type = P_STRING,
4268 .p_class = P_GLOBAL,
4269 .offset = GLOBAL_VAR(szWinbinddPrivilegedSocketDirectory),
4270 .special = NULL,
4271 .enum_list = NULL,
4272 .flags = FLAG_ADVANCED,
4275 .label = "winbind sealed pipes",
4276 .type = P_BOOL,
4277 .p_class = P_GLOBAL,
4278 .offset = GLOBAL_VAR(bWinbindSealedPipes),
4279 .special = NULL,
4280 .enum_list = NULL,
4281 .flags = FLAG_ADVANCED,
4284 {N_("DNS options"), P_SEP, P_SEPARATOR},
4286 .label = "allow dns updates",
4287 .type = P_ENUM,
4288 .p_class = P_GLOBAL,
4289 .offset = GLOBAL_VAR(allow_dns_updates),
4290 .special = NULL,
4291 .enum_list = enum_dns_update_settings,
4292 .flags = FLAG_ADVANCED,
4295 .label = "dns forwarder",
4296 .type = P_STRING,
4297 .p_class = P_GLOBAL,
4298 .offset = GLOBAL_VAR(dns_forwarder),
4299 .special = NULL,
4300 .enum_list = NULL,
4301 .flags = FLAG_ADVANCED,
4304 .label = "dns recursive queries",
4305 .type = P_BOOL,
4306 .p_class = P_GLOBAL,
4307 .offset = GLOBAL_VAR(dns_recursive_queries),
4308 .special = NULL,
4309 .enum_list = NULL
4312 .label = "dns update command",
4313 .type = P_CMDLIST,
4314 .p_class = P_GLOBAL,
4315 .offset = GLOBAL_VAR(szDNSUpdateCommand),
4316 .special = NULL,
4317 .enum_list = NULL,
4318 .flags = FLAG_ADVANCED,
4321 .label = "nsupdate command",
4322 .type = P_CMDLIST,
4323 .p_class = P_GLOBAL,
4324 .offset = GLOBAL_VAR(szNSUpdateCommand),
4325 .special = NULL,
4326 .enum_list = NULL,
4327 .flags = FLAG_ADVANCED,
4330 .label = "rndc command",
4331 .type = P_CMDLIST,
4332 .p_class = P_GLOBAL,
4333 .offset = GLOBAL_VAR(szRNDCCommand),
4334 .special = NULL,
4335 .enum_list = NULL,
4336 .flags = FLAG_ADVANCED,
4339 .label = "multicast dns register",
4340 .type = P_BOOL,
4341 .p_class = P_GLOBAL,
4342 .offset = GLOBAL_VAR(bMulticastDnsRegister),
4343 .special = NULL,
4344 .enum_list = NULL,
4345 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4348 {N_("AD DC options"), P_SEP, P_SEPARATOR},
4351 .label = "samba kcc command",
4352 .type = P_CMDLIST,
4353 .p_class = P_GLOBAL,
4354 .offset = GLOBAL_VAR(szSambaKCCCommand),
4355 .special = NULL,
4356 .enum_list = NULL,
4357 .flags = FLAG_ADVANCED,
4360 .label = "server services",
4361 .type = P_LIST,
4362 .p_class = P_GLOBAL,
4363 .offset = GLOBAL_VAR(server_services),
4364 .special = NULL,
4365 .enum_list = NULL
4368 .label = "dcerpc endpoint servers",
4369 .type = P_LIST,
4370 .p_class = P_GLOBAL,
4371 .offset = GLOBAL_VAR(dcerpc_ep_servers),
4372 .special = NULL,
4373 .enum_list = NULL
4376 .label = "spn update command",
4377 .type = P_CMDLIST,
4378 .p_class = P_GLOBAL,
4379 .offset = GLOBAL_VAR(szSPNUpdateCommand),
4380 .special = NULL,
4381 .enum_list = NULL,
4382 .flags = FLAG_ADVANCED,
4385 .label = "share backend",
4386 .type = P_STRING,
4387 .p_class = P_GLOBAL,
4388 .offset = GLOBAL_VAR(szShareBackend),
4389 .special = NULL,
4390 .enum_list = NULL
4393 .label = "ntvfs handler",
4394 .type = P_LIST,
4395 .p_class = P_LOCAL,
4396 .offset = LOCAL_VAR(ntvfs_handler),
4397 .special = NULL,
4398 .enum_list = NULL
4401 {N_("TLS options"), P_SEP, P_SEPARATOR},
4404 .label = "tls enabled",
4405 .type = P_BOOL,
4406 .p_class = P_GLOBAL,
4407 .offset = GLOBAL_VAR(tls_enabled),
4408 .special = NULL,
4409 .enum_list = NULL
4412 .label = "tls keyfile",
4413 .type = P_STRING,
4414 .p_class = P_GLOBAL,
4415 .offset = GLOBAL_VAR(tls_keyfile),
4416 .special = NULL,
4417 .enum_list = NULL
4420 .label = "tls certfile",
4421 .type = P_STRING,
4422 .p_class = P_GLOBAL,
4423 .offset = GLOBAL_VAR(tls_certfile),
4424 .special = NULL,
4425 .enum_list = NULL
4428 .label = "tls cafile",
4429 .type = P_STRING,
4430 .p_class = P_GLOBAL,
4431 .offset = GLOBAL_VAR(tls_cafile),
4432 .special = NULL,
4433 .enum_list = NULL
4436 .label = "tls crlfile",
4437 .type = P_STRING,
4438 .p_class = P_GLOBAL,
4439 .offset = GLOBAL_VAR(tls_crlfile),
4440 .special = NULL,
4441 .enum_list = NULL
4444 .label = "tls dh params file",
4445 .type = P_STRING,
4446 .p_class = P_GLOBAL,
4447 .offset = GLOBAL_VAR(tls_dhpfile),
4448 .special = NULL,
4449 .enum_list = NULL
4452 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
4455 /***************************************************************************
4456 Initialise the sDefault parameter structure for the printer values.
4457 ***************************************************************************/
4459 static void init_printer_values(struct loadparm_service *pService)
4461 /* choose defaults depending on the type of printing */
4462 switch (pService->iPrinting) {
4463 case PRINT_BSD:
4464 case PRINT_AIX:
4465 case PRINT_LPRNT:
4466 case PRINT_LPROS2:
4467 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4468 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4469 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4470 break;
4472 case PRINT_LPRNG:
4473 case PRINT_PLP:
4474 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4475 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4476 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4477 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4478 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4479 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4480 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4481 break;
4483 case PRINT_CUPS:
4484 case PRINT_IPRINT:
4485 #ifdef HAVE_CUPS
4486 /* set the lpq command to contain the destination printer
4487 name only. This is used by cups_queue_get() */
4488 string_set(&pService->szLpqcommand, "%p");
4489 string_set(&pService->szLprmcommand, "");
4490 string_set(&pService->szPrintcommand, "");
4491 string_set(&pService->szLppausecommand, "");
4492 string_set(&pService->szLpresumecommand, "");
4493 string_set(&pService->szQueuepausecommand, "");
4494 string_set(&pService->szQueueresumecommand, "");
4495 #else
4496 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4497 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4498 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4499 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4500 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4501 string_set(&pService->szQueuepausecommand, "disable '%p'");
4502 string_set(&pService->szQueueresumecommand, "enable '%p'");
4503 #endif /* HAVE_CUPS */
4504 break;
4506 case PRINT_SYSV:
4507 case PRINT_HPUX:
4508 string_set(&pService->szLpqcommand, "lpstat -o%p");
4509 string_set(&pService->szLprmcommand, "cancel %p-%j");
4510 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4511 string_set(&pService->szQueuepausecommand, "disable %p");
4512 string_set(&pService->szQueueresumecommand, "enable %p");
4513 #ifndef HPUX
4514 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4515 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4516 #endif /* HPUX */
4517 break;
4519 case PRINT_QNX:
4520 string_set(&pService->szLpqcommand, "lpq -P%p");
4521 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4522 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4523 break;
4525 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4527 case PRINT_TEST:
4528 case PRINT_VLP: {
4529 const char *tdbfile;
4530 TALLOC_CTX *tmp_ctx = talloc_stackframe();
4531 char *tmp;
4533 tdbfile = talloc_asprintf(
4534 tmp_ctx, "tdbfile=%s",
4535 lp_parm_const_string(-1, "vlp", "tdbfile",
4536 "/tmp/vlp.tdb"));
4537 if (tdbfile == NULL) {
4538 tdbfile="tdbfile=/tmp/vlp.tdb";
4541 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
4542 tdbfile);
4543 string_set(&pService->szPrintcommand,
4544 tmp ? tmp : "vlp print %p %s");
4546 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
4547 tdbfile);
4548 string_set(&pService->szLpqcommand,
4549 tmp ? tmp : "vlp lpq %p");
4551 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
4552 tdbfile);
4553 string_set(&pService->szLprmcommand,
4554 tmp ? tmp : "vlp lprm %p %j");
4556 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
4557 tdbfile);
4558 string_set(&pService->szLppausecommand,
4559 tmp ? tmp : "vlp lppause %p %j");
4561 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
4562 tdbfile);
4563 string_set(&pService->szLpresumecommand,
4564 tmp ? tmp : "vlp lpresume %p %j");
4566 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
4567 tdbfile);
4568 string_set(&pService->szQueuepausecommand,
4569 tmp ? tmp : "vlp queuepause %p");
4571 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
4572 tdbfile);
4573 string_set(&pService->szQueueresumecommand,
4574 tmp ? tmp : "vlp queueresume %p");
4575 TALLOC_FREE(tmp_ctx);
4577 break;
4579 #endif /* DEVELOPER */
4584 * Function to return the default value for the maximum number of open
4585 * file descriptors permitted. This function tries to consult the
4586 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4587 * the smaller of those.
4589 static int max_open_files(void)
4591 int sysctl_max = MAX_OPEN_FILES;
4592 int rlimit_max = MAX_OPEN_FILES;
4594 #ifdef HAVE_SYSCTLBYNAME
4596 size_t size = sizeof(sysctl_max);
4597 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4600 #endif
4602 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4604 struct rlimit rl;
4606 ZERO_STRUCT(rl);
4608 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4609 rlimit_max = rl.rlim_cur;
4611 #if defined(RLIM_INFINITY)
4612 if(rl.rlim_cur == RLIM_INFINITY)
4613 rlimit_max = MAX_OPEN_FILES;
4614 #endif
4616 #endif
4618 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4619 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4620 "minimum Windows limit (%d)\n",
4621 sysctl_max,
4622 MIN_OPEN_FILES_WINDOWS));
4623 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4626 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4627 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4628 "minimum Windows limit (%d)\n",
4629 rlimit_max,
4630 MIN_OPEN_FILES_WINDOWS));
4631 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4634 return MIN(sysctl_max, rlimit_max);
4638 * Common part of freeing allocated data for one parameter.
4640 static void free_one_parameter_common(void *parm_ptr,
4641 struct parm_struct parm)
4643 if ((parm.type == P_STRING) ||
4644 (parm.type == P_USTRING))
4646 string_free((char**)parm_ptr);
4647 } else if (parm.type == P_LIST) {
4648 TALLOC_FREE(*((char***)parm_ptr));
4653 * Free the allocated data for one parameter for a share
4654 * given as a service struct.
4656 static void free_one_parameter(struct loadparm_service *service,
4657 struct parm_struct parm)
4659 void *parm_ptr;
4661 if (parm.p_class != P_LOCAL) {
4662 return;
4665 parm_ptr = lp_parm_ptr(service, &parm);
4667 free_one_parameter_common(parm_ptr, parm);
4671 * Free the allocated parameter data of a share given
4672 * as a service struct.
4674 static void free_parameters(struct loadparm_service *service)
4676 uint32_t i;
4678 for (i=0; parm_table[i].label; i++) {
4679 free_one_parameter(service, parm_table[i]);
4684 * Free the allocated data for one parameter for a given share
4685 * specified by an snum.
4687 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4689 void *parm_ptr;
4691 if (snum < 0) {
4692 parm_ptr = lp_parm_ptr(NULL, &parm);
4693 } else if (parm.p_class != P_LOCAL) {
4694 return;
4695 } else {
4696 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
4699 free_one_parameter_common(parm_ptr, parm);
4703 * Free the allocated parameter data for a share specified
4704 * by an snum.
4706 static void free_parameters_by_snum(int snum)
4708 uint32_t i;
4710 for (i=0; parm_table[i].label; i++) {
4711 free_one_parameter_by_snum(snum, parm_table[i]);
4716 * Free the allocated global parameters.
4718 static void free_global_parameters(void)
4720 free_param_opts(&Globals.param_opt);
4721 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4724 static int map_parameter(const char *pszParmName);
4726 struct lp_stored_option {
4727 struct lp_stored_option *prev, *next;
4728 const char *label;
4729 const char *value;
4732 static struct lp_stored_option *stored_options;
4735 save options set by lp_set_cmdline() into a list. This list is
4736 re-applied when we do a globals reset, so that cmdline set options
4737 are sticky across reloads of smb.conf
4739 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
4741 struct lp_stored_option *entry, *entry_next;
4742 for (entry = stored_options; entry != NULL; entry = entry_next) {
4743 entry_next = entry->next;
4744 if (strcmp(pszParmName, entry->label) == 0) {
4745 DLIST_REMOVE(stored_options, entry);
4746 talloc_free(entry);
4747 break;
4751 entry = talloc(NULL, struct lp_stored_option);
4752 if (!entry) {
4753 return false;
4756 entry->label = talloc_strdup(entry, pszParmName);
4757 if (!entry->label) {
4758 talloc_free(entry);
4759 return false;
4762 entry->value = talloc_strdup(entry, pszParmValue);
4763 if (!entry->value) {
4764 talloc_free(entry);
4765 return false;
4768 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
4770 return true;
4773 static bool apply_lp_set_cmdline(void)
4775 struct lp_stored_option *entry = NULL;
4776 for (entry = stored_options; entry != NULL; entry = entry->next) {
4777 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
4778 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
4779 entry->label, entry->value));
4780 return false;
4783 return true;
4786 /***************************************************************************
4787 Initialise the global parameter structure.
4788 ***************************************************************************/
4790 static void init_globals(bool reinit_globals)
4792 static bool done_init = false;
4793 char *s = NULL;
4794 int i;
4796 /* If requested to initialize only once and we've already done it... */
4797 if (!reinit_globals && done_init) {
4798 /* ... then we have nothing more to do */
4799 return;
4802 if (!done_init) {
4803 /* The logfile can be set before this is invoked. Free it if so. */
4804 if (Globals.logfile != NULL) {
4805 string_free(&Globals.logfile);
4806 Globals.logfile = NULL;
4808 done_init = true;
4809 } else {
4810 free_global_parameters();
4813 /* This memset and the free_global_parameters() above will
4814 * wipe out smb.conf options set with lp_set_cmdline(). The
4815 * apply_lp_set_cmdline() call puts these values back in the
4816 * table once the defaults are set */
4817 ZERO_STRUCT(Globals);
4819 for (i = 0; parm_table[i].label; i++) {
4820 if ((parm_table[i].type == P_STRING ||
4821 parm_table[i].type == P_USTRING))
4823 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
4828 string_set(&sDefault.fstype, FSTYPE_STRING);
4829 string_set(&sDefault.szPrintjobUsername, "%U");
4831 init_printer_values(&sDefault);
4834 DEBUG(3, ("Initialising global parameters\n"));
4836 /* Must manually force to upper case here, as this does not go via the handler */
4837 string_set(&Globals.szNetbiosName, myhostname_upper());
4839 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4840 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4842 /* use the new 'hash2' method by default, with a prefix of 1 */
4843 string_set(&Globals.szManglingMethod, "hash2");
4844 Globals.mangle_prefix = 1;
4846 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4848 /* using UTF8 by default allows us to support all chars */
4849 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4851 /* Use codepage 850 as a default for the dos character set */
4852 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4855 * Allow the default PASSWD_CHAT to be overridden in local.h.
4857 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4859 string_set(&Globals.szWorkgroup, DEFAULT_WORKGROUP);
4861 string_set(&Globals.szPasswdProgram, "");
4862 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4863 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4864 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4865 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4866 string_set(&Globals.szSocketAddress, "0.0.0.0");
4868 * By default support explicit binding to broadcast
4869 * addresses.
4871 Globals.bNmbdBindExplicitBroadcast = true;
4873 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4874 smb_panic("init_globals: ENOMEM");
4876 string_set(&Globals.szServerString, s);
4877 SAFE_FREE(s);
4878 #ifdef DEVELOPER
4879 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4880 #endif
4882 string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
4884 string_set(&Globals.szLogonDrive, "");
4885 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4886 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4887 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4889 Globals.szNameResolveOrder = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
4890 string_set(&Globals.szPasswordServer, "*");
4892 Globals.AlgorithmicRidBase = BASE_RID;
4894 Globals.bLoadPrinters = true;
4895 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4897 Globals.ConfigBackend = config_backend;
4898 Globals.server_role = ROLE_AUTO;
4900 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4901 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4902 Globals.max_xmit = 0x4104;
4903 Globals.max_mux = 50; /* This is *needed* for profile support. */
4904 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4905 Globals.bDisableSpoolss = false;
4906 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4907 Globals.pwordlevel = 0;
4908 Globals.unamelevel = 0;
4909 Globals.deadtime = 0;
4910 Globals.getwd_cache = true;
4911 Globals.bLargeReadwrite = true;
4912 Globals.max_log_size = 5000;
4913 Globals.max_open_files = max_open_files();
4914 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4915 Globals.srv_maxprotocol = PROTOCOL_SMB2_10;
4916 Globals.srv_minprotocol = PROTOCOL_LANMAN1;
4917 Globals.security = SEC_USER;
4918 Globals.paranoid_server_security = true;
4919 Globals.bEncryptPasswords = true;
4920 Globals.clientSchannel = Auto;
4921 Globals.serverSchannel = Auto;
4922 Globals.bReadRaw = true;
4923 Globals.bWriteRaw = true;
4924 Globals.bNullPasswords = false;
4925 Globals.bObeyPamRestrictions = false;
4926 Globals.syslog = 1;
4927 Globals.bSyslogOnly = false;
4928 Globals.bTimestampLogs = true;
4929 string_set(&Globals.loglevel, "0");
4930 Globals.bDebugPrefixTimestamp = false;
4931 Globals.bDebugHiresTimestamp = true;
4932 Globals.bDebugPid = false;
4933 Globals.bDebugUid = false;
4934 Globals.bDebugClass = false;
4935 Globals.bEnableCoreFiles = true;
4936 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4937 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4938 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4939 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4940 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
4941 Globals.lm_interval = 60;
4942 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4943 Globals.bNISHomeMap = false;
4944 #ifdef WITH_NISPLUS_HOME
4945 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4946 #else
4947 string_set(&Globals.szNISHomeMapName, "auto.home");
4948 #endif
4949 #endif
4950 Globals.bTimeServer = false;
4951 Globals.bBindInterfacesOnly = false;
4952 Globals.bUnixPasswdSync = false;
4953 Globals.bPamPasswordChange = false;
4954 Globals.bPasswdChatDebug = false;
4955 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4956 Globals.bNTPipeSupport = true; /* Do NT pipes by default. */
4957 Globals.bNTStatusSupport = true; /* Use NT status by default. */
4958 Globals.bStatCache = true; /* use stat cache by default */
4959 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4960 Globals.restrict_anonymous = 0;
4961 Globals.bClientLanManAuth = false; /* Do NOT use the LanMan hash if it is available */
4962 Globals.bClientPlaintextAuth = false; /* Do NOT use a plaintext password even if is requested by the server */
4963 Globals.bLanmanAuth = false; /* Do NOT use the LanMan hash, even if it is supplied */
4964 Globals.bNTLMAuth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4965 Globals.bClientNTLMv2Auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
4966 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
4968 Globals.map_to_guest = 0; /* By Default, "Never" */
4969 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4970 Globals.enhanced_browsing = true;
4971 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4972 #ifdef MMAP_BLACKLIST
4973 Globals.bUseMmap = false;
4974 #else
4975 Globals.bUseMmap = true;
4976 #endif
4977 Globals.bUnicode = true;
4978 Globals.bUnixExtensions = true;
4979 Globals.bResetOnZeroVC = false;
4980 Globals.bLogWriteableFilesOnExit = false;
4981 Globals.bCreateKrb5Conf = true;
4982 Globals.winbindMaxDomainConnections = 1;
4984 /* hostname lookups can be very expensive and are broken on
4985 a large number of sites (tridge) */
4986 Globals.bHostnameLookups = false;
4988 string_set(&Globals.passdb_backend, "tdbsam");
4989 string_set(&Globals.szLdapSuffix, "");
4990 string_set(&Globals.szLdapMachineSuffix, "");
4991 string_set(&Globals.szLdapUserSuffix, "");
4992 string_set(&Globals.szLdapGroupSuffix, "");
4993 string_set(&Globals.szLdapIdmapSuffix, "");
4995 string_set(&Globals.szLdapAdminDn, "");
4996 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4997 Globals.ldap_ssl_ads = false;
4998 Globals.ldap_deref = -1;
4999 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5000 Globals.ldap_delete_dn = false;
5001 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5002 Globals.ldap_follow_referral = Auto;
5003 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5004 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5005 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5007 Globals.ldap_debug_level = 0;
5008 Globals.ldap_debug_threshold = 10;
5010 /* This is what we tell the afs client. in reality we set the token
5011 * to never expire, though, when this runs out the afs client will
5012 * forget the token. Set to 0 to get NEVERDATE.*/
5013 Globals.iAfsTokenLifetime = 604800;
5014 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5016 /* these parameters are set to defaults that are more appropriate
5017 for the increasing samba install base:
5019 as a member of the workgroup, that will possibly become a
5020 _local_ master browser (lm = true). this is opposed to a forced
5021 local master browser startup (pm = true).
5023 doesn't provide WINS server service by default (wsupp = false),
5024 and doesn't provide domain master browser services by default, either.
5028 Globals.bMsAddPrinterWizard = true;
5029 Globals.os_level = 20;
5030 Globals.bLocalMaster = true;
5031 Globals.domain_master = Auto; /* depending on bDomainLogons */
5032 Globals.bDomainLogons = false;
5033 Globals.bBrowseList = true;
5034 Globals.bWINSsupport = false;
5035 Globals.bWINSproxy = false;
5037 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5038 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5040 Globals.bWINSdnsProxy = true;
5042 Globals.bAllowTrustedDomains = true;
5043 string_set(&Globals.szIdmapBackend, "tdb");
5045 string_set(&Globals.szTemplateShell, "/bin/false");
5046 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5047 string_set(&Globals.szWinbindSeparator, "\\");
5049 string_set(&Globals.szCupsServer, "");
5050 string_set(&Globals.szIPrintServer, "");
5052 #ifdef CLUSTER_SUPPORT
5053 string_set(&Globals.ctdbdSocket, CTDB_PATH);
5054 #else
5055 string_set(&Globals.ctdbdSocket, "");
5056 #endif
5058 Globals.szClusterAddresses = NULL;
5059 Globals.clustering = false;
5060 Globals.ctdb_timeout = 0;
5061 Globals.ctdb_locktime_warn_threshold = 0;
5063 Globals.winbind_cache_time = 300; /* 5 minutes */
5064 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5065 Globals.winbind_max_clients = 200;
5066 Globals.bWinbindEnumUsers = false;
5067 Globals.bWinbindEnumGroups = false;
5068 Globals.bWinbindUseDefaultDomain = false;
5069 Globals.bWinbindTrustedDomainsOnly = false;
5070 Globals.bWinbindNestedGroups = true;
5071 Globals.winbind_expand_groups = 1;
5072 Globals.szWinbindNssInfo = (const char **)str_list_make_v3(NULL, "template", NULL);
5073 Globals.bWinbindRefreshTickets = false;
5074 Globals.bWinbindOfflineLogon = false;
5076 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5077 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5079 Globals.bPassdbExpandExplicit = false;
5081 Globals.name_cache_timeout = 660; /* In seconds */
5083 Globals.bUseSpnego = true;
5084 Globals.bClientUseSpnego = true;
5086 Globals.client_signing = SMB_SIGNING_DEFAULT;
5087 Globals.server_signing = SMB_SIGNING_DEFAULT;
5089 Globals.bDeferSharingViolations = true;
5090 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
5092 Globals.bEnablePrivileges = true;
5093 Globals.bHostMSDfs = true;
5094 Globals.bASUSupport = false;
5096 /* User defined shares. */
5097 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5098 smb_panic("init_globals: ENOMEM");
5100 string_set(&Globals.szUsersharePath, s);
5101 SAFE_FREE(s);
5102 string_set(&Globals.szUsershareTemplateShare, "");
5103 Globals.iUsershareMaxShares = 0;
5104 /* By default disallow sharing of directories not owned by the sharer. */
5105 Globals.bUsershareOwnerOnly = true;
5106 /* By default disallow guest access to usershares. */
5107 Globals.bUsershareAllowGuests = false;
5109 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5111 /* By default no shares out of the registry */
5112 Globals.bRegistryShares = false;
5114 Globals.iminreceivefile = 0;
5116 Globals.bMapUntrustedToDomain = false;
5117 Globals.bMulticastDnsRegister = true;
5119 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5120 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5121 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5122 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5124 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5126 /* Now put back the settings that were set with lp_set_cmdline() */
5127 apply_lp_set_cmdline();
5130 /*******************************************************************
5131 Convenience routine to grab string parameters into talloced memory
5132 and run standard_sub_basic on them. The buffers can be written to by
5133 callers without affecting the source string.
5134 ********************************************************************/
5136 static char *lp_string(TALLOC_CTX *ctx, const char *s)
5138 char *ret;
5140 /* The follow debug is useful for tracking down memory problems
5141 especially if you have an inner loop that is calling a lp_*()
5142 function that returns a string. Perhaps this debug should be
5143 present all the time? */
5145 #if 0
5146 DEBUG(10, ("lp_string(%s)\n", s));
5147 #endif
5148 if (!s) {
5149 return NULL;
5152 ret = talloc_sub_basic(ctx,
5153 get_current_username(),
5154 current_user_info.domain,
5156 if (trim_char(ret, '\"', '\"')) {
5157 if (strchr(ret,'\"') != NULL) {
5158 TALLOC_FREE(ret);
5159 ret = talloc_sub_basic(ctx,
5160 get_current_username(),
5161 current_user_info.domain,
5165 return ret;
5169 In this section all the functions that are used to access the
5170 parameters from the rest of the program are defined
5173 #define FN_GLOBAL_STRING(fn_name,ptr) \
5174 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
5175 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5176 const char *lp_ ## fn_name(void) {return(*(const char **)(&Globals.ptr) ? *(const char **)(&Globals.ptr) : "");}
5177 #define FN_GLOBAL_LIST(fn_name,ptr) \
5178 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
5179 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5180 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
5181 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5182 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
5183 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5184 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
5186 #define FN_LOCAL_STRING(fn_name,val) \
5187 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5188 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5189 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5190 #define FN_LOCAL_LIST(fn_name,val) \
5191 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5192 #define FN_LOCAL_BOOL(fn_name,val) \
5193 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5194 #define FN_LOCAL_INTEGER(fn_name,val) \
5195 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5197 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5198 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5199 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5200 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5201 #define FN_LOCAL_CHAR(fn_name,val) \
5202 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5205 static FN_GLOBAL_BOOL(_readraw, bReadRaw)
5206 static FN_GLOBAL_BOOL(_writeraw, bWriteRaw)
5208 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5209 * build process or in smb.conf, we use that value. Otherwise they
5210 * default to the value of lp_lockdir(). */
5211 const char *lp_statedir(void) {
5212 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5213 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5214 return(*(char **)(&Globals.szStateDir) ?
5215 *(char **)(&Globals.szStateDir) : "");
5216 else
5217 return(*(char **)(&Globals.szLockDir) ?
5218 *(char **)(&Globals.szLockDir) : "");
5220 const char *lp_cachedir(void) {
5221 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5222 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5223 return(*(char **)(&Globals.szCacheDir) ?
5224 *(char **)(&Globals.szCacheDir) : "");
5225 else
5226 return(*(char **)(&Globals.szLockDir) ?
5227 *(char **)(&Globals.szLockDir) : "");
5229 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
5230 winbindMaxDomainConnections)
5232 int lp_winbind_max_domain_connections(void)
5234 if (lp_winbind_offline_logon() &&
5235 lp_winbind_max_domain_connections_int() > 1) {
5236 DEBUG(1, ("offline logons active, restricting max domain "
5237 "connections to 1\n"));
5238 return 1;
5240 return MAX(1, lp_winbind_max_domain_connections_int());
5243 int lp_smb2_max_credits(void)
5245 if (Globals.ismb2_max_credits == 0) {
5246 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5248 return Globals.ismb2_max_credits;
5250 int lp_cups_encrypt(void)
5252 int result = 0;
5253 #ifdef HAVE_HTTPCONNECTENCRYPT
5254 switch (Globals.CupsEncrypt) {
5255 case Auto:
5256 result = HTTP_ENCRYPT_REQUIRED;
5257 break;
5258 case true:
5259 result = HTTP_ENCRYPT_ALWAYS;
5260 break;
5261 case false:
5262 result = HTTP_ENCRYPT_NEVER;
5263 break;
5265 #endif
5266 return result;
5269 /* These functions remain in source3/param for now */
5271 FN_GLOBAL_STRING(configfile, szConfigFile)
5273 #include "lib/param/param_functions.c"
5275 FN_LOCAL_STRING(servicename, szService)
5276 FN_LOCAL_CONST_STRING(const_servicename, szService)
5278 /* local prototypes */
5280 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5281 static const char *get_boolean(bool bool_value);
5282 static int getservicebyname(const char *pszServiceName,
5283 struct loadparm_service *pserviceDest);
5284 static void copy_service(struct loadparm_service *pserviceDest,
5285 struct loadparm_service *pserviceSource,
5286 struct bitmap *pcopymapDest);
5287 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5288 void *userdata);
5289 static bool do_section(const char *pszSectionName, void *userdata);
5290 static void init_copymap(struct loadparm_service *pservice);
5291 static bool hash_a_service(const char *name, int number);
5292 static void free_service_byindex(int iService);
5293 static void show_parameter(int parmIndex);
5294 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5297 * This is a helper function for parametrical options support. It returns a
5298 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5299 * parametrical functions are quite simple
5301 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
5302 const char *option)
5304 bool global_section = false;
5305 char* param_key;
5306 struct parmlist_entry *data;
5308 if (service == NULL) {
5309 data = Globals.param_opt;
5310 global_section = true;
5311 } else {
5312 data = service->param_opt;
5315 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5316 DEBUG(0,("asprintf failed!\n"));
5317 return NULL;
5320 while (data) {
5321 if (strwicmp(data->key, param_key) == 0) {
5322 string_free(&param_key);
5323 return data;
5325 data = data->next;
5328 if (!global_section) {
5329 /* Try to fetch the same option but from globals */
5330 /* but only if we are not already working with Globals */
5331 data = Globals.param_opt;
5332 while (data) {
5333 if (strwicmp(data->key, param_key) == 0) {
5334 string_free(&param_key);
5335 return data;
5337 data = data->next;
5341 string_free(&param_key);
5343 return NULL;
5347 * This is a helper function for parametrical options support. It returns a
5348 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5349 * parametrical functions are quite simple
5351 static struct parmlist_entry *get_parametrics(int snum, const char *type,
5352 const char *option)
5354 if (snum >= iNumServices) return NULL;
5356 if (snum < 0) {
5357 return get_parametrics_by_service(NULL, type, option);
5358 } else {
5359 return get_parametrics_by_service(ServicePtrs[snum], type, option);
5364 #define MISSING_PARAMETER(name) \
5365 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5367 /*******************************************************************
5368 convenience routine to return int parameters.
5369 ********************************************************************/
5370 static int lp_int(const char *s)
5373 if (!s || !*s) {
5374 MISSING_PARAMETER(lp_int);
5375 return (-1);
5378 return (int)strtol(s, NULL, 0);
5381 /*******************************************************************
5382 convenience routine to return unsigned long parameters.
5383 ********************************************************************/
5384 static unsigned long lp_ulong(const char *s)
5387 if (!s || !*s) {
5388 MISSING_PARAMETER(lp_ulong);
5389 return (0);
5392 return strtoul(s, NULL, 0);
5395 /*******************************************************************
5396 convenience routine to return boolean parameters.
5397 ********************************************************************/
5398 static bool lp_bool(const char *s)
5400 bool ret = false;
5402 if (!s || !*s) {
5403 MISSING_PARAMETER(lp_bool);
5404 return false;
5407 if (!set_boolean(s, &ret)) {
5408 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5409 return false;
5412 return ret;
5415 /*******************************************************************
5416 convenience routine to return enum parameters.
5417 ********************************************************************/
5418 static int lp_enum(const char *s,const struct enum_list *_enum)
5420 int i;
5422 if (!s || !*s || !_enum) {
5423 MISSING_PARAMETER(lp_enum);
5424 return (-1);
5427 for (i=0; _enum[i].name; i++) {
5428 if (strequal(_enum[i].name,s))
5429 return _enum[i].value;
5432 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5433 return (-1);
5436 #undef MISSING_PARAMETER
5438 /* Return parametric option from a given service. Type is a part of option before ':' */
5439 /* Parametric option has following syntax: 'Type: option = value' */
5440 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
5442 struct parmlist_entry *data = get_parametrics(snum, type, option);
5444 if (data == NULL||data->value==NULL) {
5445 if (def) {
5446 return lp_string(ctx, def);
5447 } else {
5448 return NULL;
5452 return lp_string(ctx, data->value);
5455 /* Return parametric option from a given service. Type is a part of option before ':' */
5456 /* Parametric option has following syntax: 'Type: option = value' */
5457 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5459 struct parmlist_entry *data = get_parametrics(snum, type, option);
5461 if (data == NULL||data->value==NULL)
5462 return def;
5464 return data->value;
5467 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
5469 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
5471 if (data == NULL||data->value==NULL)
5472 return NULL;
5474 return data->value;
5478 /* Return parametric option from a given service. Type is a part of option before ':' */
5479 /* Parametric option has following syntax: 'Type: option = value' */
5481 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5483 struct parmlist_entry *data = get_parametrics(snum, type, option);
5485 if (data == NULL||data->value==NULL)
5486 return (const char **)def;
5488 if (data->list==NULL) {
5489 data->list = str_list_make_v3(NULL, data->value, NULL);
5492 return (const char **)data->list;
5495 /* Return parametric option from a given service. Type is a part of option before ':' */
5496 /* Parametric option has following syntax: 'Type: option = value' */
5498 int lp_parm_int(int snum, const char *type, const char *option, int def)
5500 struct parmlist_entry *data = get_parametrics(snum, type, option);
5502 if (data && data->value && *data->value)
5503 return lp_int(data->value);
5505 return def;
5508 /* Return parametric option from a given service. Type is a part of option before ':' */
5509 /* Parametric option has following syntax: 'Type: option = value' */
5511 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5513 struct parmlist_entry *data = get_parametrics(snum, type, option);
5515 if (data && data->value && *data->value)
5516 return lp_ulong(data->value);
5518 return def;
5521 /* Return parametric option from a given service. Type is a part of option before ':' */
5522 /* Parametric option has following syntax: 'Type: option = value' */
5524 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5526 struct parmlist_entry *data = get_parametrics(snum, type, option);
5528 if (data && data->value && *data->value)
5529 return lp_bool(data->value);
5531 return def;
5534 /* Return parametric option from a given service. Type is a part of option before ':' */
5535 /* Parametric option has following syntax: 'Type: option = value' */
5537 int lp_parm_enum(int snum, const char *type, const char *option,
5538 const struct enum_list *_enum, int def)
5540 struct parmlist_entry *data = get_parametrics(snum, type, option);
5542 if (data && data->value && *data->value && _enum)
5543 return lp_enum(data->value, _enum);
5545 return def;
5549 /***************************************************************************
5550 Initialise a service to the defaults.
5551 ***************************************************************************/
5553 static void init_service(struct loadparm_service *pservice)
5555 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
5556 copy_service(pservice, &sDefault, NULL);
5561 * free a param_opts structure.
5562 * param_opts handling should be moved to talloc;
5563 * then this whole functions reduces to a TALLOC_FREE().
5566 static void free_param_opts(struct parmlist_entry **popts)
5568 struct parmlist_entry *opt, *next_opt;
5570 if (popts == NULL) {
5571 return;
5574 if (*popts != NULL) {
5575 DEBUG(5, ("Freeing parametrics:\n"));
5577 opt = *popts;
5578 while (opt != NULL) {
5579 string_free(&opt->key);
5580 string_free(&opt->value);
5581 TALLOC_FREE(opt->list);
5582 next_opt = opt->next;
5583 SAFE_FREE(opt);
5584 opt = next_opt;
5586 *popts = NULL;
5589 /***************************************************************************
5590 Free the dynamically allocated parts of a service struct.
5591 ***************************************************************************/
5593 static void free_service(struct loadparm_service *pservice)
5595 if (!pservice)
5596 return;
5598 if (pservice->szService)
5599 DEBUG(5, ("free_service: Freeing service %s\n",
5600 pservice->szService));
5602 free_parameters(pservice);
5604 string_free(&pservice->szService);
5605 TALLOC_FREE(pservice->copymap);
5607 free_param_opts(&pservice->param_opt);
5609 ZERO_STRUCTP(pservice);
5613 /***************************************************************************
5614 remove a service indexed in the ServicePtrs array from the ServiceHash
5615 and free the dynamically allocated parts
5616 ***************************************************************************/
5618 static void free_service_byindex(int idx)
5620 if ( !LP_SNUM_OK(idx) )
5621 return;
5623 ServicePtrs[idx]->valid = false;
5624 invalid_services[num_invalid_services++] = idx;
5626 /* we have to cleanup the hash record */
5628 if (ServicePtrs[idx]->szService) {
5629 char *canon_name = canonicalize_servicename(
5630 talloc_tos(),
5631 ServicePtrs[idx]->szService );
5633 dbwrap_delete_bystring(ServiceHash, canon_name );
5634 TALLOC_FREE(canon_name);
5637 free_service(ServicePtrs[idx]);
5640 /***************************************************************************
5641 Add a new service to the services array initialising it with the given
5642 service.
5643 ***************************************************************************/
5645 static int add_a_service(const struct loadparm_service *pservice, const char *name)
5647 int i;
5648 struct loadparm_service tservice;
5649 int num_to_alloc = iNumServices + 1;
5651 tservice = *pservice;
5653 /* it might already exist */
5654 if (name) {
5655 i = getservicebyname(name, NULL);
5656 if (i >= 0) {
5657 return (i);
5661 /* find an invalid one */
5662 i = iNumServices;
5663 if (num_invalid_services > 0) {
5664 i = invalid_services[--num_invalid_services];
5667 /* if not, then create one */
5668 if (i == iNumServices) {
5669 struct loadparm_service **tsp;
5670 int *tinvalid;
5672 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
5673 if (tsp == NULL) {
5674 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5675 return (-1);
5677 ServicePtrs = tsp;
5678 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct loadparm_service);
5679 if (!ServicePtrs[iNumServices]) {
5680 DEBUG(0,("add_a_service: out of memory!\n"));
5681 return (-1);
5683 iNumServices++;
5685 /* enlarge invalid_services here for now... */
5686 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5687 num_to_alloc);
5688 if (tinvalid == NULL) {
5689 DEBUG(0,("add_a_service: failed to enlarge "
5690 "invalid_services!\n"));
5691 return (-1);
5693 invalid_services = tinvalid;
5694 } else {
5695 free_service_byindex(i);
5698 ServicePtrs[i]->valid = true;
5700 init_service(ServicePtrs[i]);
5701 copy_service(ServicePtrs[i], &tservice, NULL);
5702 if (name)
5703 string_set(&ServicePtrs[i]->szService, name);
5705 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5706 i, ServicePtrs[i]->szService));
5708 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5709 return (-1);
5712 return (i);
5715 /***************************************************************************
5716 Convert a string to uppercase and remove whitespaces.
5717 ***************************************************************************/
5719 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
5721 char *result;
5723 if ( !src ) {
5724 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5725 return NULL;
5728 result = talloc_strdup(ctx, src);
5729 SMB_ASSERT(result != NULL);
5731 strlower_m(result);
5732 return result;
5735 /***************************************************************************
5736 Add a name/index pair for the services array to the hash table.
5737 ***************************************************************************/
5739 static bool hash_a_service(const char *name, int idx)
5741 char *canon_name;
5743 if ( !ServiceHash ) {
5744 DEBUG(10,("hash_a_service: creating servicehash\n"));
5745 ServiceHash = db_open_rbt(NULL);
5746 if ( !ServiceHash ) {
5747 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5748 return false;
5752 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5753 idx, name));
5755 canon_name = canonicalize_servicename(talloc_tos(), name );
5757 dbwrap_store_bystring(ServiceHash, canon_name,
5758 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5759 TDB_REPLACE);
5761 TALLOC_FREE(canon_name);
5763 return true;
5766 /***************************************************************************
5767 Add a new home service, with the specified home directory, defaults coming
5768 from service ifrom.
5769 ***************************************************************************/
5771 bool lp_add_home(const char *pszHomename, int iDefaultService,
5772 const char *user, const char *pszHomedir)
5774 int i;
5776 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
5777 pszHomedir[0] == '\0') {
5778 return false;
5781 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5783 if (i < 0)
5784 return false;
5786 if (!(*(ServicePtrs[iDefaultService]->szPath))
5787 || strequal(ServicePtrs[iDefaultService]->szPath,
5788 lp_pathname(talloc_tos(), GLOBAL_SECTION_SNUM))) {
5789 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5792 if (!(*(ServicePtrs[i]->comment))) {
5793 char *comment = NULL;
5794 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5795 return false;
5797 string_set(&ServicePtrs[i]->comment, comment);
5798 SAFE_FREE(comment);
5801 /* set the browseable flag from the global default */
5803 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5804 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
5806 ServicePtrs[i]->autoloaded = true;
5808 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5809 user, ServicePtrs[i]->szPath ));
5811 return true;
5814 /***************************************************************************
5815 Add a new service, based on an old one.
5816 ***************************************************************************/
5818 int lp_add_service(const char *pszService, int iDefaultService)
5820 if (iDefaultService < 0) {
5821 return add_a_service(&sDefault, pszService);
5824 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5827 /***************************************************************************
5828 Add the IPC service.
5829 ***************************************************************************/
5831 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5833 char *comment = NULL;
5834 int i = add_a_service(&sDefault, ipc_name);
5836 if (i < 0)
5837 return false;
5839 if (asprintf(&comment, "IPC Service (%s)",
5840 Globals.szServerString) < 0) {
5841 return false;
5844 string_set(&ServicePtrs[i]->szPath, tmpdir());
5845 string_set(&ServicePtrs[i]->szUsername, "");
5846 string_set(&ServicePtrs[i]->comment, comment);
5847 string_set(&ServicePtrs[i]->fstype, "IPC");
5848 ServicePtrs[i]->iMaxConnections = 0;
5849 ServicePtrs[i]->bAvailable = true;
5850 ServicePtrs[i]->bRead_only = true;
5851 ServicePtrs[i]->bGuest_only = false;
5852 ServicePtrs[i]->bAdministrative_share = true;
5853 ServicePtrs[i]->bGuest_ok = guest_ok;
5854 ServicePtrs[i]->bPrint_ok = false;
5855 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5857 DEBUG(3, ("adding IPC service\n"));
5859 SAFE_FREE(comment);
5860 return true;
5863 /***************************************************************************
5864 Add a new printer service, with defaults coming from service iFrom.
5865 ***************************************************************************/
5867 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5869 const char *comment = "From Printcap";
5870 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5872 if (i < 0)
5873 return false;
5875 /* note that we do NOT default the availability flag to true - */
5876 /* we take it from the default service passed. This allows all */
5877 /* dynamic printers to be disabled by disabling the [printers] */
5878 /* entry (if/when the 'available' keyword is implemented!). */
5880 /* the printer name is set to the service name. */
5881 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5882 string_set(&ServicePtrs[i]->comment, comment);
5884 /* set the browseable flag from the gloabl default */
5885 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5887 /* Printers cannot be read_only. */
5888 ServicePtrs[i]->bRead_only = false;
5889 /* No share modes on printer services. */
5890 ServicePtrs[i]->bShareModes = false;
5891 /* No oplocks on printer services. */
5892 ServicePtrs[i]->bOpLocks = false;
5893 /* Printer services must be printable. */
5894 ServicePtrs[i]->bPrint_ok = true;
5896 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5898 return true;
5902 /***************************************************************************
5903 Check whether the given parameter name is valid.
5904 Parametric options (names containing a colon) are considered valid.
5905 ***************************************************************************/
5907 bool lp_parameter_is_valid(const char *pszParmName)
5909 return ((map_parameter(pszParmName) != -1) ||
5910 (strchr(pszParmName, ':') != NULL));
5913 /***************************************************************************
5914 Check whether the given name is the name of a global parameter.
5915 Returns true for strings belonging to parameters of class
5916 P_GLOBAL, false for all other strings, also for parametric options
5917 and strings not belonging to any option.
5918 ***************************************************************************/
5920 bool lp_parameter_is_global(const char *pszParmName)
5922 int num = map_parameter(pszParmName);
5924 if (num >= 0) {
5925 return (parm_table[num].p_class == P_GLOBAL);
5928 return false;
5931 /**************************************************************************
5932 Check whether the given name is the canonical name of a parameter.
5933 Returns false if it is not a valid parameter Name.
5934 For parametric options, true is returned.
5935 **************************************************************************/
5937 bool lp_parameter_is_canonical(const char *parm_name)
5939 if (!lp_parameter_is_valid(parm_name)) {
5940 return false;
5943 return (map_parameter(parm_name) ==
5944 map_parameter_canonical(parm_name, NULL));
5947 /**************************************************************************
5948 Determine the canonical name for a parameter.
5949 Indicate when it is an inverse (boolean) synonym instead of a
5950 "usual" synonym.
5951 **************************************************************************/
5953 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5954 bool *inverse)
5956 int num;
5958 if (!lp_parameter_is_valid(parm_name)) {
5959 *canon_parm = NULL;
5960 return false;
5963 num = map_parameter_canonical(parm_name, inverse);
5964 if (num < 0) {
5965 /* parametric option */
5966 *canon_parm = parm_name;
5967 } else {
5968 *canon_parm = parm_table[num].label;
5971 return true;
5975 /**************************************************************************
5976 Determine the canonical name for a parameter.
5977 Turn the value given into the inverse boolean expression when
5978 the synonym is an invers boolean synonym.
5980 Return true if parm_name is a valid parameter name and
5981 in case it is an invers boolean synonym, if the val string could
5982 successfully be converted to the reverse bool.
5983 Return false in all other cases.
5984 **************************************************************************/
5986 bool lp_canonicalize_parameter_with_value(const char *parm_name,
5987 const char *val,
5988 const char **canon_parm,
5989 const char **canon_val)
5991 int num;
5992 bool inverse;
5994 if (!lp_parameter_is_valid(parm_name)) {
5995 *canon_parm = NULL;
5996 *canon_val = NULL;
5997 return false;
6000 num = map_parameter_canonical(parm_name, &inverse);
6001 if (num < 0) {
6002 /* parametric option */
6003 *canon_parm = parm_name;
6004 *canon_val = val;
6005 } else {
6006 *canon_parm = parm_table[num].label;
6007 if (inverse) {
6008 if (!lp_invert_boolean(val, canon_val)) {
6009 *canon_val = NULL;
6010 return false;
6012 } else {
6013 *canon_val = val;
6017 return true;
6020 /***************************************************************************
6021 Map a parameter's string representation to something we can use.
6022 Returns false if the parameter string is not recognised, else TRUE.
6023 ***************************************************************************/
6025 static int map_parameter(const char *pszParmName)
6027 int iIndex;
6029 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6030 return (-1);
6032 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6033 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6034 return (iIndex);
6036 /* Warn only if it isn't parametric option */
6037 if (strchr(pszParmName, ':') == NULL)
6038 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6039 /* We do return 'fail' for parametric options as well because they are
6040 stored in different storage
6042 return (-1);
6045 /***************************************************************************
6046 Map a parameter's string representation to the index of the canonical
6047 form of the parameter (it might be a synonym).
6048 Returns -1 if the parameter string is not recognised.
6049 ***************************************************************************/
6051 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6053 int parm_num, canon_num;
6054 bool loc_inverse = false;
6056 parm_num = map_parameter(pszParmName);
6057 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6058 /* invalid, parametric or no canidate for synonyms ... */
6059 goto done;
6062 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6063 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6064 parm_num = canon_num;
6065 goto done;
6069 done:
6070 if (inverse != NULL) {
6071 *inverse = loc_inverse;
6073 return parm_num;
6076 /***************************************************************************
6077 return true if parameter number parm1 is a synonym of parameter
6078 number parm2 (parm2 being the principal name).
6079 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
6080 false otherwise.
6081 ***************************************************************************/
6083 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6085 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
6086 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
6087 (parm_table[parm1].flags & FLAG_HIDE) &&
6088 !(parm_table[parm2].flags & FLAG_HIDE))
6090 if (inverse != NULL) {
6091 if ((parm_table[parm1].type == P_BOOLREV) &&
6092 (parm_table[parm2].type == P_BOOL))
6094 *inverse = true;
6095 } else {
6096 *inverse = false;
6099 return true;
6101 return false;
6104 /***************************************************************************
6105 Show one parameter's name, type, [values,] and flags.
6106 (helper functions for show_parameter_list)
6107 ***************************************************************************/
6109 static void show_parameter(int parmIndex)
6111 int enumIndex, flagIndex;
6112 int parmIndex2;
6113 bool hadFlag;
6114 bool hadSyn;
6115 bool inverse;
6116 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6117 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6118 "P_ENUM", "P_SEP"};
6119 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6120 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6121 FLAG_HIDE};
6122 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6123 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6124 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
6126 printf("%s=%s", parm_table[parmIndex].label,
6127 type[parm_table[parmIndex].type]);
6128 if (parm_table[parmIndex].type == P_ENUM) {
6129 printf(",");
6130 for (enumIndex=0;
6131 parm_table[parmIndex].enum_list[enumIndex].name;
6132 enumIndex++)
6134 printf("%s%s",
6135 enumIndex ? "|" : "",
6136 parm_table[parmIndex].enum_list[enumIndex].name);
6139 printf(",");
6140 hadFlag = false;
6141 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6142 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6143 printf("%s%s",
6144 hadFlag ? "|" : "",
6145 flag_names[flagIndex]);
6146 hadFlag = true;
6150 /* output synonyms */
6151 hadSyn = false;
6152 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6153 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6154 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6155 parm_table[parmIndex2].label);
6156 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6157 if (!hadSyn) {
6158 printf(" (synonyms: ");
6159 hadSyn = true;
6160 } else {
6161 printf(", ");
6163 printf("%s%s", parm_table[parmIndex2].label,
6164 inverse ? "[i]" : "");
6167 if (hadSyn) {
6168 printf(")");
6171 printf("\n");
6174 /***************************************************************************
6175 Show all parameter's name, type, [values,] and flags.
6176 ***************************************************************************/
6178 void show_parameter_list(void)
6180 int classIndex, parmIndex;
6181 const char *section_names[] = { "local", "global", NULL};
6183 for (classIndex=0; section_names[classIndex]; classIndex++) {
6184 printf("[%s]\n", section_names[classIndex]);
6185 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6186 if (parm_table[parmIndex].p_class == classIndex) {
6187 show_parameter(parmIndex);
6193 /***************************************************************************
6194 Check if a given string correctly represents a boolean value.
6195 ***************************************************************************/
6197 bool lp_string_is_valid_boolean(const char *parm_value)
6199 return set_boolean(parm_value, NULL);
6202 /***************************************************************************
6203 Get the standard string representation of a boolean value ("yes" or "no")
6204 ***************************************************************************/
6206 static const char *get_boolean(bool bool_value)
6208 static const char *yes_str = "yes";
6209 static const char *no_str = "no";
6211 return (bool_value ? yes_str : no_str);
6214 /***************************************************************************
6215 Provide the string of the negated boolean value associated to the boolean
6216 given as a string. Returns false if the passed string does not correctly
6217 represent a boolean.
6218 ***************************************************************************/
6220 bool lp_invert_boolean(const char *str, const char **inverse_str)
6222 bool val;
6224 if (!set_boolean(str, &val)) {
6225 return false;
6228 *inverse_str = get_boolean(!val);
6229 return true;
6232 /***************************************************************************
6233 Provide the canonical string representation of a boolean value given
6234 as a string. Return true on success, false if the string given does
6235 not correctly represent a boolean.
6236 ***************************************************************************/
6238 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6240 bool val;
6242 if (!set_boolean(str, &val)) {
6243 return false;
6246 *canon_str = get_boolean(val);
6247 return true;
6250 /***************************************************************************
6251 Find a service by name. Otherwise works like get_service.
6252 ***************************************************************************/
6254 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
6256 int iService = -1;
6257 char *canon_name;
6258 TDB_DATA data;
6259 NTSTATUS status;
6261 if (ServiceHash == NULL) {
6262 return -1;
6265 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6267 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
6268 &data);
6270 if (NT_STATUS_IS_OK(status) &&
6271 (data.dptr != NULL) &&
6272 (data.dsize == sizeof(iService)))
6274 iService = *(int *)data.dptr;
6277 TALLOC_FREE(canon_name);
6279 if ((iService != -1) && (LP_SNUM_OK(iService))
6280 && (pserviceDest != NULL)) {
6281 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6284 return (iService);
6287 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
6288 struct loadparm_service *lp_service(const char *pszServiceName)
6290 int iService = getservicebyname(pszServiceName, NULL);
6291 if (iService == -1 || !LP_SNUM_OK(iService)) {
6292 return NULL;
6294 return ServicePtrs[iService];
6297 struct loadparm_service *lp_servicebynum(int snum)
6299 if ((snum == -1) || !LP_SNUM_OK(snum)) {
6300 return NULL;
6302 return ServicePtrs[snum];
6305 struct loadparm_service *lp_default_loadparm_service()
6307 return &sDefault;
6311 /***************************************************************************
6312 Copy a service structure to another.
6313 If pcopymapDest is NULL then copy all fields
6314 ***************************************************************************/
6317 * Add a parametric option to a parmlist_entry,
6318 * replacing old value, if already present.
6320 static void set_param_opt(struct parmlist_entry **opt_list,
6321 const char *opt_name,
6322 const char *opt_value,
6323 unsigned priority)
6325 struct parmlist_entry *new_opt, *opt;
6326 bool not_added;
6328 if (opt_list == NULL) {
6329 return;
6332 opt = *opt_list;
6333 not_added = true;
6335 /* Traverse destination */
6336 while (opt) {
6337 /* If we already have same option, override it */
6338 if (strwicmp(opt->key, opt_name) == 0) {
6339 if ((opt->priority & FLAG_CMDLINE) &&
6340 !(priority & FLAG_CMDLINE)) {
6341 /* it's been marked as not to be
6342 overridden */
6343 return;
6345 string_free(&opt->value);
6346 TALLOC_FREE(opt->list);
6347 opt->value = SMB_STRDUP(opt_value);
6348 opt->priority = priority;
6349 not_added = false;
6350 break;
6352 opt = opt->next;
6354 if (not_added) {
6355 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
6356 new_opt->key = SMB_STRDUP(opt_name);
6357 new_opt->value = SMB_STRDUP(opt_value);
6358 new_opt->list = NULL;
6359 new_opt->priority = priority;
6360 DLIST_ADD(*opt_list, new_opt);
6364 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
6365 struct bitmap *pcopymapDest)
6367 int i;
6368 bool bcopyall = (pcopymapDest == NULL);
6369 struct parmlist_entry *data;
6371 for (i = 0; parm_table[i].label; i++)
6372 if (parm_table[i].p_class == P_LOCAL &&
6373 (bcopyall || bitmap_query(pcopymapDest,i))) {
6374 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
6375 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
6377 switch (parm_table[i].type) {
6378 case P_BOOL:
6379 case P_BOOLREV:
6380 *(bool *)dest_ptr = *(bool *)src_ptr;
6381 break;
6383 case P_INTEGER:
6384 case P_ENUM:
6385 case P_OCTAL:
6386 case P_BYTES:
6387 *(int *)dest_ptr = *(int *)src_ptr;
6388 break;
6390 case P_CHAR:
6391 *(char *)dest_ptr = *(char *)src_ptr;
6392 break;
6394 case P_STRING:
6395 string_set((char **)dest_ptr,
6396 *(char **)src_ptr);
6397 break;
6399 case P_USTRING:
6401 char *upper_string = strupper_talloc(talloc_tos(),
6402 *(char **)src_ptr);
6403 string_set((char **)dest_ptr,
6404 upper_string);
6405 TALLOC_FREE(upper_string);
6406 break;
6408 case P_LIST:
6409 TALLOC_FREE(*((char ***)dest_ptr));
6410 *((char ***)dest_ptr) = str_list_copy(NULL,
6411 *(const char ***)src_ptr);
6412 break;
6413 default:
6414 break;
6418 if (bcopyall) {
6419 init_copymap(pserviceDest);
6420 if (pserviceSource->copymap)
6421 bitmap_copy(pserviceDest->copymap,
6422 pserviceSource->copymap);
6425 data = pserviceSource->param_opt;
6426 while (data) {
6427 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
6428 data = data->next;
6432 /***************************************************************************
6433 Check a service for consistency. Return false if the service is in any way
6434 incomplete or faulty, else true.
6435 ***************************************************************************/
6437 bool service_ok(int iService)
6439 bool bRetval;
6441 bRetval = true;
6442 if (ServicePtrs[iService]->szService[0] == '\0') {
6443 DEBUG(0, ("The following message indicates an internal error:\n"));
6444 DEBUG(0, ("No service name in service entry.\n"));
6445 bRetval = false;
6448 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6449 /* I can't see why you'd want a non-printable printer service... */
6450 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6451 if (!ServicePtrs[iService]->bPrint_ok) {
6452 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6453 ServicePtrs[iService]->szService));
6454 ServicePtrs[iService]->bPrint_ok = true;
6456 /* [printers] service must also be non-browsable. */
6457 if (ServicePtrs[iService]->bBrowseable)
6458 ServicePtrs[iService]->bBrowseable = false;
6461 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6462 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6463 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6465 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6466 ServicePtrs[iService]->szService));
6467 ServicePtrs[iService]->bAvailable = false;
6470 /* If a service is flagged unavailable, log the fact at level 1. */
6471 if (!ServicePtrs[iService]->bAvailable)
6472 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6473 ServicePtrs[iService]->szService));
6475 return (bRetval);
6478 static struct smbconf_ctx *lp_smbconf_ctx(void)
6480 sbcErr err;
6481 static struct smbconf_ctx *conf_ctx = NULL;
6483 if (conf_ctx == NULL) {
6484 err = smbconf_init(NULL, &conf_ctx, "registry:");
6485 if (!SBC_ERROR_IS_OK(err)) {
6486 DEBUG(1, ("error initializing registry configuration: "
6487 "%s\n", sbcErrorString(err)));
6488 conf_ctx = NULL;
6492 return conf_ctx;
6495 static bool process_smbconf_service(struct smbconf_service *service)
6497 uint32_t count;
6498 bool ret;
6500 if (service == NULL) {
6501 return false;
6504 ret = do_section(service->name, NULL);
6505 if (ret != true) {
6506 return false;
6508 for (count = 0; count < service->num_params; count++) {
6509 ret = do_parameter(service->param_names[count],
6510 service->param_values[count],
6511 NULL);
6512 if (ret != true) {
6513 return false;
6516 if (iServiceIndex >= 0) {
6517 return service_ok(iServiceIndex);
6519 return true;
6523 * load a service from registry and activate it
6525 bool process_registry_service(const char *service_name)
6527 sbcErr err;
6528 struct smbconf_service *service = NULL;
6529 TALLOC_CTX *mem_ctx = talloc_stackframe();
6530 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6531 bool ret = false;
6533 if (conf_ctx == NULL) {
6534 goto done;
6537 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6539 if (!smbconf_share_exists(conf_ctx, service_name)) {
6541 * Registry does not contain data for this service (yet),
6542 * but make sure lp_load doesn't return false.
6544 ret = true;
6545 goto done;
6548 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6549 if (!SBC_ERROR_IS_OK(err)) {
6550 goto done;
6553 ret = process_smbconf_service(service);
6554 if (!ret) {
6555 goto done;
6558 /* store the csn */
6559 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6561 done:
6562 TALLOC_FREE(mem_ctx);
6563 return ret;
6567 * process_registry_globals
6569 static bool process_registry_globals(void)
6571 bool ret;
6573 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6575 ret = do_parameter("registry shares", "yes", NULL);
6576 if (!ret) {
6577 return ret;
6580 return process_registry_service(GLOBAL_NAME);
6583 bool process_registry_shares(void)
6585 sbcErr err;
6586 uint32_t count;
6587 struct smbconf_service **service = NULL;
6588 uint32_t num_shares = 0;
6589 TALLOC_CTX *mem_ctx = talloc_stackframe();
6590 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6591 bool ret = false;
6593 if (conf_ctx == NULL) {
6594 goto done;
6597 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6598 if (!SBC_ERROR_IS_OK(err)) {
6599 goto done;
6602 ret = true;
6604 for (count = 0; count < num_shares; count++) {
6605 if (strequal(service[count]->name, GLOBAL_NAME)) {
6606 continue;
6608 ret = process_smbconf_service(service[count]);
6609 if (!ret) {
6610 goto done;
6614 /* store the csn */
6615 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6617 done:
6618 TALLOC_FREE(mem_ctx);
6619 return ret;
6623 * reload those shares from registry that are already
6624 * activated in the services array.
6626 static bool reload_registry_shares(void)
6628 int i;
6629 bool ret = true;
6631 for (i = 0; i < iNumServices; i++) {
6632 if (!VALID(i)) {
6633 continue;
6636 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
6637 continue;
6640 ret = process_registry_service(ServicePtrs[i]->szService);
6641 if (!ret) {
6642 goto done;
6646 done:
6647 return ret;
6651 #define MAX_INCLUDE_DEPTH 100
6653 static uint8_t include_depth;
6655 static struct file_lists {
6656 struct file_lists *next;
6657 char *name;
6658 char *subfname;
6659 time_t modtime;
6660 } *file_lists = NULL;
6662 /*******************************************************************
6663 Keep a linked list of all config files so we know when one has changed
6664 it's date and needs to be reloaded.
6665 ********************************************************************/
6667 static void add_to_file_list(const char *fname, const char *subfname)
6669 struct file_lists *f = file_lists;
6671 while (f) {
6672 if (f->name && !strcmp(f->name, fname))
6673 break;
6674 f = f->next;
6677 if (!f) {
6678 f = SMB_MALLOC_P(struct file_lists);
6679 if (!f)
6680 return;
6681 f->next = file_lists;
6682 f->name = SMB_STRDUP(fname);
6683 if (!f->name) {
6684 SAFE_FREE(f);
6685 return;
6687 f->subfname = SMB_STRDUP(subfname);
6688 if (!f->subfname) {
6689 SAFE_FREE(f->name);
6690 SAFE_FREE(f);
6691 return;
6693 file_lists = f;
6694 f->modtime = file_modtime(subfname);
6695 } else {
6696 time_t t = file_modtime(subfname);
6697 if (t)
6698 f->modtime = t;
6700 return;
6704 * Free the file lists
6706 static void free_file_list(void)
6708 struct file_lists *f;
6709 struct file_lists *next;
6711 f = file_lists;
6712 while( f ) {
6713 next = f->next;
6714 SAFE_FREE( f->name );
6715 SAFE_FREE( f->subfname );
6716 SAFE_FREE( f );
6717 f = next;
6719 file_lists = NULL;
6724 * Utility function for outsiders to check if we're running on registry.
6726 bool lp_config_backend_is_registry(void)
6728 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6732 * Utility function to check if the config backend is FILE.
6734 bool lp_config_backend_is_file(void)
6736 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6739 /*******************************************************************
6740 Check if a config file has changed date.
6741 ********************************************************************/
6743 bool lp_file_list_changed(void)
6745 struct file_lists *f = file_lists;
6747 DEBUG(6, ("lp_file_list_changed()\n"));
6749 while (f) {
6750 time_t mod_time;
6752 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6753 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6755 if (conf_ctx == NULL) {
6756 return false;
6758 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6759 NULL))
6761 DEBUGADD(6, ("registry config changed\n"));
6762 return true;
6764 } else {
6765 char *n2 = NULL;
6766 n2 = talloc_sub_basic(talloc_tos(),
6767 get_current_username(),
6768 current_user_info.domain,
6769 f->name);
6770 if (!n2) {
6771 return false;
6773 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6774 f->name, n2, ctime(&f->modtime)));
6776 mod_time = file_modtime(n2);
6778 if (mod_time &&
6779 ((f->modtime != mod_time) ||
6780 (f->subfname == NULL) ||
6781 (strcmp(n2, f->subfname) != 0)))
6783 DEBUGADD(6,
6784 ("file %s modified: %s\n", n2,
6785 ctime(&mod_time)));
6786 f->modtime = mod_time;
6787 SAFE_FREE(f->subfname);
6788 f->subfname = SMB_STRDUP(n2);
6789 TALLOC_FREE(n2);
6790 return true;
6792 TALLOC_FREE(n2);
6794 f = f->next;
6796 return false;
6801 * Initialize iconv conversion descriptors.
6803 * This is called the first time it is needed, and also called again
6804 * every time the configuration is reloaded, because the charset or
6805 * codepage might have changed.
6807 static void init_iconv(void)
6809 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
6810 lp_unix_charset(),
6811 true, global_iconv_handle);
6814 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6816 if (strcmp(*ptr, pszParmValue) != 0) {
6817 string_set(ptr, pszParmValue);
6818 init_iconv();
6820 return true;
6823 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6825 bool is_utf8 = false;
6826 size_t len = strlen(pszParmValue);
6828 if (len == 4 || len == 5) {
6829 /* Don't use StrCaseCmp here as we don't want to
6830 initialize iconv. */
6831 if ((toupper_m(pszParmValue[0]) == 'U') &&
6832 (toupper_m(pszParmValue[1]) == 'T') &&
6833 (toupper_m(pszParmValue[2]) == 'F')) {
6834 if (len == 4) {
6835 if (pszParmValue[3] == '8') {
6836 is_utf8 = true;
6838 } else {
6839 if (pszParmValue[3] == '-' &&
6840 pszParmValue[4] == '8') {
6841 is_utf8 = true;
6847 if (strcmp(*ptr, pszParmValue) != 0) {
6848 if (is_utf8) {
6849 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
6850 "be UTF8, using (default value) %s instead.\n",
6851 DEFAULT_DOS_CHARSET));
6852 pszParmValue = DEFAULT_DOS_CHARSET;
6854 string_set(ptr, pszParmValue);
6855 init_iconv();
6857 return true;
6860 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6862 bool ret = true;
6863 char *realm = strupper_talloc(talloc_tos(), pszParmValue);
6864 char *dnsdomain = strlower_talloc(realm, pszParmValue);
6866 ret &= string_set(&Globals.szRealm, pszParmValue);
6867 ret &= string_set(&Globals.szRealm_upper, realm);
6868 ret &= string_set(&Globals.szRealm_lower, dnsdomain);
6869 TALLOC_FREE(realm);
6871 return ret;
6874 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6876 TALLOC_FREE(Globals.szNetbiosAliases);
6877 Globals.szNetbiosAliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
6878 return set_netbios_aliases(Globals.szNetbiosAliases);
6881 /***************************************************************************
6882 Handle the include operation.
6883 ***************************************************************************/
6884 static bool bAllowIncludeRegistry = true;
6886 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6888 char *fname;
6890 if (include_depth >= MAX_INCLUDE_DEPTH) {
6891 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6892 include_depth));
6893 return false;
6896 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6897 if (!bAllowIncludeRegistry) {
6898 return true;
6900 if (bInGlobalSection) {
6901 bool ret;
6902 include_depth++;
6903 ret = process_registry_globals();
6904 include_depth--;
6905 return ret;
6906 } else {
6907 DEBUG(1, ("\"include = registry\" only effective "
6908 "in %s section\n", GLOBAL_NAME));
6909 return false;
6913 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
6914 current_user_info.domain,
6915 pszParmValue);
6917 add_to_file_list(pszParmValue, fname);
6919 string_set(ptr, fname);
6921 if (file_exist(fname)) {
6922 bool ret;
6923 include_depth++;
6924 ret = pm_process(fname, do_section, do_parameter, NULL);
6925 include_depth--;
6926 TALLOC_FREE(fname);
6927 return ret;
6930 DEBUG(2, ("Can't find include file %s\n", fname));
6931 TALLOC_FREE(fname);
6932 return true;
6935 /***************************************************************************
6936 Handle the interpretation of the copy parameter.
6937 ***************************************************************************/
6939 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6941 bool bRetval;
6942 int iTemp;
6943 struct loadparm_service serviceTemp;
6945 string_set(ptr, pszParmValue);
6947 init_service(&serviceTemp);
6949 bRetval = false;
6951 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6953 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6954 if (iTemp == iServiceIndex) {
6955 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6956 } else {
6957 copy_service(ServicePtrs[iServiceIndex],
6958 &serviceTemp,
6959 ServicePtrs[iServiceIndex]->copymap);
6960 bRetval = true;
6962 } else {
6963 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6964 bRetval = false;
6967 free_service(&serviceTemp);
6968 return (bRetval);
6971 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
6973 Globals.ldap_debug_level = lp_int(pszParmValue);
6974 init_ldap_debugging();
6975 return true;
6978 /***************************************************************************
6979 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6980 parameters is:
6982 [global]
6984 idmap uid = 1000-1999
6985 idmap gid = 700-899
6987 We only do simple parsing checks here. The strings are parsed into useful
6988 structures in the idmap daemon code.
6990 ***************************************************************************/
6992 /* Some lp_ routines to return idmap [ug]id information */
6994 static uid_t idmap_uid_low, idmap_uid_high;
6995 static gid_t idmap_gid_low, idmap_gid_high;
6997 bool lp_idmap_uid(uid_t *low, uid_t *high)
6999 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7000 return false;
7002 if (low)
7003 *low = idmap_uid_low;
7005 if (high)
7006 *high = idmap_uid_high;
7008 return true;
7011 bool lp_idmap_gid(gid_t *low, gid_t *high)
7013 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7014 return false;
7016 if (low)
7017 *low = idmap_gid_low;
7019 if (high)
7020 *high = idmap_gid_high;
7022 return true;
7025 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7027 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7029 return true;
7032 /* Do some simple checks on "idmap [ug]id" parameter values */
7034 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7036 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7038 return true;
7041 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7043 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7045 return true;
7048 /***************************************************************************
7049 Handle the DEBUG level list.
7050 ***************************************************************************/
7052 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
7054 string_set(ptr, pszParmValueIn);
7055 return debug_parse_levels(pszParmValueIn);
7058 /***************************************************************************
7059 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7060 ***************************************************************************/
7062 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
7064 const char *suffix_string;
7066 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
7067 Globals.szLdapSuffix );
7068 if ( !suffix_string ) {
7069 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7070 return "";
7073 return suffix_string;
7076 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
7078 if (Globals.szLdapMachineSuffix[0])
7079 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
7081 return lp_string(ctx, Globals.szLdapSuffix);
7084 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
7086 if (Globals.szLdapUserSuffix[0])
7087 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
7089 return lp_string(ctx, Globals.szLdapSuffix);
7092 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
7094 if (Globals.szLdapGroupSuffix[0])
7095 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
7097 return lp_string(ctx, Globals.szLdapSuffix);
7100 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
7102 if (Globals.szLdapIdmapSuffix[0])
7103 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
7105 return lp_string(ctx, Globals.szLdapSuffix);
7108 /****************************************************************************
7109 set the value for a P_ENUM
7110 ***************************************************************************/
7112 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7113 int *ptr )
7115 int i;
7117 for (i = 0; parm->enum_list[i].name; i++) {
7118 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7119 *ptr = parm->enum_list[i].value;
7120 return;
7123 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7124 pszParmValue, parm->label));
7127 /***************************************************************************
7128 ***************************************************************************/
7130 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
7132 static int parm_num = -1;
7133 struct loadparm_service *s;
7135 if ( parm_num == -1 )
7136 parm_num = map_parameter( "printing" );
7138 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7140 if ( snum < 0 )
7141 s = &sDefault;
7142 else
7143 s = ServicePtrs[snum];
7145 init_printer_values( s );
7147 return true;
7151 /***************************************************************************
7152 Initialise a copymap.
7153 ***************************************************************************/
7155 static void init_copymap(struct loadparm_service *pservice)
7157 int i;
7159 TALLOC_FREE(pservice->copymap);
7161 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7162 if (!pservice->copymap)
7163 DEBUG(0,
7164 ("Couldn't allocate copymap!! (size %d)\n",
7165 (int)NUMPARAMETERS));
7166 else
7167 for (i = 0; i < NUMPARAMETERS; i++)
7168 bitmap_set(pservice->copymap, i);
7172 return the parameter pointer for a parameter
7174 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
7176 if (service == NULL) {
7177 if (parm->p_class == P_LOCAL)
7178 return (void *)(((char *)&sDefault)+parm->offset);
7179 else if (parm->p_class == P_GLOBAL)
7180 return (void *)(((char *)&Globals)+parm->offset);
7181 else return NULL;
7182 } else {
7183 return (void *)(((char *)service) + parm->offset);
7187 /***************************************************************************
7188 Return the local pointer to a parameter given the service number and parameter
7189 ***************************************************************************/
7191 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
7193 return lp_parm_ptr(ServicePtrs[snum], parm);
7196 /***************************************************************************
7197 Process a parameter for a particular service number. If snum < 0
7198 then assume we are in the globals.
7199 ***************************************************************************/
7201 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7203 int parmnum, i;
7204 void *parm_ptr = NULL; /* where we are going to store the result */
7205 struct parmlist_entry **opt_list;
7207 parmnum = map_parameter(pszParmName);
7209 if (parmnum < 0) {
7210 if (strchr(pszParmName, ':') == NULL) {
7211 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7212 pszParmName));
7213 return true;
7217 * We've got a parametric option
7220 opt_list = (snum < 0)
7221 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7222 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7224 return true;
7227 /* if it's already been set by the command line, then we don't
7228 override here */
7229 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7230 return true;
7233 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7234 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7235 pszParmName));
7238 /* we might point at a service, the default service or a global */
7239 if (snum < 0) {
7240 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
7241 } else {
7242 if (parm_table[parmnum].p_class == P_GLOBAL) {
7243 DEBUG(0,
7244 ("Global parameter %s found in service section!\n",
7245 pszParmName));
7246 return true;
7248 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
7251 if (snum >= 0) {
7252 if (!ServicePtrs[snum]->copymap)
7253 init_copymap(ServicePtrs[snum]);
7255 /* this handles the aliases - set the copymap for other entries with
7256 the same data pointer */
7257 for (i = 0; parm_table[i].label; i++) {
7258 if ((parm_table[i].offset == parm_table[parmnum].offset)
7259 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
7260 bitmap_clear(ServicePtrs[snum]->copymap, i);
7265 /* if it is a special case then go ahead */
7266 if (parm_table[parmnum].special) {
7267 return parm_table[parmnum].special(NULL, snum, pszParmValue,
7268 (char **)parm_ptr);
7271 /* now switch on the type of variable it is */
7272 switch (parm_table[parmnum].type)
7274 case P_BOOL:
7275 *(bool *)parm_ptr = lp_bool(pszParmValue);
7276 break;
7278 case P_BOOLREV:
7279 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7280 break;
7282 case P_INTEGER:
7283 *(int *)parm_ptr = lp_int(pszParmValue);
7284 break;
7286 case P_CHAR:
7287 *(char *)parm_ptr = *pszParmValue;
7288 break;
7290 case P_OCTAL:
7291 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7292 if ( i != 1 ) {
7293 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7295 break;
7297 case P_BYTES:
7299 uint64_t val;
7300 if (conv_str_size_error(pszParmValue, &val)) {
7301 if (val <= INT_MAX) {
7302 *(int *)parm_ptr = (int)val;
7303 break;
7307 DEBUG(0,("lp_do_parameter(%s): value is not "
7308 "a valid size specifier!\n", pszParmValue));
7309 return false;
7312 case P_LIST:
7313 case P_CMDLIST:
7314 TALLOC_FREE(*((char ***)parm_ptr));
7315 *(char ***)parm_ptr = str_list_make_v3(
7316 NULL, pszParmValue, NULL);
7317 break;
7319 case P_STRING:
7320 string_set((char **)parm_ptr, pszParmValue);
7321 break;
7323 case P_USTRING:
7325 char *upper_string = strupper_talloc(talloc_tos(),
7326 pszParmValue);
7327 string_set((char **)parm_ptr, upper_string);
7328 TALLOC_FREE(upper_string);
7329 break;
7331 case P_ENUM:
7332 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7333 break;
7334 case P_SEP:
7335 break;
7338 return true;
7341 /***************************************************************************
7342 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
7343 FLAG_CMDLINE won't be overridden by loads from smb.conf.
7344 ***************************************************************************/
7346 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
7348 int parmnum, i;
7349 parmnum = map_parameter(pszParmName);
7350 if (parmnum >= 0) {
7351 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
7352 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
7353 return false;
7355 parm_table[parmnum].flags |= FLAG_CMDLINE;
7357 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
7358 * be grouped in the table, so we don't have to search the
7359 * whole table */
7360 for (i=parmnum-1;
7361 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
7362 && parm_table[i].p_class == parm_table[parmnum].p_class;
7363 i--) {
7364 parm_table[i].flags |= FLAG_CMDLINE;
7366 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
7367 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
7368 parm_table[i].flags |= FLAG_CMDLINE;
7371 if (store_values) {
7372 store_lp_set_cmdline(pszParmName, pszParmValue);
7374 return true;
7377 /* it might be parametric */
7378 if (strchr(pszParmName, ':') != NULL) {
7379 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
7380 if (store_values) {
7381 store_lp_set_cmdline(pszParmName, pszParmValue);
7383 return true;
7386 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7387 return true;
7390 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
7392 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
7395 /***************************************************************************
7396 Process a parameter.
7397 ***************************************************************************/
7399 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7400 void *userdata)
7402 if (!bInGlobalSection && bGlobalOnly)
7403 return true;
7405 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7407 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7408 pszParmName, pszParmValue));
7412 set a option from the commandline in 'a=b' format. Use to support --option
7414 bool lp_set_option(const char *option)
7416 char *p, *s;
7417 bool ret;
7419 s = talloc_strdup(NULL, option);
7420 if (!s) {
7421 return false;
7424 p = strchr(s, '=');
7425 if (!p) {
7426 talloc_free(s);
7427 return false;
7430 *p = 0;
7432 /* skip white spaces after the = sign */
7433 do {
7434 p++;
7435 } while (*p == ' ');
7437 ret = lp_set_cmdline(s, p);
7438 talloc_free(s);
7439 return ret;
7442 /**************************************************************************
7443 Print a parameter of the specified type.
7444 ***************************************************************************/
7446 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7448 /* For the seperation of lists values that we print below */
7449 const char *list_sep = ", ";
7450 int i;
7451 switch (p->type)
7453 case P_ENUM:
7454 for (i = 0; p->enum_list[i].name; i++) {
7455 if (*(int *)ptr == p->enum_list[i].value) {
7456 fprintf(f, "%s",
7457 p->enum_list[i].name);
7458 break;
7461 break;
7463 case P_BOOL:
7464 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7465 break;
7467 case P_BOOLREV:
7468 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7469 break;
7471 case P_INTEGER:
7472 case P_BYTES:
7473 fprintf(f, "%d", *(int *)ptr);
7474 break;
7476 case P_CHAR:
7477 fprintf(f, "%c", *(char *)ptr);
7478 break;
7480 case P_OCTAL: {
7481 int val = *(int *)ptr;
7482 if (val == -1) {
7483 fprintf(f, "-1");
7484 } else {
7485 fprintf(f, "0%o", val);
7487 break;
7490 case P_CMDLIST:
7491 list_sep = " ";
7492 /* fall through */
7493 case P_LIST:
7494 if ((char ***)ptr && *(char ***)ptr) {
7495 char **list = *(char ***)ptr;
7496 for (; *list; list++) {
7497 /* surround strings with whitespace in double quotes */
7498 if (*(list+1) == NULL) {
7499 /* last item, no extra separator */
7500 list_sep = "";
7502 if ( strchr_m( *list, ' ' ) ) {
7503 fprintf(f, "\"%s\"%s", *list, list_sep);
7504 } else {
7505 fprintf(f, "%s%s", *list, list_sep);
7509 break;
7511 case P_STRING:
7512 case P_USTRING:
7513 if (*(char **)ptr) {
7514 fprintf(f, "%s", *(char **)ptr);
7516 break;
7517 case P_SEP:
7518 break;
7522 /***************************************************************************
7523 Check if two parameters are equal.
7524 ***************************************************************************/
7526 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7528 switch (type) {
7529 case P_BOOL:
7530 case P_BOOLREV:
7531 return (*((bool *)ptr1) == *((bool *)ptr2));
7533 case P_INTEGER:
7534 case P_ENUM:
7535 case P_OCTAL:
7536 case P_BYTES:
7537 return (*((int *)ptr1) == *((int *)ptr2));
7539 case P_CHAR:
7540 return (*((char *)ptr1) == *((char *)ptr2));
7542 case P_LIST:
7543 case P_CMDLIST:
7544 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7546 case P_STRING:
7547 case P_USTRING:
7549 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7550 if (p1 && !*p1)
7551 p1 = NULL;
7552 if (p2 && !*p2)
7553 p2 = NULL;
7554 return (p1 == p2 || strequal(p1, p2));
7556 case P_SEP:
7557 break;
7559 return false;
7562 /***************************************************************************
7563 Initialize any local varients in the sDefault table.
7564 ***************************************************************************/
7566 void init_locals(void)
7568 /* None as yet. */
7571 /***************************************************************************
7572 Process a new section (service). At this stage all sections are services.
7573 Later we'll have special sections that permit server parameters to be set.
7574 Returns true on success, false on failure.
7575 ***************************************************************************/
7577 static bool do_section(const char *pszSectionName, void *userdata)
7579 bool bRetval;
7580 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7581 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7582 bRetval = false;
7584 /* if we were in a global section then do the local inits */
7585 if (bInGlobalSection && !isglobal)
7586 init_locals();
7588 /* if we've just struck a global section, note the fact. */
7589 bInGlobalSection = isglobal;
7591 /* check for multiple global sections */
7592 if (bInGlobalSection) {
7593 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7594 return true;
7597 if (!bInGlobalSection && bGlobalOnly)
7598 return true;
7600 /* if we have a current service, tidy it up before moving on */
7601 bRetval = true;
7603 if (iServiceIndex >= 0)
7604 bRetval = service_ok(iServiceIndex);
7606 /* if all is still well, move to the next record in the services array */
7607 if (bRetval) {
7608 /* We put this here to avoid an odd message order if messages are */
7609 /* issued by the post-processing of a previous section. */
7610 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7612 iServiceIndex = add_a_service(&sDefault, pszSectionName);
7613 if (iServiceIndex < 0) {
7614 DEBUG(0, ("Failed to add a new service\n"));
7615 return false;
7617 /* Clean all parametric options for service */
7618 /* They will be added during parsing again */
7619 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
7622 return bRetval;
7626 /***************************************************************************
7627 Determine if a partcular base parameter is currentl set to the default value.
7628 ***************************************************************************/
7630 static bool is_default(int i)
7632 if (!defaults_saved)
7633 return false;
7634 switch (parm_table[i].type) {
7635 case P_LIST:
7636 case P_CMDLIST:
7637 return str_list_equal((const char **)parm_table[i].def.lvalue,
7638 *(const char ***)lp_parm_ptr(NULL,
7639 &parm_table[i]));
7640 case P_STRING:
7641 case P_USTRING:
7642 return strequal(parm_table[i].def.svalue,
7643 *(char **)lp_parm_ptr(NULL,
7644 &parm_table[i]));
7645 case P_BOOL:
7646 case P_BOOLREV:
7647 return parm_table[i].def.bvalue ==
7648 *(bool *)lp_parm_ptr(NULL,
7649 &parm_table[i]);
7650 case P_CHAR:
7651 return parm_table[i].def.cvalue ==
7652 *(char *)lp_parm_ptr(NULL,
7653 &parm_table[i]);
7654 case P_INTEGER:
7655 case P_OCTAL:
7656 case P_ENUM:
7657 case P_BYTES:
7658 return parm_table[i].def.ivalue ==
7659 *(int *)lp_parm_ptr(NULL,
7660 &parm_table[i]);
7661 case P_SEP:
7662 break;
7664 return false;
7667 /***************************************************************************
7668 Display the contents of the global structure.
7669 ***************************************************************************/
7671 static void dump_globals(FILE *f)
7673 int i;
7674 struct parmlist_entry *data;
7676 fprintf(f, "[global]\n");
7678 for (i = 0; parm_table[i].label; i++)
7679 if (parm_table[i].p_class == P_GLOBAL &&
7680 !(parm_table[i].flags & FLAG_META) &&
7681 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
7682 if (defaults_saved && is_default(i))
7683 continue;
7684 fprintf(f, "\t%s = ", parm_table[i].label);
7685 print_parameter(&parm_table[i], lp_parm_ptr(NULL,
7686 &parm_table[i]),
7688 fprintf(f, "\n");
7690 if (Globals.param_opt != NULL) {
7691 data = Globals.param_opt;
7692 while(data) {
7693 fprintf(f, "\t%s = %s\n", data->key, data->value);
7694 data = data->next;
7700 /***************************************************************************
7701 Return true if a local parameter is currently set to the global default.
7702 ***************************************************************************/
7704 bool lp_is_default(int snum, struct parm_struct *parm)
7706 return equal_parameter(parm->type,
7707 lp_parm_ptr(ServicePtrs[snum], parm),
7708 lp_parm_ptr(NULL, parm));
7711 /***************************************************************************
7712 Display the contents of a single services record.
7713 ***************************************************************************/
7715 static void dump_a_service(struct loadparm_service *pService, FILE * f)
7717 int i;
7718 struct parmlist_entry *data;
7720 if (pService != &sDefault)
7721 fprintf(f, "[%s]\n", pService->szService);
7723 for (i = 0; parm_table[i].label; i++) {
7725 if (parm_table[i].p_class == P_LOCAL &&
7726 !(parm_table[i].flags & FLAG_META) &&
7727 (*parm_table[i].label != '-') &&
7728 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7730 if (pService == &sDefault) {
7731 if (defaults_saved && is_default(i))
7732 continue;
7733 } else {
7734 if (equal_parameter(parm_table[i].type,
7735 lp_parm_ptr(pService, &parm_table[i]),
7736 lp_parm_ptr(NULL, &parm_table[i])))
7737 continue;
7740 fprintf(f, "\t%s = ", parm_table[i].label);
7741 print_parameter(&parm_table[i],
7742 lp_parm_ptr(pService, &parm_table[i]),
7744 fprintf(f, "\n");
7748 if (pService->param_opt != NULL) {
7749 data = pService->param_opt;
7750 while(data) {
7751 fprintf(f, "\t%s = %s\n", data->key, data->value);
7752 data = data->next;
7757 /***************************************************************************
7758 Display the contents of a parameter of a single services record.
7759 ***************************************************************************/
7761 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7763 int i;
7764 bool result = false;
7765 parm_class p_class;
7766 unsigned flag = 0;
7767 fstring local_parm_name;
7768 char *parm_opt;
7769 const char *parm_opt_value;
7771 /* check for parametrical option */
7772 fstrcpy( local_parm_name, parm_name);
7773 parm_opt = strchr( local_parm_name, ':');
7775 if (parm_opt) {
7776 *parm_opt = '\0';
7777 parm_opt++;
7778 if (strlen(parm_opt)) {
7779 parm_opt_value = lp_parm_const_string( snum,
7780 local_parm_name, parm_opt, NULL);
7781 if (parm_opt_value) {
7782 printf( "%s\n", parm_opt_value);
7783 result = true;
7786 return result;
7789 /* check for a key and print the value */
7790 if (isGlobal) {
7791 p_class = P_GLOBAL;
7792 flag = FLAG_GLOBAL;
7793 } else
7794 p_class = P_LOCAL;
7796 for (i = 0; parm_table[i].label; i++) {
7797 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7798 !(parm_table[i].flags & FLAG_META) &&
7799 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7800 (*parm_table[i].label != '-') &&
7801 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
7803 void *ptr;
7805 if (isGlobal) {
7806 ptr = lp_parm_ptr(NULL,
7807 &parm_table[i]);
7808 } else {
7809 ptr = lp_parm_ptr(ServicePtrs[snum],
7810 &parm_table[i]);
7813 print_parameter(&parm_table[i],
7814 ptr, f);
7815 fprintf(f, "\n");
7816 result = true;
7817 break;
7821 return result;
7824 /***************************************************************************
7825 Return info about the requested parameter (given as a string).
7826 Return NULL when the string is not a valid parameter name.
7827 ***************************************************************************/
7829 struct parm_struct *lp_get_parameter(const char *param_name)
7831 int num = map_parameter(param_name);
7833 if (num < 0) {
7834 return NULL;
7837 return &parm_table[num];
7840 /***************************************************************************
7841 Return info about the next parameter in a service.
7842 snum==GLOBAL_SECTION_SNUM gives the globals.
7843 Return NULL when out of parameters.
7844 ***************************************************************************/
7846 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7848 if (snum < 0) {
7849 /* do the globals */
7850 for (; parm_table[*i].label; (*i)++) {
7851 if (parm_table[*i].p_class == P_SEPARATOR)
7852 return &parm_table[(*i)++];
7854 if ((*parm_table[*i].label == '-'))
7855 continue;
7857 if ((*i) > 0
7858 && (parm_table[*i].offset ==
7859 parm_table[(*i) - 1].offset)
7860 && (parm_table[*i].p_class ==
7861 parm_table[(*i) - 1].p_class))
7862 continue;
7864 if (is_default(*i) && !allparameters)
7865 continue;
7867 return &parm_table[(*i)++];
7869 } else {
7870 struct loadparm_service *pService = ServicePtrs[snum];
7872 for (; parm_table[*i].label; (*i)++) {
7873 if (parm_table[*i].p_class == P_SEPARATOR)
7874 return &parm_table[(*i)++];
7876 if (parm_table[*i].p_class == P_LOCAL &&
7877 (*parm_table[*i].label != '-') &&
7878 ((*i) == 0 ||
7879 (parm_table[*i].offset !=
7880 parm_table[(*i) - 1].offset)))
7882 if (allparameters ||
7883 !equal_parameter(parm_table[*i].type,
7884 lp_parm_ptr(pService,
7885 &parm_table[*i]),
7886 lp_parm_ptr(NULL,
7887 &parm_table[*i])))
7889 return &parm_table[(*i)++];
7895 return NULL;
7899 #if 0
7900 /***************************************************************************
7901 Display the contents of a single copy structure.
7902 ***************************************************************************/
7903 static void dump_copy_map(bool *pcopymap)
7905 int i;
7906 if (!pcopymap)
7907 return;
7909 printf("\n\tNon-Copied parameters:\n");
7911 for (i = 0; parm_table[i].label; i++)
7912 if (parm_table[i].p_class == P_LOCAL &&
7913 parm_table[i].ptr && !pcopymap[i] &&
7914 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7916 printf("\t\t%s\n", parm_table[i].label);
7919 #endif
7921 /***************************************************************************
7922 Return TRUE if the passed service number is within range.
7923 ***************************************************************************/
7925 bool lp_snum_ok(int iService)
7927 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7930 /***************************************************************************
7931 Auto-load some home services.
7932 ***************************************************************************/
7934 static void lp_add_auto_services(char *str)
7936 char *s;
7937 char *p;
7938 int homes;
7939 char *saveptr;
7941 if (!str)
7942 return;
7944 s = SMB_STRDUP(str);
7945 if (!s)
7946 return;
7948 homes = lp_servicenumber(HOMES_NAME);
7950 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7951 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7952 char *home;
7954 if (lp_servicenumber(p) >= 0)
7955 continue;
7957 home = get_user_home_dir(talloc_tos(), p);
7959 if (home && home[0] && homes >= 0)
7960 lp_add_home(p, homes, p, home);
7962 TALLOC_FREE(home);
7964 SAFE_FREE(s);
7967 /***************************************************************************
7968 Auto-load one printer.
7969 ***************************************************************************/
7971 void lp_add_one_printer(const char *name, const char *comment,
7972 const char *location, void *pdata)
7974 int printers = lp_servicenumber(PRINTERS_NAME);
7975 int i;
7977 if (lp_servicenumber(name) < 0) {
7978 lp_add_printer(name, printers);
7979 if ((i = lp_servicenumber(name)) >= 0) {
7980 string_set(&ServicePtrs[i]->comment, comment);
7981 ServicePtrs[i]->autoloaded = true;
7986 /***************************************************************************
7987 Have we loaded a services file yet?
7988 ***************************************************************************/
7990 bool lp_loaded(void)
7992 return (bLoaded);
7995 /***************************************************************************
7996 Unload unused services.
7997 ***************************************************************************/
7999 void lp_killunused(struct smbd_server_connection *sconn,
8000 bool (*snumused) (struct smbd_server_connection *, int))
8002 int i;
8003 for (i = 0; i < iNumServices; i++) {
8004 if (!VALID(i))
8005 continue;
8007 /* don't kill autoloaded or usershare services */
8008 if ( ServicePtrs[i]->autoloaded ||
8009 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8010 continue;
8013 if (!snumused || !snumused(sconn, i)) {
8014 free_service_byindex(i);
8020 * Kill all except autoloaded and usershare services - convenience wrapper
8022 void lp_kill_all_services(void)
8024 lp_killunused(NULL, NULL);
8027 /***************************************************************************
8028 Unload a service.
8029 ***************************************************************************/
8031 void lp_killservice(int iServiceIn)
8033 if (VALID(iServiceIn)) {
8034 free_service_byindex(iServiceIn);
8038 /***************************************************************************
8039 Save the curent values of all global and sDefault parameters into the
8040 defaults union. This allows swat and testparm to show only the
8041 changed (ie. non-default) parameters.
8042 ***************************************************************************/
8044 static void lp_save_defaults(void)
8046 int i;
8047 for (i = 0; parm_table[i].label; i++) {
8048 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
8049 && parm_table[i].p_class == parm_table[i - 1].p_class)
8050 continue;
8051 switch (parm_table[i].type) {
8052 case P_LIST:
8053 case P_CMDLIST:
8054 parm_table[i].def.lvalue = str_list_copy(
8055 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
8056 break;
8057 case P_STRING:
8058 case P_USTRING:
8059 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
8060 break;
8061 case P_BOOL:
8062 case P_BOOLREV:
8063 parm_table[i].def.bvalue =
8064 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
8065 break;
8066 case P_CHAR:
8067 parm_table[i].def.cvalue =
8068 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
8069 break;
8070 case P_INTEGER:
8071 case P_OCTAL:
8072 case P_ENUM:
8073 case P_BYTES:
8074 parm_table[i].def.ivalue =
8075 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
8076 break;
8077 case P_SEP:
8078 break;
8081 defaults_saved = true;
8084 /***********************************************************
8085 If we should send plaintext/LANMAN passwords in the clinet
8086 ************************************************************/
8088 static void set_allowed_client_auth(void)
8090 if (Globals.bClientNTLMv2Auth) {
8091 Globals.bClientLanManAuth = false;
8093 if (!Globals.bClientLanManAuth) {
8094 Globals.bClientPlaintextAuth = false;
8098 /***************************************************************************
8099 JRA.
8100 The following code allows smbd to read a user defined share file.
8101 Yes, this is my intent. Yes, I'm comfortable with that...
8103 THE FOLLOWING IS SECURITY CRITICAL CODE.
8105 It washes your clothes, it cleans your house, it guards you while you sleep...
8106 Do not f%^k with it....
8107 ***************************************************************************/
8109 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8111 /***************************************************************************
8112 Check allowed stat state of a usershare file.
8113 Ensure we print out who is dicking with us so the admin can
8114 get their sorry ass fired.
8115 ***************************************************************************/
8117 static bool check_usershare_stat(const char *fname,
8118 const SMB_STRUCT_STAT *psbuf)
8120 if (!S_ISREG(psbuf->st_ex_mode)) {
8121 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8122 "not a regular file\n",
8123 fname, (unsigned int)psbuf->st_ex_uid ));
8124 return false;
8127 /* Ensure this doesn't have the other write bit set. */
8128 if (psbuf->st_ex_mode & S_IWOTH) {
8129 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8130 "public write. Refusing to allow as a usershare file.\n",
8131 fname, (unsigned int)psbuf->st_ex_uid ));
8132 return false;
8135 /* Should be 10k or less. */
8136 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8137 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8138 "too large (%u) to be a user share file.\n",
8139 fname, (unsigned int)psbuf->st_ex_uid,
8140 (unsigned int)psbuf->st_ex_size ));
8141 return false;
8144 return true;
8147 /***************************************************************************
8148 Parse the contents of a usershare file.
8149 ***************************************************************************/
8151 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8152 SMB_STRUCT_STAT *psbuf,
8153 const char *servicename,
8154 int snum,
8155 char **lines,
8156 int numlines,
8157 char **pp_sharepath,
8158 char **pp_comment,
8159 char **pp_cp_servicename,
8160 struct security_descriptor **ppsd,
8161 bool *pallow_guest)
8163 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8164 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8165 int us_vers;
8166 DIR *dp;
8167 SMB_STRUCT_STAT sbuf;
8168 char *sharepath = NULL;
8169 char *comment = NULL;
8171 *pp_sharepath = NULL;
8172 *pp_comment = NULL;
8174 *pallow_guest = false;
8176 if (numlines < 4) {
8177 return USERSHARE_MALFORMED_FILE;
8180 if (strcmp(lines[0], "#VERSION 1") == 0) {
8181 us_vers = 1;
8182 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8183 us_vers = 2;
8184 if (numlines < 5) {
8185 return USERSHARE_MALFORMED_FILE;
8187 } else {
8188 return USERSHARE_BAD_VERSION;
8191 if (strncmp(lines[1], "path=", 5) != 0) {
8192 return USERSHARE_MALFORMED_PATH;
8195 sharepath = talloc_strdup(ctx, &lines[1][5]);
8196 if (!sharepath) {
8197 return USERSHARE_POSIX_ERR;
8199 trim_string(sharepath, " ", " ");
8201 if (strncmp(lines[2], "comment=", 8) != 0) {
8202 return USERSHARE_MALFORMED_COMMENT_DEF;
8205 comment = talloc_strdup(ctx, &lines[2][8]);
8206 if (!comment) {
8207 return USERSHARE_POSIX_ERR;
8209 trim_string(comment, " ", " ");
8210 trim_char(comment, '"', '"');
8212 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8213 return USERSHARE_MALFORMED_ACL_DEF;
8216 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8217 return USERSHARE_ACL_ERR;
8220 if (us_vers == 2) {
8221 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8222 return USERSHARE_MALFORMED_ACL_DEF;
8224 if (lines[4][9] == 'y') {
8225 *pallow_guest = true;
8228 /* Backwards compatible extension to file version #2. */
8229 if (numlines > 5) {
8230 if (strncmp(lines[5], "sharename=", 10) != 0) {
8231 return USERSHARE_MALFORMED_SHARENAME_DEF;
8233 if (!strequal(&lines[5][10], servicename)) {
8234 return USERSHARE_BAD_SHARENAME;
8236 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8237 if (!*pp_cp_servicename) {
8238 return USERSHARE_POSIX_ERR;
8243 if (*pp_cp_servicename == NULL) {
8244 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8245 if (!*pp_cp_servicename) {
8246 return USERSHARE_POSIX_ERR;
8250 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8251 /* Path didn't change, no checks needed. */
8252 *pp_sharepath = sharepath;
8253 *pp_comment = comment;
8254 return USERSHARE_OK;
8257 /* The path *must* be absolute. */
8258 if (sharepath[0] != '/') {
8259 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8260 servicename, sharepath));
8261 return USERSHARE_PATH_NOT_ABSOLUTE;
8264 /* If there is a usershare prefix deny list ensure one of these paths
8265 doesn't match the start of the user given path. */
8266 if (prefixdenylist) {
8267 int i;
8268 for ( i=0; prefixdenylist[i]; i++ ) {
8269 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8270 servicename, i, prefixdenylist[i], sharepath ));
8271 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8272 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8273 "usershare prefix deny list entries.\n",
8274 servicename, sharepath));
8275 return USERSHARE_PATH_IS_DENIED;
8280 /* If there is a usershare prefix allow list ensure one of these paths
8281 does match the start of the user given path. */
8283 if (prefixallowlist) {
8284 int i;
8285 for ( i=0; prefixallowlist[i]; i++ ) {
8286 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8287 servicename, i, prefixallowlist[i], sharepath ));
8288 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8289 break;
8292 if (prefixallowlist[i] == NULL) {
8293 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8294 "usershare prefix allow list entries.\n",
8295 servicename, sharepath));
8296 return USERSHARE_PATH_NOT_ALLOWED;
8300 /* Ensure this is pointing to a directory. */
8301 dp = opendir(sharepath);
8303 if (!dp) {
8304 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8305 servicename, sharepath));
8306 return USERSHARE_PATH_NOT_DIRECTORY;
8309 /* Ensure the owner of the usershare file has permission to share
8310 this directory. */
8312 if (sys_stat(sharepath, &sbuf, false) == -1) {
8313 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8314 servicename, sharepath, strerror(errno) ));
8315 closedir(dp);
8316 return USERSHARE_POSIX_ERR;
8319 closedir(dp);
8321 if (!S_ISDIR(sbuf.st_ex_mode)) {
8322 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8323 servicename, sharepath ));
8324 return USERSHARE_PATH_NOT_DIRECTORY;
8327 /* Check if sharing is restricted to owner-only. */
8328 /* psbuf is the stat of the usershare definition file,
8329 sbuf is the stat of the target directory to be shared. */
8331 if (lp_usershare_owner_only()) {
8332 /* root can share anything. */
8333 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8334 return USERSHARE_PATH_NOT_ALLOWED;
8338 *pp_sharepath = sharepath;
8339 *pp_comment = comment;
8340 return USERSHARE_OK;
8343 /***************************************************************************
8344 Deal with a usershare file.
8345 Returns:
8346 >= 0 - snum
8347 -1 - Bad name, invalid contents.
8348 - service name already existed and not a usershare, problem
8349 with permissions to share directory etc.
8350 ***************************************************************************/
8352 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8354 SMB_STRUCT_STAT sbuf;
8355 SMB_STRUCT_STAT lsbuf;
8356 char *fname = NULL;
8357 char *sharepath = NULL;
8358 char *comment = NULL;
8359 char *cp_service_name = NULL;
8360 char **lines = NULL;
8361 int numlines = 0;
8362 int fd = -1;
8363 int iService = -1;
8364 TALLOC_CTX *ctx = talloc_stackframe();
8365 struct security_descriptor *psd = NULL;
8366 bool guest_ok = false;
8367 char *canon_name = NULL;
8368 bool added_service = false;
8369 int ret = -1;
8371 /* Ensure share name doesn't contain invalid characters. */
8372 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8373 DEBUG(0,("process_usershare_file: share name %s contains "
8374 "invalid characters (any of %s)\n",
8375 file_name, INVALID_SHARENAME_CHARS ));
8376 goto out;
8379 canon_name = canonicalize_servicename(ctx, file_name);
8380 if (!canon_name) {
8381 goto out;
8384 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8385 if (!fname) {
8386 goto out;
8389 /* Minimize the race condition by doing an lstat before we
8390 open and fstat. Ensure this isn't a symlink link. */
8392 if (sys_lstat(fname, &lsbuf, false) != 0) {
8393 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8394 fname, strerror(errno) ));
8395 goto out;
8398 /* This must be a regular file, not a symlink, directory or
8399 other strange filetype. */
8400 if (!check_usershare_stat(fname, &lsbuf)) {
8401 goto out;
8405 TDB_DATA data;
8406 NTSTATUS status;
8408 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
8409 canon_name, &data);
8411 iService = -1;
8413 if (NT_STATUS_IS_OK(status) &&
8414 (data.dptr != NULL) &&
8415 (data.dsize == sizeof(iService))) {
8416 memcpy(&iService, data.dptr, sizeof(iService));
8420 if (iService != -1 &&
8421 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8422 &lsbuf.st_ex_mtime) == 0) {
8423 /* Nothing changed - Mark valid and return. */
8424 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8425 canon_name ));
8426 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8427 ret = iService;
8428 goto out;
8431 /* Try and open the file read only - no symlinks allowed. */
8432 #ifdef O_NOFOLLOW
8433 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
8434 #else
8435 fd = open(fname, O_RDONLY, 0);
8436 #endif
8438 if (fd == -1) {
8439 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8440 fname, strerror(errno) ));
8441 goto out;
8444 /* Now fstat to be *SURE* it's a regular file. */
8445 if (sys_fstat(fd, &sbuf, false) != 0) {
8446 close(fd);
8447 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8448 fname, strerror(errno) ));
8449 goto out;
8452 /* Is it the same dev/inode as was lstated ? */
8453 if (!check_same_stat(&lsbuf, &sbuf)) {
8454 close(fd);
8455 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8456 "Symlink spoofing going on ?\n", fname ));
8457 goto out;
8460 /* This must be a regular file, not a symlink, directory or
8461 other strange filetype. */
8462 if (!check_usershare_stat(fname, &sbuf)) {
8463 goto out;
8466 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8468 close(fd);
8469 if (lines == NULL) {
8470 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8471 fname, (unsigned int)sbuf.st_ex_uid ));
8472 goto out;
8475 if (parse_usershare_file(ctx, &sbuf, file_name,
8476 iService, lines, numlines, &sharepath,
8477 &comment, &cp_service_name,
8478 &psd, &guest_ok) != USERSHARE_OK) {
8479 goto out;
8482 /* Everything ok - add the service possibly using a template. */
8483 if (iService < 0) {
8484 const struct loadparm_service *sp = &sDefault;
8485 if (snum_template != -1) {
8486 sp = ServicePtrs[snum_template];
8489 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8490 DEBUG(0, ("process_usershare_file: Failed to add "
8491 "new service %s\n", cp_service_name));
8492 goto out;
8495 added_service = true;
8497 /* Read only is controlled by usershare ACL below. */
8498 ServicePtrs[iService]->bRead_only = false;
8501 /* Write the ACL of the new/modified share. */
8502 if (!set_share_security(canon_name, psd)) {
8503 DEBUG(0, ("process_usershare_file: Failed to set share "
8504 "security for user share %s\n",
8505 canon_name ));
8506 goto out;
8509 /* If from a template it may be marked invalid. */
8510 ServicePtrs[iService]->valid = true;
8512 /* Set the service as a valid usershare. */
8513 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8515 /* Set guest access. */
8516 if (lp_usershare_allow_guests()) {
8517 ServicePtrs[iService]->bGuest_ok = guest_ok;
8520 /* And note when it was loaded. */
8521 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8522 string_set(&ServicePtrs[iService]->szPath, sharepath);
8523 string_set(&ServicePtrs[iService]->comment, comment);
8525 ret = iService;
8527 out:
8529 if (ret == -1 && iService != -1 && added_service) {
8530 lp_remove_service(iService);
8533 TALLOC_FREE(lines);
8534 TALLOC_FREE(ctx);
8535 return ret;
8538 /***************************************************************************
8539 Checks if a usershare entry has been modified since last load.
8540 ***************************************************************************/
8542 static bool usershare_exists(int iService, struct timespec *last_mod)
8544 SMB_STRUCT_STAT lsbuf;
8545 const char *usersharepath = Globals.szUsersharePath;
8546 char *fname;
8548 if (asprintf(&fname, "%s/%s",
8549 usersharepath,
8550 ServicePtrs[iService]->szService) < 0) {
8551 return false;
8554 if (sys_lstat(fname, &lsbuf, false) != 0) {
8555 SAFE_FREE(fname);
8556 return false;
8559 if (!S_ISREG(lsbuf.st_ex_mode)) {
8560 SAFE_FREE(fname);
8561 return false;
8564 SAFE_FREE(fname);
8565 *last_mod = lsbuf.st_ex_mtime;
8566 return true;
8569 /***************************************************************************
8570 Load a usershare service by name. Returns a valid servicenumber or -1.
8571 ***************************************************************************/
8573 int load_usershare_service(const char *servicename)
8575 SMB_STRUCT_STAT sbuf;
8576 const char *usersharepath = Globals.szUsersharePath;
8577 int max_user_shares = Globals.iUsershareMaxShares;
8578 int snum_template = -1;
8580 if (*usersharepath == 0 || max_user_shares == 0) {
8581 return -1;
8584 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8585 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8586 usersharepath, strerror(errno) ));
8587 return -1;
8590 if (!S_ISDIR(sbuf.st_ex_mode)) {
8591 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8592 usersharepath ));
8593 return -1;
8597 * This directory must be owned by root, and have the 't' bit set.
8598 * It also must not be writable by "other".
8601 #ifdef S_ISVTX
8602 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8603 #else
8604 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8605 #endif
8606 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8607 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8608 usersharepath ));
8609 return -1;
8612 /* Ensure the template share exists if it's set. */
8613 if (Globals.szUsershareTemplateShare[0]) {
8614 /* We can't use lp_servicenumber here as we are recommending that
8615 template shares have -valid=false set. */
8616 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8617 if (ServicePtrs[snum_template]->szService &&
8618 strequal(ServicePtrs[snum_template]->szService,
8619 Globals.szUsershareTemplateShare)) {
8620 break;
8624 if (snum_template == -1) {
8625 DEBUG(0,("load_usershare_service: usershare template share %s "
8626 "does not exist.\n",
8627 Globals.szUsershareTemplateShare ));
8628 return -1;
8632 return process_usershare_file(usersharepath, servicename, snum_template);
8635 /***************************************************************************
8636 Load all user defined shares from the user share directory.
8637 We only do this if we're enumerating the share list.
8638 This is the function that can delete usershares that have
8639 been removed.
8640 ***************************************************************************/
8642 int load_usershare_shares(struct smbd_server_connection *sconn,
8643 bool (*snumused) (struct smbd_server_connection *, int))
8645 DIR *dp;
8646 SMB_STRUCT_STAT sbuf;
8647 struct dirent *de;
8648 int num_usershares = 0;
8649 int max_user_shares = Globals.iUsershareMaxShares;
8650 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8651 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8652 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8653 int iService;
8654 int snum_template = -1;
8655 const char *usersharepath = Globals.szUsersharePath;
8656 int ret = lp_numservices();
8657 TALLOC_CTX *tmp_ctx;
8659 if (max_user_shares == 0 || *usersharepath == '\0') {
8660 return lp_numservices();
8663 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8664 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8665 usersharepath, strerror(errno) ));
8666 return ret;
8670 * This directory must be owned by root, and have the 't' bit set.
8671 * It also must not be writable by "other".
8674 #ifdef S_ISVTX
8675 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8676 #else
8677 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8678 #endif
8679 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8680 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8681 usersharepath ));
8682 return ret;
8685 /* Ensure the template share exists if it's set. */
8686 if (Globals.szUsershareTemplateShare[0]) {
8687 /* We can't use lp_servicenumber here as we are recommending that
8688 template shares have -valid=false set. */
8689 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8690 if (ServicePtrs[snum_template]->szService &&
8691 strequal(ServicePtrs[snum_template]->szService,
8692 Globals.szUsershareTemplateShare)) {
8693 break;
8697 if (snum_template == -1) {
8698 DEBUG(0,("load_usershare_shares: usershare template share %s "
8699 "does not exist.\n",
8700 Globals.szUsershareTemplateShare ));
8701 return ret;
8705 /* Mark all existing usershares as pending delete. */
8706 for (iService = iNumServices - 1; iService >= 0; iService--) {
8707 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8708 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8712 dp = opendir(usersharepath);
8713 if (!dp) {
8714 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8715 usersharepath, strerror(errno) ));
8716 return ret;
8719 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8720 (de = readdir(dp));
8721 num_dir_entries++ ) {
8722 int r;
8723 const char *n = de->d_name;
8725 /* Ignore . and .. */
8726 if (*n == '.') {
8727 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8728 continue;
8732 if (n[0] == ':') {
8733 /* Temporary file used when creating a share. */
8734 num_tmp_dir_entries++;
8737 /* Allow 20% tmp entries. */
8738 if (num_tmp_dir_entries > allowed_tmp_entries) {
8739 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8740 "in directory %s\n",
8741 num_tmp_dir_entries, usersharepath));
8742 break;
8745 r = process_usershare_file(usersharepath, n, snum_template);
8746 if (r == 0) {
8747 /* Update the services count. */
8748 num_usershares++;
8749 if (num_usershares >= max_user_shares) {
8750 DEBUG(0,("load_usershare_shares: max user shares reached "
8751 "on file %s in directory %s\n",
8752 n, usersharepath ));
8753 break;
8755 } else if (r == -1) {
8756 num_bad_dir_entries++;
8759 /* Allow 20% bad entries. */
8760 if (num_bad_dir_entries > allowed_bad_entries) {
8761 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8762 "in directory %s\n",
8763 num_bad_dir_entries, usersharepath));
8764 break;
8767 /* Allow 20% bad entries. */
8768 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8769 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8770 "in directory %s\n",
8771 num_dir_entries, usersharepath));
8772 break;
8776 closedir(dp);
8778 /* Sweep through and delete any non-refreshed usershares that are
8779 not currently in use. */
8780 tmp_ctx = talloc_stackframe();
8781 for (iService = iNumServices - 1; iService >= 0; iService--) {
8782 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8783 char *servname;
8785 if (snumused && snumused(sconn, iService)) {
8786 continue;
8789 servname = lp_servicename(tmp_ctx, iService);
8791 /* Remove from the share ACL db. */
8792 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8793 servname ));
8794 delete_share_security(servname);
8795 free_service_byindex(iService);
8798 talloc_free(tmp_ctx);
8800 return lp_numservices();
8803 /********************************************************
8804 Destroy global resources allocated in this file
8805 ********************************************************/
8807 void gfree_loadparm(void)
8809 int i;
8811 free_file_list();
8813 /* Free resources allocated to services */
8815 for ( i = 0; i < iNumServices; i++ ) {
8816 if ( VALID(i) ) {
8817 free_service_byindex(i);
8821 SAFE_FREE( ServicePtrs );
8822 iNumServices = 0;
8824 /* Now release all resources allocated to global
8825 parameters and the default service */
8827 free_global_parameters();
8831 /***************************************************************************
8832 Allow client apps to specify that they are a client
8833 ***************************************************************************/
8834 static void lp_set_in_client(bool b)
8836 in_client = b;
8840 /***************************************************************************
8841 Determine if we're running in a client app
8842 ***************************************************************************/
8843 static bool lp_is_in_client(void)
8845 return in_client;
8848 /***************************************************************************
8849 Load the services array from the services file. Return true on success,
8850 false on failure.
8851 ***************************************************************************/
8853 static bool lp_load_ex(const char *pszFname,
8854 bool global_only,
8855 bool save_defaults,
8856 bool add_ipc,
8857 bool initialize_globals,
8858 bool allow_include_registry,
8859 bool load_all_shares)
8861 char *n2 = NULL;
8862 bool bRetval;
8864 bRetval = false;
8866 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8868 bInGlobalSection = true;
8869 bGlobalOnly = global_only;
8870 bAllowIncludeRegistry = allow_include_registry;
8872 init_globals(initialize_globals);
8874 free_file_list();
8876 if (save_defaults) {
8877 init_locals();
8878 lp_save_defaults();
8881 if (!initialize_globals) {
8882 free_param_opts(&Globals.param_opt);
8883 apply_lp_set_cmdline();
8886 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
8888 /* We get sections first, so have to start 'behind' to make up */
8889 iServiceIndex = -1;
8891 if (lp_config_backend_is_file()) {
8892 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
8893 current_user_info.domain,
8894 pszFname);
8895 if (!n2) {
8896 smb_panic("lp_load_ex: out of memory");
8899 add_to_file_list(pszFname, n2);
8901 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8902 TALLOC_FREE(n2);
8904 /* finish up the last section */
8905 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8906 if (bRetval) {
8907 if (iServiceIndex >= 0) {
8908 bRetval = service_ok(iServiceIndex);
8912 if (lp_config_backend_is_registry()) {
8913 /* config backend changed to registry in config file */
8915 * We need to use this extra global variable here to
8916 * survive restart: init_globals uses this as a default
8917 * for ConfigBackend. Otherwise, init_globals would
8918 * send us into an endless loop here.
8920 config_backend = CONFIG_BACKEND_REGISTRY;
8921 /* start over */
8922 DEBUG(1, ("lp_load_ex: changing to config backend "
8923 "registry\n"));
8924 init_globals(true);
8925 lp_kill_all_services();
8926 return lp_load_ex(pszFname, global_only, save_defaults,
8927 add_ipc, initialize_globals,
8928 allow_include_registry,
8929 load_all_shares);
8931 } else if (lp_config_backend_is_registry()) {
8932 bRetval = process_registry_globals();
8933 } else {
8934 DEBUG(0, ("Illegal config backend given: %d\n",
8935 lp_config_backend()));
8936 bRetval = false;
8939 if (bRetval && lp_registry_shares()) {
8940 if (load_all_shares) {
8941 bRetval = process_registry_shares();
8942 } else {
8943 bRetval = reload_registry_shares();
8948 char *serv = lp_auto_services(talloc_tos());
8949 lp_add_auto_services(serv);
8950 TALLOC_FREE(serv);
8953 if (add_ipc) {
8954 /* When 'restrict anonymous = 2' guest connections to ipc$
8955 are denied */
8956 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8957 if ( lp_enable_asu_support() ) {
8958 lp_add_ipc("ADMIN$", false);
8962 set_allowed_client_auth();
8964 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
8965 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
8966 lp_passwordserver()));
8969 bLoaded = true;
8971 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8972 /* if bWINSsupport is true and we are in the client */
8973 if (lp_is_in_client() && Globals.bWINSsupport) {
8974 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8977 init_iconv();
8979 fault_configure(smb_panic_s3);
8981 bAllowIncludeRegistry = true;
8983 return (bRetval);
8986 bool lp_load(const char *pszFname,
8987 bool global_only,
8988 bool save_defaults,
8989 bool add_ipc,
8990 bool initialize_globals)
8992 return lp_load_ex(pszFname,
8993 global_only,
8994 save_defaults,
8995 add_ipc,
8996 initialize_globals,
8997 true, /* allow_include_registry */
8998 false); /* load_all_shares*/
9001 bool lp_load_initial_only(const char *pszFname)
9003 return lp_load_ex(pszFname,
9004 true, /* global only */
9005 false, /* save_defaults */
9006 false, /* add_ipc */
9007 true, /* initialize_globals */
9008 false, /* allow_include_registry */
9009 false); /* load_all_shares*/
9013 * most common lp_load wrapper, loading only the globals
9015 bool lp_load_global(const char *file_name)
9017 return lp_load_ex(file_name,
9018 true, /* global_only */
9019 false, /* save_defaults */
9020 false, /* add_ipc */
9021 true, /* initialize_globals */
9022 true, /* allow_include_registry */
9023 false); /* load_all_shares*/
9027 * lp_load wrapper, especially for clients
9029 bool lp_load_client(const char *file_name)
9031 lp_set_in_client(true);
9033 return lp_load_global(file_name);
9037 * lp_load wrapper, loading only globals, but intended
9038 * for subsequent calls, not reinitializing the globals
9039 * to default values
9041 bool lp_load_global_no_reinit(const char *file_name)
9043 return lp_load_ex(file_name,
9044 true, /* global_only */
9045 false, /* save_defaults */
9046 false, /* add_ipc */
9047 false, /* initialize_globals */
9048 true, /* allow_include_registry */
9049 false); /* load_all_shares*/
9053 * lp_load wrapper, especially for clients, no reinitialization
9055 bool lp_load_client_no_reinit(const char *file_name)
9057 lp_set_in_client(true);
9059 return lp_load_global_no_reinit(file_name);
9062 bool lp_load_with_registry_shares(const char *pszFname,
9063 bool global_only,
9064 bool save_defaults,
9065 bool add_ipc,
9066 bool initialize_globals)
9068 return lp_load_ex(pszFname,
9069 global_only,
9070 save_defaults,
9071 add_ipc,
9072 initialize_globals,
9073 true, /* allow_include_registry */
9074 true); /* load_all_shares*/
9077 /***************************************************************************
9078 Return the max number of services.
9079 ***************************************************************************/
9081 int lp_numservices(void)
9083 return (iNumServices);
9086 /***************************************************************************
9087 Display the contents of the services array in human-readable form.
9088 ***************************************************************************/
9090 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9092 int iService;
9094 if (show_defaults)
9095 defaults_saved = false;
9097 dump_globals(f);
9099 dump_a_service(&sDefault, f);
9101 for (iService = 0; iService < maxtoprint; iService++) {
9102 fprintf(f,"\n");
9103 lp_dump_one(f, show_defaults, iService);
9107 /***************************************************************************
9108 Display the contents of one service in human-readable form.
9109 ***************************************************************************/
9111 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9113 if (VALID(snum)) {
9114 if (ServicePtrs[snum]->szService[0] == '\0')
9115 return;
9116 dump_a_service(ServicePtrs[snum], f);
9120 /***************************************************************************
9121 Return the number of the service with the given name, or -1 if it doesn't
9122 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9123 getservicebyname()! This works ONLY if all services have been loaded, and
9124 does not copy the found service.
9125 ***************************************************************************/
9127 int lp_servicenumber(const char *pszServiceName)
9129 int iService;
9130 fstring serviceName;
9132 if (!pszServiceName) {
9133 return GLOBAL_SECTION_SNUM;
9136 for (iService = iNumServices - 1; iService >= 0; iService--) {
9137 if (VALID(iService) && ServicePtrs[iService]->szService) {
9139 * The substitution here is used to support %U is
9140 * service names
9142 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9143 standard_sub_basic(get_current_username(),
9144 current_user_info.domain,
9145 serviceName,sizeof(serviceName));
9146 if (strequal(serviceName, pszServiceName)) {
9147 break;
9152 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9153 struct timespec last_mod;
9155 if (!usershare_exists(iService, &last_mod)) {
9156 /* Remove the share security tdb entry for it. */
9157 delete_share_security(lp_servicename(talloc_tos(), iService));
9158 /* Remove it from the array. */
9159 free_service_byindex(iService);
9160 /* Doesn't exist anymore. */
9161 return GLOBAL_SECTION_SNUM;
9164 /* Has it been modified ? If so delete and reload. */
9165 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9166 &last_mod) < 0) {
9167 /* Remove it from the array. */
9168 free_service_byindex(iService);
9169 /* and now reload it. */
9170 iService = load_usershare_service(pszServiceName);
9174 if (iService < 0) {
9175 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9176 return GLOBAL_SECTION_SNUM;
9179 return (iService);
9182 /*******************************************************************
9183 A useful volume label function.
9184 ********************************************************************/
9186 const char *volume_label(TALLOC_CTX *ctx, int snum)
9188 char *ret;
9189 const char *label = lp_volume(ctx, snum);
9190 if (!*label) {
9191 label = lp_servicename(ctx, snum);
9194 /* This returns a 33 byte guarenteed null terminated string. */
9195 ret = talloc_strndup(ctx, label, 32);
9196 if (!ret) {
9197 return "";
9199 return ret;
9202 /*******************************************************************
9203 Get the default server type we will announce as via nmbd.
9204 ********************************************************************/
9206 int lp_default_server_announce(void)
9208 int default_server_announce = 0;
9209 default_server_announce |= SV_TYPE_WORKSTATION;
9210 default_server_announce |= SV_TYPE_SERVER;
9211 default_server_announce |= SV_TYPE_SERVER_UNIX;
9213 /* note that the flag should be set only if we have a
9214 printer service but nmbd doesn't actually load the
9215 services so we can't tell --jerry */
9217 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9219 default_server_announce |= SV_TYPE_SERVER_NT;
9220 default_server_announce |= SV_TYPE_NT;
9222 switch (lp_server_role()) {
9223 case ROLE_DOMAIN_MEMBER:
9224 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9225 break;
9226 case ROLE_DOMAIN_PDC:
9227 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9228 break;
9229 case ROLE_DOMAIN_BDC:
9230 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9231 break;
9232 case ROLE_STANDALONE:
9233 default:
9234 break;
9236 if (lp_time_server())
9237 default_server_announce |= SV_TYPE_TIME_SOURCE;
9239 if (lp_host_msdfs())
9240 default_server_announce |= SV_TYPE_DFS_SERVER;
9242 return default_server_announce;
9245 /***********************************************************
9246 If we are PDC then prefer us as DMB
9247 ************************************************************/
9249 bool lp_domain_master(void)
9251 if (Globals.domain_master == Auto)
9252 return (lp_server_role() == ROLE_DOMAIN_PDC);
9254 return (bool)Globals.domain_master;
9257 /***********************************************************
9258 If we are PDC then prefer us as DMB
9259 ************************************************************/
9261 static bool lp_domain_master_true_or_auto(void)
9263 if (Globals.domain_master) /* auto or yes */
9264 return true;
9266 return false;
9269 /***********************************************************
9270 If we are DMB then prefer us as LMB
9271 ************************************************************/
9273 bool lp_preferred_master(void)
9275 if (Globals.iPreferredMaster == Auto)
9276 return (lp_local_master() && lp_domain_master());
9278 return (bool)Globals.iPreferredMaster;
9281 /*******************************************************************
9282 Remove a service.
9283 ********************************************************************/
9285 void lp_remove_service(int snum)
9287 ServicePtrs[snum]->valid = false;
9288 invalid_services[num_invalid_services++] = snum;
9291 /*******************************************************************
9292 Copy a service.
9293 ********************************************************************/
9295 void lp_copy_service(int snum, const char *new_name)
9297 do_section(new_name, NULL);
9298 if (snum >= 0) {
9299 snum = lp_servicenumber(new_name);
9300 if (snum >= 0) {
9301 char *name = lp_servicename(talloc_tos(), snum);
9302 lp_do_parameter(snum, "copy", name);
9307 const char *lp_printername(TALLOC_CTX *ctx, int snum)
9309 const char *ret = lp__printername(talloc_tos(), snum);
9310 if (ret == NULL || *ret == '\0') {
9311 ret = lp_const_servicename(snum);
9314 return ret;
9318 /***********************************************************
9319 Allow daemons such as winbindd to fix their logfile name.
9320 ************************************************************/
9322 void lp_set_logfile(const char *name)
9324 string_set(&Globals.logfile, name);
9325 debug_set_logfile(name);
9328 /*******************************************************************
9329 Return the max print jobs per queue.
9330 ********************************************************************/
9332 int lp_maxprintjobs(int snum)
9334 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9335 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9336 maxjobs = PRINT_MAX_JOBID - 1;
9338 return maxjobs;
9341 const char *lp_printcapname(void)
9343 if ((Globals.szPrintcapname != NULL) &&
9344 (Globals.szPrintcapname[0] != '\0'))
9345 return Globals.szPrintcapname;
9347 if (sDefault.iPrinting == PRINT_CUPS) {
9348 #ifdef HAVE_CUPS
9349 return "cups";
9350 #else
9351 return "lpstat";
9352 #endif
9355 if (sDefault.iPrinting == PRINT_BSD)
9356 return "/etc/printcap";
9358 return PRINTCAP_NAME;
9361 static uint32 spoolss_state;
9363 bool lp_disable_spoolss( void )
9365 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9366 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9368 return spoolss_state == SVCCTL_STOPPED ? true : false;
9371 void lp_set_spoolss_state( uint32 state )
9373 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9375 spoolss_state = state;
9378 uint32 lp_get_spoolss_state( void )
9380 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9383 /*******************************************************************
9384 Ensure we don't use sendfile if server smb signing is active.
9385 ********************************************************************/
9387 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9389 bool sign_active = false;
9391 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9392 if (get_Protocol() < PROTOCOL_NT1) {
9393 return false;
9395 if (signing_state) {
9396 sign_active = smb_signing_is_active(signing_state);
9398 return (lp__use_sendfile(snum) &&
9399 (get_remote_arch() != RA_WIN95) &&
9400 !sign_active);
9403 /*******************************************************************
9404 Turn off sendfile if we find the underlying OS doesn't support it.
9405 ********************************************************************/
9407 void set_use_sendfile(int snum, bool val)
9409 if (LP_SNUM_OK(snum))
9410 ServicePtrs[snum]->bUseSendfile = val;
9411 else
9412 sDefault.bUseSendfile = val;
9415 /*******************************************************************
9416 Turn off storing DOS attributes if this share doesn't support it.
9417 ********************************************************************/
9419 void set_store_dos_attributes(int snum, bool val)
9421 if (!LP_SNUM_OK(snum))
9422 return;
9423 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9426 void lp_set_mangling_method(const char *new_method)
9428 string_set(&Globals.szManglingMethod, new_method);
9431 /*******************************************************************
9432 Global state for POSIX pathname processing.
9433 ********************************************************************/
9435 static bool posix_pathnames;
9437 bool lp_posix_pathnames(void)
9439 return posix_pathnames;
9442 /*******************************************************************
9443 Change everything needed to ensure POSIX pathname processing (currently
9444 not much).
9445 ********************************************************************/
9447 void lp_set_posix_pathnames(void)
9449 posix_pathnames = true;
9452 /*******************************************************************
9453 Global state for POSIX lock processing - CIFS unix extensions.
9454 ********************************************************************/
9456 bool posix_default_lock_was_set;
9457 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9459 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9461 if (posix_default_lock_was_set) {
9462 return posix_cifsx_locktype;
9463 } else {
9464 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9468 /*******************************************************************
9469 ********************************************************************/
9471 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9473 posix_default_lock_was_set = true;
9474 posix_cifsx_locktype = val;
9477 int lp_min_receive_file_size(void)
9479 if (Globals.iminreceivefile < 0) {
9480 return 0;
9482 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9485 /*******************************************************************
9486 If socket address is an empty character string, it is necessary to
9487 define it as "0.0.0.0".
9488 ********************************************************************/
9490 const char *lp_socket_address(void)
9492 char *sock_addr = Globals.szSocketAddress;
9494 if (sock_addr[0] == '\0'){
9495 string_set(&Globals.szSocketAddress, "0.0.0.0");
9497 return Globals.szSocketAddress;
9500 /*******************************************************************
9501 Safe wide links checks.
9502 This helper function always verify the validity of wide links,
9503 even after a configuration file reload.
9504 ********************************************************************/
9506 static bool lp_widelinks_internal(int snum)
9508 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9509 sDefault.bWidelinks);
9512 void widelinks_warning(int snum)
9514 if (lp_allow_insecure_widelinks()) {
9515 return;
9518 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9519 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9520 "These parameters are incompatible. "
9521 "Wide links will be disabled for this share.\n",
9522 lp_servicename(talloc_tos(), snum) ));
9526 bool lp_widelinks(int snum)
9528 /* wide links is always incompatible with unix extensions */
9529 if (lp_unix_extensions()) {
9531 * Unless we have "allow insecure widelinks"
9532 * turned on.
9534 if (!lp_allow_insecure_widelinks()) {
9535 return false;
9539 return lp_widelinks_internal(snum);
9542 bool lp_writeraw(void)
9544 if (lp_async_smb_echo_handler()) {
9545 return false;
9547 return lp__writeraw();
9550 bool lp_readraw(void)
9552 if (lp_async_smb_echo_handler()) {
9553 return false;
9555 return lp__readraw();
9558 int lp_server_role(void)
9560 return lp_find_server_role(lp__server_role(),
9561 lp__security(),
9562 lp__domain_logons(),
9563 lp_domain_master_true_or_auto());
9566 int lp_security(void)
9568 return lp_find_security(lp__server_role(),
9569 lp__security());