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) James Myers 2003 <myersjj@samba.org>
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 3 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/locale.h"
60 #include "system/network.h" /* needed for TCP_NODELAY */
61 #include "smb_server/smb_server.h"
62 #include "libcli/raw/signing.h"
63 #include "lib/util/dlinklist.h"
64 #include "param/param.h"
65 #include "param/loadparm.h"
67 static bool bLoaded = false;
69 struct loadparm_context *global_loadparm = NULL;
71 #define standard_sub_basic talloc_strdup
73 static bool do_parameter(const char *, const char *, void *);
74 static bool defaults_saved = false;
77 struct param_opt *prev, *next;
84 * This structure describes global (ie., server-wide) parameters.
86 struct loadparm_global
88 enum server_role server_role;
100 char *szShareBackend;
104 char *szWINS_CONFIG_URL;
108 char *jsonrpcServicesDir;
109 char **szPasswordServers;
110 char *szSocketOptions;
112 char **szWINSservers;
114 char *szSocketAddress;
115 char *szAnnounceVersion; /* This is initialised in init_globals */
118 char **szNetbiosAliases;
119 char *szNetbiosScope;
120 char *szDomainOtherSIDs;
121 char **szNameResolveOrder;
122 char **dcerpc_ep_servers;
123 char **server_services;
124 char *ntptr_providor;
125 char *szWinbindSeparator;
126 char *szWinbinddSocketDirectory;
127 char *szTemplateShell;
128 char *szTemplateHomedir;
129 int bWinbindSealedPipes;
130 char *swat_directory;
145 int paranoid_server_security;
148 int announce_as; /* This is initialised in init_globals */
155 char *socket_options;
160 int bPreferredMaster;
161 int bEncryptPasswords;
163 int bObeyPamRestrictions;
168 int bBindInterfacesOnly;
170 int bNTStatusSupport;
176 int bClientPlaintextAuth;
177 int bClientLanManAuth;
178 int bClientNTLMv2Auth;
179 int client_use_spnego_principal;
185 struct param_opt *param_opt;
190 * This structure describes a single service.
192 struct loadparm_service
204 char **ntvfs_handler;
217 int iCreate_force_mode;
224 struct param_opt *param_opt;
226 char dummy[3]; /* for alignment */
230 /* This is a default service used to prime a services structure */
231 static struct loadparm_service sDefault = {
232 NULL, /* szService */
235 NULL, /* szInclude */
236 NULL, /* szPrintername */
237 NULL, /* szHostsallow */
238 NULL, /* szHostsdeny */
242 NULL, /* ntvfs_handler */
243 1000, /* iMaxPrintJobs */
244 0, /* iMaxConnections */
246 true, /* bAvailable */
247 true, /* bBrowseable */
248 true, /* bRead_only */
249 false, /* bPrint_ok */
250 false, /* bMap_system */
251 false, /* bMap_hidden */
252 true, /* bMap_archive */
253 true, /* bStrictLocking */
254 0744, /* iCreate_mask */
255 0000, /* iCreate_force_mode */
256 0755, /* iDir_mask */
257 0000, /* iDir_force_mode */
259 false, /* bMSDfsRoot */
260 false, /* bStrictSync */
261 false, /* bCIFileSystem */
262 NULL, /* Parametric options */
267 /* local variables */
268 static struct loadparm_context {
269 struct loadparm_global Globals;
270 struct loadparm_service **ServicePtrs;
272 struct loadparm_service *currentService;
273 bool bInGlobalSection;
275 struct file_lists *next;
282 .currentService = NULL,
283 .bInGlobalSection = true,
288 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
290 /* prototypes for the special type handlers */
291 static bool handle_include(struct loadparm_context *lp_ctx,
292 const char *pszParmValue, char **ptr);
293 static bool handle_copy(struct loadparm_context *lp_ctx,
294 const char *pszParmValue, char **ptr);
296 static const struct enum_list enum_protocol[] = {
297 {PROTOCOL_SMB2, "SMB2"},
298 {PROTOCOL_NT1, "NT1"},
299 {PROTOCOL_LANMAN2, "LANMAN2"},
300 {PROTOCOL_LANMAN1, "LANMAN1"},
301 {PROTOCOL_CORE, "CORE"},
302 {PROTOCOL_COREPLUS, "COREPLUS"},
303 {PROTOCOL_COREPLUS, "CORE+"},
307 static const struct enum_list enum_security[] = {
308 {SEC_SHARE, "SHARE"},
313 static const struct enum_list enum_announce_as[] = {
314 {ANNOUNCE_AS_NT_SERVER, "NT"},
315 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
316 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
317 {ANNOUNCE_AS_WIN95, "win95"},
318 {ANNOUNCE_AS_WFW, "WfW"},
322 static const struct enum_list enum_bool_auto[] = {
333 /* Client-side offline caching policy types */
334 #define CSC_POLICY_MANUAL 0
335 #define CSC_POLICY_DOCUMENTS 1
336 #define CSC_POLICY_PROGRAMS 2
337 #define CSC_POLICY_DISABLE 3
339 static const struct enum_list enum_csc_policy[] = {
340 {CSC_POLICY_MANUAL, "manual"},
341 {CSC_POLICY_DOCUMENTS, "documents"},
342 {CSC_POLICY_PROGRAMS, "programs"},
343 {CSC_POLICY_DISABLE, "disable"},
347 /* SMB signing types. */
348 static const struct enum_list enum_smb_signing_vals[] = {
349 {SMB_SIGNING_OFF, "No"},
350 {SMB_SIGNING_OFF, "False"},
351 {SMB_SIGNING_OFF, "0"},
352 {SMB_SIGNING_OFF, "Off"},
353 {SMB_SIGNING_OFF, "disabled"},
354 {SMB_SIGNING_SUPPORTED, "Yes"},
355 {SMB_SIGNING_SUPPORTED, "True"},
356 {SMB_SIGNING_SUPPORTED, "1"},
357 {SMB_SIGNING_SUPPORTED, "On"},
358 {SMB_SIGNING_SUPPORTED, "enabled"},
359 {SMB_SIGNING_REQUIRED, "required"},
360 {SMB_SIGNING_REQUIRED, "mandatory"},
361 {SMB_SIGNING_REQUIRED, "force"},
362 {SMB_SIGNING_REQUIRED, "forced"},
363 {SMB_SIGNING_REQUIRED, "enforced"},
364 {SMB_SIGNING_AUTO, "auto"},
368 static const struct enum_list enum_server_role[] = {
369 {ROLE_STANDALONE, "standalone"},
370 {ROLE_DOMAIN_MEMBER, "member server"},
371 {ROLE_DOMAIN_CONTROLLER, "domain controller"},
376 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
378 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
379 * is implied in current control logic. This may change at some later time. A
380 * flag value of 0 means - show as development option only.
382 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
383 * screen in SWAT. This is used to exclude parameters as well as to squash all
384 * parameters that have been duplicated by pseudonyms.
386 static struct parm_struct parm_table[] = {
387 {"Base Options", P_SEP, P_SEPARATOR},
389 {"server role", P_ENUM, P_GLOBAL, &loadparm.Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
391 {"dos charset", P_STRING, P_GLOBAL, &dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"unix charset", P_STRING, P_GLOBAL, &unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"ncalrpc dir", P_STRING, P_GLOBAL, &loadparm.Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
394 {"display charset", P_STRING, P_GLOBAL, &display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
395 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
396 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
397 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
398 {"workgroup", P_USTRING, P_GLOBAL, &loadparm.Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"realm", P_STRING, P_GLOBAL, &loadparm.Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"netbios name", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"netbios aliases", P_LIST, P_GLOBAL, &loadparm.Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
402 {"netbios scope", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
403 {"server string", P_STRING, P_GLOBAL, &loadparm.Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
404 {"interfaces", P_LIST, P_GLOBAL, &loadparm.Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"bind interfaces only", P_BOOL, P_GLOBAL, &loadparm.Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
406 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
407 {"ntptr providor", P_STRING, P_GLOBAL, &loadparm.Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
408 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &loadparm.Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
409 {"server services", P_LIST, P_GLOBAL, &loadparm.Globals.server_services, NULL, NULL, FLAG_ADVANCED},
411 {"Security Options", P_SEP, P_SEPARATOR},
413 {"security", P_ENUM, P_GLOBAL, &loadparm.Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
414 {"encrypt passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
415 {"null passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"obey pam restrictions", P_BOOL, P_GLOBAL, &loadparm.Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"password server", P_LIST, P_GLOBAL, &loadparm.Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
418 {"sam database", P_STRING, P_GLOBAL, &loadparm.Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"secrets database", P_STRING, P_GLOBAL, &loadparm.Globals.szSECRETS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"spoolss database", P_STRING, P_GLOBAL, &loadparm.Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"wins config database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"wins database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"private dir", P_STRING, P_GLOBAL, &loadparm.Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"passwd chat", P_STRING, P_GLOBAL, &loadparm.Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"password level", P_INTEGER, P_GLOBAL, &loadparm.Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"ntlm auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"client lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
430 {"client plaintext auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
431 {"client use spnego principal", P_BOOL, P_GLOBAL, &loadparm.Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
433 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
435 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
436 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
437 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
438 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
440 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
441 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
443 {"Logging Options", P_SEP, P_SEPARATOR},
445 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
447 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"Protocol Options", P_SEP, P_SEPARATOR},
451 {"smb ports", P_LIST, P_GLOBAL, &loadparm.Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"nbt port", P_INTEGER, P_GLOBAL, &loadparm.Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"dgram port", P_INTEGER, P_GLOBAL, &loadparm.Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"cldap port", P_INTEGER, P_GLOBAL, &loadparm.Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"krb5 port", P_INTEGER, P_GLOBAL, &loadparm.Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"kpasswd port", P_INTEGER, P_GLOBAL, &loadparm.Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"web port", P_INTEGER, P_GLOBAL, &loadparm.Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"tls enabled", P_BOOL, P_GLOBAL, &loadparm.Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"tls keyfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
460 {"tls certfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
461 {"tls cafile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
462 {"tls crlfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
463 {"tls dh params file", P_STRING, P_GLOBAL, &loadparm.Globals.tls_dhpfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
464 {"swat directory", P_STRING, P_GLOBAL, &loadparm.Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
465 {"large readwrite", P_BOOL, P_GLOBAL, &loadparm.Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
466 {"server max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
467 {"server min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
468 {"client max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
469 {"client min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
470 {"unicode", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
471 {"read raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
472 {"write raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
473 {"disable netbios", P_BOOL, P_GLOBAL, &loadparm.Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
475 {"nt status support", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
477 {"announce version", P_STRING, P_GLOBAL, &loadparm.Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
478 {"announce as", P_ENUM, P_GLOBAL, &loadparm.Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
479 {"max mux", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
480 {"max xmit", P_BYTES, P_GLOBAL, &loadparm.Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
482 {"name resolve order", P_LIST, P_GLOBAL, &loadparm.Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
483 {"max wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
484 {"min wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
485 {"time server", P_BOOL, P_GLOBAL, &loadparm.Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
486 {"unix extensions", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
487 {"use spnego", P_BOOL, P_GLOBAL, &loadparm.Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
488 {"server signing", P_ENUM, P_GLOBAL, &loadparm.Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
489 {"client signing", P_ENUM, P_GLOBAL, &loadparm.Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
490 {"rpc big endian", P_BOOL, P_GLOBAL, &loadparm.Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
492 {"Tuning Options", P_SEP, P_SEPARATOR},
494 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
495 {"paranoid server security", P_BOOL, P_GLOBAL, &loadparm.Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
496 {"socket options", P_STRING, P_GLOBAL, &loadparm.Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
498 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
499 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
501 {"Printing Options", P_SEP, P_SEPARATOR},
503 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
504 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
505 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
507 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
508 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
510 {"Filename Handling", P_SEP, P_SEPARATOR},
512 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
513 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
514 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
516 {"Domain Options", P_SEP, P_SEPARATOR},
518 {"Logon Options", P_SEP, P_SEPARATOR},
521 {"Browse Options", P_SEP, P_SEPARATOR},
523 {"preferred master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
524 {"prefered master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
525 {"local master", P_BOOL, P_GLOBAL, &loadparm.Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
526 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
527 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
529 {"WINS Options", P_SEP, P_SEPARATOR},
531 {"wins server", P_LIST, P_GLOBAL, &loadparm.Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
532 {"wins support", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
533 {"dns proxy", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
534 {"wins hook", P_STRING, P_GLOBAL, &loadparm.Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
536 {"Locking Options", P_SEP, P_SEPARATOR},
538 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
540 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
542 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
544 {"config file", P_STRING, P_GLOBAL, &loadparm.Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
545 {"share backend", P_STRING, P_GLOBAL, &loadparm.Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"preload", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"auto services", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"lock dir", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_HIDE},
549 {"lock directory", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"modules dir", P_STRING, P_GLOBAL, &loadparm.Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"pid directory", P_STRING, P_GLOBAL, &loadparm.Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"js include", P_LIST, P_GLOBAL, &loadparm.Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"setup directory", P_STRING, P_GLOBAL, &loadparm.Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"socket address", P_STRING, P_GLOBAL, &loadparm.Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
556 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
557 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
559 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
560 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
561 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
563 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
566 {"host msdfs", P_BOOL, P_GLOBAL, &loadparm.Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"winbind separator", P_STRING, P_GLOBAL, &loadparm.Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
568 {"winbindd socket directory", P_STRING, P_GLOBAL, &loadparm.Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
569 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &loadparm.Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
570 {"template shell", P_STRING, P_GLOBAL, &loadparm.Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
571 {"template homedir", P_STRING, P_GLOBAL, &loadparm.Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
573 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
578 return the parameter table
580 struct parm_struct *lp_parm_table(void)
585 static TALLOC_CTX *lp_talloc;
587 /******************************************************************* a
588 Free up temporary memory - called from the main loop.
589 ********************************************************************/
591 void lp_talloc_free(void)
595 talloc_free(lp_talloc);
599 /*******************************************************************
600 Convenience routine to grab string parameters into temporary memory
601 and run standard_sub_basic on them. The buffers can be written to by
602 callers without affecting the source string.
603 ********************************************************************/
605 static const char *lp_string(const char *s)
607 #if 0 /* until REWRITE done to make thread-safe */
608 size_t len = s ? strlen(s) : 0;
612 /* The follow debug is useful for tracking down memory problems
613 especially if you have an inner loop that is calling a lp_*()
614 function that returns a string. Perhaps this debug should be
615 present all the time? */
618 DEBUG(10, ("lp_string(%s)\n", s));
621 #if 0 /* until REWRITE done to make thread-safe */
623 lp_talloc = talloc_init("lp_talloc");
625 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
633 strlcpy(ret, s, len);
635 if (trim_string(ret, "\"", "\"")) {
636 if (strchr(ret,'"') != NULL)
637 strlcpy(ret, s, len);
640 standard_sub_basic(ret,len+100);
647 In this section all the functions that are used to access the
648 parameters from the rest of the program are defined
651 #define FN_GLOBAL_STRING(fn_name,ptr) \
652 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
653 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
654 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
655 #define FN_GLOBAL_LIST(fn_name,ptr) \
656 const char **fn_name(void) {return(*(const char ***)(ptr));}
657 #define FN_GLOBAL_BOOL(fn_name,ptr) \
658 bool fn_name(void) {return((bool)*(int *)(ptr));}
660 #define FN_GLOBAL_CHAR(fn_name,ptr) \
661 char fn_name(void) {return(*(char *)(ptr));}
663 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
664 int fn_name(void) {return(*(int *)(ptr));}
666 #define FN_LOCAL_STRING(fn_name,val) \
667 const char *fn_name(struct loadparm_service *service) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault.val)));}
668 #define FN_LOCAL_CONST_STRING(fn_name,val) \
669 const char *fn_name(struct loadparm_service *service) {return (const char *)(service != NULL && service->val != NULL) ? service->val : sDefault.val;}
670 #define FN_LOCAL_LIST(fn_name,val) \
671 const char **fn_name(struct loadparm_service *service) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault.val);}
672 #define FN_LOCAL_BOOL(fn_name,val) \
673 bool fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
674 #define FN_LOCAL_INTEGER(fn_name,val) \
675 int fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
677 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &loadparm.Globals.server_role)
678 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &loadparm.Globals.smb_ports)
679 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &loadparm.Globals.nbt_port)
680 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &loadparm.Globals.dgram_port)
681 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &loadparm.Globals.cldap_port)
682 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &loadparm.Globals.krb5_port)
683 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &loadparm.Globals.kpasswd_port)
684 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &loadparm.Globals.web_port)
685 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &dos_charset)
686 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, &loadparm.Globals.swat_directory)
687 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &loadparm.Globals.tls_enabled)
688 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &loadparm.Globals.tls_keyfile)
689 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &loadparm.Globals.tls_certfile)
690 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &loadparm.Globals.tls_cafile)
691 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &loadparm.Globals.tls_crlfile)
692 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_dhpfile, &loadparm.Globals.tls_dhpfile)
693 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &unix_charset)
694 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &display_charset)
695 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &loadparm.Globals.szConfigFile)
696 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, &loadparm.Globals.szShareBackend)
697 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &loadparm.Globals.szSAM_URL)
698 _PUBLIC_ FN_GLOBAL_STRING(lp_secrets_url, &loadparm.Globals.szSECRETS_URL)
699 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &loadparm.Globals.szSPOOLSS_URL)
700 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &loadparm.Globals.szWINS_CONFIG_URL)
701 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &loadparm.Globals.szWINS_URL)
702 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &loadparm.Globals.szWinbindSeparator)
703 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &loadparm.Globals.szWinbinddSocketDirectory)
704 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_shell, &loadparm.Globals.szTemplateShell)
705 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_homedir, &loadparm.Globals.szTemplateHomedir)
706 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &loadparm.Globals.bWinbindSealedPipes)
707 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &loadparm.Globals.szPrivateDir)
708 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &loadparm.Globals.szServerString)
709 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &loadparm.Globals.szLockDir)
710 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &loadparm.Globals.szModulesDir)
711 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &loadparm.Globals.szSetupDir)
712 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &loadparm.Globals.ncalrpc_dir)
713 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &loadparm.Globals.szPidDir)
714 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &loadparm.Globals.dcerpc_ep_servers)
715 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &loadparm.Globals.server_services)
716 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &loadparm.Globals.ntptr_providor)
717 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &loadparm.Globals.szAutoServices)
718 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &loadparm.Globals.szPasswdChat)
719 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &loadparm.Globals.szPasswordServers)
720 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &loadparm.Globals.szNameResolveOrder)
721 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &loadparm.Globals.szRealm)
722 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &loadparm.Globals.socket_options)
723 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &loadparm.Globals.szWorkgroup)
724 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &loadparm.Globals.szNetbiosName)
725 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &loadparm.Globals.szNetbiosScope)
726 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &loadparm.Globals.szWINSservers)
727 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &loadparm.Globals.szInterfaces)
728 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &loadparm.Globals.szSocketAddress)
729 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &loadparm.Globals.szNetbiosAliases)
731 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &loadparm.Globals.bDisableNetbios)
732 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &loadparm.Globals.bWINSsupport)
733 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &loadparm.Globals.bWINSdnsProxy)
734 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &loadparm.Globals.szWINSHook)
735 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &loadparm.Globals.bLocalMaster)
736 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &loadparm.Globals.bReadRaw)
737 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &loadparm.Globals.bLargeReadwrite)
738 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &loadparm.Globals.bWriteRaw)
739 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &loadparm.Globals.bNullPasswords)
740 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &loadparm.Globals.bObeyPamRestrictions)
741 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &loadparm.Globals.bEncryptPasswords)
742 _PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, &loadparm.Globals.bTimeServer)
743 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &loadparm.Globals.bBindInterfacesOnly)
744 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &loadparm.Globals.bUnicode)
745 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &loadparm.Globals.bNTStatusSupport)
746 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &loadparm.Globals.bLanmanAuth)
747 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &loadparm.Globals.bNTLMAuth)
748 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &loadparm.Globals.bClientPlaintextAuth)
749 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &loadparm.Globals.bClientLanManAuth)
750 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &loadparm.Globals.bClientNTLMv2Auth)
751 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &loadparm.Globals.client_use_spnego_principal)
752 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &loadparm.Globals.bHostMSDfs)
753 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &loadparm.Globals.bUnixExtensions)
754 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &loadparm.Globals.bUseSpnego)
755 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &loadparm.Globals.bRpcBigEndian)
756 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &loadparm.Globals.max_wins_ttl)
757 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &loadparm.Globals.min_wins_ttl)
758 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &loadparm.Globals.max_mux)
759 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &loadparm.Globals.max_xmit)
760 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &loadparm.Globals.pwordlevel)
761 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &loadparm.Globals.srv_maxprotocol)
762 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &loadparm.Globals.srv_minprotocol)
763 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &loadparm.Globals.cli_maxprotocol)
764 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &loadparm.Globals.cli_minprotocol)
765 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &loadparm.Globals.security)
766 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &loadparm.Globals.paranoid_server_security)
767 _PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, &loadparm.Globals.announce_as)
768 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &loadparm.Globals.jsInclude)
769 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
770 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
771 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
772 static FN_LOCAL_STRING(_lp_printername, szPrintername)
773 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
774 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
775 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
776 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
777 static FN_LOCAL_STRING(lp_volume, volume)
778 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
779 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
780 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
781 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
782 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
783 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
784 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
785 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
786 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
787 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
788 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
789 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
790 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
791 _PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
792 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
793 _PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
794 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
795 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &loadparm.Globals.server_signing)
796 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &loadparm.Globals.client_signing)
798 /* local prototypes */
799 static int map_parameter(const char *pszParmName);
800 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
801 const char *pszServiceName);
802 static void copy_service(struct loadparm_service *pserviceDest,
803 struct loadparm_service *pserviceSource,
805 static bool service_ok(struct loadparm_service *service);
806 static bool do_section(const char *pszSectionName, void *);
807 static void init_copymap(struct loadparm_service *pservice);
809 /* This is a helper function for parametrical options support. */
810 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
811 /* Actual parametrical functions are quite simple */
812 const char *lp_get_parametric(struct loadparm_service *service,
813 const char *type, const char *option)
816 struct param_opt *data;
818 data = (service == NULL ? loadparm.Globals.param_opt : service->param_opt);
820 asprintf(&vfskey, "%s:%s", type, option);
824 if (strcmp(data->key, vfskey) == 0) {
831 if (service != NULL) {
832 /* Try to fetch the same option but from globals */
833 /* but only if we are not already working with Globals */
834 for (data = loadparm.Globals.param_opt; data;
836 if (strcmp(data->key, vfskey) == 0) {
849 /*******************************************************************
850 convenience routine to return int parameters.
851 ********************************************************************/
852 static int lp_int(const char *s)
856 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
860 return strtol(s, NULL, 0);
863 /*******************************************************************
864 convenience routine to return unsigned long parameters.
865 ********************************************************************/
866 static int lp_ulong(const char *s)
870 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
874 return strtoul(s, NULL, 0);
877 /*******************************************************************
878 convenience routine to return unsigned long parameters.
879 ********************************************************************/
880 static double lp_double(const char *s)
884 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
888 return strtod(s, NULL);
891 /*******************************************************************
892 convenience routine to return boolean parameters.
893 ********************************************************************/
894 static bool lp_bool(const char *s)
899 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
903 if (!set_boolean(s, &ret)) {
904 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
912 /* Return parametric option from a given service. Type is a part of option before ':' */
913 /* Parametric option has following syntax: 'Type: option = value' */
914 /* Returned value is allocated in 'lp_talloc' context */
916 const char *lp_parm_string(struct loadparm_service *service, const char *type,
919 const char *value = lp_get_parametric(service, type, option);
922 return lp_string(value);
927 /* Return parametric option from a given service. Type is a part of option before ':' */
928 /* Parametric option has following syntax: 'Type: option = value' */
929 /* Returned value is allocated in 'lp_talloc' context */
931 const char **lp_parm_string_list(struct loadparm_service *service,
933 const char *option, const char *separator)
935 const char *value = lp_get_parametric(service, type, option);
938 return str_list_make(talloc_autofree_context(), value,
944 /* Return parametric option from a given service. Type is a part of option before ':' */
945 /* Parametric option has following syntax: 'Type: option = value' */
947 int lp_parm_int(struct loadparm_service *service, const char *type,
948 const char *option, int default_v)
950 const char *value = lp_get_parametric(service, type, option);
953 return lp_int(value);
958 /* Return parametric option from a given service. Type is a part of
960 * Parametric option has following syntax: 'Type: option = value'.
963 int lp_parm_bytes(struct loadparm_service *service, const char *type,
964 const char *option, int default_v)
968 const char *value = lp_get_parametric(service, type, option);
970 if (value && conv_str_size(value, &bval)) {
971 if (bval <= INT_MAX) {
979 /* Return parametric option from a given service. Type is a part of option before ':' */
980 /* Parametric option has following syntax: 'Type: option = value' */
982 unsigned long lp_parm_ulong(struct loadparm_service *service, const char *type,
983 const char *option, unsigned long default_v)
985 const char *value = lp_get_parametric(service, type, option);
988 return lp_ulong(value);
994 double lp_parm_double(struct loadparm_service *service, const char *type,
995 const char *option, double default_v)
997 const char *value = lp_get_parametric(service, type, option);
1000 return lp_double(value);
1005 /* Return parametric option from a given service. Type is a part of option before ':' */
1006 /* Parametric option has following syntax: 'Type: option = value' */
1008 bool lp_parm_bool(struct loadparm_service *service, const char *type,
1009 const char *option, bool default_v)
1011 const char *value = lp_get_parametric(service, type, option);
1014 return lp_bool(value);
1020 /***************************************************************************
1021 Initialise a service to the defaults.
1022 ***************************************************************************/
1024 static struct loadparm_service *init_service(TALLOC_CTX *mem_ctx)
1026 struct loadparm_service *pservice =
1027 talloc_zero(mem_ctx, struct loadparm_service);
1028 copy_service(pservice, &sDefault, NULL);
1033 Set a string value, deallocating any existing space, and allocing the space
1036 static bool string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
1043 *dest = talloc_strdup(mem_ctx, src);
1044 if ((*dest) == NULL) {
1045 DEBUG(0,("Out of memory in string_init\n"));
1054 /***************************************************************************
1055 Add a new service to the services array initialising it with the given
1057 ***************************************************************************/
1059 static struct loadparm_service *add_a_service(struct loadparm_context *lp_ctx,
1060 const struct loadparm_service *pservice,
1064 struct loadparm_service tservice;
1065 int num_to_alloc = lp_ctx->iNumServices + 1;
1066 struct param_opt *data, *pdata;
1068 tservice = *pservice;
1070 /* it might already exist */
1072 struct loadparm_service *service = getservicebyname(lp_ctx,
1074 if (service != NULL) {
1075 /* Clean all parametric options for service */
1076 /* They will be added during parsing again */
1077 data = service->param_opt;
1083 service->param_opt = NULL;
1088 /* find an invalid one */
1089 for (i = 0; i < lp_ctx->iNumServices; i++)
1090 if (lp_ctx->ServicePtrs[i] == NULL)
1093 /* if not, then create one */
1094 if (i == lp_ctx->iNumServices) {
1095 struct loadparm_service **tsp;
1097 tsp = realloc_p(lp_ctx->ServicePtrs, struct loadparm_service *,
1101 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1105 lp_ctx->ServicePtrs = tsp;
1106 lp_ctx->ServicePtrs[lp_ctx->iNumServices] = NULL;
1109 lp_ctx->iNumServices++;
1112 lp_ctx->ServicePtrs[i] = init_service(talloc_autofree_context());
1113 if (lp_ctx->ServicePtrs[i] == NULL) {
1114 DEBUG(0,("add_a_service: out of memory!\n"));
1117 copy_service(lp_ctx->ServicePtrs[i], &tservice, NULL);
1119 string_set(lp_ctx->ServicePtrs[i], &lp_ctx->ServicePtrs[i]->szService, name);
1120 return lp_ctx->ServicePtrs[i];
1123 /***************************************************************************
1124 Add a new home service, with the specified home directory, defaults coming
1126 ***************************************************************************/
1128 bool lp_add_home(struct loadparm_context *lp_ctx,
1129 const char *pszHomename,
1130 struct loadparm_service *default_service,
1131 const char *user, const char *pszHomedir)
1133 struct loadparm_service *service;
1135 service = add_a_service(lp_ctx, default_service, pszHomename);
1137 if (service == NULL)
1140 if (!(*(default_service->szPath))
1141 || strequal(default_service->szPath, sDefault.szPath)) {
1142 service->szPath = talloc_strdup(service, pszHomedir);
1144 service->szPath = string_sub_talloc(service, lp_pathname(default_service),"%H", pszHomedir);
1147 if (!(*(service->comment))) {
1148 service->comment = talloc_asprintf(service, "Home directory of %s", user);
1150 service->bAvailable = default_service->bAvailable;
1151 service->bBrowseable = default_service->bBrowseable;
1153 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
1154 pszHomename, user, service->szPath));
1159 /***************************************************************************
1160 Add a new service, based on an old one.
1161 ***************************************************************************/
1163 struct loadparm_service *lp_add_service(struct loadparm_context *lp_ctx,
1164 const char *pszService,
1165 struct loadparm_service *default_service)
1167 return add_a_service(lp_ctx, default_service, pszService);
1170 /***************************************************************************
1171 Add the IPC service.
1172 ***************************************************************************/
1174 static bool lp_add_hidden(struct loadparm_context *lp_ctx, const char *name,
1177 struct loadparm_service *service = add_a_service(lp_ctx, &sDefault, name);
1179 if (service == NULL)
1182 string_set(service, &service->szPath, tmpdir());
1184 service->comment = talloc_asprintf(service, "%s Service (%s)",
1185 fstype, lp_ctx->Globals.szServerString);
1186 string_set(service, &service->fstype, fstype);
1187 service->iMaxConnections = -1;
1188 service->bAvailable = true;
1189 service->bRead_only = true;
1190 service->bPrint_ok = false;
1191 service->bBrowseable = false;
1193 if (strcasecmp(fstype, "IPC") == 0) {
1194 lp_do_service_parameter(lp_ctx, service, "ntvfs handler",
1198 DEBUG(3, ("adding hidden service %s\n", name));
1203 /***************************************************************************
1204 Add a new printer service, with defaults coming from service iFrom.
1205 ***************************************************************************/
1207 bool lp_add_printer(struct loadparm_context *lp_ctx,
1208 const char *pszPrintername,
1209 struct loadparm_service *default_service)
1211 const char *comment = "From Printcap";
1212 struct loadparm_service *service;
1213 service = add_a_service(lp_ctx, default_service, pszPrintername);
1215 if (service == NULL)
1218 /* note that we do NOT default the availability flag to True - */
1219 /* we take it from the default service passed. This allows all */
1220 /* dynamic printers to be disabled by disabling the [printers] */
1221 /* entry (if/when the 'available' keyword is implemented!). */
1223 /* the printer name is set to the service name. */
1224 string_set(service, &service->szPrintername, pszPrintername);
1225 string_set(service, &service->comment, comment);
1226 service->bBrowseable = sDefault.bBrowseable;
1227 /* Printers cannot be read_only. */
1228 service->bRead_only = false;
1229 /* Printer services must be printable. */
1230 service->bPrint_ok = true;
1232 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1237 /***************************************************************************
1238 Map a parameter's string representation to something we can use.
1239 Returns False if the parameter string is not recognised, else TRUE.
1240 ***************************************************************************/
1242 static int map_parameter(const char *pszParmName)
1246 if (*pszParmName == '-')
1249 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1250 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1253 /* Warn only if it isn't parametric option */
1254 if (strchr(pszParmName, ':') == NULL)
1255 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1256 /* We do return 'fail' for parametric options as well because they are
1257 stored in different storage
1264 return the parameter structure for a parameter
1266 struct parm_struct *lp_parm_struct(const char *name)
1268 int parmnum = map_parameter(name);
1269 if (parmnum == -1) return NULL;
1270 return &parm_table[parmnum];
1274 return the parameter pointer for a parameter
1276 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
1278 if (service == NULL)
1281 return ((char *)service) + PTR_DIFF(parm->ptr, &sDefault);
1284 /***************************************************************************
1285 Find a service by name. Otherwise works like get_service.
1286 ***************************************************************************/
1288 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
1289 const char *pszServiceName)
1293 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
1294 if (lp_ctx->ServicePtrs[iService] != NULL &&
1295 strwicmp(lp_ctx->ServicePtrs[iService]->szService, pszServiceName) == 0) {
1296 return lp_ctx->ServicePtrs[iService];
1302 /***************************************************************************
1303 Copy a service structure to another.
1304 If pcopymapDest is NULL then copy all fields
1305 ***************************************************************************/
1307 static void copy_service(struct loadparm_service *pserviceDest,
1308 struct loadparm_service *pserviceSource,
1312 bool bcopyall = (pcopymapDest == NULL);
1313 struct param_opt *data, *pdata, *paramo;
1316 for (i = 0; parm_table[i].label; i++)
1317 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1318 (bcopyall || pcopymapDest[i])) {
1319 void *def_ptr = parm_table[i].ptr;
1321 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1324 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1327 switch (parm_table[i].type) {
1329 *(int *)dest_ptr = *(int *)src_ptr;
1335 *(int *)dest_ptr = *(int *)src_ptr;
1339 string_set(pserviceDest,
1345 string_set(pserviceDest,
1348 strupper(*(char **)dest_ptr);
1351 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1352 *(const char ***)src_ptr);
1360 init_copymap(pserviceDest);
1361 if (pserviceSource->copymap)
1362 memcpy((void *)pserviceDest->copymap,
1363 (void *)pserviceSource->copymap,
1364 sizeof(int) * NUMPARAMETERS);
1367 data = pserviceSource->param_opt;
1370 pdata = pserviceDest->param_opt;
1371 /* Traverse destination */
1373 /* If we already have same option, override it */
1374 if (strcmp(pdata->key, data->key) == 0) {
1375 talloc_free(pdata->value);
1376 pdata->value = talloc_reference(pdata,
1381 pdata = pdata->next;
1384 paramo = talloc(pserviceDest, struct param_opt);
1387 paramo->key = talloc_reference(paramo, data->key);
1388 paramo->value = talloc_reference(paramo, data->value);
1389 DLIST_ADD(pserviceDest->param_opt, paramo);
1395 /***************************************************************************
1396 Check a service for consistency. Return False if the service is in any way
1397 incomplete or faulty, else True.
1398 ***************************************************************************/
1400 static bool service_ok(struct loadparm_service *service)
1405 if (service->szService[0] == '\0') {
1406 DEBUG(0, ("The following message indicates an internal error:\n"));
1407 DEBUG(0, ("No service name in service entry.\n"));
1411 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1412 /* I can't see why you'd want a non-printable printer service... */
1413 if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
1414 if (!service->bPrint_ok) {
1415 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1416 service->szService));
1417 service->bPrint_ok = true;
1419 /* [printers] service must also be non-browsable. */
1420 if (service->bBrowseable)
1421 service->bBrowseable = false;
1424 /* If a service is flagged unavailable, log the fact at level 0. */
1425 if (!service->bAvailable)
1426 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1427 service->szService));
1433 /*******************************************************************
1434 Keep a linked list of all config files so we know when one has changed
1435 it's date and needs to be reloaded.
1436 ********************************************************************/
1438 static void add_to_file_list(struct loadparm_context *lp_ctx,
1439 const char *fname, const char *subfname)
1441 struct file_lists *f = lp_ctx->file_lists;
1444 if (f->name && !strcmp(f->name, fname))
1450 f = talloc(talloc_autofree_context(), struct file_lists);
1453 f->next = lp_ctx->file_lists;
1454 f->name = talloc_strdup(f, fname);
1459 f->subfname = talloc_strdup(f, subfname);
1464 lp_ctx->file_lists = f;
1465 f->modtime = file_modtime(subfname);
1467 time_t t = file_modtime(subfname);
1473 /*******************************************************************
1474 Check if a config file has changed date.
1475 ********************************************************************/
1477 bool lp_file_list_changed(struct loadparm_context *lp_ctx)
1479 struct file_lists *f;
1480 DEBUG(6, ("lp_file_list_changed()\n"));
1482 for (f = lp_ctx->file_lists; f != NULL; f = f->next) {
1486 n2 = standard_sub_basic(talloc_autofree_context(), f->name);
1488 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1489 f->name, n2, ctime(&f->modtime)));
1491 mod_time = file_modtime(n2);
1493 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1494 DEBUGADD(6, ("file %s modified: %s\n", n2,
1496 f->modtime = mod_time;
1497 talloc_free(f->subfname);
1498 f->subfname = talloc_strdup(f, n2);
1505 /***************************************************************************
1506 Handle the include operation.
1507 ***************************************************************************/
1509 static bool handle_include(struct loadparm_context *lp_ctx,
1510 const char *pszParmValue, char **ptr)
1512 char *fname = standard_sub_basic(talloc_autofree_context(),
1515 add_to_file_list(lp_ctx, pszParmValue, fname);
1517 string_set(talloc_autofree_context(), ptr, fname);
1519 if (file_exist(fname))
1520 return pm_process(fname, do_section, do_parameter, lp_ctx);
1522 DEBUG(2, ("Can't find include file %s\n", fname));
1527 /***************************************************************************
1528 Handle the interpretation of the copy parameter.
1529 ***************************************************************************/
1531 static bool handle_copy(struct loadparm_context *lp_ctx,
1532 const char *pszParmValue, char **ptr)
1535 struct loadparm_service *serviceTemp;
1537 string_set(talloc_autofree_context(), ptr, pszParmValue);
1541 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1543 if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) {
1544 if (serviceTemp == lp_ctx->currentService) {
1545 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1547 copy_service(lp_ctx->currentService,
1549 lp_ctx->currentService->copymap);
1553 DEBUG(0, ("Unable to copy service - source not found: %s\n",
1561 /***************************************************************************
1562 Initialise a copymap.
1563 ***************************************************************************/
1565 static void init_copymap(struct loadparm_service *pservice)
1568 talloc_free(pservice->copymap);
1569 pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS);
1570 if (pservice->copymap == NULL) {
1572 ("Couldn't allocate copymap!! (size %d)\n",
1573 (int)NUMPARAMETERS));
1576 for (i = 0; i < NUMPARAMETERS; i++)
1577 pservice->copymap[i] = true;
1580 /***************************************************************************
1581 Process a parametric option
1582 ***************************************************************************/
1583 static bool lp_do_parameter_parametric(struct loadparm_service *service,
1584 const char *pszParmName,
1585 const char *pszParmValue, int flags)
1587 struct param_opt *paramo, *data;
1589 TALLOC_CTX *mem_ctx;
1591 while (isspace((unsigned char)*pszParmName)) {
1595 name = strdup(pszParmName);
1596 if (!name) return false;
1600 if (service == NULL) {
1601 data = loadparm.Globals.param_opt;
1602 mem_ctx = talloc_autofree_context();
1604 data = service->param_opt;
1608 /* Traverse destination */
1609 for (paramo=data; paramo; paramo=paramo->next) {
1610 /* If we already have the option set, override it unless
1611 it was a command line option and the new one isn't */
1612 if (strcmp(paramo->key, name) == 0) {
1613 if ((paramo->flags & FLAG_CMDLINE) &&
1614 !(flags & FLAG_CMDLINE)) {
1618 talloc_free(paramo->value);
1619 paramo->value = talloc_strdup(paramo, pszParmValue);
1620 paramo->flags = flags;
1626 paramo = talloc(mem_ctx, struct param_opt);
1629 paramo->key = talloc_strdup(paramo, name);
1630 paramo->value = talloc_strdup(paramo, pszParmValue);
1631 paramo->flags = flags;
1632 if (service == NULL) {
1633 DLIST_ADD(loadparm.Globals.param_opt, paramo);
1635 DLIST_ADD(service->param_opt, paramo);
1643 static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1644 const char *pszParmName, const char *pszParmValue,
1645 struct loadparm_context *lp_ctx)
1648 /* if it is a special case then go ahead */
1649 if (parm_table[parmnum].special) {
1650 parm_table[parmnum].special(lp_ctx, pszParmValue,
1655 /* now switch on the type of variable it is */
1656 switch (parm_table[parmnum].type)
1660 if (!set_boolean(pszParmValue, &b)) {
1661 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1664 *(int *)parm_ptr = b;
1669 *(int *)parm_ptr = atoi(pszParmValue);
1673 *(int *)parm_ptr = strtol(pszParmValue, NULL, 8);
1679 if (conv_str_size(pszParmValue, &val)) {
1680 if (val <= INT_MAX) {
1681 *(int *)parm_ptr = (int)val;
1686 DEBUG(0,("lp_do_parameter(%s): value is not "
1687 "a valid size specifier!\n", pszParmValue));
1692 *(const char ***)parm_ptr = str_list_make(mem_ctx,
1693 pszParmValue, NULL);
1697 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1701 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1702 strupper(*(char **)parm_ptr);
1706 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1709 parm_table[parmnum].enum_list[i].name)) {
1711 parm_table[parmnum].
1716 if (!parm_table[parmnum].enum_list[i].name) {
1717 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1718 pszParmValue, pszParmName));
1726 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1727 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1728 /* we have to also unset FLAG_DEFAULT on aliases */
1729 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1730 parm_table[i].flags &= ~FLAG_DEFAULT;
1732 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1733 parm_table[i].flags &= ~FLAG_DEFAULT;
1740 bool lp_do_global_parameter(struct loadparm_context *lp_ctx,
1741 const char *pszParmName, const char *pszParmValue)
1743 int parmnum = map_parameter(pszParmName);
1747 if (strchr(pszParmName, ':')) {
1748 return lp_do_parameter_parametric(NULL, pszParmName, pszParmValue, 0);
1750 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1754 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1755 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1759 /* if the flag has been set on the command line, then don't allow override,
1760 but don't report an error */
1761 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1765 parm_ptr = parm_table[parmnum].ptr;
1767 return set_variable(talloc_autofree_context(), parmnum, parm_ptr,
1768 pszParmName, pszParmValue, lp_ctx);
1771 bool lp_do_service_parameter(struct loadparm_context *lp_ctx,
1772 struct loadparm_service *service,
1773 const char *pszParmName, const char *pszParmValue)
1775 void *def_ptr = NULL;
1778 int parmnum = map_parameter(pszParmName);
1781 if (strchr(pszParmName, ':')) {
1782 return lp_do_parameter_parametric(service, pszParmName, pszParmValue, 0);
1784 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1788 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1789 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1793 /* if the flag has been set on the command line, then don't allow override,
1794 but don't report an error */
1795 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1799 def_ptr = parm_table[parmnum].ptr;
1801 if (parm_table[parmnum].class == P_GLOBAL) {
1803 ("Global parameter %s found in service section!\n",
1807 parm_ptr = ((char *)service) + PTR_DIFF(def_ptr, &sDefault);
1809 if (!service->copymap)
1810 init_copymap(service);
1812 /* this handles the aliases - set the copymap for other
1813 * entries with the same data pointer */
1814 for (i = 0; parm_table[i].label; i++)
1815 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1816 service->copymap[i] = false;
1818 return set_variable(service, parmnum, parm_ptr, pszParmName,
1819 pszParmValue, lp_ctx);
1822 /***************************************************************************
1823 Process a parameter.
1824 ***************************************************************************/
1826 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1829 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
1831 if (lp_ctx->bInGlobalSection)
1832 return lp_do_global_parameter(lp_ctx, pszParmName,
1835 return lp_do_service_parameter(lp_ctx, lp_ctx->currentService,
1836 pszParmName, pszParmValue);
1840 variable argument do parameter
1842 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
1843 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx,
1844 const char *pszParmName, const char *fmt, ...)
1851 s = talloc_vasprintf(NULL, fmt, ap);
1853 ret = lp_do_global_parameter(lp_ctx, pszParmName, s);
1860 set a parameter from the commandline - this is called from command line parameter
1861 parsing code. It sets the parameter then marks the parameter as unable to be modified
1862 by smb.conf processing
1864 bool lp_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName,
1865 const char *pszParmValue)
1867 int parmnum = map_parameter(pszParmName);
1870 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1873 if (parmnum < 0 && strchr(pszParmName, ':')) {
1874 /* set a parametric option */
1875 return lp_do_parameter_parametric(NULL, pszParmName, pszParmValue, FLAG_CMDLINE);
1879 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1883 /* reset the CMDLINE flag in case this has been called before */
1884 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1886 if (!lp_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
1890 parm_table[parmnum].flags |= FLAG_CMDLINE;
1892 /* we have to also set FLAG_CMDLINE on aliases */
1893 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1894 parm_table[i].flags |= FLAG_CMDLINE;
1896 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1897 parm_table[i].flags |= FLAG_CMDLINE;
1904 set a option from the commandline in 'a=b' format. Use to support --option
1906 bool lp_set_option(struct loadparm_context *lp_ctx, const char *option)
1924 ret = lp_set_cmdline(lp_ctx, s, p+1);
1930 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1932 /***************************************************************************
1933 Print a parameter of the specified type.
1934 ***************************************************************************/
1936 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1942 for (i = 0; p->enum_list[i].name; i++) {
1943 if (*(int *)ptr == p->enum_list[i].value) {
1945 p->enum_list[i].name);
1952 fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr));
1957 fprintf(f, "%d", *(int *)ptr);
1961 fprintf(f, "0%o", *(int *)ptr);
1965 if ((char ***)ptr && *(char ***)ptr) {
1966 char **list = *(char ***)ptr;
1968 for (; *list; list++)
1969 fprintf(f, "%s%s", *list,
1970 ((*(list+1))?", ":""));
1976 if (*(char **)ptr) {
1977 fprintf(f, "%s", *(char **)ptr);
1985 /***************************************************************************
1986 Check if two parameters are equal.
1987 ***************************************************************************/
1989 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
1993 return (*((int *)ptr1) == *((int *)ptr2));
1999 return (*((int *)ptr1) == *((int *)ptr2));
2002 return str_list_equal((const char **)(*(char ***)ptr1),
2003 (const char **)(*(char ***)ptr2));
2008 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2013 return (p1 == p2 || strequal(p1, p2));
2021 /***************************************************************************
2022 Process a new section (service). At this stage all sections are services.
2023 Later we'll have special sections that permit server parameters to be set.
2024 Returns True on success, False on failure.
2025 ***************************************************************************/
2027 static bool do_section(const char *pszSectionName, void *userdata)
2029 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2031 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2032 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2035 /* if we've just struck a global section, note the fact. */
2036 lp_ctx->bInGlobalSection = isglobal;
2038 /* check for multiple global sections */
2039 if (lp_ctx->bInGlobalSection) {
2040 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2044 /* if we have a current service, tidy it up before moving on */
2047 if (lp_ctx->currentService != NULL)
2048 bRetval = service_ok(lp_ctx->currentService);
2050 /* if all is still well, move to the next record in the services array */
2052 /* We put this here to avoid an odd message order if messages are */
2053 /* issued by the post-processing of a previous section. */
2054 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2056 if ((lp_ctx->currentService = add_a_service(lp_ctx, &sDefault,
2059 DEBUG(0, ("Failed to add a new service\n"));
2068 /***************************************************************************
2069 Determine if a partcular base parameter is currentl set to the default value.
2070 ***************************************************************************/
2072 static bool is_default(int i)
2074 if (!defaults_saved)
2076 switch (parm_table[i].type) {
2078 return str_list_equal((const char **)parm_table[i].def.lvalue,
2079 (const char **)(*(char ***)parm_table[i].ptr));
2082 return strequal(parm_table[i].def.svalue,
2083 *(char **)parm_table[i].ptr);
2085 return parm_table[i].def.bvalue ==
2086 *(int *)parm_table[i].ptr;
2091 return parm_table[i].def.ivalue ==
2092 *(int *)parm_table[i].ptr;
2099 /***************************************************************************
2100 Display the contents of the global structure.
2101 ***************************************************************************/
2103 static void dump_globals(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults)
2106 struct param_opt *data;
2108 fprintf(f, "# Global parameters\n[global]\n");
2110 for (i = 0; parm_table[i].label; i++)
2111 if (parm_table[i].class == P_GLOBAL &&
2112 parm_table[i].ptr &&
2113 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2114 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2116 fprintf(f, "\t%s = ", parm_table[i].label);
2117 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2120 if (lp_ctx->Globals.param_opt != NULL) {
2121 for (data = lp_ctx->Globals.param_opt; data;
2122 data = data->next) {
2123 fprintf(f, "\t%s = %s\n", data->key, data->value);
2129 /***************************************************************************
2130 Display the contents of a single services record.
2131 ***************************************************************************/
2133 static void dump_a_service(struct loadparm_service * pService, FILE * f)
2136 struct param_opt *data;
2138 if (pService != &sDefault)
2139 fprintf(f, "\n[%s]\n", pService->szService);
2141 for (i = 0; parm_table[i].label; i++)
2142 if (parm_table[i].class == P_LOCAL &&
2143 parm_table[i].ptr &&
2144 (*parm_table[i].label != '-') &&
2145 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2146 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2148 if (pService == &sDefault) {
2149 if (defaults_saved && is_default(i))
2152 if (equal_parameter(parm_table[i].type,
2153 ((char *)pService) +
2155 ((char *)&sDefault) +
2160 fprintf(f, "\t%s = ", parm_table[i].label);
2161 print_parameter(&parm_table[i],
2162 ((char *)pService) + pdiff, f);
2165 if (pService->param_opt != NULL) {
2166 for (data = pService->param_opt; data; data = data->next) {
2167 fprintf(f, "\t%s = %s\n", data->key, data->value);
2172 bool lp_dump_a_parameter(struct loadparm_context *lp_ctx, int snum, char *parm_name, FILE * f,
2175 struct loadparm_service * pService = lp_ctx->ServicePtrs[snum];
2176 struct parm_struct *parm;
2179 parm = lp_parm_struct(parm_name);
2187 ptr = ((char *)pService) +
2188 PTR_DIFF(parm->ptr, &sDefault);
2190 print_parameter(parm,
2196 /***************************************************************************
2197 Return info about the next service in a service. snum==-1 gives the globals.
2198 Return NULL when out of parameters.
2199 ***************************************************************************/
2201 struct parm_struct *lp_next_parameter(struct loadparm_context *lp_ctx, int snum, int *i,
2205 /* do the globals */
2206 for (; parm_table[*i].label; (*i)++) {
2207 if (parm_table[*i].class == P_SEPARATOR)
2208 return &parm_table[(*i)++];
2210 if (!parm_table[*i].ptr
2211 || (*parm_table[*i].label == '-'))
2215 && (parm_table[*i].ptr ==
2216 parm_table[(*i) - 1].ptr))
2219 return &parm_table[(*i)++];
2222 struct loadparm_service *pService = lp_ctx->ServicePtrs[snum];
2224 for (; parm_table[*i].label; (*i)++) {
2225 if (parm_table[*i].class == P_SEPARATOR)
2226 return &parm_table[(*i)++];
2228 if (parm_table[*i].class == P_LOCAL &&
2229 parm_table[*i].ptr &&
2230 (*parm_table[*i].label != '-') &&
2232 (parm_table[*i].ptr !=
2233 parm_table[(*i) - 1].ptr)))
2236 PTR_DIFF(parm_table[*i].ptr,
2239 if (allparameters ||
2240 !equal_parameter(parm_table[*i].type,
2241 ((char *)pService) +
2243 ((char *)&sDefault) +
2246 return &parm_table[(*i)++];
2256 /***************************************************************************
2257 Auto-load some home services.
2258 ***************************************************************************/
2260 static void lp_add_auto_services(struct loadparm_context *lp_ctx,
2266 /***************************************************************************
2267 Have we loaded a services file yet?
2268 ***************************************************************************/
2270 bool lp_loaded(void)
2275 /***************************************************************************
2276 Unload unused services.
2277 ***************************************************************************/
2279 void lp_killunused(struct loadparm_context *lp_ctx,
2280 struct smbsrv_connection *smb,
2281 bool (*snumused) (struct smbsrv_connection *, int))
2284 for (i = 0; i < lp_ctx->iNumServices; i++) {
2285 if (lp_ctx->ServicePtrs[i] == NULL)
2288 if (!snumused || !snumused(smb, i)) {
2289 talloc_free(lp_ctx->ServicePtrs[i]);
2290 lp_ctx->ServicePtrs[i] = NULL;
2295 /***************************************************************************
2296 Initialise the global parameter structure.
2297 ***************************************************************************/
2298 bool loadparm_init(struct loadparm_context *lp_ctx)
2303 lp_ctx->bInGlobalSection = true;
2305 DEBUG(3, ("Initialising global parameters\n"));
2307 for (i = 0; parm_table[i].label; i++) {
2308 if ((parm_table[i].type == P_STRING ||
2309 parm_table[i].type == P_USTRING) &&
2310 parm_table[i].ptr &&
2311 !(parm_table[i].flags & FLAG_CMDLINE)) {
2312 string_set(talloc_autofree_context(),
2313 (char **)parm_table[i].ptr, "");
2317 lp_do_global_parameter(lp_ctx, "config file", dyn_CONFIGFILE);
2319 lp_do_global_parameter(lp_ctx, "share backend", "classic");
2321 lp_do_global_parameter(lp_ctx, "server role", "standalone");
2323 /* options that can be set on the command line must be initialised via
2324 the slower lp_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2326 lp_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2328 lp_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2329 myname = get_myname();
2330 lp_do_global_parameter(lp_ctx, "netbios name", myname);
2332 lp_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
2334 lp_do_global_parameter(lp_ctx, "fstype", FSTYPE_STRING);
2335 lp_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2336 lp_do_global_parameter(lp_ctx, "max connections", "-1");
2338 lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo");
2339 lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap web kdc drepl winbind");
2340 lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb");
2341 lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain");
2342 lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind");
2343 lp_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain");
2344 lp_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2345 lp_do_global_parameter(lp_ctx, "sam database", "sam.ldb");
2346 lp_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb");
2347 lp_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb");
2348 lp_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb");
2349 lp_do_global_parameter(lp_ctx, "wins database", "wins.ldb");
2350 lp_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2352 /* This hive should be dynamically generated by Samba using
2353 data from the sam, but for the moment leave it in a tdb to
2354 keep regedt32 from popping up an annoying dialog. */
2355 lp_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2357 /* using UTF8 by default allows us to support all chars */
2358 lp_do_global_parameter(lp_ctx, "unix charset", "UTF8");
2360 /* Use codepage 850 as a default for the dos character set */
2361 lp_do_global_parameter(lp_ctx, "dos charset", "CP850");
2364 * Allow the default PASSWD_CHAT to be overridden in local.h.
2366 lp_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2368 lp_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2369 lp_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2370 lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR);
2371 lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2373 lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0");
2374 lp_do_global_parameter_var(lp_ctx, "server string",
2375 "Samba %s", SAMBA_VERSION_STRING);
2377 lp_do_global_parameter_var(lp_ctx, "announce version", "%d.%d",
2378 DEFAULT_MAJOR_VERSION,
2379 DEFAULT_MINOR_VERSION);
2381 lp_do_global_parameter(lp_ctx, "password server", "*");
2383 lp_do_global_parameter(lp_ctx, "max mux", "50");
2384 lp_do_global_parameter(lp_ctx, "max xmit", "12288");
2385 lp_do_global_parameter(lp_ctx, "password level", "0");
2386 lp_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2387 lp_do_global_parameter(lp_ctx, "server min protocol", "CORE");
2388 lp_do_global_parameter(lp_ctx, "server max protocol", "NT1");
2389 lp_do_global_parameter(lp_ctx, "client min protocol", "CORE");
2390 lp_do_global_parameter(lp_ctx, "client max protocol", "NT1");
2391 lp_do_global_parameter(lp_ctx, "security", "USER");
2392 lp_do_global_parameter(lp_ctx, "paranoid server security", "True");
2393 lp_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2394 lp_do_global_parameter(lp_ctx, "ReadRaw", "True");
2395 lp_do_global_parameter(lp_ctx, "WriteRaw", "True");
2396 lp_do_global_parameter(lp_ctx, "NullPasswords", "False");
2397 lp_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2398 lp_do_global_parameter(lp_ctx, "announce as", "NT SERVER");
2400 lp_do_global_parameter(lp_ctx, "TimeServer", "False");
2401 lp_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2402 lp_do_global_parameter(lp_ctx, "Unicode", "True");
2403 lp_do_global_parameter(lp_ctx, "ClientLanManAuth", "True");
2404 lp_do_global_parameter(lp_ctx, "LanmanAuth", "True");
2405 lp_do_global_parameter(lp_ctx, "NTLMAuth", "True");
2406 lp_do_global_parameter(lp_ctx, "client use spnego principal", "False");
2408 lp_do_global_parameter(lp_ctx, "UnixExtensions", "False");
2410 lp_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2411 lp_do_global_parameter(lp_ctx, "LocalMaster", "True");
2413 lp_do_global_parameter(lp_ctx, "wins support", "False");
2414 lp_do_global_parameter(lp_ctx, "dns proxy", "True");
2416 lp_do_global_parameter(lp_ctx, "winbind separator", "\\");
2417 lp_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2418 lp_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2419 lp_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2420 lp_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
2422 lp_do_global_parameter(lp_ctx, "client signing", "Yes");
2423 lp_do_global_parameter(lp_ctx, "server signing", "auto");
2425 lp_do_global_parameter(lp_ctx, "use spnego", "True");
2427 lp_do_global_parameter(lp_ctx, "smb ports", "445 139");
2428 lp_do_global_parameter(lp_ctx, "nbt port", "137");
2429 lp_do_global_parameter(lp_ctx, "dgram port", "138");
2430 lp_do_global_parameter(lp_ctx, "cldap port", "389");
2431 lp_do_global_parameter(lp_ctx, "krb5 port", "88");
2432 lp_do_global_parameter(lp_ctx, "kpasswd port", "464");
2433 lp_do_global_parameter(lp_ctx, "web port", "901");
2434 lp_do_global_parameter(lp_ctx, "swat directory", dyn_SWATDIR);
2436 lp_do_global_parameter(lp_ctx, "nt status support", "True");
2438 lp_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2439 lp_do_global_parameter(lp_ctx, "min wins ttl", "10");
2441 lp_do_global_parameter(lp_ctx, "tls enabled", "True");
2442 lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2443 lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2444 lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2445 lp_do_global_parameter_var(lp_ctx, "js include", "%s", dyn_JSDIR);
2446 lp_do_global_parameter_var(lp_ctx, "setup directory", "%s",
2449 for (i = 0; parm_table[i].label; i++) {
2450 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
2451 parm_table[i].flags |= FLAG_DEFAULT;
2458 /***************************************************************************
2459 Load the services array from the services file. Return True on success,
2461 ***************************************************************************/
2467 struct param_opt *data;
2468 struct loadparm_context *lp_ctx = &loadparm;
2470 global_loadparm = lp_ctx;
2474 if (lp_ctx->Globals.param_opt != NULL) {
2475 struct param_opt *next;
2476 for (data = lp_ctx->Globals.param_opt; data; data=next) {
2478 if (data->flags & FLAG_CMDLINE) continue;
2479 DLIST_REMOVE(lp_ctx->Globals.param_opt, data);
2484 if (!loadparm_init(lp_ctx))
2487 lp_ctx->bInGlobalSection = true;
2488 n2 = standard_sub_basic(talloc_autofree_context(), lp_configfile());
2489 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2491 add_to_file_list(lp_ctx, lp_configfile(), n2);
2493 /* We get sections first, so have to start 'behind' to make up */
2494 lp_ctx->currentService = NULL;
2495 bRetval = pm_process(n2, do_section, do_parameter, lp_ctx);
2497 /* finish up the last section */
2498 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2500 if (lp_ctx->currentService != NULL)
2501 bRetval = service_ok(lp_ctx->currentService);
2503 lp_add_auto_services(lp_ctx, lp_auto_services());
2505 lp_add_hidden(lp_ctx, "IPC$", "IPC");
2506 lp_add_hidden(lp_ctx, "ADMIN$", "DISK");
2510 if (!lp_ctx->Globals.szWINSservers && lp_ctx->Globals.bWINSsupport) {
2511 lp_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
2519 /***************************************************************************
2520 Return the max number of services.
2521 ***************************************************************************/
2523 int lp_numservices(struct loadparm_context *lp_ctx)
2525 return lp_ctx->iNumServices;
2528 /***************************************************************************
2529 Display the contents of the services array in human-readable form.
2530 ***************************************************************************/
2532 void lp_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
2538 defaults_saved = false;
2540 dump_globals(lp_ctx, f, show_defaults);
2542 dump_a_service(&sDefault, f);
2544 for (iService = 0; iService < maxtoprint; iService++)
2545 lp_dump_one(f, show_defaults, lp_ctx->ServicePtrs[iService]);
2548 /***************************************************************************
2549 Display the contents of one service in human-readable form.
2550 ***************************************************************************/
2552 void lp_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service)
2554 if (service != NULL) {
2555 if (service->szService[0] == '\0')
2557 dump_a_service(service, f);
2561 struct loadparm_service *lp_servicebynum(struct loadparm_context *lp_ctx,
2564 return lp_ctx->ServicePtrs[snum];
2567 struct loadparm_service *lp_service(struct loadparm_context *lp_ctx,
2568 const char *service_name)
2573 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
2574 if (lp_ctx->ServicePtrs[iService] &&
2575 lp_ctx->ServicePtrs[iService]->szService) {
2577 * The substitution here is used to support %U is
2580 serviceName = standard_sub_basic(
2581 lp_ctx->ServicePtrs[iService],
2582 lp_ctx->ServicePtrs[iService]->szService);
2583 if (strequal(serviceName, service_name))
2584 return lp_ctx->ServicePtrs[iService];
2588 DEBUG(7,("lp_servicenumber: couldn't find %s\n", service_name));
2593 /*******************************************************************
2594 A useful volume label function.
2595 ********************************************************************/
2596 const char *volume_label(struct loadparm_service *service)
2598 const char *ret = lp_volume(service);
2600 return lp_servicename(service);
2605 /***********************************************************
2606 If we are PDC then prefer us as DMB
2607 ************************************************************/
2609 bool lp_domain_logons(void)
2611 return (lp_server_role() == ROLE_DOMAIN_CONTROLLER);
2614 const char *lp_printername(struct loadparm_service *service)
2616 const char *ret = _lp_printername(service);
2617 if (ret == NULL || (ret != NULL && *ret == '\0'))
2618 ret = lp_const_servicename(service);
2624 /*******************************************************************
2625 Return the max print jobs per queue.
2626 ********************************************************************/
2628 int lp_maxprintjobs(struct loadparm_service *service)
2630 int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2631 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2632 maxjobs = PRINT_MAX_JOBID - 1;