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 static bool do_parameter(const char *, const char *, void *);
73 static bool defaults_saved = false;
76 struct param_opt *prev, *next;
83 * This structure describes global (ie., server-wide) parameters.
87 enum server_role server_role;
103 char *szWINS_CONFIG_URL;
107 char *jsonrpcServicesDir;
108 char **szPasswordServers;
109 char *szSocketOptions;
111 char **szWINSservers;
113 char *szSocketAddress;
114 char *szAnnounceVersion; /* This is initialised in init_globals */
117 char **szNetbiosAliases;
118 char *szNetbiosScope;
119 char *szDomainOtherSIDs;
120 char **szNameResolveOrder;
121 char **dcerpc_ep_servers;
122 char **server_services;
123 char *ntptr_providor;
124 char *szWinbindSeparator;
125 char *szWinbinddSocketDirectory;
126 char *szTemplateShell;
127 char *szTemplateHomedir;
128 int bWinbindSealedPipes;
129 char *webapps_directory;
144 int paranoid_server_security;
147 int announce_as; /* This is initialised in init_globals */
154 char *socket_options;
159 int bPreferredMaster;
160 int bEncryptPasswords;
162 int bObeyPamRestrictions;
167 int bBindInterfacesOnly;
169 int bNTStatusSupport;
175 int bClientPlaintextAuth;
176 int bClientLanManAuth;
177 int bClientNTLMv2Auth;
178 int client_use_spnego_principal;
184 struct param_opt *param_opt;
189 * This structure describes a single service.
191 struct loadparm_service
203 char **ntvfs_handler;
216 int iCreate_force_mode;
223 struct param_opt *param_opt;
225 char dummy[3]; /* for alignment */
229 /* This is a default service used to prime a services structure */
230 static struct loadparm_service sDefault = {
231 NULL, /* szService */
234 NULL, /* szInclude */
235 NULL, /* szPrintername */
236 NULL, /* szHostsallow */
237 NULL, /* szHostsdeny */
241 NULL, /* ntvfs_handler */
242 1000, /* iMaxPrintJobs */
243 0, /* iMaxConnections */
245 true, /* bAvailable */
246 true, /* bBrowseable */
247 true, /* bRead_only */
248 false, /* bPrint_ok */
249 false, /* bMap_system */
250 false, /* bMap_hidden */
251 true, /* bMap_archive */
252 true, /* bStrictLocking */
253 0744, /* iCreate_mask */
254 0000, /* iCreate_force_mode */
255 0755, /* iDir_mask */
256 0000, /* iDir_force_mode */
258 false, /* bMSDfsRoot */
259 false, /* bStrictSync */
260 false, /* bCIFileSystem */
261 NULL, /* Parametric options */
266 /* local variables */
267 static struct loadparm_context {
268 struct global Globals;
269 struct loadparm_service **ServicePtrs;
271 struct loadparm_service *currentService;
272 bool bInGlobalSection;
274 struct file_lists *next;
281 .currentService = NULL,
282 .bInGlobalSection = true,
287 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
289 /* prototypes for the special type handlers */
290 static bool handle_include(struct loadparm_context *lp_ctx,
291 const char *pszParmValue, char **ptr);
292 static bool handle_copy(struct loadparm_context *lp_ctx,
293 const char *pszParmValue, char **ptr);
295 static const struct enum_list enum_protocol[] = {
296 {PROTOCOL_SMB2, "SMB2"},
297 {PROTOCOL_NT1, "NT1"},
298 {PROTOCOL_LANMAN2, "LANMAN2"},
299 {PROTOCOL_LANMAN1, "LANMAN1"},
300 {PROTOCOL_CORE, "CORE"},
301 {PROTOCOL_COREPLUS, "COREPLUS"},
302 {PROTOCOL_COREPLUS, "CORE+"},
306 static const struct enum_list enum_security[] = {
307 {SEC_SHARE, "SHARE"},
312 static const struct enum_list enum_announce_as[] = {
313 {ANNOUNCE_AS_NT_SERVER, "NT"},
314 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
315 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
316 {ANNOUNCE_AS_WIN95, "win95"},
317 {ANNOUNCE_AS_WFW, "WfW"},
321 static const struct enum_list enum_bool_auto[] = {
332 /* Client-side offline caching policy types */
333 #define CSC_POLICY_MANUAL 0
334 #define CSC_POLICY_DOCUMENTS 1
335 #define CSC_POLICY_PROGRAMS 2
336 #define CSC_POLICY_DISABLE 3
338 static const struct enum_list enum_csc_policy[] = {
339 {CSC_POLICY_MANUAL, "manual"},
340 {CSC_POLICY_DOCUMENTS, "documents"},
341 {CSC_POLICY_PROGRAMS, "programs"},
342 {CSC_POLICY_DISABLE, "disable"},
346 /* SMB signing types. */
347 static const struct enum_list enum_smb_signing_vals[] = {
348 {SMB_SIGNING_OFF, "No"},
349 {SMB_SIGNING_OFF, "False"},
350 {SMB_SIGNING_OFF, "0"},
351 {SMB_SIGNING_OFF, "Off"},
352 {SMB_SIGNING_OFF, "disabled"},
353 {SMB_SIGNING_SUPPORTED, "Yes"},
354 {SMB_SIGNING_SUPPORTED, "True"},
355 {SMB_SIGNING_SUPPORTED, "1"},
356 {SMB_SIGNING_SUPPORTED, "On"},
357 {SMB_SIGNING_SUPPORTED, "enabled"},
358 {SMB_SIGNING_REQUIRED, "required"},
359 {SMB_SIGNING_REQUIRED, "mandatory"},
360 {SMB_SIGNING_REQUIRED, "force"},
361 {SMB_SIGNING_REQUIRED, "forced"},
362 {SMB_SIGNING_REQUIRED, "enforced"},
363 {SMB_SIGNING_AUTO, "auto"},
367 static const struct enum_list enum_server_role[] = {
368 {ROLE_STANDALONE, "standalone"},
369 {ROLE_DOMAIN_MEMBER, "member server"},
370 {ROLE_DOMAIN_CONTROLLER, "domain controller"},
375 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
377 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
378 * is implied in current control logic. This may change at some later time. A
379 * flag value of 0 means - show as development option only.
381 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
382 * screen in SWAT. This is used to exclude parameters as well as to squash all
383 * parameters that have been duplicated by pseudonyms.
385 static struct parm_struct parm_table[] = {
386 {"Base Options", P_SEP, P_SEPARATOR},
388 {"server role", P_ENUM, P_GLOBAL, &loadparm.Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
390 {"dos charset", P_STRING, P_GLOBAL, &dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
391 {"unix charset", P_STRING, P_GLOBAL, &unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"ncalrpc dir", P_STRING, P_GLOBAL, &loadparm.Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"display charset", P_STRING, P_GLOBAL, &display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
394 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
395 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
396 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
397 {"workgroup", P_USTRING, P_GLOBAL, &loadparm.Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
398 {"realm", P_STRING, P_GLOBAL, &loadparm.Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"netbios name", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"netbios aliases", P_LIST, P_GLOBAL, &loadparm.Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"netbios scope", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
402 {"server string", P_STRING, P_GLOBAL, &loadparm.Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
403 {"interfaces", P_LIST, P_GLOBAL, &loadparm.Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
404 {"bind interfaces only", P_BOOL, P_GLOBAL, &loadparm.Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
406 {"ntptr providor", P_STRING, P_GLOBAL, &loadparm.Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
407 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &loadparm.Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
408 {"server services", P_LIST, P_GLOBAL, &loadparm.Globals.server_services, NULL, NULL, FLAG_ADVANCED},
410 {"Security Options", P_SEP, P_SEPARATOR},
412 {"security", P_ENUM, P_GLOBAL, &loadparm.Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
413 {"encrypt passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
414 {"null passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"obey pam restrictions", P_BOOL, P_GLOBAL, &loadparm.Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"password server", P_LIST, P_GLOBAL, &loadparm.Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
417 {"sam database", P_STRING, P_GLOBAL, &loadparm.Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"secrets database", P_STRING, P_GLOBAL, &loadparm.Globals.szSECRETS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"spoolss database", P_STRING, P_GLOBAL, &loadparm.Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"wins config database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"wins database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"private dir", P_STRING, P_GLOBAL, &loadparm.Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"passwd chat", P_STRING, P_GLOBAL, &loadparm.Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"password level", P_INTEGER, P_GLOBAL, &loadparm.Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"ntlm auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"client lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"client plaintext auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
430 {"client use spnego principal", P_BOOL, P_GLOBAL, &loadparm.Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
432 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
434 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
435 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
436 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
437 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
439 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
440 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
442 {"Logging Options", P_SEP, P_SEPARATOR},
444 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
446 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"Protocol Options", P_SEP, P_SEPARATOR},
450 {"smb ports", P_LIST, P_GLOBAL, &loadparm.Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"nbt port", P_INTEGER, P_GLOBAL, &loadparm.Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"dgram port", P_INTEGER, P_GLOBAL, &loadparm.Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"cldap port", P_INTEGER, P_GLOBAL, &loadparm.Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"krb5 port", P_INTEGER, P_GLOBAL, &loadparm.Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"kpasswd port", P_INTEGER, P_GLOBAL, &loadparm.Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"web port", P_INTEGER, P_GLOBAL, &loadparm.Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"tls enabled", P_BOOL, P_GLOBAL, &loadparm.Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"tls keyfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"tls certfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
460 {"tls cafile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
461 {"tls crlfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
462 {"tls dh params file", P_STRING, P_GLOBAL, &loadparm.Globals.tls_dhpfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
463 {"web application directory", P_STRING, P_GLOBAL, &loadparm.Globals.webapps_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
464 {"large readwrite", P_BOOL, P_GLOBAL, &loadparm.Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
465 {"server max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
466 {"server min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
467 {"client max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
468 {"client min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
469 {"unicode", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
470 {"read raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
471 {"write raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
472 {"disable netbios", P_BOOL, P_GLOBAL, &loadparm.Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"nt status support", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"announce version", P_STRING, P_GLOBAL, &loadparm.Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
477 {"announce as", P_ENUM, P_GLOBAL, &loadparm.Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
478 {"max mux", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
479 {"max xmit", P_BYTES, P_GLOBAL, &loadparm.Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
481 {"name resolve order", P_LIST, P_GLOBAL, &loadparm.Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
482 {"max wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
483 {"min wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
484 {"time server", P_BOOL, P_GLOBAL, &loadparm.Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
485 {"unix extensions", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
486 {"use spnego", P_BOOL, P_GLOBAL, &loadparm.Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
487 {"server signing", P_ENUM, P_GLOBAL, &loadparm.Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
488 {"client signing", P_ENUM, P_GLOBAL, &loadparm.Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
489 {"rpc big endian", P_BOOL, P_GLOBAL, &loadparm.Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
491 {"Tuning Options", P_SEP, P_SEPARATOR},
493 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
494 {"paranoid server security", P_BOOL, P_GLOBAL, &loadparm.Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
495 {"socket options", P_STRING, P_GLOBAL, &loadparm.Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
497 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
498 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
500 {"Printing Options", P_SEP, P_SEPARATOR},
502 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
503 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
504 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
506 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
507 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
509 {"Filename Handling", P_SEP, P_SEPARATOR},
511 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
512 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
513 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
515 {"Domain Options", P_SEP, P_SEPARATOR},
517 {"Logon Options", P_SEP, P_SEPARATOR},
520 {"Browse Options", P_SEP, P_SEPARATOR},
522 {"preferred master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
523 {"prefered master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
524 {"local master", P_BOOL, P_GLOBAL, &loadparm.Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
525 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
526 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
528 {"WINS Options", P_SEP, P_SEPARATOR},
530 {"wins server", P_LIST, P_GLOBAL, &loadparm.Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
531 {"wins support", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
532 {"dns proxy", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
533 {"wins hook", P_STRING, P_GLOBAL, &loadparm.Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
535 {"Locking Options", P_SEP, P_SEPARATOR},
537 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
539 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
541 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
543 {"config file", P_STRING, P_GLOBAL, &loadparm.Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
544 {"share backend", P_STRING, P_GLOBAL, &loadparm.Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"preload", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"auto services", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"lock dir", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_HIDE},
548 {"lock directory", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"modules dir", P_STRING, P_GLOBAL, &loadparm.Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"pid directory", P_STRING, P_GLOBAL, &loadparm.Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"js include", P_LIST, P_GLOBAL, &loadparm.Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"jsonrpc services directory", P_STRING, P_GLOBAL, &loadparm.Globals.jsonrpcServicesDir, 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_webapps_directory, &loadparm.Globals.webapps_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_GLOBAL_STRING(lp_jsonrpc_services_dir, &loadparm.Globals.jsonrpcServicesDir)
770 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
771 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
772 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
773 static FN_LOCAL_STRING(_lp_printername, szPrintername)
774 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
775 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
776 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
777 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
778 static FN_LOCAL_STRING(lp_volume, volume)
779 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
780 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
781 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
782 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
783 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
784 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
785 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
786 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
787 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
788 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
789 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
790 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
791 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
792 _PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
793 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
794 _PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
795 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
796 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &loadparm.Globals.server_signing)
797 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &loadparm.Globals.client_signing)
799 /* local prototypes */
800 static int map_parameter(const char *pszParmName);
801 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
802 const char *pszServiceName);
803 static void copy_service(struct loadparm_service *pserviceDest,
804 struct loadparm_service *pserviceSource,
806 static bool service_ok(struct loadparm_service *service);
807 static bool do_section(const char *pszSectionName, void *);
808 static void init_copymap(struct loadparm_service *pservice);
810 /* This is a helper function for parametrical options support. */
811 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
812 /* Actual parametrical functions are quite simple */
813 const char *lp_get_parametric(struct loadparm_service *service,
814 const char *type, const char *option)
817 struct param_opt *data;
819 data = (service == NULL ? loadparm.Globals.param_opt : service->param_opt);
821 asprintf(&vfskey, "%s:%s", type, option);
825 if (strcmp(data->key, vfskey) == 0) {
832 if (service != NULL) {
833 /* Try to fetch the same option but from globals */
834 /* but only if we are not already working with Globals */
835 for (data = loadparm.Globals.param_opt; data;
837 if (strcmp(data->key, vfskey) == 0) {
850 /*******************************************************************
851 convenience routine to return int parameters.
852 ********************************************************************/
853 static int lp_int(const char *s)
857 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
861 return strtol(s, NULL, 0);
864 /*******************************************************************
865 convenience routine to return unsigned long parameters.
866 ********************************************************************/
867 static int lp_ulong(const char *s)
871 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
875 return strtoul(s, NULL, 0);
878 /*******************************************************************
879 convenience routine to return unsigned long parameters.
880 ********************************************************************/
881 static double lp_double(const char *s)
885 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
889 return strtod(s, NULL);
892 /*******************************************************************
893 convenience routine to return boolean parameters.
894 ********************************************************************/
895 static bool lp_bool(const char *s)
900 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
904 if (!set_boolean(s, &ret)) {
905 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
913 /* Return parametric option from a given service. Type is a part of option before ':' */
914 /* Parametric option has following syntax: 'Type: option = value' */
915 /* Returned value is allocated in 'lp_talloc' context */
917 const char *lp_parm_string(struct loadparm_service *service, const char *type,
920 const char *value = lp_get_parametric(service, type, option);
923 return lp_string(value);
928 /* Return parametric option from a given service. Type is a part of option before ':' */
929 /* Parametric option has following syntax: 'Type: option = value' */
930 /* Returned value is allocated in 'lp_talloc' context */
932 const char **lp_parm_string_list(struct loadparm_service *service,
934 const char *option, const char *separator)
936 const char *value = lp_get_parametric(service, type, option);
939 return str_list_make(talloc_autofree_context(), value,
945 /* Return parametric option from a given service. Type is a part of option before ':' */
946 /* Parametric option has following syntax: 'Type: option = value' */
948 int lp_parm_int(struct loadparm_service *service, const char *type,
949 const char *option, int default_v)
951 const char *value = lp_get_parametric(service, type, option);
954 return lp_int(value);
959 /* Return parametric option from a given service. Type is a part of
961 * Parametric option has following syntax: 'Type: option = value'.
964 int lp_parm_bytes(struct loadparm_service *service, const char *type,
965 const char *option, int default_v)
969 const char *value = lp_get_parametric(service, type, option);
971 if (value && conv_str_size(value, &bval)) {
972 if (bval <= INT_MAX) {
980 /* Return parametric option from a given service. Type is a part of option before ':' */
981 /* Parametric option has following syntax: 'Type: option = value' */
983 unsigned long lp_parm_ulong(struct loadparm_service *service, const char *type,
984 const char *option, unsigned long default_v)
986 const char *value = lp_get_parametric(service, type, option);
989 return lp_ulong(value);
995 double lp_parm_double(struct loadparm_service *service, const char *type,
996 const char *option, double default_v)
998 const char *value = lp_get_parametric(service, type, option);
1001 return lp_double(value);
1006 /* Return parametric option from a given service. Type is a part of option before ':' */
1007 /* Parametric option has following syntax: 'Type: option = value' */
1009 bool lp_parm_bool(struct loadparm_service *service, const char *type,
1010 const char *option, bool default_v)
1012 const char *value = lp_get_parametric(service, type, option);
1015 return lp_bool(value);
1021 /***************************************************************************
1022 Initialise a service to the defaults.
1023 ***************************************************************************/
1025 static struct loadparm_service *init_service(TALLOC_CTX *mem_ctx)
1027 struct loadparm_service *pservice =
1028 talloc_zero(mem_ctx, struct loadparm_service);
1029 copy_service(pservice, &sDefault, NULL);
1033 /***************************************************************************
1034 Add a new service to the services array initialising it with the given
1036 ***************************************************************************/
1038 static struct loadparm_service *add_a_service(struct loadparm_context *lp_ctx,
1039 const struct loadparm_service *pservice,
1043 struct loadparm_service tservice;
1044 int num_to_alloc = lp_ctx->iNumServices + 1;
1045 struct param_opt *data, *pdata;
1047 tservice = *pservice;
1049 /* it might already exist */
1051 struct loadparm_service *service = getservicebyname(lp_ctx,
1053 if (service != NULL) {
1054 /* Clean all parametric options for service */
1055 /* They will be added during parsing again */
1056 data = service->param_opt;
1062 service->param_opt = NULL;
1067 /* find an invalid one */
1068 for (i = 0; i < lp_ctx->iNumServices; i++)
1069 if (lp_ctx->ServicePtrs[i] == NULL)
1072 /* if not, then create one */
1073 if (i == lp_ctx->iNumServices) {
1074 struct loadparm_service **tsp;
1076 tsp = realloc_p(lp_ctx->ServicePtrs, struct loadparm_service *,
1080 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1084 lp_ctx->ServicePtrs = tsp;
1085 lp_ctx->ServicePtrs[lp_ctx->iNumServices] = NULL;
1088 lp_ctx->iNumServices++;
1091 lp_ctx->ServicePtrs[i] = init_service(talloc_autofree_context());
1092 if (lp_ctx->ServicePtrs[i] == NULL) {
1093 DEBUG(0,("add_a_service: out of memory!\n"));
1096 copy_service(lp_ctx->ServicePtrs[i], &tservice, NULL);
1098 string_set(lp_ctx->ServicePtrs[i], &lp_ctx->ServicePtrs[i]->szService, name);
1099 return lp_ctx->ServicePtrs[i];
1102 /***************************************************************************
1103 Add a new home service, with the specified home directory, defaults coming
1105 ***************************************************************************/
1107 bool lp_add_home(struct loadparm_context *lp_ctx,
1108 const char *pszHomename,
1109 struct loadparm_service *default_service,
1110 const char *user, const char *pszHomedir)
1112 struct loadparm_service *service;
1115 service = add_a_service(lp_ctx, default_service, pszHomename);
1117 if (service == NULL)
1120 if (!(*(default_service->szPath))
1121 || strequal(default_service->szPath, sDefault.szPath)) {
1122 pstrcpy(newHomedir, pszHomedir);
1124 pstrcpy(newHomedir, lp_pathname(default_service));
1125 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1128 string_set(service, &service->szPath, newHomedir);
1130 if (!(*(service->comment))) {
1131 service->comment = talloc_asprintf(service, "Home directory of %s", user);
1133 service->bAvailable = default_service->bAvailable;
1134 service->bBrowseable = default_service->bBrowseable;
1136 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
1137 pszHomename, user, newHomedir));
1142 /***************************************************************************
1143 Add a new service, based on an old one.
1144 ***************************************************************************/
1146 struct loadparm_service *lp_add_service(struct loadparm_context *lp_ctx,
1147 const char *pszService,
1148 struct loadparm_service *default_service)
1150 return add_a_service(lp_ctx, default_service, pszService);
1153 /***************************************************************************
1154 Add the IPC service.
1155 ***************************************************************************/
1157 static bool lp_add_hidden(struct loadparm_context *lp_ctx, const char *name,
1160 struct loadparm_service *service = add_a_service(lp_ctx, &sDefault, name);
1162 if (service == NULL)
1165 string_set(service, &service->szPath, tmpdir());
1167 service->comment = talloc_asprintf(service, "%s Service (%s)",
1168 fstype, loadparm.Globals.szServerString);
1169 string_set(service, &service->fstype, fstype);
1170 service->iMaxConnections = -1;
1171 service->bAvailable = true;
1172 service->bRead_only = true;
1173 service->bPrint_ok = false;
1174 service->bBrowseable = false;
1176 if (strcasecmp(fstype, "IPC") == 0) {
1177 lp_do_service_parameter(lp_ctx, service, "ntvfs handler",
1181 DEBUG(3, ("adding hidden service %s\n", name));
1186 /***************************************************************************
1187 Add a new printer service, with defaults coming from service iFrom.
1188 ***************************************************************************/
1190 bool lp_add_printer(struct loadparm_context *lp_ctx,
1191 const char *pszPrintername,
1192 struct loadparm_service *default_service)
1194 const char *comment = "From Printcap";
1195 struct loadparm_service *service;
1196 service = add_a_service(lp_ctx, default_service, pszPrintername);
1198 if (service == NULL)
1201 /* note that we do NOT default the availability flag to True - */
1202 /* we take it from the default service passed. This allows all */
1203 /* dynamic printers to be disabled by disabling the [printers] */
1204 /* entry (if/when the 'available' keyword is implemented!). */
1206 /* the printer name is set to the service name. */
1207 string_set(service, &service->szPrintername, pszPrintername);
1208 string_set(service, &service->comment, comment);
1209 service->bBrowseable = sDefault.bBrowseable;
1210 /* Printers cannot be read_only. */
1211 service->bRead_only = false;
1212 /* Printer services must be printable. */
1213 service->bPrint_ok = true;
1215 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1220 /***************************************************************************
1221 Map a parameter's string representation to something we can use.
1222 Returns False if the parameter string is not recognised, else TRUE.
1223 ***************************************************************************/
1225 static int map_parameter(const char *pszParmName)
1229 if (*pszParmName == '-')
1232 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1233 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1236 /* Warn only if it isn't parametric option */
1237 if (strchr(pszParmName, ':') == NULL)
1238 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1239 /* We do return 'fail' for parametric options as well because they are
1240 stored in different storage
1247 return the parameter structure for a parameter
1249 struct parm_struct *lp_parm_struct(const char *name)
1251 int parmnum = map_parameter(name);
1252 if (parmnum == -1) return NULL;
1253 return &parm_table[parmnum];
1257 return the parameter pointer for a parameter
1259 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
1261 if (service == NULL)
1264 return ((char *)service) + PTR_DIFF(parm->ptr, &sDefault);
1267 /***************************************************************************
1268 Find a service by name. Otherwise works like get_service.
1269 ***************************************************************************/
1271 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
1272 const char *pszServiceName)
1276 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
1277 if (lp_ctx->ServicePtrs[iService] != NULL &&
1278 strwicmp(lp_ctx->ServicePtrs[iService]->szService, pszServiceName) == 0) {
1279 return lp_ctx->ServicePtrs[iService];
1285 /***************************************************************************
1286 Copy a service structure to another.
1287 If pcopymapDest is NULL then copy all fields
1288 ***************************************************************************/
1290 static void copy_service(struct loadparm_service *pserviceDest,
1291 struct loadparm_service *pserviceSource,
1295 bool bcopyall = (pcopymapDest == NULL);
1296 struct param_opt *data, *pdata, *paramo;
1299 for (i = 0; parm_table[i].label; i++)
1300 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1301 (bcopyall || pcopymapDest[i])) {
1302 void *def_ptr = parm_table[i].ptr;
1304 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1307 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1310 switch (parm_table[i].type) {
1312 *(int *)dest_ptr = *(int *)src_ptr;
1318 *(int *)dest_ptr = *(int *)src_ptr;
1322 string_set(pserviceDest,
1328 string_set(pserviceDest,
1331 strupper(*(char **)dest_ptr);
1334 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1335 *(const char ***)src_ptr);
1343 init_copymap(pserviceDest);
1344 if (pserviceSource->copymap)
1345 memcpy((void *)pserviceDest->copymap,
1346 (void *)pserviceSource->copymap,
1347 sizeof(int) * NUMPARAMETERS);
1350 data = pserviceSource->param_opt;
1353 pdata = pserviceDest->param_opt;
1354 /* Traverse destination */
1356 /* If we already have same option, override it */
1357 if (strcmp(pdata->key, data->key) == 0) {
1358 talloc_free(pdata->value);
1359 pdata->value = talloc_reference(pdata,
1364 pdata = pdata->next;
1367 paramo = talloc(pserviceDest, struct param_opt);
1370 paramo->key = talloc_reference(paramo, data->key);
1371 paramo->value = talloc_reference(paramo, data->value);
1372 DLIST_ADD(pserviceDest->param_opt, paramo);
1378 /***************************************************************************
1379 Check a service for consistency. Return False if the service is in any way
1380 incomplete or faulty, else True.
1381 ***************************************************************************/
1383 static bool service_ok(struct loadparm_service *service)
1388 if (service->szService[0] == '\0') {
1389 DEBUG(0, ("The following message indicates an internal error:\n"));
1390 DEBUG(0, ("No service name in service entry.\n"));
1394 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1395 /* I can't see why you'd want a non-printable printer service... */
1396 if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
1397 if (!service->bPrint_ok) {
1398 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1399 service->szService));
1400 service->bPrint_ok = true;
1402 /* [printers] service must also be non-browsable. */
1403 if (service->bBrowseable)
1404 service->bBrowseable = false;
1407 /* If a service is flagged unavailable, log the fact at level 0. */
1408 if (!service->bAvailable)
1409 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1410 service->szService));
1416 /*******************************************************************
1417 Keep a linked list of all config files so we know when one has changed
1418 it's date and needs to be reloaded.
1419 ********************************************************************/
1421 static void add_to_file_list(struct loadparm_context *lp_ctx,
1422 const char *fname, const char *subfname)
1424 struct file_lists *f = lp_ctx->file_lists;
1427 if (f->name && !strcmp(f->name, fname))
1433 f = talloc(talloc_autofree_context(), struct file_lists);
1436 f->next = lp_ctx->file_lists;
1437 f->name = talloc_strdup(f, fname);
1442 f->subfname = talloc_strdup(f, subfname);
1447 lp_ctx->file_lists = f;
1448 f->modtime = file_modtime(subfname);
1450 time_t t = file_modtime(subfname);
1456 /*******************************************************************
1457 Check if a config file has changed date.
1458 ********************************************************************/
1460 bool lp_file_list_changed(struct loadparm_context *lp_ctx)
1462 struct file_lists *f;
1463 DEBUG(6, ("lp_file_list_changed()\n"));
1465 for (f = lp_ctx->file_lists; f != NULL; f = f->next) {
1469 n2 = standard_sub_basic(talloc_autofree_context(), f->name);
1471 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1472 f->name, n2, ctime(&f->modtime)));
1474 mod_time = file_modtime(n2);
1476 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1477 DEBUGADD(6, ("file %s modified: %s\n", n2,
1479 f->modtime = mod_time;
1480 talloc_free(f->subfname);
1481 f->subfname = talloc_strdup(f, n2);
1488 /***************************************************************************
1489 Handle the include operation.
1490 ***************************************************************************/
1492 static bool handle_include(struct loadparm_context *lp_ctx,
1493 const char *pszParmValue, char **ptr)
1495 char *fname = standard_sub_basic(talloc_autofree_context(),
1498 add_to_file_list(lp_ctx, pszParmValue, fname);
1500 string_set(talloc_autofree_context(), ptr, fname);
1502 if (file_exist(fname))
1503 return pm_process(fname, do_section, do_parameter, lp_ctx);
1505 DEBUG(2, ("Can't find include file %s\n", fname));
1510 /***************************************************************************
1511 Handle the interpretation of the copy parameter.
1512 ***************************************************************************/
1514 static bool handle_copy(struct loadparm_context *lp_ctx,
1515 const char *pszParmValue, char **ptr)
1518 struct loadparm_service *serviceTemp;
1520 string_set(talloc_autofree_context(), ptr, pszParmValue);
1524 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1526 if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) {
1527 if (serviceTemp == lp_ctx->currentService) {
1528 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1530 copy_service(lp_ctx->currentService,
1532 lp_ctx->currentService->copymap);
1536 DEBUG(0, ("Unable to copy service - source not found: %s\n",
1544 /***************************************************************************
1545 Initialise a copymap.
1546 ***************************************************************************/
1548 static void init_copymap(struct loadparm_service *pservice)
1551 talloc_free(pservice->copymap);
1552 pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS);
1553 if (pservice->copymap == NULL) {
1555 ("Couldn't allocate copymap!! (size %d)\n",
1556 (int)NUMPARAMETERS));
1559 for (i = 0; i < NUMPARAMETERS; i++)
1560 pservice->copymap[i] = true;
1563 /***************************************************************************
1564 Process a parametric option
1565 ***************************************************************************/
1566 static bool lp_do_parameter_parametric(struct loadparm_service *service,
1567 const char *pszParmName,
1568 const char *pszParmValue, int flags)
1570 struct param_opt *paramo, *data;
1572 TALLOC_CTX *mem_ctx;
1574 while (isspace((unsigned char)*pszParmName)) {
1578 name = strdup(pszParmName);
1579 if (!name) return false;
1583 if (service == NULL) {
1584 data = loadparm.Globals.param_opt;
1585 mem_ctx = talloc_autofree_context();
1587 data = service->param_opt;
1591 /* Traverse destination */
1592 for (paramo=data; paramo; paramo=paramo->next) {
1593 /* If we already have the option set, override it unless
1594 it was a command line option and the new one isn't */
1595 if (strcmp(paramo->key, name) == 0) {
1596 if ((paramo->flags & FLAG_CMDLINE) &&
1597 !(flags & FLAG_CMDLINE)) {
1601 talloc_free(paramo->value);
1602 paramo->value = talloc_strdup(paramo, pszParmValue);
1603 paramo->flags = flags;
1609 paramo = talloc(mem_ctx, struct param_opt);
1612 paramo->key = talloc_strdup(paramo, name);
1613 paramo->value = talloc_strdup(paramo, pszParmValue);
1614 paramo->flags = flags;
1615 if (service == NULL) {
1616 DLIST_ADD(loadparm.Globals.param_opt, paramo);
1618 DLIST_ADD(service->param_opt, paramo);
1626 static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1627 const char *pszParmName, const char *pszParmValue,
1628 struct loadparm_context *lp_ctx)
1631 /* if it is a special case then go ahead */
1632 if (parm_table[parmnum].special) {
1633 parm_table[parmnum].special(lp_ctx, pszParmValue,
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, lp_ctx);
1754 bool lp_do_service_parameter(struct loadparm_context *lp_ctx,
1755 struct loadparm_service *service,
1756 const char *pszParmName, const char *pszParmValue)
1758 void *def_ptr = NULL;
1761 int parmnum = map_parameter(pszParmName);
1764 if (strchr(pszParmName, ':')) {
1765 return lp_do_parameter_parametric(service, pszParmName, pszParmValue, 0);
1767 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1771 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1772 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1776 /* if the flag has been set on the command line, then don't allow override,
1777 but don't report an error */
1778 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1782 def_ptr = parm_table[parmnum].ptr;
1784 if (parm_table[parmnum].class == P_GLOBAL) {
1786 ("Global parameter %s found in service section!\n",
1790 parm_ptr = ((char *)service) + PTR_DIFF(def_ptr, &sDefault);
1792 if (!service->copymap)
1793 init_copymap(service);
1795 /* this handles the aliases - set the copymap for other
1796 * entries with the same data pointer */
1797 for (i = 0; parm_table[i].label; i++)
1798 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1799 service->copymap[i] = false;
1801 return set_variable(service, parmnum, parm_ptr, pszParmName,
1802 pszParmValue, lp_ctx);
1805 /***************************************************************************
1806 Process a parameter.
1807 ***************************************************************************/
1809 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1812 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
1814 if (lp_ctx->bInGlobalSection)
1815 return lp_do_global_parameter(lp_ctx, pszParmName,
1818 return lp_do_service_parameter(lp_ctx, lp_ctx->currentService,
1819 pszParmName, pszParmValue);
1823 variable argument do parameter
1825 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
1826 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx,
1827 const char *pszParmName, const char *fmt, ...)
1834 s = talloc_vasprintf(NULL, fmt, ap);
1836 ret = lp_do_global_parameter(lp_ctx, pszParmName, s);
1843 set a parameter from the commandline - this is called from command line parameter
1844 parsing code. It sets the parameter then marks the parameter as unable to be modified
1845 by smb.conf processing
1847 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1849 int parmnum = map_parameter(pszParmName);
1852 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1855 if (parmnum < 0 && strchr(pszParmName, ':')) {
1856 /* set a parametric option */
1857 return lp_do_parameter_parametric(NULL, pszParmName, pszParmValue, FLAG_CMDLINE);
1861 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1865 /* reset the CMDLINE flag in case this has been called before */
1866 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1868 if (!lp_do_global_parameter(&loadparm, pszParmName, pszParmValue)) {
1872 parm_table[parmnum].flags |= FLAG_CMDLINE;
1874 /* we have to also set FLAG_CMDLINE on aliases */
1875 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1876 parm_table[i].flags |= FLAG_CMDLINE;
1878 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1879 parm_table[i].flags |= FLAG_CMDLINE;
1886 set a option from the commandline in 'a=b' format. Use to support --option
1888 bool lp_set_option(const char *option)
1906 ret = lp_set_cmdline(s, p+1);
1912 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1914 /***************************************************************************
1915 Print a parameter of the specified type.
1916 ***************************************************************************/
1918 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1924 for (i = 0; p->enum_list[i].name; i++) {
1925 if (*(int *)ptr == p->enum_list[i].value) {
1927 p->enum_list[i].name);
1934 fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr));
1939 fprintf(f, "%d", *(int *)ptr);
1943 fprintf(f, "0%o", *(int *)ptr);
1947 if ((char ***)ptr && *(char ***)ptr) {
1948 char **list = *(char ***)ptr;
1950 for (; *list; list++)
1951 fprintf(f, "%s%s", *list,
1952 ((*(list+1))?", ":""));
1958 if (*(char **)ptr) {
1959 fprintf(f, "%s", *(char **)ptr);
1967 /***************************************************************************
1968 Check if two parameters are equal.
1969 ***************************************************************************/
1971 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
1975 return (*((int *)ptr1) == *((int *)ptr2));
1981 return (*((int *)ptr1) == *((int *)ptr2));
1984 return str_list_equal((const char **)(*(char ***)ptr1),
1985 (const char **)(*(char ***)ptr2));
1990 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1995 return (p1 == p2 || strequal(p1, p2));
2003 /***************************************************************************
2004 Process a new section (service). At this stage all sections are services.
2005 Later we'll have special sections that permit server parameters to be set.
2006 Returns True on success, False on failure.
2007 ***************************************************************************/
2009 static bool do_section(const char *pszSectionName, void *userdata)
2011 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2013 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2014 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2017 /* if we've just struck a global section, note the fact. */
2018 lp_ctx->bInGlobalSection = isglobal;
2020 /* check for multiple global sections */
2021 if (lp_ctx->bInGlobalSection) {
2022 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2026 /* if we have a current service, tidy it up before moving on */
2029 if (lp_ctx->currentService != NULL)
2030 bRetval = service_ok(lp_ctx->currentService);
2032 /* if all is still well, move to the next record in the services array */
2034 /* We put this here to avoid an odd message order if messages are */
2035 /* issued by the post-processing of a previous section. */
2036 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2038 if ((loadparm.currentService = add_a_service(lp_ctx, &sDefault,
2041 DEBUG(0, ("Failed to add a new service\n"));
2050 /***************************************************************************
2051 Determine if a partcular base parameter is currentl set to the default value.
2052 ***************************************************************************/
2054 static bool is_default(int i)
2056 if (!defaults_saved)
2058 switch (parm_table[i].type) {
2060 return str_list_equal((const char **)parm_table[i].def.lvalue,
2061 (const char **)(*(char ***)parm_table[i].ptr));
2064 return strequal(parm_table[i].def.svalue,
2065 *(char **)parm_table[i].ptr);
2067 return parm_table[i].def.bvalue ==
2068 *(int *)parm_table[i].ptr;
2073 return parm_table[i].def.ivalue ==
2074 *(int *)parm_table[i].ptr;
2081 /***************************************************************************
2082 Display the contents of the global structure.
2083 ***************************************************************************/
2085 static void dump_globals(FILE *f, bool show_defaults)
2088 struct param_opt *data;
2090 fprintf(f, "# Global parameters\n[global]\n");
2092 for (i = 0; parm_table[i].label; i++)
2093 if (parm_table[i].class == P_GLOBAL &&
2094 parm_table[i].ptr &&
2095 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2096 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2098 fprintf(f, "\t%s = ", parm_table[i].label);
2099 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2102 if (loadparm.Globals.param_opt != NULL) {
2103 for (data = loadparm.Globals.param_opt; data;
2104 data = data->next) {
2105 fprintf(f, "\t%s = %s\n", data->key, data->value);
2111 /***************************************************************************
2112 Display the contents of a single services record.
2113 ***************************************************************************/
2115 static void dump_a_service(struct loadparm_service * pService, FILE * f)
2118 struct param_opt *data;
2120 if (pService != &sDefault)
2121 fprintf(f, "\n[%s]\n", pService->szService);
2123 for (i = 0; parm_table[i].label; i++)
2124 if (parm_table[i].class == P_LOCAL &&
2125 parm_table[i].ptr &&
2126 (*parm_table[i].label != '-') &&
2127 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2128 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2130 if (pService == &sDefault) {
2131 if (defaults_saved && is_default(i))
2134 if (equal_parameter(parm_table[i].type,
2135 ((char *)pService) +
2137 ((char *)&sDefault) +
2142 fprintf(f, "\t%s = ", parm_table[i].label);
2143 print_parameter(&parm_table[i],
2144 ((char *)pService) + pdiff, f);
2147 if (pService->param_opt != NULL) {
2148 for (data = pService->param_opt; data; data = data->next) {
2149 fprintf(f, "\t%s = %s\n", data->key, data->value);
2154 bool lp_dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2156 struct loadparm_service * pService = loadparm.ServicePtrs[snum];
2157 struct parm_struct *parm;
2160 parm = lp_parm_struct(parm_name);
2168 ptr = ((char *)pService) +
2169 PTR_DIFF(parm->ptr, &sDefault);
2171 print_parameter(parm,
2177 /***************************************************************************
2178 Return info about the next service in a service. snum==-1 gives the globals.
2179 Return NULL when out of parameters.
2180 ***************************************************************************/
2182 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2185 /* do the globals */
2186 for (; parm_table[*i].label; (*i)++) {
2187 if (parm_table[*i].class == P_SEPARATOR)
2188 return &parm_table[(*i)++];
2190 if (!parm_table[*i].ptr
2191 || (*parm_table[*i].label == '-'))
2195 && (parm_table[*i].ptr ==
2196 parm_table[(*i) - 1].ptr))
2199 return &parm_table[(*i)++];
2202 struct loadparm_service *pService = loadparm.ServicePtrs[snum];
2204 for (; parm_table[*i].label; (*i)++) {
2205 if (parm_table[*i].class == P_SEPARATOR)
2206 return &parm_table[(*i)++];
2208 if (parm_table[*i].class == P_LOCAL &&
2209 parm_table[*i].ptr &&
2210 (*parm_table[*i].label != '-') &&
2212 (parm_table[*i].ptr !=
2213 parm_table[(*i) - 1].ptr)))
2216 PTR_DIFF(parm_table[*i].ptr,
2219 if (allparameters ||
2220 !equal_parameter(parm_table[*i].type,
2221 ((char *)pService) +
2223 ((char *)&sDefault) +
2226 return &parm_table[(*i)++];
2236 /***************************************************************************
2237 Auto-load some home services.
2238 ***************************************************************************/
2240 static void lp_add_auto_services(struct loadparm_context *lp_ctx,
2246 /***************************************************************************
2247 Have we loaded a services file yet?
2248 ***************************************************************************/
2250 bool lp_loaded(void)
2255 /***************************************************************************
2256 Unload unused services.
2257 ***************************************************************************/
2259 void lp_killunused(struct smbsrv_connection *smb, bool (*snumused) (struct smbsrv_connection *, int))
2262 for (i = 0; i < loadparm.iNumServices; i++) {
2263 if (loadparm.ServicePtrs[i] == NULL)
2266 if (!snumused || !snumused(smb, i)) {
2267 talloc_free(loadparm.ServicePtrs[i]);
2268 loadparm.ServicePtrs[i] = NULL;
2273 /***************************************************************************
2274 Initialise the global parameter structure.
2275 ***************************************************************************/
2276 bool loadparm_init(struct loadparm_context *lp_ctx)
2281 DEBUG(3, ("Initialising global parameters\n"));
2283 for (i = 0; parm_table[i].label; i++) {
2284 if ((parm_table[i].type == P_STRING ||
2285 parm_table[i].type == P_USTRING) &&
2286 parm_table[i].ptr &&
2287 !(parm_table[i].flags & FLAG_CMDLINE)) {
2288 string_set(talloc_autofree_context(),
2289 (char **)parm_table[i].ptr, "");
2293 lp_do_global_parameter(lp_ctx, "config file", dyn_CONFIGFILE);
2295 lp_do_global_parameter(lp_ctx, "share backend", "classic");
2297 lp_do_global_parameter(lp_ctx, "server role", "standalone");
2299 /* options that can be set on the command line must be initialised via
2300 the slower lp_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2302 lp_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2304 lp_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2305 myname = get_myname();
2306 lp_do_global_parameter(lp_ctx, "netbios name", myname);
2308 lp_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
2310 lp_do_global_parameter(lp_ctx, "fstype", FSTYPE_STRING);
2311 lp_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2312 lp_do_global_parameter(lp_ctx, "max connections", "-1");
2314 lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo");
2315 lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap web kdc drepl winbind");
2316 lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb");
2317 lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain");
2318 lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind");
2319 lp_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain");
2320 lp_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2321 lp_do_global_parameter(lp_ctx, "sam database", "sam.ldb");
2322 lp_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb");
2323 lp_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb");
2324 lp_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb");
2325 lp_do_global_parameter(lp_ctx, "wins database", "wins.ldb");
2326 lp_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2328 /* This hive should be dynamically generated by Samba using
2329 data from the sam, but for the moment leave it in a tdb to
2330 keep regedt32 from popping up an annoying dialog. */
2331 lp_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2333 /* using UTF8 by default allows us to support all chars */
2334 lp_do_global_parameter(lp_ctx, "unix charset", "UTF8");
2336 /* Use codepage 850 as a default for the dos character set */
2337 lp_do_global_parameter(lp_ctx, "dos charset", "CP850");
2340 * Allow the default PASSWD_CHAT to be overridden in local.h.
2342 lp_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2344 lp_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2345 lp_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2346 lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR);
2347 lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2349 lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0");
2350 lp_do_global_parameter_var(lp_ctx, "server string",
2351 "Samba %s", SAMBA_VERSION_STRING);
2353 lp_do_global_parameter_var(lp_ctx, "announce version", "%d.%d",
2354 DEFAULT_MAJOR_VERSION,
2355 DEFAULT_MINOR_VERSION);
2357 lp_do_global_parameter(lp_ctx, "password server", "*");
2359 lp_do_global_parameter(lp_ctx, "max mux", "50");
2360 lp_do_global_parameter(lp_ctx, "max xmit", "12288");
2361 lp_do_global_parameter(lp_ctx, "password level", "0");
2362 lp_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2363 lp_do_global_parameter(lp_ctx, "server min protocol", "CORE");
2364 lp_do_global_parameter(lp_ctx, "server max protocol", "NT1");
2365 lp_do_global_parameter(lp_ctx, "client min protocol", "CORE");
2366 lp_do_global_parameter(lp_ctx, "client max protocol", "NT1");
2367 lp_do_global_parameter(lp_ctx, "security", "USER");
2368 lp_do_global_parameter(lp_ctx, "paranoid server security", "True");
2369 lp_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2370 lp_do_global_parameter(lp_ctx, "ReadRaw", "True");
2371 lp_do_global_parameter(lp_ctx, "WriteRaw", "True");
2372 lp_do_global_parameter(lp_ctx, "NullPasswords", "False");
2373 lp_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2374 lp_do_global_parameter(lp_ctx, "announce as", "NT SERVER");
2376 lp_do_global_parameter(lp_ctx, "TimeServer", "False");
2377 lp_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2378 lp_do_global_parameter(lp_ctx, "Unicode", "True");
2379 lp_do_global_parameter(lp_ctx, "ClientLanManAuth", "True");
2380 lp_do_global_parameter(lp_ctx, "LanmanAuth", "True");
2381 lp_do_global_parameter(lp_ctx, "NTLMAuth", "True");
2382 lp_do_global_parameter(lp_ctx, "client use spnego principal", "False");
2384 lp_do_global_parameter(lp_ctx, "UnixExtensions", "False");
2386 lp_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2387 lp_do_global_parameter(lp_ctx, "LocalMaster", "True");
2389 lp_do_global_parameter(lp_ctx, "wins support", "False");
2390 lp_do_global_parameter(lp_ctx, "dns proxy", "True");
2392 lp_do_global_parameter(lp_ctx, "winbind separator", "\\");
2393 lp_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2394 lp_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2395 lp_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2396 lp_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
2398 lp_do_global_parameter(lp_ctx, "client signing", "Yes");
2399 lp_do_global_parameter(lp_ctx, "server signing", "auto");
2401 lp_do_global_parameter(lp_ctx, "use spnego", "True");
2403 lp_do_global_parameter(lp_ctx, "smb ports", "445 139");
2404 lp_do_global_parameter(lp_ctx, "nbt port", "137");
2405 lp_do_global_parameter(lp_ctx, "dgram port", "138");
2406 lp_do_global_parameter(lp_ctx, "cldap port", "389");
2407 lp_do_global_parameter(lp_ctx, "krb5 port", "88");
2408 lp_do_global_parameter(lp_ctx, "kpasswd port", "464");
2409 lp_do_global_parameter(lp_ctx, "web port", "901");
2410 lp_do_global_parameter(lp_ctx, "web application directory", dyn_WEBAPPSDIR);
2411 lp_do_global_parameter(lp_ctx, "jsonrpc services directory", dyn_SERVICESDIR);
2413 lp_do_global_parameter(lp_ctx, "nt status support", "True");
2415 lp_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2416 lp_do_global_parameter(lp_ctx, "min wins ttl", "10");
2418 lp_do_global_parameter(lp_ctx, "tls enabled", "True");
2419 lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2420 lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2421 lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2422 lp_do_global_parameter_var(lp_ctx, "js include", "%s", dyn_JSDIR);
2423 lp_do_global_parameter_var(lp_ctx, "setup directory", "%s",
2426 for (i = 0; parm_table[i].label; i++) {
2427 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
2428 parm_table[i].flags |= FLAG_DEFAULT;
2435 /***************************************************************************
2436 Load the services array from the services file. Return True on success,
2438 ***************************************************************************/
2444 struct param_opt *data;
2445 struct loadparm_context *lp_ctx = &loadparm;
2449 if (lp_ctx->Globals.param_opt != NULL) {
2450 struct param_opt *next;
2451 for (data = lp_ctx->Globals.param_opt; data; data=next) {
2453 if (data->flags & FLAG_CMDLINE) continue;
2454 DLIST_REMOVE(lp_ctx->Globals.param_opt, data);
2459 if (!loadparm_init(lp_ctx))
2462 lp_ctx->bInGlobalSection = true;
2463 n2 = standard_sub_basic(talloc_autofree_context(), lp_configfile());
2464 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2466 add_to_file_list(lp_ctx, lp_configfile(), n2);
2468 /* We get sections first, so have to start 'behind' to make up */
2469 lp_ctx->currentService = NULL;
2470 bRetval = pm_process(n2, do_section, do_parameter, lp_ctx);
2472 /* finish up the last section */
2473 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2475 if (lp_ctx->currentService != NULL)
2476 bRetval = service_ok(lp_ctx->currentService);
2478 lp_add_auto_services(lp_ctx, lp_auto_services());
2480 lp_add_hidden(lp_ctx, "IPC$", "IPC");
2481 lp_add_hidden(lp_ctx, "ADMIN$", "DISK");
2485 if (!lp_ctx->Globals.szWINSservers && lp_ctx->Globals.bWINSsupport) {
2486 lp_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
2494 /***************************************************************************
2495 Return the max number of services.
2496 ***************************************************************************/
2498 int lp_numservices(struct loadparm_context *lp_ctx)
2500 return lp_ctx->iNumServices;
2503 /***************************************************************************
2504 Display the contents of the services array in human-readable form.
2505 ***************************************************************************/
2507 void lp_dump(FILE *f, bool show_defaults, int maxtoprint,
2508 struct loadparm_context *lp_ctx)
2513 defaults_saved = false;
2515 dump_globals(f, show_defaults);
2517 dump_a_service(&sDefault, f);
2519 for (iService = 0; iService < maxtoprint; iService++)
2520 lp_dump_one(f, show_defaults, lp_ctx->ServicePtrs[iService]);
2523 /***************************************************************************
2524 Display the contents of one service in human-readable form.
2525 ***************************************************************************/
2527 void lp_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service)
2529 if (service != NULL) {
2530 if (service->szService[0] == '\0')
2532 dump_a_service(service, f);
2536 struct loadparm_service *lp_servicebynum(int snum)
2538 return loadparm.ServicePtrs[snum];
2541 struct loadparm_service *lp_service(const char *service_name)
2543 int snum = lp_servicenumber(service_name);
2546 return loadparm.ServicePtrs[snum];
2549 /***************************************************************************
2550 Return the number of the service with the given name, or -1 if it doesn't
2551 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2552 getservicebyname()! This works ONLY if all services have been loaded, and
2553 does not copy the found service.
2554 ***************************************************************************/
2556 int lp_servicenumber(const char *pszServiceName)
2562 for (iService = loadparm.iNumServices - 1; iService >= 0; iService--) {
2563 if (loadparm.ServicePtrs[iService] &&
2564 loadparm.ServicePtrs[iService]->szService) {
2566 * The substitution here is used to support %U is
2569 serviceName = standard_sub_basic(loadparm.ServicePtrs[iService],
2570 loadparm.ServicePtrs[iService]->szService);
2571 if (strequal(serviceName, pszServiceName))
2577 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2582 /*******************************************************************
2583 A useful volume label function.
2584 ********************************************************************/
2585 const char *volume_label(struct loadparm_service *service)
2587 const char *ret = lp_volume(service);
2589 return lp_servicename(service);
2594 /***********************************************************
2595 If we are PDC then prefer us as DMB
2596 ************************************************************/
2598 bool lp_domain_logons(void)
2600 return (lp_server_role() == ROLE_DOMAIN_CONTROLLER);
2603 const char *lp_printername(struct loadparm_service *service)
2605 const char *ret = _lp_printername(service);
2606 if (ret == NULL || (ret != NULL && *ret == '\0'))
2607 ret = lp_const_servicename(service);
2613 /*******************************************************************
2614 Return the max print jobs per queue.
2615 ********************************************************************/
2617 int lp_maxprintjobs(struct loadparm_service *service)
2619 int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2620 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2621 maxjobs = PRINT_MAX_JOBID - 1;