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"
68 static bool bLoaded = false;
70 #define standard_sub_basic talloc_strdup
72 /* some helpful bits */
73 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < loadparm.iNumServices) && VALID(i))
74 #define VALID(i) (loadparm.ServicePtrs[i] != NULL)
76 static bool do_parameter(const char *, const char *, void *);
78 static bool defaults_saved = false;
81 struct param_opt *prev, *next;
88 * This structure describes global (ie., server-wide) parameters.
92 enum server_role server_role;
100 char *szServerString;
101 char *szAutoServices;
104 char *szShareBackend;
108 char *szWINS_CONFIG_URL;
112 char *jsonrpcServicesDir;
113 char **szPasswordServers;
114 char *szSocketOptions;
116 char **szWINSservers;
118 char *szSocketAddress;
119 char *szAnnounceVersion; /* This is initialised in init_globals */
122 char **szNetbiosAliases;
123 char *szNetbiosScope;
124 char *szDomainOtherSIDs;
125 char **szNameResolveOrder;
126 char **dcerpc_ep_servers;
127 char **server_services;
128 char *ntptr_providor;
129 char *szWinbindSeparator;
130 char *szWinbinddSocketDirectory;
131 char *szTemplateShell;
132 char *szTemplateHomedir;
133 int bWinbindSealedPipes;
134 char *webapps_directory;
149 int paranoid_server_security;
152 int announce_as; /* This is initialised in init_globals */
159 char *socket_options;
164 int bPreferredMaster;
165 int bEncryptPasswords;
167 int bObeyPamRestrictions;
172 int bBindInterfacesOnly;
174 int bNTStatusSupport;
180 int bClientPlaintextAuth;
181 int bClientLanManAuth;
182 int bClientNTLMv2Auth;
183 int client_use_spnego_principal;
189 struct param_opt *param_opt;
194 * This structure describes a single service.
208 char **ntvfs_handler;
221 int iCreate_force_mode;
228 struct param_opt *param_opt;
230 char dummy[3]; /* for alignment */
234 /* This is a default service used to prime a services structure */
235 static struct service sDefault = {
236 NULL, /* szService */
239 NULL, /* szInclude */
240 NULL, /* szPrintername */
241 NULL, /* szHostsallow */
242 NULL, /* szHostsdeny */
246 NULL, /* ntvfs_handler */
247 1000, /* iMaxPrintJobs */
248 0, /* iMaxConnections */
250 true, /* bAvailable */
251 true, /* bBrowseable */
252 true, /* bRead_only */
253 false, /* bPrint_ok */
254 false, /* bMap_system */
255 false, /* bMap_hidden */
256 true, /* bMap_archive */
257 true, /* bStrictLocking */
258 0744, /* iCreate_mask */
259 0000, /* iCreate_force_mode */
260 0755, /* iDir_mask */
261 0000, /* iDir_force_mode */
263 false, /* bMSDfsRoot */
264 false, /* bStrictSync */
265 false, /* bCIFileSystem */
266 NULL, /* Parametric options */
271 /* local variables */
272 static struct loadparm_context {
273 struct global Globals;
274 struct service **ServicePtrs;
276 struct service *currentService;
277 bool bInGlobalSection;
280 .currentService = NULL,
281 .bInGlobalSection = true,
285 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
287 /* prototypes for the special type handlers */
288 static bool handle_include(const char *pszParmValue, char **ptr);
289 static bool handle_copy(const char *pszParmValue, char **ptr);
291 static const struct enum_list enum_protocol[] = {
292 {PROTOCOL_SMB2, "SMB2"},
293 {PROTOCOL_NT1, "NT1"},
294 {PROTOCOL_LANMAN2, "LANMAN2"},
295 {PROTOCOL_LANMAN1, "LANMAN1"},
296 {PROTOCOL_CORE, "CORE"},
297 {PROTOCOL_COREPLUS, "COREPLUS"},
298 {PROTOCOL_COREPLUS, "CORE+"},
302 static const struct enum_list enum_security[] = {
303 {SEC_SHARE, "SHARE"},
308 static const struct enum_list enum_announce_as[] = {
309 {ANNOUNCE_AS_NT_SERVER, "NT"},
310 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
311 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
312 {ANNOUNCE_AS_WIN95, "win95"},
313 {ANNOUNCE_AS_WFW, "WfW"},
317 static const struct enum_list enum_bool_auto[] = {
328 /* Client-side offline caching policy types */
329 #define CSC_POLICY_MANUAL 0
330 #define CSC_POLICY_DOCUMENTS 1
331 #define CSC_POLICY_PROGRAMS 2
332 #define CSC_POLICY_DISABLE 3
334 static const struct enum_list enum_csc_policy[] = {
335 {CSC_POLICY_MANUAL, "manual"},
336 {CSC_POLICY_DOCUMENTS, "documents"},
337 {CSC_POLICY_PROGRAMS, "programs"},
338 {CSC_POLICY_DISABLE, "disable"},
342 /* SMB signing types. */
343 static const struct enum_list enum_smb_signing_vals[] = {
344 {SMB_SIGNING_OFF, "No"},
345 {SMB_SIGNING_OFF, "False"},
346 {SMB_SIGNING_OFF, "0"},
347 {SMB_SIGNING_OFF, "Off"},
348 {SMB_SIGNING_OFF, "disabled"},
349 {SMB_SIGNING_SUPPORTED, "Yes"},
350 {SMB_SIGNING_SUPPORTED, "True"},
351 {SMB_SIGNING_SUPPORTED, "1"},
352 {SMB_SIGNING_SUPPORTED, "On"},
353 {SMB_SIGNING_SUPPORTED, "enabled"},
354 {SMB_SIGNING_REQUIRED, "required"},
355 {SMB_SIGNING_REQUIRED, "mandatory"},
356 {SMB_SIGNING_REQUIRED, "force"},
357 {SMB_SIGNING_REQUIRED, "forced"},
358 {SMB_SIGNING_REQUIRED, "enforced"},
359 {SMB_SIGNING_AUTO, "auto"},
363 static const struct enum_list enum_server_role[] = {
364 {ROLE_STANDALONE, "standalone"},
365 {ROLE_DOMAIN_MEMBER, "member server"},
366 {ROLE_DOMAIN_CONTROLLER, "domain controller"},
371 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
373 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
374 * is implied in current control logic. This may change at some later time. A
375 * flag value of 0 means - show as development option only.
377 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
378 * screen in SWAT. This is used to exclude parameters as well as to squash all
379 * parameters that have been duplicated by pseudonyms.
381 static struct parm_struct parm_table[] = {
382 {"Base Options", P_SEP, P_SEPARATOR},
384 {"server role", P_ENUM, P_GLOBAL, &loadparm.Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
386 {"dos charset", P_STRING, P_GLOBAL, &dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
387 {"unix charset", P_STRING, P_GLOBAL, &unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
388 {"ncalrpc dir", P_STRING, P_GLOBAL, &loadparm.Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
389 {"display charset", P_STRING, P_GLOBAL, &display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
390 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
391 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
392 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
393 {"workgroup", P_USTRING, P_GLOBAL, &loadparm.Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
394 {"realm", P_STRING, P_GLOBAL, &loadparm.Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"netbios name", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
396 {"netbios aliases", P_LIST, P_GLOBAL, &loadparm.Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
397 {"netbios scope", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
398 {"server string", P_STRING, P_GLOBAL, &loadparm.Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
399 {"interfaces", P_LIST, P_GLOBAL, &loadparm.Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"bind interfaces only", P_BOOL, P_GLOBAL, &loadparm.Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
402 {"ntptr providor", P_STRING, P_GLOBAL, &loadparm.Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
403 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &loadparm.Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
404 {"server services", P_LIST, P_GLOBAL, &loadparm.Globals.server_services, NULL, NULL, FLAG_ADVANCED},
406 {"Security Options", P_SEP, P_SEPARATOR},
408 {"security", P_ENUM, P_GLOBAL, &loadparm.Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
409 {"encrypt passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
410 {"null passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"obey pam restrictions", P_BOOL, P_GLOBAL, &loadparm.Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
412 {"password server", P_LIST, P_GLOBAL, &loadparm.Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
413 {"sam database", P_STRING, P_GLOBAL, &loadparm.Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"secrets database", P_STRING, P_GLOBAL, &loadparm.Globals.szSECRETS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"spoolss database", P_STRING, P_GLOBAL, &loadparm.Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"wins config database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"wins database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"private dir", P_STRING, P_GLOBAL, &loadparm.Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"passwd chat", P_STRING, P_GLOBAL, &loadparm.Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"password level", P_INTEGER, P_GLOBAL, &loadparm.Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"ntlm auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"client plaintext auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"client use spnego principal", P_BOOL, P_GLOBAL, &loadparm.Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
430 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
431 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
432 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
433 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
435 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
436 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
438 {"Logging Options", P_SEP, P_SEPARATOR},
440 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
442 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"Protocol Options", P_SEP, P_SEPARATOR},
446 {"smb ports", P_LIST, P_GLOBAL, &loadparm.Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"nbt port", P_INTEGER, P_GLOBAL, &loadparm.Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"dgram port", P_INTEGER, P_GLOBAL, &loadparm.Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"cldap port", P_INTEGER, P_GLOBAL, &loadparm.Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"krb5 port", P_INTEGER, P_GLOBAL, &loadparm.Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"kpasswd port", P_INTEGER, P_GLOBAL, &loadparm.Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"web port", P_INTEGER, P_GLOBAL, &loadparm.Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"tls enabled", P_BOOL, P_GLOBAL, &loadparm.Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"tls keyfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"tls certfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"tls cafile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"tls crlfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"tls dh params file", P_STRING, P_GLOBAL, &loadparm.Globals.tls_dhpfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"web application directory", P_STRING, P_GLOBAL, &loadparm.Globals.webapps_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
460 {"large readwrite", P_BOOL, P_GLOBAL, &loadparm.Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
461 {"server max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
462 {"server min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
463 {"client max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
464 {"client min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
465 {"unicode", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
466 {"read raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
467 {"write raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
468 {"disable netbios", P_BOOL, P_GLOBAL, &loadparm.Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
470 {"nt status support", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
472 {"announce version", P_STRING, P_GLOBAL, &loadparm.Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
473 {"announce as", P_ENUM, P_GLOBAL, &loadparm.Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
474 {"max mux", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
475 {"max xmit", P_BYTES, P_GLOBAL, &loadparm.Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
477 {"name resolve order", P_LIST, P_GLOBAL, &loadparm.Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
478 {"max wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
479 {"min wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
480 {"time server", P_BOOL, P_GLOBAL, &loadparm.Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
481 {"unix extensions", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
482 {"use spnego", P_BOOL, P_GLOBAL, &loadparm.Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
483 {"server signing", P_ENUM, P_GLOBAL, &loadparm.Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
484 {"client signing", P_ENUM, P_GLOBAL, &loadparm.Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
485 {"rpc big endian", P_BOOL, P_GLOBAL, &loadparm.Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
487 {"Tuning Options", P_SEP, P_SEPARATOR},
489 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
490 {"paranoid server security", P_BOOL, P_GLOBAL, &loadparm.Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
491 {"socket options", P_STRING, P_GLOBAL, &loadparm.Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
493 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
494 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
496 {"Printing Options", P_SEP, P_SEPARATOR},
498 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
499 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
500 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
502 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
503 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
505 {"Filename Handling", P_SEP, P_SEPARATOR},
507 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
508 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
509 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
511 {"Domain Options", P_SEP, P_SEPARATOR},
513 {"Logon Options", P_SEP, P_SEPARATOR},
516 {"Browse Options", P_SEP, P_SEPARATOR},
518 {"preferred master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
519 {"prefered master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
520 {"local master", P_BOOL, P_GLOBAL, &loadparm.Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
521 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
522 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
524 {"WINS Options", P_SEP, P_SEPARATOR},
526 {"wins server", P_LIST, P_GLOBAL, &loadparm.Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
527 {"wins support", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
528 {"dns proxy", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
529 {"wins hook", P_STRING, P_GLOBAL, &loadparm.Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
531 {"Locking Options", P_SEP, P_SEPARATOR},
533 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
535 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
537 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
539 {"config file", P_STRING, P_GLOBAL, &loadparm.Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
540 {"share backend", P_STRING, P_GLOBAL, &loadparm.Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"preload", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"auto services", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"lock dir", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_HIDE},
544 {"lock directory", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"modules dir", P_STRING, P_GLOBAL, &loadparm.Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"pid directory", P_STRING, P_GLOBAL, &loadparm.Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"js include", P_LIST, P_GLOBAL, &loadparm.Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"jsonrpc services directory", P_STRING, P_GLOBAL, &loadparm.Globals.jsonrpcServicesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"setup directory", P_STRING, P_GLOBAL, &loadparm.Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"socket address", P_STRING, P_GLOBAL, &loadparm.Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
552 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
553 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
555 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
556 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
557 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
559 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
562 {"host msdfs", P_BOOL, P_GLOBAL, &loadparm.Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"winbind separator", P_STRING, P_GLOBAL, &loadparm.Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
564 {"winbindd socket directory", P_STRING, P_GLOBAL, &loadparm.Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
565 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &loadparm.Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
566 {"template shell", P_STRING, P_GLOBAL, &loadparm.Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
567 {"template homedir", P_STRING, P_GLOBAL, &loadparm.Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
569 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
574 return the parameter table
576 struct parm_struct *lp_parm_table(void)
581 static TALLOC_CTX *lp_talloc;
583 /******************************************************************* a
584 Free up temporary memory - called from the main loop.
585 ********************************************************************/
587 void lp_talloc_free(void)
591 talloc_free(lp_talloc);
595 /*******************************************************************
596 Convenience routine to grab string parameters into temporary memory
597 and run standard_sub_basic on them. The buffers can be written to by
598 callers without affecting the source string.
599 ********************************************************************/
601 static const char *lp_string(const char *s)
603 #if 0 /* until REWRITE done to make thread-safe */
604 size_t len = s ? strlen(s) : 0;
608 /* The follow debug is useful for tracking down memory problems
609 especially if you have an inner loop that is calling a lp_*()
610 function that returns a string. Perhaps this debug should be
611 present all the time? */
614 DEBUG(10, ("lp_string(%s)\n", s));
617 #if 0 /* until REWRITE done to make thread-safe */
619 lp_talloc = talloc_init("lp_talloc");
621 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
629 strlcpy(ret, s, len);
631 if (trim_string(ret, "\"", "\"")) {
632 if (strchr(ret,'"') != NULL)
633 strlcpy(ret, s, len);
636 standard_sub_basic(ret,len+100);
643 In this section all the functions that are used to access the
644 parameters from the rest of the program are defined
647 #define FN_GLOBAL_STRING(fn_name,ptr) \
648 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
649 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
650 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
651 #define FN_GLOBAL_LIST(fn_name,ptr) \
652 const char **fn_name(void) {return(*(const char ***)(ptr));}
653 #define FN_GLOBAL_BOOL(fn_name,ptr) \
654 bool fn_name(void) {return((bool)*(int *)(ptr));}
656 #define FN_GLOBAL_CHAR(fn_name,ptr) \
657 char fn_name(void) {return(*(char *)(ptr));}
659 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
660 int fn_name(void) {return(*(int *)(ptr));}
662 #define FN_LOCAL_STRING(fn_name,val) \
663 const char *fn_name(struct service *service) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault.val)));}
664 #define FN_LOCAL_CONST_STRING(fn_name,val) \
665 const char *fn_name(struct service *service) {return (const char *)(service != NULL && service->val != NULL) ? service->val : sDefault.val;}
666 #define FN_LOCAL_LIST(fn_name,val) \
667 const char **fn_name(struct service *service) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault.val);}
668 #define FN_LOCAL_BOOL(fn_name,val) \
669 bool fn_name(struct service *service) {return((service != NULL)? service->val : sDefault.val);}
670 #define FN_LOCAL_INTEGER(fn_name,val) \
671 int fn_name(struct service *service) {return((service != NULL)? service->val : sDefault.val);}
673 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &loadparm.Globals.server_role)
674 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &loadparm.Globals.smb_ports)
675 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &loadparm.Globals.nbt_port)
676 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &loadparm.Globals.dgram_port)
677 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &loadparm.Globals.cldap_port)
678 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &loadparm.Globals.krb5_port)
679 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &loadparm.Globals.kpasswd_port)
680 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &loadparm.Globals.web_port)
681 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &dos_charset)
682 _PUBLIC_ FN_GLOBAL_STRING(lp_webapps_directory, &loadparm.Globals.webapps_directory)
683 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &loadparm.Globals.tls_enabled)
684 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &loadparm.Globals.tls_keyfile)
685 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &loadparm.Globals.tls_certfile)
686 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &loadparm.Globals.tls_cafile)
687 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &loadparm.Globals.tls_crlfile)
688 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_dhpfile, &loadparm.Globals.tls_dhpfile)
689 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &unix_charset)
690 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &display_charset)
691 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &loadparm.Globals.szConfigFile)
692 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, &loadparm.Globals.szShareBackend)
693 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &loadparm.Globals.szSAM_URL)
694 _PUBLIC_ FN_GLOBAL_STRING(lp_secrets_url, &loadparm.Globals.szSECRETS_URL)
695 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &loadparm.Globals.szSPOOLSS_URL)
696 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &loadparm.Globals.szWINS_CONFIG_URL)
697 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &loadparm.Globals.szWINS_URL)
698 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &loadparm.Globals.szWinbindSeparator)
699 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &loadparm.Globals.szWinbinddSocketDirectory)
700 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_shell, &loadparm.Globals.szTemplateShell)
701 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_homedir, &loadparm.Globals.szTemplateHomedir)
702 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &loadparm.Globals.bWinbindSealedPipes)
703 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &loadparm.Globals.szPrivateDir)
704 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &loadparm.Globals.szServerString)
705 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &loadparm.Globals.szLockDir)
706 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &loadparm.Globals.szModulesDir)
707 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &loadparm.Globals.szSetupDir)
708 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &loadparm.Globals.ncalrpc_dir)
709 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &loadparm.Globals.szPidDir)
710 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &loadparm.Globals.dcerpc_ep_servers)
711 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &loadparm.Globals.server_services)
712 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &loadparm.Globals.ntptr_providor)
713 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &loadparm.Globals.szAutoServices)
714 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &loadparm.Globals.szPasswdChat)
715 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &loadparm.Globals.szPasswordServers)
716 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &loadparm.Globals.szNameResolveOrder)
717 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &loadparm.Globals.szRealm)
718 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &loadparm.Globals.socket_options)
719 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &loadparm.Globals.szWorkgroup)
720 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &loadparm.Globals.szNetbiosName)
721 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &loadparm.Globals.szNetbiosScope)
722 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &loadparm.Globals.szWINSservers)
723 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &loadparm.Globals.szInterfaces)
724 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &loadparm.Globals.szSocketAddress)
725 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &loadparm.Globals.szNetbiosAliases)
727 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &loadparm.Globals.bDisableNetbios)
728 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &loadparm.Globals.bWINSsupport)
729 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &loadparm.Globals.bWINSdnsProxy)
730 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &loadparm.Globals.szWINSHook)
731 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &loadparm.Globals.bLocalMaster)
732 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &loadparm.Globals.bReadRaw)
733 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &loadparm.Globals.bLargeReadwrite)
734 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &loadparm.Globals.bWriteRaw)
735 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &loadparm.Globals.bNullPasswords)
736 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &loadparm.Globals.bObeyPamRestrictions)
737 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &loadparm.Globals.bEncryptPasswords)
738 _PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, &loadparm.Globals.bTimeServer)
739 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &loadparm.Globals.bBindInterfacesOnly)
740 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &loadparm.Globals.bUnicode)
741 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &loadparm.Globals.bNTStatusSupport)
742 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &loadparm.Globals.bLanmanAuth)
743 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &loadparm.Globals.bNTLMAuth)
744 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &loadparm.Globals.bClientPlaintextAuth)
745 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &loadparm.Globals.bClientLanManAuth)
746 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &loadparm.Globals.bClientNTLMv2Auth)
747 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &loadparm.Globals.client_use_spnego_principal)
748 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &loadparm.Globals.bHostMSDfs)
749 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &loadparm.Globals.bUnixExtensions)
750 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &loadparm.Globals.bUseSpnego)
751 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &loadparm.Globals.bRpcBigEndian)
752 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &loadparm.Globals.max_wins_ttl)
753 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &loadparm.Globals.min_wins_ttl)
754 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &loadparm.Globals.max_mux)
755 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &loadparm.Globals.max_xmit)
756 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &loadparm.Globals.pwordlevel)
757 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &loadparm.Globals.srv_maxprotocol)
758 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &loadparm.Globals.srv_minprotocol)
759 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &loadparm.Globals.cli_maxprotocol)
760 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &loadparm.Globals.cli_minprotocol)
761 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &loadparm.Globals.security)
762 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &loadparm.Globals.paranoid_server_security)
763 _PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, &loadparm.Globals.announce_as)
764 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &loadparm.Globals.jsInclude)
765 _PUBLIC_ FN_GLOBAL_STRING(lp_jsonrpc_services_dir, &loadparm.Globals.jsonrpcServicesDir)
766 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
767 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
768 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
769 static FN_LOCAL_STRING(_lp_printername, szPrintername)
770 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
771 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
772 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
773 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
774 static FN_LOCAL_STRING(lp_volume, volume)
775 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
776 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
777 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
778 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
779 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
780 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
781 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
782 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
783 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
784 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
785 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
786 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
787 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
788 _PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
789 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
790 _PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
791 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
792 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &loadparm.Globals.server_signing)
793 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &loadparm.Globals.client_signing)
795 /* local prototypes */
796 static int map_parameter(const char *pszParmName);
797 static struct service *getservicebyname(const char *pszServiceName);
798 static void copy_service(struct service *pserviceDest,
799 struct service *pserviceSource, int *pcopymapDest);
800 static bool service_ok(struct service *service);
801 static bool do_section(const char *pszSectionName, void *);
802 static void init_copymap(struct service *pservice);
804 /* This is a helper function for parametrical options support. */
805 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
806 /* Actual parametrical functions are quite simple */
807 const char *lp_get_parametric(struct service *service, const char *type,
811 struct param_opt *data;
813 data = (service == NULL ? loadparm.Globals.param_opt : service->param_opt);
815 asprintf(&vfskey, "%s:%s", type, option);
819 if (strcmp(data->key, vfskey) == 0) {
826 if (service != NULL) {
827 /* Try to fetch the same option but from globals */
828 /* but only if we are not already working with Globals */
829 for (data = loadparm.Globals.param_opt; data;
831 if (strcmp(data->key, vfskey) == 0) {
844 /*******************************************************************
845 convenience routine to return int parameters.
846 ********************************************************************/
847 static int lp_int(const char *s)
851 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
855 return strtol(s, NULL, 0);
858 /*******************************************************************
859 convenience routine to return unsigned long parameters.
860 ********************************************************************/
861 static int lp_ulong(const char *s)
865 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
869 return strtoul(s, NULL, 0);
872 /*******************************************************************
873 convenience routine to return unsigned long parameters.
874 ********************************************************************/
875 static double lp_double(const char *s)
879 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
883 return strtod(s, NULL);
886 /*******************************************************************
887 convenience routine to return boolean parameters.
888 ********************************************************************/
889 static bool lp_bool(const char *s)
894 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
898 if (!set_boolean(s, &ret)) {
899 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
907 /* Return parametric option from a given service. Type is a part of option before ':' */
908 /* Parametric option has following syntax: 'Type: option = value' */
909 /* Returned value is allocated in 'lp_talloc' context */
911 const char *lp_parm_string(struct service *service, const char *type,
914 const char *value = lp_get_parametric(service, type, option);
917 return lp_string(value);
922 /* Return parametric option from a given service. Type is a part of option before ':' */
923 /* Parametric option has following syntax: 'Type: option = value' */
924 /* Returned value is allocated in 'lp_talloc' context */
926 const char **lp_parm_string_list(struct service *service, const char *type,
927 const char *option, const char *separator)
929 const char *value = lp_get_parametric(service, type, option);
932 return str_list_make(talloc_autofree_context(), value,
938 /* Return parametric option from a given service. Type is a part of option before ':' */
939 /* Parametric option has following syntax: 'Type: option = value' */
941 int lp_parm_int(struct service *service, const char *type, const char *option,
944 const char *value = lp_get_parametric(service, type, option);
947 return lp_int(value);
952 /* Return parametric option from a given service. Type is a part of
954 * Parametric option has following syntax: 'Type: option = value'.
957 int lp_parm_bytes(struct service *service, const char *type,
958 const char *option, int default_v)
962 const char *value = lp_get_parametric(service, type, option);
964 if (value && conv_str_size(value, &bval)) {
965 if (bval <= INT_MAX) {
973 /* Return parametric option from a given service. Type is a part of option before ':' */
974 /* Parametric option has following syntax: 'Type: option = value' */
976 unsigned long lp_parm_ulong(struct service *service, const char *type,
977 const char *option, unsigned long default_v)
979 const char *value = lp_get_parametric(service, type, option);
982 return lp_ulong(value);
988 double lp_parm_double(struct service *service, const char *type,
989 const char *option, double default_v)
991 const char *value = lp_get_parametric(service, type, option);
994 return lp_double(value);
999 /* Return parametric option from a given service. Type is a part of option before ':' */
1000 /* Parametric option has following syntax: 'Type: option = value' */
1002 bool lp_parm_bool(struct service *service, const char *type,
1003 const char *option, bool default_v)
1005 const char *value = lp_get_parametric(service, type, option);
1008 return lp_bool(value);
1014 /***************************************************************************
1015 Initialise a service to the defaults.
1016 ***************************************************************************/
1018 static struct service *init_service(TALLOC_CTX *mem_ctx)
1020 struct service *pservice = talloc_zero(mem_ctx, struct service);
1021 copy_service(pservice, &sDefault, NULL);
1025 /***************************************************************************
1026 Add a new service to the services array initialising it with the given
1028 ***************************************************************************/
1030 static struct service *add_a_service(struct loadparm_context *lp_ctx,
1031 const struct service *pservice,
1035 struct service tservice;
1036 int num_to_alloc = lp_ctx->iNumServices + 1;
1037 struct param_opt *data, *pdata;
1039 tservice = *pservice;
1041 /* it might already exist */
1043 struct service *service = getservicebyname(name);
1044 if (service != NULL) {
1045 /* Clean all parametric options for service */
1046 /* They will be added during parsing again */
1047 data = service->param_opt;
1053 service->param_opt = NULL;
1058 /* find an invalid one */
1059 for (i = 0; i < lp_ctx->iNumServices; i++)
1060 if (lp_ctx->ServicePtrs[i] == NULL)
1063 /* if not, then create one */
1064 if (i == lp_ctx->iNumServices) {
1065 struct service **tsp;
1067 tsp = realloc_p(lp_ctx->ServicePtrs, struct service *,
1071 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1075 lp_ctx->ServicePtrs = tsp;
1076 lp_ctx->ServicePtrs[lp_ctx->iNumServices] = NULL;
1079 lp_ctx->iNumServices++;
1082 lp_ctx->ServicePtrs[i] = init_service(talloc_autofree_context());
1083 if (lp_ctx->ServicePtrs[i] == NULL) {
1084 DEBUG(0,("add_a_service: out of memory!\n"));
1087 copy_service(lp_ctx->ServicePtrs[i], &tservice, NULL);
1089 string_set(lp_ctx->ServicePtrs[i], &lp_ctx->ServicePtrs[i]->szService, name);
1090 return lp_ctx->ServicePtrs[i];
1093 /***************************************************************************
1094 Add a new home service, with the specified home directory, defaults coming
1096 ***************************************************************************/
1098 bool lp_add_home(struct loadparm_context *lp_ctx,
1099 const char *pszHomename, struct service *default_service,
1100 const char *user, const char *pszHomedir)
1102 struct service *service;
1105 service = add_a_service(lp_ctx, default_service, pszHomename);
1107 if (service == NULL)
1110 if (!(*(default_service->szPath))
1111 || strequal(default_service->szPath, sDefault.szPath)) {
1112 pstrcpy(newHomedir, pszHomedir);
1114 pstrcpy(newHomedir, lp_pathname(default_service));
1115 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1118 string_set(service, &service->szPath, newHomedir);
1120 if (!(*(service->comment))) {
1121 service->comment = talloc_asprintf(service, "Home directory of %s", user);
1123 service->bAvailable = default_service->bAvailable;
1124 service->bBrowseable = default_service->bBrowseable;
1126 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
1127 pszHomename, user, newHomedir));
1132 /***************************************************************************
1133 Add a new service, based on an old one.
1134 ***************************************************************************/
1136 struct service *lp_add_service(struct loadparm_context *lp_ctx,
1137 const char *pszService,
1138 struct service *default_service)
1140 return add_a_service(lp_ctx, default_service, pszService);
1143 /***************************************************************************
1144 Add the IPC service.
1145 ***************************************************************************/
1147 static bool lp_add_hidden(struct loadparm_context *lp_ctx, const char *name,
1150 struct service *service = add_a_service(lp_ctx, &sDefault, name);
1152 if (service == NULL)
1155 string_set(service, &service->szPath, tmpdir());
1157 service->comment = talloc_asprintf(service, "%s Service (%s)",
1158 fstype, loadparm.Globals.szServerString);
1159 string_set(service, &service->fstype, fstype);
1160 service->iMaxConnections = -1;
1161 service->bAvailable = true;
1162 service->bRead_only = true;
1163 service->bPrint_ok = false;
1164 service->bBrowseable = false;
1166 if (strcasecmp(fstype, "IPC") == 0) {
1167 lp_do_service_parameter(service, "ntvfs handler", "default");
1170 DEBUG(3, ("adding hidden service %s\n", name));
1175 /***************************************************************************
1176 Add a new printer service, with defaults coming from service iFrom.
1177 ***************************************************************************/
1179 bool lp_add_printer(struct loadparm_context *lp_ctx,
1180 const char *pszPrintername,
1181 struct service *default_service)
1183 const char *comment = "From Printcap";
1184 struct service *service;
1185 service = add_a_service(lp_ctx, default_service, pszPrintername);
1187 if (service == NULL)
1190 /* note that we do NOT default the availability flag to True - */
1191 /* we take it from the default service passed. This allows all */
1192 /* dynamic printers to be disabled by disabling the [printers] */
1193 /* entry (if/when the 'available' keyword is implemented!). */
1195 /* the printer name is set to the service name. */
1196 string_set(service, &service->szPrintername, pszPrintername);
1197 string_set(service, &service->comment, comment);
1198 service->bBrowseable = sDefault.bBrowseable;
1199 /* Printers cannot be read_only. */
1200 service->bRead_only = false;
1201 /* Printer services must be printable. */
1202 service->bPrint_ok = true;
1204 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1209 /***************************************************************************
1210 Map a parameter's string representation to something we can use.
1211 Returns False if the parameter string is not recognised, else TRUE.
1212 ***************************************************************************/
1214 static int map_parameter(const char *pszParmName)
1218 if (*pszParmName == '-')
1221 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1222 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1225 /* Warn only if it isn't parametric option */
1226 if (strchr(pszParmName, ':') == NULL)
1227 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1228 /* We do return 'fail' for parametric options as well because they are
1229 stored in different storage
1236 return the parameter structure for a parameter
1238 struct parm_struct *lp_parm_struct(const char *name)
1240 int parmnum = map_parameter(name);
1241 if (parmnum == -1) return NULL;
1242 return &parm_table[parmnum];
1246 return the parameter pointer for a parameter
1248 void *lp_parm_ptr(struct service *service, struct parm_struct *parm)
1250 if (service == NULL)
1253 return ((char *)service) + PTR_DIFF(parm->ptr, &sDefault);
1256 /***************************************************************************
1257 Find a service by name. Otherwise works like get_service.
1258 ***************************************************************************/
1260 static struct service *getservicebyname(const char *pszServiceName)
1264 for (iService = loadparm.iNumServices - 1; iService >= 0; iService--)
1265 if (VALID(iService) &&
1266 strwicmp(loadparm.ServicePtrs[iService]->szService, pszServiceName) == 0) {
1267 return loadparm.ServicePtrs[iService];
1273 /***************************************************************************
1274 Copy a service structure to another.
1275 If pcopymapDest is NULL then copy all fields
1276 ***************************************************************************/
1278 static void copy_service(struct service *pserviceDest,
1279 struct service *pserviceSource,
1283 bool bcopyall = (pcopymapDest == NULL);
1284 struct param_opt *data, *pdata, *paramo;
1287 for (i = 0; parm_table[i].label; i++)
1288 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1289 (bcopyall || pcopymapDest[i])) {
1290 void *def_ptr = parm_table[i].ptr;
1292 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1295 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1298 switch (parm_table[i].type) {
1300 *(int *)dest_ptr = *(int *)src_ptr;
1306 *(int *)dest_ptr = *(int *)src_ptr;
1310 string_set(pserviceDest,
1316 string_set(pserviceDest,
1319 strupper(*(char **)dest_ptr);
1322 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1323 *(const char ***)src_ptr);
1331 init_copymap(pserviceDest);
1332 if (pserviceSource->copymap)
1333 memcpy((void *)pserviceDest->copymap,
1334 (void *)pserviceSource->copymap,
1335 sizeof(int) * NUMPARAMETERS);
1338 data = pserviceSource->param_opt;
1341 pdata = pserviceDest->param_opt;
1342 /* Traverse destination */
1344 /* If we already have same option, override it */
1345 if (strcmp(pdata->key, data->key) == 0) {
1346 talloc_free(pdata->value);
1347 pdata->value = talloc_reference(pdata,
1352 pdata = pdata->next;
1355 paramo = talloc(pserviceDest, struct param_opt);
1358 paramo->key = talloc_reference(paramo, data->key);
1359 paramo->value = talloc_reference(paramo, data->value);
1360 DLIST_ADD(pserviceDest->param_opt, paramo);
1366 /***************************************************************************
1367 Check a service for consistency. Return False if the service is in any way
1368 incomplete or faulty, else True.
1369 ***************************************************************************/
1371 static bool service_ok(struct service *service)
1376 if (service->szService[0] == '\0') {
1377 DEBUG(0, ("The following message indicates an internal error:\n"));
1378 DEBUG(0, ("No service name in service entry.\n"));
1382 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1383 /* I can't see why you'd want a non-printable printer service... */
1384 if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
1385 if (!service->bPrint_ok) {
1386 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1387 service->szService));
1388 service->bPrint_ok = true;
1390 /* [printers] service must also be non-browsable. */
1391 if (service->bBrowseable)
1392 service->bBrowseable = false;
1395 /* If a service is flagged unavailable, log the fact at level 0. */
1396 if (!service->bAvailable)
1397 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1398 service->szService));
1403 static struct file_lists {
1404 struct file_lists *next;
1408 } *file_lists = NULL;
1410 /*******************************************************************
1411 Keep a linked list of all config files so we know when one has changed
1412 it's date and needs to be reloaded.
1413 ********************************************************************/
1415 static void add_to_file_list(const char *fname, const char *subfname)
1417 struct file_lists *f = file_lists;
1420 if (f->name && !strcmp(f->name, fname))
1426 f = talloc(talloc_autofree_context(), struct file_lists);
1429 f->next = file_lists;
1430 f->name = talloc_strdup(f, fname);
1435 f->subfname = talloc_strdup(f, subfname);
1441 f->modtime = file_modtime(subfname);
1443 time_t t = file_modtime(subfname);
1449 /*******************************************************************
1450 Check if a config file has changed date.
1451 ********************************************************************/
1453 bool lp_file_list_changed(void)
1455 struct file_lists *f;
1456 DEBUG(6, ("lp_file_list_changed()\n"));
1458 for (f = file_lists; f != NULL; f = f->next) {
1462 n2 = standard_sub_basic(talloc_autofree_context(), f->name);
1464 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1465 f->name, n2, ctime(&f->modtime)));
1467 mod_time = file_modtime(n2);
1469 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1470 DEBUGADD(6, ("file %s modified: %s\n", n2,
1472 f->modtime = mod_time;
1473 talloc_free(f->subfname);
1474 f->subfname = talloc_strdup(f, n2);
1481 /***************************************************************************
1482 Handle the include operation.
1483 ***************************************************************************/
1485 static bool handle_include(const char *pszParmValue, char **ptr)
1487 char *fname = standard_sub_basic(talloc_autofree_context(),
1490 add_to_file_list(pszParmValue, fname);
1492 string_set(talloc_autofree_context(), ptr, fname);
1494 if (file_exist(fname))
1495 return pm_process(fname, do_section, do_parameter, &loadparm);
1497 DEBUG(2, ("Can't find include file %s\n", fname));
1502 /***************************************************************************
1503 Handle the interpretation of the copy parameter.
1504 ***************************************************************************/
1506 static bool handle_copy(const char *pszParmValue, char **ptr)
1509 struct service *serviceTemp;
1511 string_set(talloc_autofree_context(), ptr, pszParmValue);
1515 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1517 if ((serviceTemp = getservicebyname(pszParmValue)) != NULL) {
1518 if (serviceTemp == loadparm.currentService) {
1519 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1521 copy_service(loadparm.currentService,
1523 loadparm.currentService->copymap);
1527 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1534 /***************************************************************************
1535 Initialise a copymap.
1536 ***************************************************************************/
1538 static void init_copymap(struct service *pservice)
1541 talloc_free(pservice->copymap);
1542 pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS);
1543 if (pservice->copymap == NULL) {
1545 ("Couldn't allocate copymap!! (size %d)\n",
1546 (int)NUMPARAMETERS));
1549 for (i = 0; i < NUMPARAMETERS; i++)
1550 pservice->copymap[i] = true;
1553 #if 0 /* not used anywhere */
1554 /***************************************************************************
1555 Return the local pointer to a parameter given the service number and the
1556 pointer into the default structure.
1557 ***************************************************************************/
1559 void *lp_local_ptr(int snum, void *ptr)
1561 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1565 /***************************************************************************
1566 Process a parametric option
1567 ***************************************************************************/
1568 static bool lp_do_parameter_parametric(struct service *service,
1569 const char *pszParmName,
1570 const char *pszParmValue, int flags)
1572 struct param_opt *paramo, *data;
1574 TALLOC_CTX *mem_ctx;
1576 while (isspace((unsigned char)*pszParmName)) {
1580 name = strdup(pszParmName);
1581 if (!name) return false;
1585 if (service == NULL) {
1586 data = loadparm.Globals.param_opt;
1587 mem_ctx = talloc_autofree_context();
1589 data = service->param_opt;
1593 /* Traverse destination */
1594 for (paramo=data; paramo; paramo=paramo->next) {
1595 /* If we already have the option set, override it unless
1596 it was a command line option and the new one isn't */
1597 if (strcmp(paramo->key, name) == 0) {
1598 if ((paramo->flags & FLAG_CMDLINE) &&
1599 !(flags & FLAG_CMDLINE)) {
1603 talloc_free(paramo->value);
1604 paramo->value = talloc_strdup(paramo, pszParmValue);
1605 paramo->flags = flags;
1611 paramo = talloc(mem_ctx, struct param_opt);
1614 paramo->key = talloc_strdup(paramo, name);
1615 paramo->value = talloc_strdup(paramo, pszParmValue);
1616 paramo->flags = flags;
1617 if (service == NULL) {
1618 DLIST_ADD(loadparm.Globals.param_opt, paramo);
1620 DLIST_ADD(service->param_opt, paramo);
1628 static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1629 const char *pszParmName, const char *pszParmValue)
1632 /* if it is a special case then go ahead */
1633 if (parm_table[parmnum].special) {
1634 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1638 /* now switch on the type of variable it is */
1639 switch (parm_table[parmnum].type)
1643 if (!set_boolean(pszParmValue, &b)) {
1644 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1647 *(int *)parm_ptr = b;
1652 *(int *)parm_ptr = atoi(pszParmValue);
1656 *(int *)parm_ptr = strtol(pszParmValue, NULL, 8);
1662 if (conv_str_size(pszParmValue, &val)) {
1663 if (val <= INT_MAX) {
1664 *(int *)parm_ptr = (int)val;
1669 DEBUG(0,("lp_do_parameter(%s): value is not "
1670 "a valid size specifier!\n", pszParmValue));
1675 *(const char ***)parm_ptr = str_list_make(mem_ctx,
1676 pszParmValue, NULL);
1680 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1684 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1685 strupper(*(char **)parm_ptr);
1689 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1692 parm_table[parmnum].enum_list[i].name)) {
1694 parm_table[parmnum].
1699 if (!parm_table[parmnum].enum_list[i].name) {
1700 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1701 pszParmValue, pszParmName));
1709 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1710 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1711 /* we have to also unset FLAG_DEFAULT on aliases */
1712 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1713 parm_table[i].flags &= ~FLAG_DEFAULT;
1715 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1716 parm_table[i].flags &= ~FLAG_DEFAULT;
1723 bool lp_do_global_parameter(struct loadparm_context *lp_ctx,
1724 const char *pszParmName, const char *pszParmValue)
1726 int parmnum = map_parameter(pszParmName);
1730 if (strchr(pszParmName, ':')) {
1731 return lp_do_parameter_parametric(NULL, pszParmName, pszParmValue, 0);
1733 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1737 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1738 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1742 /* if the flag has been set on the command line, then don't allow override,
1743 but don't report an error */
1744 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1748 parm_ptr = parm_table[parmnum].ptr;
1750 return set_variable(talloc_autofree_context(), parmnum, parm_ptr,
1751 pszParmName, pszParmValue);
1754 bool lp_do_service_parameter(struct service *service,
1755 const char *pszParmName, const char *pszParmValue)
1757 void *def_ptr = NULL;
1760 int parmnum = map_parameter(pszParmName);
1763 if (strchr(pszParmName, ':')) {
1764 return lp_do_parameter_parametric(service, pszParmName, pszParmValue, 0);
1766 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1770 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1771 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1775 /* if the flag has been set on the command line, then don't allow override,
1776 but don't report an error */
1777 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1781 def_ptr = parm_table[parmnum].ptr;
1783 if (parm_table[parmnum].class == P_GLOBAL) {
1785 ("Global parameter %s found in service section!\n",
1789 parm_ptr = ((char *)service) + PTR_DIFF(def_ptr, &sDefault);
1791 if (!service->copymap)
1792 init_copymap(service);
1794 /* this handles the aliases - set the copymap for other
1795 * entries with the same data pointer */
1796 for (i = 0; parm_table[i].label; i++)
1797 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1798 service->copymap[i] = false;
1800 return set_variable(service, parmnum, parm_ptr, pszParmName,
1804 /***************************************************************************
1805 Process a parameter for a particular service number. If snum < 0
1806 then assume we are in the globals.
1807 ***************************************************************************/
1808 bool lp_do_parameter(struct service *service, const char *pszParmName,
1809 const char *pszParmValue)
1811 if (service == NULL) {
1812 return lp_do_global_parameter(&loadparm, pszParmName,
1815 return lp_do_service_parameter(service,
1816 pszParmName, pszParmValue);
1821 /***************************************************************************
1822 Process a parameter.
1823 ***************************************************************************/
1825 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1828 if (loadparm.bInGlobalSection)
1829 return lp_do_global_parameter(&loadparm, pszParmName,
1832 return lp_do_service_parameter(loadparm.currentService,
1833 pszParmName, pszParmValue);
1837 variable argument do parameter
1839 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
1840 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx,
1841 const char *pszParmName, const char *fmt, ...)
1848 s = talloc_vasprintf(NULL, fmt, ap);
1850 ret = lp_do_global_parameter(lp_ctx, pszParmName, s);
1857 set a parameter from the commandline - this is called from command line parameter
1858 parsing code. It sets the parameter then marks the parameter as unable to be modified
1859 by smb.conf processing
1861 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1863 int parmnum = map_parameter(pszParmName);
1866 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1869 if (parmnum < 0 && strchr(pszParmName, ':')) {
1870 /* set a parametric option */
1871 return lp_do_parameter_parametric(NULL, pszParmName, pszParmValue, FLAG_CMDLINE);
1875 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1879 /* reset the CMDLINE flag in case this has been called before */
1880 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1882 if (!lp_do_parameter(NULL, pszParmName, pszParmValue)) {
1886 parm_table[parmnum].flags |= FLAG_CMDLINE;
1888 /* we have to also set FLAG_CMDLINE on aliases */
1889 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1890 parm_table[i].flags |= FLAG_CMDLINE;
1892 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1893 parm_table[i].flags |= FLAG_CMDLINE;
1900 set a option from the commandline in 'a=b' format. Use to support --option
1902 bool lp_set_option(const char *option)
1920 ret = lp_set_cmdline(s, p+1);
1926 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1928 /***************************************************************************
1929 Print a parameter of the specified type.
1930 ***************************************************************************/
1932 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1938 for (i = 0; p->enum_list[i].name; i++) {
1939 if (*(int *)ptr == p->enum_list[i].value) {
1941 p->enum_list[i].name);
1948 fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr));
1953 fprintf(f, "%d", *(int *)ptr);
1957 fprintf(f, "0%o", *(int *)ptr);
1961 if ((char ***)ptr && *(char ***)ptr) {
1962 char **list = *(char ***)ptr;
1964 for (; *list; list++)
1965 fprintf(f, "%s%s", *list,
1966 ((*(list+1))?", ":""));
1972 if (*(char **)ptr) {
1973 fprintf(f, "%s", *(char **)ptr);
1981 /***************************************************************************
1982 Check if two parameters are equal.
1983 ***************************************************************************/
1985 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
1989 return (*((int *)ptr1) == *((int *)ptr2));
1995 return (*((int *)ptr1) == *((int *)ptr2));
1998 return str_list_equal((const char **)(*(char ***)ptr1),
1999 (const char **)(*(char ***)ptr2));
2004 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2009 return (p1 == p2 || strequal(p1, p2));
2017 /***************************************************************************
2018 Process a new section (service). At this stage all sections are services.
2019 Later we'll have special sections that permit server parameters to be set.
2020 Returns True on success, False on failure.
2021 ***************************************************************************/
2023 static bool do_section(const char *pszSectionName, void *userdata)
2025 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2027 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2028 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2031 /* if we've just struck a global section, note the fact. */
2032 lp_ctx->bInGlobalSection = isglobal;
2034 /* check for multiple global sections */
2035 if (lp_ctx->bInGlobalSection) {
2036 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2040 /* if we have a current service, tidy it up before moving on */
2043 if (lp_ctx->currentService != NULL)
2044 bRetval = service_ok(lp_ctx->currentService);
2046 /* if all is still well, move to the next record in the services array */
2048 /* We put this here to avoid an odd message order if messages are */
2049 /* issued by the post-processing of a previous section. */
2050 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2052 if ((loadparm.currentService = add_a_service(lp_ctx, &sDefault,
2055 DEBUG(0, ("Failed to add a new service\n"));
2064 /***************************************************************************
2065 Determine if a partcular base parameter is currentl set to the default value.
2066 ***************************************************************************/
2068 static bool is_default(int i)
2070 if (!defaults_saved)
2072 switch (parm_table[i].type) {
2074 return str_list_equal((const char **)parm_table[i].def.lvalue,
2075 (const char **)(*(char ***)parm_table[i].ptr));
2078 return strequal(parm_table[i].def.svalue,
2079 *(char **)parm_table[i].ptr);
2081 return parm_table[i].def.bvalue ==
2082 *(int *)parm_table[i].ptr;
2087 return parm_table[i].def.ivalue ==
2088 *(int *)parm_table[i].ptr;
2095 /***************************************************************************
2096 Display the contents of the global structure.
2097 ***************************************************************************/
2099 static void dump_globals(FILE *f, bool show_defaults)
2102 struct param_opt *data;
2104 fprintf(f, "# Global parameters\n[global]\n");
2106 for (i = 0; parm_table[i].label; i++)
2107 if (parm_table[i].class == P_GLOBAL &&
2108 parm_table[i].ptr &&
2109 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2110 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2112 fprintf(f, "\t%s = ", parm_table[i].label);
2113 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2116 if (loadparm.Globals.param_opt != NULL) {
2117 for (data = loadparm.Globals.param_opt; data;
2118 data = data->next) {
2119 fprintf(f, "\t%s = %s\n", data->key, data->value);
2125 /***************************************************************************
2126 Display the contents of a single services record.
2127 ***************************************************************************/
2129 static void dump_a_service(struct service * pService, FILE * f)
2132 struct param_opt *data;
2134 if (pService != &sDefault)
2135 fprintf(f, "\n[%s]\n", pService->szService);
2137 for (i = 0; parm_table[i].label; i++)
2138 if (parm_table[i].class == P_LOCAL &&
2139 parm_table[i].ptr &&
2140 (*parm_table[i].label != '-') &&
2141 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2142 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2144 if (pService == &sDefault) {
2145 if (defaults_saved && is_default(i))
2148 if (equal_parameter(parm_table[i].type,
2149 ((char *)pService) +
2151 ((char *)&sDefault) +
2156 fprintf(f, "\t%s = ", parm_table[i].label);
2157 print_parameter(&parm_table[i],
2158 ((char *)pService) + pdiff, f);
2161 if (pService->param_opt != NULL) {
2162 for (data = pService->param_opt; data; data = data->next) {
2163 fprintf(f, "\t%s = %s\n", data->key, data->value);
2168 bool lp_dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2170 struct service * pService = loadparm.ServicePtrs[snum];
2171 struct parm_struct *parm;
2174 parm = lp_parm_struct(parm_name);
2182 ptr = ((char *)pService) +
2183 PTR_DIFF(parm->ptr, &sDefault);
2185 print_parameter(parm,
2191 /***************************************************************************
2192 Return info about the next service in a service. snum==-1 gives the globals.
2193 Return NULL when out of parameters.
2194 ***************************************************************************/
2196 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2199 /* do the globals */
2200 for (; parm_table[*i].label; (*i)++) {
2201 if (parm_table[*i].class == P_SEPARATOR)
2202 return &parm_table[(*i)++];
2204 if (!parm_table[*i].ptr
2205 || (*parm_table[*i].label == '-'))
2209 && (parm_table[*i].ptr ==
2210 parm_table[(*i) - 1].ptr))
2213 return &parm_table[(*i)++];
2216 struct service *pService = loadparm.ServicePtrs[snum];
2218 for (; parm_table[*i].label; (*i)++) {
2219 if (parm_table[*i].class == P_SEPARATOR)
2220 return &parm_table[(*i)++];
2222 if (parm_table[*i].class == P_LOCAL &&
2223 parm_table[*i].ptr &&
2224 (*parm_table[*i].label != '-') &&
2226 (parm_table[*i].ptr !=
2227 parm_table[(*i) - 1].ptr)))
2230 PTR_DIFF(parm_table[*i].ptr,
2233 if (allparameters ||
2234 !equal_parameter(parm_table[*i].type,
2235 ((char *)pService) +
2237 ((char *)&sDefault) +
2240 return &parm_table[(*i)++];
2250 /***************************************************************************
2251 Return TRUE if the passed service number is within range.
2252 ***************************************************************************/
2254 bool lp_snum_ok(int iService)
2256 return (LP_SNUM_OK(iService) && loadparm.ServicePtrs[iService]->bAvailable);
2259 /***************************************************************************
2260 Auto-load some home services.
2261 ***************************************************************************/
2263 static void lp_add_auto_services(struct loadparm_context *lp_ctx,
2269 /***************************************************************************
2270 Have we loaded a services file yet?
2271 ***************************************************************************/
2273 bool lp_loaded(void)
2278 /***************************************************************************
2279 Unload unused services.
2280 ***************************************************************************/
2282 void lp_killunused(struct smbsrv_connection *smb, bool (*snumused) (struct smbsrv_connection *, int))
2285 for (i = 0; i < loadparm.iNumServices; i++) {
2289 if (!snumused || !snumused(smb, i)) {
2290 talloc_free(loadparm.ServicePtrs[i]);
2291 loadparm.ServicePtrs[i] = NULL;
2296 /***************************************************************************
2298 ***************************************************************************/
2300 void lp_killservice(int iServiceIn)
2302 if (VALID(iServiceIn)) {
2303 talloc_free(loadparm.ServicePtrs[iServiceIn]);
2304 loadparm.ServicePtrs[iServiceIn] = NULL;
2308 /***************************************************************************
2309 Initialise the global parameter structure.
2310 ***************************************************************************/
2311 bool loadparm_init(struct loadparm_context *lp_ctx)
2316 DEBUG(3, ("Initialising global parameters\n"));
2318 for (i = 0; parm_table[i].label; i++) {
2319 if ((parm_table[i].type == P_STRING ||
2320 parm_table[i].type == P_USTRING) &&
2321 parm_table[i].ptr &&
2322 !(parm_table[i].flags & FLAG_CMDLINE)) {
2323 string_set(talloc_autofree_context(),
2324 (char **)parm_table[i].ptr, "");
2328 lp_do_global_parameter(lp_ctx, "config file", dyn_CONFIGFILE);
2330 lp_do_global_parameter(lp_ctx, "share backend", "classic");
2332 lp_do_global_parameter(lp_ctx, "server role", "standalone");
2334 /* options that can be set on the command line must be initialised via
2335 the slower lp_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2337 lp_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2339 lp_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2340 myname = get_myname();
2341 lp_do_global_parameter(lp_ctx, "netbios name", myname);
2343 lp_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
2345 lp_do_global_parameter(lp_ctx, "fstype", FSTYPE_STRING);
2346 lp_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2347 lp_do_global_parameter(lp_ctx, "max connections", "-1");
2349 lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo");
2350 lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap web kdc drepl winbind");
2351 lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb");
2352 lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain");
2353 lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind");
2354 lp_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain");
2355 lp_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2356 lp_do_global_parameter(lp_ctx, "sam database", "sam.ldb");
2357 lp_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb");
2358 lp_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb");
2359 lp_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb");
2360 lp_do_global_parameter(lp_ctx, "wins database", "wins.ldb");
2361 lp_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2363 /* This hive should be dynamically generated by Samba using
2364 data from the sam, but for the moment leave it in a tdb to
2365 keep regedt32 from popping up an annoying dialog. */
2366 lp_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2368 /* using UTF8 by default allows us to support all chars */
2369 lp_do_global_parameter(lp_ctx, "unix charset", "UTF8");
2371 /* Use codepage 850 as a default for the dos character set */
2372 lp_do_global_parameter(lp_ctx, "dos charset", "CP850");
2375 * Allow the default PASSWD_CHAT to be overridden in local.h.
2377 lp_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2379 lp_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2380 lp_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2381 lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR);
2382 lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2384 lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0");
2385 lp_do_global_parameter_var(lp_ctx, "server string",
2386 "Samba %s", SAMBA_VERSION_STRING);
2388 lp_do_global_parameter_var(lp_ctx, "announce version", "%d.%d",
2389 DEFAULT_MAJOR_VERSION,
2390 DEFAULT_MINOR_VERSION);
2392 lp_do_global_parameter(lp_ctx, "password server", "*");
2394 lp_do_global_parameter(lp_ctx, "max mux", "50");
2395 lp_do_global_parameter(lp_ctx, "max xmit", "12288");
2396 lp_do_global_parameter(lp_ctx, "password level", "0");
2397 lp_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2398 lp_do_global_parameter(lp_ctx, "server min protocol", "CORE");
2399 lp_do_global_parameter(lp_ctx, "server max protocol", "NT1");
2400 lp_do_global_parameter(lp_ctx, "client min protocol", "CORE");
2401 lp_do_global_parameter(lp_ctx, "client max protocol", "NT1");
2402 lp_do_global_parameter(lp_ctx, "security", "USER");
2403 lp_do_global_parameter(lp_ctx, "paranoid server security", "True");
2404 lp_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2405 lp_do_global_parameter(lp_ctx, "ReadRaw", "True");
2406 lp_do_global_parameter(lp_ctx, "WriteRaw", "True");
2407 lp_do_global_parameter(lp_ctx, "NullPasswords", "False");
2408 lp_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2409 lp_do_global_parameter(lp_ctx, "announce as", "NT SERVER");
2411 lp_do_global_parameter(lp_ctx, "TimeServer", "False");
2412 lp_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2413 lp_do_global_parameter(lp_ctx, "Unicode", "True");
2414 lp_do_global_parameter(lp_ctx, "ClientLanManAuth", "True");
2415 lp_do_global_parameter(lp_ctx, "LanmanAuth", "True");
2416 lp_do_global_parameter(lp_ctx, "NTLMAuth", "True");
2417 lp_do_global_parameter(lp_ctx, "client use spnego principal", "False");
2419 lp_do_global_parameter(lp_ctx, "UnixExtensions", "False");
2421 lp_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2422 lp_do_global_parameter(lp_ctx, "LocalMaster", "True");
2424 lp_do_global_parameter(lp_ctx, "wins support", "False");
2425 lp_do_global_parameter(lp_ctx, "dns proxy", "True");
2427 lp_do_global_parameter(lp_ctx, "winbind separator", "\\");
2428 lp_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2429 lp_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2430 lp_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2431 lp_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
2433 lp_do_global_parameter(lp_ctx, "client signing", "Yes");
2434 lp_do_global_parameter(lp_ctx, "server signing", "auto");
2436 lp_do_global_parameter(lp_ctx, "use spnego", "True");
2438 lp_do_global_parameter(lp_ctx, "smb ports", "445 139");
2439 lp_do_global_parameter(lp_ctx, "nbt port", "137");
2440 lp_do_global_parameter(lp_ctx, "dgram port", "138");
2441 lp_do_global_parameter(lp_ctx, "cldap port", "389");
2442 lp_do_global_parameter(lp_ctx, "krb5 port", "88");
2443 lp_do_global_parameter(lp_ctx, "kpasswd port", "464");
2444 lp_do_global_parameter(lp_ctx, "web port", "901");
2445 lp_do_global_parameter(lp_ctx, "web application directory", dyn_WEBAPPSDIR);
2446 lp_do_global_parameter(lp_ctx, "jsonrpc services directory", dyn_SERVICESDIR);
2448 lp_do_global_parameter(lp_ctx, "nt status support", "True");
2450 lp_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2451 lp_do_global_parameter(lp_ctx, "min wins ttl", "10");
2453 lp_do_global_parameter(lp_ctx, "tls enabled", "True");
2454 lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2455 lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2456 lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2457 lp_do_global_parameter_var(lp_ctx, "js include", "%s", dyn_JSDIR);
2458 lp_do_global_parameter_var(lp_ctx, "setup directory", "%s",
2461 for (i = 0; parm_table[i].label; i++) {
2462 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
2463 parm_table[i].flags |= FLAG_DEFAULT;
2470 /***************************************************************************
2471 Load the services array from the services file. Return True on success,
2473 ***************************************************************************/
2479 struct param_opt *data;
2483 if (loadparm.Globals.param_opt != NULL) {
2484 struct param_opt *next;
2485 for (data=loadparm.Globals.param_opt; data; data=next) {
2487 if (data->flags & FLAG_CMDLINE) continue;
2488 DLIST_REMOVE(loadparm.Globals.param_opt, data);
2493 if (!loadparm_init(&loadparm))
2496 loadparm.bInGlobalSection = true;
2497 n2 = standard_sub_basic(talloc_autofree_context(), lp_configfile());
2498 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2500 add_to_file_list(lp_configfile(), n2);
2502 /* We get sections first, so have to start 'behind' to make up */
2503 loadparm.currentService = NULL;
2504 bRetval = pm_process(n2, do_section, do_parameter, &loadparm);
2506 /* finish up the last section */
2507 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2509 if (loadparm.currentService != NULL)
2510 bRetval = service_ok(loadparm.currentService);
2512 lp_add_auto_services(&loadparm, lp_auto_services());
2514 lp_add_hidden(&loadparm, "IPC$", "IPC");
2515 lp_add_hidden(&loadparm, "ADMIN$", "DISK");
2519 if (!loadparm.Globals.szWINSservers && loadparm.Globals.bWINSsupport) {
2520 lp_do_parameter(NULL, "wins server", "127.0.0.1");
2528 /***************************************************************************
2529 Return the max number of services.
2530 ***************************************************************************/
2532 int lp_numservices(void)
2534 return loadparm.iNumServices;
2537 /***************************************************************************
2538 Display the contents of the services array in human-readable form.
2539 ***************************************************************************/
2541 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
2546 defaults_saved = false;
2548 dump_globals(f, show_defaults);
2550 dump_a_service(&sDefault, f);
2552 for (iService = 0; iService < maxtoprint; iService++)
2553 lp_dump_one(f, show_defaults, loadparm.ServicePtrs[iService]);
2556 /***************************************************************************
2557 Display the contents of one service in human-readable form.
2558 ***************************************************************************/
2560 void lp_dump_one(FILE *f, bool show_defaults, struct service *service)
2562 if (service != NULL) {
2563 if (service->szService[0] == '\0')
2565 dump_a_service(service, f);
2569 struct service *lp_servicebynum(int snum)
2571 return loadparm.ServicePtrs[snum];
2574 struct service *lp_service(const char *service_name)
2576 int snum = lp_servicenumber(service_name);
2579 return loadparm.ServicePtrs[snum];
2582 /***************************************************************************
2583 Return the number of the service with the given name, or -1 if it doesn't
2584 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2585 getservicebyname()! This works ONLY if all services have been loaded, and
2586 does not copy the found service.
2587 ***************************************************************************/
2589 int lp_servicenumber(const char *pszServiceName)
2595 for (iService = loadparm.iNumServices - 1; iService >= 0; iService--) {
2596 if (VALID(iService) && loadparm.ServicePtrs[iService]->szService) {
2598 * The substitution here is used to support %U is
2601 serviceName = standard_sub_basic(loadparm.ServicePtrs[iService],
2602 loadparm.ServicePtrs[iService]->szService);
2603 if (strequal(serviceName, pszServiceName))
2609 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2614 int lp_find_valid_service(const char *pszServiceName)
2618 iService = lp_servicenumber(pszServiceName);
2620 if (iService >= 0 && !lp_snum_ok(iService)) {
2621 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService, pszServiceName));
2625 if (iService == -1) {
2626 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName));
2632 /*******************************************************************
2633 A useful volume label function.
2634 ********************************************************************/
2635 const char *volume_label(struct service *service)
2637 const char *ret = lp_volume(service);
2639 return lp_servicename(service);
2644 /***********************************************************
2645 If we are PDC then prefer us as DMB
2646 ************************************************************/
2648 bool lp_domain_logons(void)
2650 return (lp_server_role() == ROLE_DOMAIN_CONTROLLER);
2653 /*******************************************************************
2655 ********************************************************************/
2657 void lp_remove_service(int snum)
2659 loadparm.ServicePtrs[snum] = NULL;
2662 const char *lp_printername(struct service *service)
2664 const char *ret = _lp_printername(service);
2665 if (ret == NULL || (ret != NULL && *ret == '\0'))
2666 ret = lp_const_servicename(service);
2672 /*******************************************************************
2673 Return the max print jobs per queue.
2674 ********************************************************************/
2676 int lp_maxprintjobs(int snum)
2678 int maxjobs = LP_SNUM_OK(snum) ? loadparm.ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2679 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2680 maxjobs = PRINT_MAX_JOBID - 1;