2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 3 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/locale.h"
60 #include "system/network.h" /* needed for TCP_NODELAY */
61 #include "smb_server/smb_server.h"
62 #include "libcli/raw/signing.h"
63 #include "lib/util/dlinklist.h"
64 #include "param/param.h"
65 #include "param/loadparm.h"
67 #define standard_sub_basic talloc_strdup
69 static bool do_parameter(const char *, const char *, void *);
70 static bool defaults_saved = false;
73 * This structure describes global (ie., server-wide) parameters.
75 struct loadparm_global
77 enum server_role server_role;
79 const char **smb_ports;
83 char *display_charset;
91 const char *szConfigFile;
96 char *szWINS_CONFIG_URL;
99 const char **jsInclude;
100 char *jsonrpcServicesDir;
101 const char **szPasswordServers;
102 char *szSocketOptions;
104 const char **szWINSservers;
105 const char **szInterfaces;
106 char *szSocketAddress;
107 char *szAnnounceVersion; /* This is initialised in init_globals */
110 const char **szNetbiosAliases;
111 char *szNetbiosScope;
112 char *szDomainOtherSIDs;
113 const char **szNameResolveOrder;
114 const char **dcerpc_ep_servers;
115 const char **server_services;
116 char *ntptr_providor;
117 char *szWinbindSeparator;
118 char *szWinbinddSocketDirectory;
119 char *szTemplateShell;
120 char *szTemplateHomedir;
121 int bWinbindSealedPipes;
122 char *swat_directory;
140 int paranoid_server_security;
143 int announce_as; /* This is initialised in init_globals */
150 char *socket_options;
155 int bPreferredMaster;
156 int bEncryptPasswords;
158 int bObeyPamRestrictions;
163 int bBindInterfacesOnly;
165 int bNTStatusSupport;
171 int bClientPlaintextAuth;
172 int bClientLanManAuth;
173 int bClientNTLMv2Auth;
174 int client_use_spnego_principal;
180 struct param_opt *param_opt;
185 * This structure describes a single service.
187 struct loadparm_service
199 char **ntvfs_handler;
212 int iCreate_force_mode;
219 struct param_opt *param_opt;
221 char dummy[3]; /* for alignment */
225 /* This is a default service used to prime a services structure */
226 struct loadparm_service sDefault = {
231 .szPrintername = NULL,
232 .szHostsallow = NULL,
237 .ntvfs_handler = NULL,
238 .iMaxPrintJobs = 1000,
239 .iMaxConnections = 0,
245 .bMap_system = false,
246 .bMap_hidden = false,
247 .bMap_archive = true,
248 .bStrictLocking = true,
249 .iCreate_mask = 0744,
250 .iCreate_force_mode = 0000,
252 .iDir_force_mode = 0000,
255 .bStrictSync = false,
256 .bCIFileSystem = false,
259 /* local variables */
260 struct loadparm_context {
261 struct loadparm_global *globals;
262 struct loadparm_service **ServicePtrs;
264 struct loadparm_service *currentService;
265 bool bInGlobalSection;
267 struct file_lists *next;
274 struct loadparm_context *global_loadparm = NULL;
276 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
278 /* prototypes for the special type handlers */
279 static bool handle_include(struct loadparm_context *lp_ctx,
280 const char *pszParmValue, char **ptr);
281 static bool handle_copy(struct loadparm_context *lp_ctx,
282 const char *pszParmValue, char **ptr);
283 static bool handle_debuglevel(struct loadparm_context *lp_ctx,
284 const char *pszParmValue, char **ptr);
285 static bool handle_logfile(struct loadparm_context *lp_ctx,
286 const char *pszParmValue, char **ptr);
288 static const struct enum_list enum_protocol[] = {
289 {PROTOCOL_SMB2, "SMB2"},
290 {PROTOCOL_NT1, "NT1"},
291 {PROTOCOL_LANMAN2, "LANMAN2"},
292 {PROTOCOL_LANMAN1, "LANMAN1"},
293 {PROTOCOL_CORE, "CORE"},
294 {PROTOCOL_COREPLUS, "COREPLUS"},
295 {PROTOCOL_COREPLUS, "CORE+"},
299 static const struct enum_list enum_security[] = {
300 {SEC_SHARE, "SHARE"},
305 static const struct enum_list enum_announce_as[] = {
306 {ANNOUNCE_AS_NT_SERVER, "NT"},
307 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
308 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
309 {ANNOUNCE_AS_WIN95, "win95"},
310 {ANNOUNCE_AS_WFW, "WfW"},
314 static const struct enum_list enum_bool_auto[] = {
325 /* Client-side offline caching policy types */
328 CSC_POLICY_DOCUMENTS=1,
329 CSC_POLICY_PROGRAMS=2,
333 static const struct enum_list enum_csc_policy[] = {
334 {CSC_POLICY_MANUAL, "manual"},
335 {CSC_POLICY_DOCUMENTS, "documents"},
336 {CSC_POLICY_PROGRAMS, "programs"},
337 {CSC_POLICY_DISABLE, "disable"},
341 /* SMB signing types. */
342 static const struct enum_list enum_smb_signing_vals[] = {
343 {SMB_SIGNING_OFF, "No"},
344 {SMB_SIGNING_OFF, "False"},
345 {SMB_SIGNING_OFF, "0"},
346 {SMB_SIGNING_OFF, "Off"},
347 {SMB_SIGNING_OFF, "disabled"},
348 {SMB_SIGNING_SUPPORTED, "Yes"},
349 {SMB_SIGNING_SUPPORTED, "True"},
350 {SMB_SIGNING_SUPPORTED, "1"},
351 {SMB_SIGNING_SUPPORTED, "On"},
352 {SMB_SIGNING_SUPPORTED, "enabled"},
353 {SMB_SIGNING_REQUIRED, "required"},
354 {SMB_SIGNING_REQUIRED, "mandatory"},
355 {SMB_SIGNING_REQUIRED, "force"},
356 {SMB_SIGNING_REQUIRED, "forced"},
357 {SMB_SIGNING_REQUIRED, "enforced"},
358 {SMB_SIGNING_AUTO, "auto"},
362 static const struct enum_list enum_server_role[] = {
363 {ROLE_STANDALONE, "standalone"},
364 {ROLE_DOMAIN_MEMBER, "member server"},
365 {ROLE_DOMAIN_CONTROLLER, "domain controller"},
370 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
372 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
373 * is implied in current control logic. This may change at some later time. A
374 * flag value of 0 means - show as development option only.
376 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
377 * screen in SWAT. This is used to exclude parameters as well as to squash all
378 * parameters that have been duplicated by pseudonyms.
381 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
382 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
384 static struct parm_struct parm_table[] = {
385 {"config file", P_STRING, P_GLOBAL, GLOBAL_VAR(szConfigFile), NULL, NULL, FLAG_HIDE},
387 {"server role", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_role), NULL, enum_server_role, FLAG_BASIC},
389 {"dos charset", P_STRING, P_GLOBAL, GLOBAL_VAR(dos_charset), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
390 {"unix charset", P_STRING, P_GLOBAL, GLOBAL_VAR(unix_charset), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
391 {"ncalrpc dir", P_STRING, P_GLOBAL, GLOBAL_VAR(ncalrpc_dir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"display charset", P_STRING, P_GLOBAL, GLOBAL_VAR(display_charset), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"comment", P_STRING, P_LOCAL, LOCAL_VAR(comment), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
394 {"path", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
395 {"directory", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL, FLAG_HIDE},
396 {"workgroup", P_USTRING, P_GLOBAL, GLOBAL_VAR(szWorkgroup), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
397 {"realm", P_STRING, P_GLOBAL, GLOBAL_VAR(szRealm), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
398 {"netbios name", P_USTRING, P_GLOBAL, GLOBAL_VAR(szNetbiosName), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"netbios aliases", P_LIST, P_GLOBAL, GLOBAL_VAR(szNetbiosAliases), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"netbios scope", P_USTRING, P_GLOBAL, GLOBAL_VAR(szNetbiosScope), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
401 {"server string", P_STRING, P_GLOBAL, GLOBAL_VAR(szServerString), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
402 {"interfaces", P_LIST, P_GLOBAL, GLOBAL_VAR(szInterfaces), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
403 {"bind interfaces only", P_BOOL, P_GLOBAL, GLOBAL_VAR(bBindInterfacesOnly), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
404 {"ntvfs handler", P_LIST, P_LOCAL, LOCAL_VAR(ntvfs_handler), NULL, NULL, FLAG_ADVANCED},
405 {"ntptr providor", P_STRING, P_GLOBAL, GLOBAL_VAR(ntptr_providor), NULL, NULL, FLAG_ADVANCED},
406 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, GLOBAL_VAR(dcerpc_ep_servers), NULL, NULL, FLAG_ADVANCED},
407 {"server services", P_LIST, P_GLOBAL, GLOBAL_VAR(server_services), NULL, NULL, FLAG_ADVANCED},
409 {"security", P_ENUM, P_GLOBAL, GLOBAL_VAR(security), NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
410 {"encrypt passwords", P_BOOL, P_GLOBAL, GLOBAL_VAR(bEncryptPasswords), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
411 {"null passwords", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNullPasswords), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
412 {"obey pam restrictions", P_BOOL, P_GLOBAL, GLOBAL_VAR(bObeyPamRestrictions), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"password server", P_LIST, P_GLOBAL, GLOBAL_VAR(szPasswordServers), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
414 {"sam database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSAM_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"secrets database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSECRETS_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"spoolss database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSPOOLSS_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"wins config database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_CONFIG_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"wins database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"private dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szPrivateDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"passwd chat", P_STRING, P_GLOBAL, GLOBAL_VAR(szPasswdChat), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"password level", P_INTEGER, P_GLOBAL, GLOBAL_VAR(pwordlevel), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"lanman auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLanmanAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"ntlm auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNTLMAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientNTLMv2Auth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"client lanman auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientLanManAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"client plaintext auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientPlaintextAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"client use spnego principal", P_BOOL, P_GLOBAL, GLOBAL_VAR(client_use_spnego_principal), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"read only", P_BOOL, P_LOCAL, LOCAL_VAR(bRead_only), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
431 {"create mask", P_OCTAL, P_LOCAL, LOCAL_VAR(iCreate_mask), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
432 {"force create mode", P_OCTAL, P_LOCAL, LOCAL_VAR(iCreate_force_mode), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
433 {"directory mask", P_OCTAL, P_LOCAL, LOCAL_VAR(iDir_mask), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
434 {"force directory mode", P_OCTAL, P_LOCAL, LOCAL_VAR(iDir_force_mode), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
436 {"hosts allow", P_LIST, P_LOCAL, LOCAL_VAR(szHostsallow), NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
437 {"hosts deny", P_LIST, P_LOCAL, LOCAL_VAR(szHostsdeny), NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
439 {"log level", P_INTEGER, P_GLOBAL, GLOBAL_VAR(debuglevel), handle_debuglevel, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"debuglevel", P_INTEGER, P_GLOBAL, GLOBAL_VAR(debuglevel), handle_debuglevel, NULL, FLAG_HIDE},
441 {"log file", P_STRING, P_GLOBAL, GLOBAL_VAR(logfile), handle_logfile, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"smb ports", P_LIST, P_GLOBAL, GLOBAL_VAR(smb_ports), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"nbt port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(nbt_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"dgram port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(dgram_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"cldap port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(cldap_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"krb5 port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(krb5_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"kpasswd port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(kpasswd_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"web port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(web_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"tls enabled", P_BOOL, P_GLOBAL, GLOBAL_VAR(tls_enabled), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"tls keyfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_keyfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"tls certfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_certfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"tls cafile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_cafile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"tls crlfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_crlfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"tls dh params file", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_dhpfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"swat directory", P_STRING, P_GLOBAL, GLOBAL_VAR(swat_directory), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"large readwrite", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLargeReadwrite), NULL, NULL, FLAG_DEVELOPER},
458 {"server max protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(srv_maxprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
459 {"server min protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(srv_minprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
460 {"client max protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(cli_maxprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
461 {"client min protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(cli_minprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
462 {"unicode", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUnicode), NULL, NULL, FLAG_DEVELOPER},
463 {"read raw", P_BOOL, P_GLOBAL, GLOBAL_VAR(bReadRaw), NULL, NULL, FLAG_DEVELOPER},
464 {"write raw", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWriteRaw), NULL, NULL, FLAG_DEVELOPER},
465 {"disable netbios", P_BOOL, P_GLOBAL, GLOBAL_VAR(bDisableNetbios), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
467 {"nt status support", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNTStatusSupport), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"announce version", P_STRING, P_GLOBAL, GLOBAL_VAR(szAnnounceVersion), NULL, NULL, FLAG_DEVELOPER},
470 {"announce as", P_ENUM, P_GLOBAL, GLOBAL_VAR(announce_as), NULL, enum_announce_as, FLAG_DEVELOPER},
471 {"max mux", P_INTEGER, P_GLOBAL, GLOBAL_VAR(max_mux), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
472 {"max xmit", P_BYTES, P_GLOBAL, GLOBAL_VAR(max_xmit), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"name resolve order", P_LIST, P_GLOBAL, GLOBAL_VAR(szNameResolveOrder), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
475 {"max wins ttl", P_INTEGER, P_GLOBAL, GLOBAL_VAR(max_wins_ttl), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"min wins ttl", P_INTEGER, P_GLOBAL, GLOBAL_VAR(min_wins_ttl), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
477 {"time server", P_BOOL, P_GLOBAL, GLOBAL_VAR(bTimeServer), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
478 {"unix extensions", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUnixExtensions), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
479 {"use spnego", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUseSpnego), NULL, NULL, FLAG_DEVELOPER},
480 {"server signing", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_signing), NULL, enum_smb_signing_vals, FLAG_ADVANCED},
481 {"client signing", P_ENUM, P_GLOBAL, GLOBAL_VAR(client_signing), NULL, enum_smb_signing_vals, FLAG_ADVANCED},
482 {"rpc big endian", P_BOOL, P_GLOBAL, GLOBAL_VAR(bRpcBigEndian), NULL, NULL, FLAG_DEVELOPER},
484 {"max connections", P_INTEGER, P_LOCAL, LOCAL_VAR(iMaxConnections), NULL, NULL, FLAG_SHARE},
485 {"paranoid server security", P_BOOL, P_GLOBAL, GLOBAL_VAR(paranoid_server_security), NULL, NULL, FLAG_DEVELOPER},
486 {"socket options", P_STRING, P_GLOBAL, GLOBAL_VAR(socket_options), NULL, NULL, FLAG_DEVELOPER},
488 {"strict sync", P_BOOL, P_LOCAL, LOCAL_VAR(bStrictSync), NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
489 {"case insensitive filesystem", P_BOOL, P_LOCAL, LOCAL_VAR(bCIFileSystem), NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
491 {"max print jobs", P_INTEGER, P_LOCAL, LOCAL_VAR(iMaxPrintJobs), NULL, NULL, FLAG_PRINT},
492 {"printable", P_BOOL, P_LOCAL, LOCAL_VAR(bPrint_ok), NULL, NULL, FLAG_PRINT},
493 {"print ok", P_BOOL, P_LOCAL, LOCAL_VAR(bPrint_ok), NULL, NULL, FLAG_HIDE},
495 {"printer name", P_STRING, P_LOCAL, LOCAL_VAR(szPrintername), NULL, NULL, FLAG_PRINT},
496 {"printer", P_STRING, P_LOCAL, LOCAL_VAR(szPrintername), NULL, NULL, FLAG_HIDE},
498 {"map system", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_system), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
499 {"map hidden", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_hidden), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
500 {"map archive", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_archive), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
502 {"preferred master", P_ENUM, P_GLOBAL, GLOBAL_VAR(bPreferredMaster), NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
503 {"prefered master", P_ENUM, P_GLOBAL, GLOBAL_VAR(bPreferredMaster), NULL, enum_bool_auto, FLAG_HIDE},
504 {"local master", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLocalMaster), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
505 {"browseable", P_BOOL, P_LOCAL, LOCAL_VAR(bBrowseable), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
506 {"browsable", P_BOOL, P_LOCAL, LOCAL_VAR(bBrowseable), NULL, NULL, FLAG_HIDE},
508 {"wins server", P_LIST, P_GLOBAL, GLOBAL_VAR(szWINSservers), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
509 {"wins support", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWINSsupport), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
510 {"dns proxy", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWINSdnsProxy), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
511 {"wins hook", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINSHook), NULL, NULL, FLAG_ADVANCED},
513 {"csc policy", P_ENUM, P_LOCAL, LOCAL_VAR(iCSCPolicy), NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
515 {"strict locking", P_BOOL, P_LOCAL, LOCAL_VAR(bStrictLocking), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
517 {"share backend", P_STRING, P_GLOBAL, GLOBAL_VAR(szShareBackend), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
518 {"preload", P_STRING, P_GLOBAL, GLOBAL_VAR(szAutoServices), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
519 {"auto services", P_STRING, P_GLOBAL, GLOBAL_VAR(szAutoServices), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
520 {"lock dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL, FLAG_HIDE},
521 {"lock directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
522 {"modules dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szModulesDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
523 {"pid directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szPidDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
524 {"js include", P_LIST, P_GLOBAL, GLOBAL_VAR(jsInclude), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
525 {"setup directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szSetupDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
527 {"socket address", P_STRING, P_GLOBAL, GLOBAL_VAR(szSocketAddress), NULL, NULL, FLAG_DEVELOPER},
528 {"copy", P_STRING, P_LOCAL, LOCAL_VAR(szCopy), handle_copy, NULL, FLAG_HIDE},
529 {"include", P_STRING, P_LOCAL, LOCAL_VAR(szInclude), handle_include, NULL, FLAG_HIDE},
531 {"available", P_BOOL, P_LOCAL, LOCAL_VAR(bAvailable), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
532 {"volume", P_STRING, P_LOCAL, LOCAL_VAR(volume), NULL, NULL, FLAG_SHARE },
533 {"fstype", P_STRING, P_LOCAL, LOCAL_VAR(fstype), NULL, NULL, FLAG_SHARE},
535 {"panic action", P_STRING, P_GLOBAL, GLOBAL_VAR(panic_action), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"msdfs root", P_BOOL, P_LOCAL, LOCAL_VAR(bMSDfsRoot), NULL, NULL, FLAG_SHARE},
538 {"host msdfs", P_BOOL, P_GLOBAL, GLOBAL_VAR(bHostMSDfs), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"winbind separator", P_STRING, P_GLOBAL, GLOBAL_VAR(szWinbindSeparator), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
540 {"winbindd socket directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szWinbinddSocketDirectory), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
541 {"winbind sealed pipes", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWinbindSealedPipes), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
542 {"template shell", P_STRING, P_GLOBAL, GLOBAL_VAR(szTemplateShell), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
543 {"template homedir", P_STRING, P_GLOBAL, GLOBAL_VAR(szTemplateHomedir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
545 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
550 return the parameter table
552 struct parm_struct *lp_parm_table(void)
557 static TALLOC_CTX *lp_talloc;
559 /******************************************************************* a
560 Free up temporary memory - called from the main loop.
561 ********************************************************************/
563 void lp_talloc_free(void)
567 talloc_free(lp_talloc);
571 /*******************************************************************
572 Convenience routine to grab string parameters into temporary memory
573 and run standard_sub_basic on them. The buffers can be written to by
574 callers without affecting the source string.
575 ********************************************************************/
577 static const char *lp_string(const char *s)
579 #if 0 /* until REWRITE done to make thread-safe */
580 size_t len = s ? strlen(s) : 0;
584 /* The follow debug is useful for tracking down memory problems
585 especially if you have an inner loop that is calling a lp_*()
586 function that returns a string. Perhaps this debug should be
587 present all the time? */
590 DEBUG(10, ("lp_string(%s)\n", s));
593 #if 0 /* until REWRITE done to make thread-safe */
595 lp_talloc = talloc_init("lp_talloc");
597 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
605 strlcpy(ret, s, len);
607 if (trim_string(ret, "\"", "\"")) {
608 if (strchr(ret,'"') != NULL)
609 strlcpy(ret, s, len);
612 standard_sub_basic(ret,len+100);
619 In this section all the functions that are used to access the
620 parameters from the rest of the program are defined
623 #define FN_GLOBAL_STRING(fn_name,var_name) \
624 const char *fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : "";}
625 #define FN_GLOBAL_CONST_STRING(fn_name,var_name) \
626 const char *fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_ctx->globals->var_name : "";}
627 #define FN_GLOBAL_LIST(fn_name,var_name) \
628 const char **fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name;}
629 #define FN_GLOBAL_BOOL(fn_name,var_name) \
630 bool fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return false; return lp_ctx->globals->var_name;}
632 #define FN_GLOBAL_CHAR(fn_name,ptr) \
633 char fn_name(void) {return(*(char *)(ptr));}
635 #define FN_GLOBAL_INTEGER(fn_name,var_name) \
636 int fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return 0; return lp_ctx->globals->var_name;}
638 #define FN_LOCAL_STRING(fn_name,val) \
639 const char *fn_name(struct loadparm_service *service) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault.val)));}
640 #define FN_LOCAL_CONST_STRING(fn_name,val) \
641 const char *fn_name(struct loadparm_service *service) {return (const char *)(service != NULL && service->val != NULL) ? service->val : sDefault.val;}
642 #define FN_LOCAL_LIST(fn_name,val) \
643 const char **fn_name(struct loadparm_service *service) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault.val);}
644 #define FN_LOCAL_BOOL(fn_name,val) \
645 bool fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
646 #define FN_LOCAL_INTEGER(fn_name,val) \
647 int fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
649 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, server_role)
650 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, smb_ports)
651 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, nbt_port)
652 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, dgram_port)
653 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, cldap_port)
654 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, krb5_port)
655 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, kpasswd_port)
656 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, web_port)
657 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, swat_directory)
658 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, tls_enabled)
659 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, tls_keyfile)
660 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, tls_certfile)
661 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, tls_cafile)
662 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, tls_crlfile)
663 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_dhpfile, tls_dhpfile)
664 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, szShareBackend)
665 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, szSAM_URL)
666 _PUBLIC_ FN_GLOBAL_STRING(lp_secrets_url, szSECRETS_URL)
667 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, szSPOOLSS_URL)
668 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, szWINS_CONFIG_URL)
669 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, szWINS_URL)
670 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
671 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, szWinbinddSocketDirectory)
672 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
673 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
674 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, bWinbindSealedPipes)
675 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, szPrivateDir)
676 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, szServerString)
677 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, szLockDir)
678 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, szModulesDir)
679 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, szSetupDir)
680 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, ncalrpc_dir)
681 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, dos_charset)
682 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, unix_charset)
683 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, display_charset)
684 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, szPidDir)
685 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, dcerpc_ep_servers)
686 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, server_services)
687 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, ntptr_providor)
688 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
689 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
690 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, szPasswordServers)
691 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, szNameResolveOrder)
692 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, szRealm)
693 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, socket_options)
694 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, szWorkgroup)
695 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, szNetbiosName)
696 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, szNetbiosScope)
697 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
698 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
699 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, szSocketAddress)
700 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
702 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
703 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, bWINSsupport)
704 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, bWINSdnsProxy)
705 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
706 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, szConfigFile)
707 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
708 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, bReadRaw)
709 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
710 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, bWriteRaw)
711 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
712 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
713 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
714 _PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
715 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
716 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, bUnicode)
717 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
718 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
719 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
720 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
721 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
722 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
723 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
724 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
725 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
726 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
727 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, bRpcBigEndian)
728 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
729 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
730 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
731 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, max_xmit)
732 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
733 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, srv_maxprotocol)
734 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, srv_minprotocol)
735 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, cli_maxprotocol)
736 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, cli_minprotocol)
737 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, security)
738 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
739 _PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, announce_as)
740 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, jsInclude)
741 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
742 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
743 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
744 static FN_LOCAL_STRING(_lp_printername, szPrintername)
745 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
746 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
747 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
748 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
749 static FN_LOCAL_STRING(lp_volume, volume)
750 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
751 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
752 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
753 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
754 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
755 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
756 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
757 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
758 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
759 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
760 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
761 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
762 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
763 _PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
764 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
765 _PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
766 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
767 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
768 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
770 /* local prototypes */
771 static int map_parameter(const char *pszParmName);
772 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
773 const char *pszServiceName);
774 static void copy_service(struct loadparm_service *pserviceDest,
775 struct loadparm_service *pserviceSource,
777 static bool service_ok(struct loadparm_service *service);
778 static bool do_section(const char *pszSectionName, void *);
779 static void init_copymap(struct loadparm_service *pservice);
781 /* This is a helper function for parametrical options support. */
782 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
783 /* Actual parametrical functions are quite simple */
784 const char *lp_get_parametric(struct loadparm_context *lp_ctx,
785 struct loadparm_service *service,
786 const char *type, const char *option)
789 struct param_opt *data;
791 data = (service == NULL ? lp_ctx->globals->param_opt : service->param_opt);
793 asprintf(&vfskey, "%s:%s", type, option);
797 if (strcmp(data->key, vfskey) == 0) {
804 if (service != NULL) {
805 /* Try to fetch the same option but from globals */
806 /* but only if we are not already working with globals */
807 for (data = lp_ctx->globals->param_opt; data;
809 if (strcmp(data->key, vfskey) == 0) {
822 /*******************************************************************
823 convenience routine to return int parameters.
824 ********************************************************************/
825 static int lp_int(const char *s)
829 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
833 return strtol(s, NULL, 0);
836 /*******************************************************************
837 convenience routine to return unsigned long parameters.
838 ********************************************************************/
839 static int lp_ulong(const char *s)
843 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
847 return strtoul(s, NULL, 0);
850 /*******************************************************************
851 convenience routine to return unsigned long parameters.
852 ********************************************************************/
853 static double lp_double(const char *s)
857 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
861 return strtod(s, NULL);
864 /*******************************************************************
865 convenience routine to return boolean parameters.
866 ********************************************************************/
867 static bool lp_bool(const char *s)
872 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
876 if (!set_boolean(s, &ret)) {
877 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
885 /* Return parametric option from a given service. Type is a part of option before ':' */
886 /* Parametric option has following syntax: 'Type: option = value' */
887 /* Returned value is allocated in 'lp_talloc' context */
889 const char *lp_parm_string(struct loadparm_context *lp_ctx,
890 struct loadparm_service *service, const char *type,
893 const char *value = lp_get_parametric(lp_ctx, service, type, option);
896 return lp_string(value);
901 /* Return parametric option from a given service. Type is a part of option before ':' */
902 /* Parametric option has following syntax: 'Type: option = value' */
903 /* Returned value is allocated in 'lp_talloc' context */
905 const char **lp_parm_string_list(struct loadparm_context *lp_ctx,
906 struct loadparm_service *service,
908 const char *option, const char *separator)
910 const char *value = lp_get_parametric(lp_ctx, service, type, option);
913 return str_list_make(talloc_autofree_context(), value,
919 /* Return parametric option from a given service. Type is a part of option before ':' */
920 /* Parametric option has following syntax: 'Type: option = value' */
922 int lp_parm_int(struct loadparm_context *lp_ctx,
923 struct loadparm_service *service, const char *type,
924 const char *option, int default_v)
926 const char *value = lp_get_parametric(lp_ctx, service, type, option);
929 return lp_int(value);
934 /* Return parametric option from a given service. Type is a part of
936 * Parametric option has following syntax: 'Type: option = value'.
939 int lp_parm_bytes(struct loadparm_context *lp_ctx,
940 struct loadparm_service *service, const char *type,
941 const char *option, int default_v)
945 const char *value = lp_get_parametric(lp_ctx, service, type, option);
947 if (value && conv_str_size(value, &bval)) {
948 if (bval <= INT_MAX) {
956 /* Return parametric option from a given service. Type is a part of option before ':' */
957 /* Parametric option has following syntax: 'Type: option = value' */
959 unsigned long lp_parm_ulong(struct loadparm_context *lp_ctx,
960 struct loadparm_service *service, const char *type,
961 const char *option, unsigned long default_v)
963 const char *value = lp_get_parametric(lp_ctx, service, type, option);
966 return lp_ulong(value);
972 double lp_parm_double(struct loadparm_context *lp_ctx,
973 struct loadparm_service *service, const char *type,
974 const char *option, double default_v)
976 const char *value = lp_get_parametric(lp_ctx, service, type, option);
979 return lp_double(value);
984 /* Return parametric option from a given service. Type is a part of option before ':' */
985 /* Parametric option has following syntax: 'Type: option = value' */
987 bool lp_parm_bool(struct loadparm_context *lp_ctx,
988 struct loadparm_service *service, const char *type,
989 const char *option, bool default_v)
991 const char *value = lp_get_parametric(lp_ctx, service, type, option);
994 return lp_bool(value);
1000 /***************************************************************************
1001 Initialise a service to the defaults.
1002 ***************************************************************************/
1004 static struct loadparm_service *init_service(TALLOC_CTX *mem_ctx)
1006 struct loadparm_service *pservice =
1007 talloc_zero(mem_ctx, struct loadparm_service);
1008 copy_service(pservice, &sDefault, NULL);
1013 Set a string value, deallocating any existing space, and allocing the space
1016 static bool string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
1023 *dest = talloc_strdup(mem_ctx, src);
1024 if ((*dest) == NULL) {
1025 DEBUG(0,("Out of memory in string_init\n"));
1034 /***************************************************************************
1035 Add a new service to the services array initialising it with the given
1037 ***************************************************************************/
1039 struct loadparm_service *lp_add_service(struct loadparm_context *lp_ctx,
1040 const struct loadparm_service *pservice,
1044 struct loadparm_service tservice;
1045 int num_to_alloc = lp_ctx->iNumServices + 1;
1046 struct param_opt *data, *pdata;
1048 tservice = *pservice;
1050 /* it might already exist */
1052 struct loadparm_service *service = getservicebyname(lp_ctx,
1054 if (service != NULL) {
1055 /* Clean all parametric options for service */
1056 /* They will be added during parsing again */
1057 data = service->param_opt;
1063 service->param_opt = NULL;
1068 /* find an invalid one */
1069 for (i = 0; i < lp_ctx->iNumServices; i++)
1070 if (lp_ctx->ServicePtrs[i] == NULL)
1073 /* if not, then create one */
1074 if (i == lp_ctx->iNumServices) {
1075 struct loadparm_service **tsp;
1077 tsp = talloc_realloc(lp_ctx, lp_ctx->ServicePtrs, struct loadparm_service *,
1081 DEBUG(0,("lp_add_service: failed to enlarge ServicePtrs!\n"));
1085 lp_ctx->ServicePtrs = tsp;
1086 lp_ctx->ServicePtrs[lp_ctx->iNumServices] = NULL;
1089 lp_ctx->iNumServices++;
1092 lp_ctx->ServicePtrs[i] = init_service(lp_ctx);
1093 if (lp_ctx->ServicePtrs[i] == NULL) {
1094 DEBUG(0,("lp_add_service: out of memory!\n"));
1097 copy_service(lp_ctx->ServicePtrs[i], &tservice, NULL);
1099 string_set(lp_ctx->ServicePtrs[i], &lp_ctx->ServicePtrs[i]->szService, name);
1100 return lp_ctx->ServicePtrs[i];
1103 /***************************************************************************
1104 Add a new home service, with the specified home directory, defaults coming
1106 ***************************************************************************/
1108 bool lp_add_home(struct loadparm_context *lp_ctx,
1109 const char *pszHomename,
1110 struct loadparm_service *default_service,
1111 const char *user, const char *pszHomedir)
1113 struct loadparm_service *service;
1115 service = lp_add_service(lp_ctx, default_service, pszHomename);
1117 if (service == NULL)
1120 if (!(*(default_service->szPath))
1121 || strequal(default_service->szPath, sDefault.szPath)) {
1122 service->szPath = talloc_strdup(service, pszHomedir);
1124 service->szPath = string_sub_talloc(service, lp_pathname(default_service),"%H", pszHomedir);
1127 if (!(*(service->comment))) {
1128 service->comment = talloc_asprintf(service, "Home directory of %s", user);
1130 service->bAvailable = default_service->bAvailable;
1131 service->bBrowseable = default_service->bBrowseable;
1133 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
1134 pszHomename, user, service->szPath));
1139 /***************************************************************************
1140 Add the IPC service.
1141 ***************************************************************************/
1143 static bool lp_add_hidden(struct loadparm_context *lp_ctx, const char *name,
1146 struct loadparm_service *service = lp_add_service(lp_ctx, &sDefault, name);
1148 if (service == NULL)
1151 string_set(service, &service->szPath, tmpdir());
1153 service->comment = talloc_asprintf(service, "%s Service (%s)",
1154 fstype, lp_ctx->globals->szServerString);
1155 string_set(service, &service->fstype, fstype);
1156 service->iMaxConnections = -1;
1157 service->bAvailable = true;
1158 service->bRead_only = true;
1159 service->bPrint_ok = false;
1160 service->bBrowseable = false;
1162 if (strcasecmp(fstype, "IPC") == 0) {
1163 lp_do_service_parameter(lp_ctx, service, "ntvfs handler",
1167 DEBUG(3, ("adding hidden service %s\n", name));
1172 /***************************************************************************
1173 Add a new printer service, with defaults coming from service iFrom.
1174 ***************************************************************************/
1176 bool lp_add_printer(struct loadparm_context *lp_ctx,
1177 const char *pszPrintername,
1178 struct loadparm_service *default_service)
1180 const char *comment = "From Printcap";
1181 struct loadparm_service *service;
1182 service = lp_add_service(lp_ctx, default_service, pszPrintername);
1184 if (service == NULL)
1187 /* note that we do NOT default the availability flag to True - */
1188 /* we take it from the default service passed. This allows all */
1189 /* dynamic printers to be disabled by disabling the [printers] */
1190 /* entry (if/when the 'available' keyword is implemented!). */
1192 /* the printer name is set to the service name. */
1193 string_set(service, &service->szPrintername, pszPrintername);
1194 string_set(service, &service->comment, comment);
1195 service->bBrowseable = sDefault.bBrowseable;
1196 /* Printers cannot be read_only. */
1197 service->bRead_only = false;
1198 /* Printer services must be printable. */
1199 service->bPrint_ok = true;
1201 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1206 /***************************************************************************
1207 Map a parameter's string representation to something we can use.
1208 Returns False if the parameter string is not recognised, else TRUE.
1209 ***************************************************************************/
1211 static int map_parameter(const char *pszParmName)
1215 if (*pszParmName == '-')
1218 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1219 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1222 /* Warn only if it isn't parametric option */
1223 if (strchr(pszParmName, ':') == NULL)
1224 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1225 /* We do return 'fail' for parametric options as well because they are
1226 stored in different storage
1233 return the parameter structure for a parameter
1235 struct parm_struct *lp_parm_struct(const char *name)
1237 int parmnum = map_parameter(name);
1238 if (parmnum == -1) return NULL;
1239 return &parm_table[parmnum];
1243 return the parameter pointer for a parameter
1245 void *lp_parm_ptr(struct loadparm_context *lp_ctx,
1246 struct loadparm_service *service, struct parm_struct *parm)
1248 if (service == NULL) {
1249 if (parm->class == P_LOCAL)
1250 return ((char *)&sDefault)+parm->offset;
1251 else if (parm->class == P_GLOBAL)
1252 return ((char *)lp_ctx->globals)+parm->offset;
1255 return ((char *)service) + parm->offset;
1259 /***************************************************************************
1260 Find a service by name. Otherwise works like get_service.
1261 ***************************************************************************/
1263 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
1264 const char *pszServiceName)
1268 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
1269 if (lp_ctx->ServicePtrs[iService] != NULL &&
1270 strwicmp(lp_ctx->ServicePtrs[iService]->szService, pszServiceName) == 0) {
1271 return lp_ctx->ServicePtrs[iService];
1277 /***************************************************************************
1278 Copy a service structure to another.
1279 If pcopymapDest is NULL then copy all fields
1280 ***************************************************************************/
1282 static void copy_service(struct loadparm_service *pserviceDest,
1283 struct loadparm_service *pserviceSource,
1287 bool bcopyall = (pcopymapDest == NULL);
1288 struct param_opt *data, *pdata, *paramo;
1291 for (i = 0; parm_table[i].label; i++)
1292 if (parm_table[i].offset != -1 && parm_table[i].class == P_LOCAL &&
1293 (bcopyall || pcopymapDest[i])) {
1295 ((char *)pserviceSource) + parm_table[i].offset;
1297 ((char *)pserviceDest) + parm_table[i].offset;
1299 switch (parm_table[i].type) {
1301 *(int *)dest_ptr = *(int *)src_ptr;
1307 *(int *)dest_ptr = *(int *)src_ptr;
1311 string_set(pserviceDest,
1317 string_set(pserviceDest,
1320 strupper(*(char **)dest_ptr);
1323 *(const char ***)dest_ptr = str_list_copy(pserviceDest,
1324 *(const char ***)src_ptr);
1332 init_copymap(pserviceDest);
1333 if (pserviceSource->copymap)
1334 memcpy((void *)pserviceDest->copymap,
1335 (void *)pserviceSource->copymap,
1336 sizeof(int) * NUMPARAMETERS);
1339 data = pserviceSource->param_opt;
1342 pdata = pserviceDest->param_opt;
1343 /* Traverse destination */
1345 /* If we already have same option, override it */
1346 if (strcmp(pdata->key, data->key) == 0) {
1347 talloc_free(pdata->value);
1348 pdata->value = talloc_reference(pdata,
1353 pdata = pdata->next;
1356 paramo = talloc(pserviceDest, struct param_opt);
1359 paramo->key = talloc_reference(paramo, data->key);
1360 paramo->value = talloc_reference(paramo, data->value);
1361 DLIST_ADD(pserviceDest->param_opt, paramo);
1367 /***************************************************************************
1368 Check a service for consistency. Return False if the service is in any way
1369 incomplete or faulty, else True.
1370 ***************************************************************************/
1372 static bool service_ok(struct loadparm_service *service)
1377 if (service->szService[0] == '\0') {
1378 DEBUG(0, ("The following message indicates an internal error:\n"));
1379 DEBUG(0, ("No service name in service entry.\n"));
1383 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1384 /* I can't see why you'd want a non-printable printer service... */
1385 if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
1386 if (!service->bPrint_ok) {
1387 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1388 service->szService));
1389 service->bPrint_ok = true;
1391 /* [printers] service must also be non-browsable. */
1392 if (service->bBrowseable)
1393 service->bBrowseable = false;
1396 /* If a service is flagged unavailable, log the fact at level 0. */
1397 if (!service->bAvailable)
1398 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1399 service->szService));
1405 /*******************************************************************
1406 Keep a linked list of all config files so we know when one has changed
1407 it's date and needs to be reloaded.
1408 ********************************************************************/
1410 static void add_to_file_list(struct loadparm_context *lp_ctx,
1411 const char *fname, const char *subfname)
1413 struct file_lists *f = lp_ctx->file_lists;
1416 if (f->name && !strcmp(f->name, fname))
1422 f = talloc(lp_ctx, struct file_lists);
1425 f->next = lp_ctx->file_lists;
1426 f->name = talloc_strdup(f, fname);
1431 f->subfname = talloc_strdup(f, subfname);
1436 lp_ctx->file_lists = f;
1437 f->modtime = file_modtime(subfname);
1439 time_t t = file_modtime(subfname);
1445 /*******************************************************************
1446 Check if a config file has changed date.
1447 ********************************************************************/
1449 bool lp_file_list_changed(struct loadparm_context *lp_ctx)
1451 struct file_lists *f;
1452 DEBUG(6, ("lp_file_list_changed()\n"));
1454 for (f = lp_ctx->file_lists; f != NULL; f = f->next) {
1458 n2 = standard_sub_basic(lp_ctx, f->name);
1460 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1461 f->name, n2, ctime(&f->modtime)));
1463 mod_time = file_modtime(n2);
1465 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1466 DEBUGADD(6, ("file %s modified: %s\n", n2,
1468 f->modtime = mod_time;
1469 talloc_free(f->subfname);
1470 f->subfname = talloc_strdup(f, n2);
1477 /***************************************************************************
1478 Handle the include operation.
1479 ***************************************************************************/
1481 static bool handle_include(struct loadparm_context *lp_ctx,
1482 const char *pszParmValue, char **ptr)
1484 char *fname = standard_sub_basic(lp_ctx, pszParmValue);
1486 add_to_file_list(lp_ctx, pszParmValue, fname);
1488 string_set(lp_ctx, ptr, fname);
1490 if (file_exist(fname))
1491 return pm_process(fname, do_section, do_parameter, lp_ctx);
1493 DEBUG(2, ("Can't find include file %s\n", fname));
1498 /***************************************************************************
1499 Handle the interpretation of the copy parameter.
1500 ***************************************************************************/
1502 static bool handle_copy(struct loadparm_context *lp_ctx,
1503 const char *pszParmValue, char **ptr)
1506 struct loadparm_service *serviceTemp;
1508 string_set(lp_ctx, ptr, pszParmValue);
1512 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1514 if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) {
1515 if (serviceTemp == lp_ctx->currentService) {
1516 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1518 copy_service(lp_ctx->currentService,
1520 lp_ctx->currentService->copymap);
1524 DEBUG(0, ("Unable to copy service - source not found: %s\n",
1532 static bool handle_debuglevel(struct loadparm_context *lp_ctx,
1533 const char *pszParmValue, char **ptr)
1535 DEBUGLEVEL = atoi(pszParmValue);
1540 static bool handle_logfile(struct loadparm_context *lp_ctx,
1541 const char *pszParmValue, char **ptr)
1543 logfile = pszParmValue;
1547 /***************************************************************************
1548 Initialise a copymap.
1549 ***************************************************************************/
1551 static void init_copymap(struct loadparm_service *pservice)
1554 talloc_free(pservice->copymap);
1555 pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS);
1556 if (pservice->copymap == NULL) {
1558 ("Couldn't allocate copymap!! (size %d)\n",
1559 (int)NUMPARAMETERS));
1562 for (i = 0; i < NUMPARAMETERS; i++)
1563 pservice->copymap[i] = true;
1566 /***************************************************************************
1567 Process a parametric option
1568 ***************************************************************************/
1569 static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
1570 struct loadparm_service *service,
1571 const char *pszParmName,
1572 const char *pszParmValue, int flags)
1574 struct param_opt *paramo, *data;
1576 TALLOC_CTX *mem_ctx;
1578 while (isspace((unsigned char)*pszParmName)) {
1582 name = strdup(pszParmName);
1583 if (!name) return false;
1587 if (service == NULL) {
1588 data = lp_ctx->globals->param_opt;
1589 mem_ctx = lp_ctx->globals;
1591 data = service->param_opt;
1595 /* Traverse destination */
1596 for (paramo=data; paramo; paramo=paramo->next) {
1597 /* If we already have the option set, override it unless
1598 it was a command line option and the new one isn't */
1599 if (strcmp(paramo->key, name) == 0) {
1600 if ((paramo->flags & FLAG_CMDLINE) &&
1601 !(flags & FLAG_CMDLINE)) {
1605 talloc_free(paramo->value);
1606 paramo->value = talloc_strdup(paramo, pszParmValue);
1607 paramo->flags = flags;
1613 paramo = talloc(mem_ctx, struct param_opt);
1616 paramo->key = talloc_strdup(paramo, name);
1617 paramo->value = talloc_strdup(paramo, pszParmValue);
1618 paramo->flags = flags;
1619 if (service == NULL) {
1620 DLIST_ADD(lp_ctx->globals->param_opt, paramo);
1622 DLIST_ADD(service->param_opt, paramo);
1630 static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1631 const char *pszParmName, const char *pszParmValue,
1632 struct loadparm_context *lp_ctx)
1635 /* if it is a special case then go ahead */
1636 if (parm_table[parmnum].special) {
1637 parm_table[parmnum].special(lp_ctx, pszParmValue,
1642 /* now switch on the type of variable it is */
1643 switch (parm_table[parmnum].type)
1647 if (!set_boolean(pszParmValue, &b)) {
1648 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1651 *(int *)parm_ptr = b;
1656 *(int *)parm_ptr = atoi(pszParmValue);
1660 *(int *)parm_ptr = strtol(pszParmValue, NULL, 8);
1666 if (conv_str_size(pszParmValue, &val)) {
1667 if (val <= INT_MAX) {
1668 *(int *)parm_ptr = (int)val;
1673 DEBUG(0,("lp_do_parameter(%s): value is not "
1674 "a valid size specifier!\n", pszParmValue));
1679 *(const char ***)parm_ptr = str_list_make(mem_ctx,
1680 pszParmValue, NULL);
1684 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1688 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1689 strupper(*(char **)parm_ptr);
1693 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1696 parm_table[parmnum].enum_list[i].name)) {
1698 parm_table[parmnum].
1703 if (!parm_table[parmnum].enum_list[i].name) {
1704 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1705 pszParmValue, pszParmName));
1711 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1712 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1713 /* we have to also unset FLAG_DEFAULT on aliases */
1714 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
1715 parm_table[i].flags &= ~FLAG_DEFAULT;
1717 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) {
1718 parm_table[i].flags &= ~FLAG_DEFAULT;
1725 bool lp_do_global_parameter(struct loadparm_context *lp_ctx,
1726 const char *pszParmName, const char *pszParmValue)
1728 int parmnum = map_parameter(pszParmName);
1732 if (strchr(pszParmName, ':')) {
1733 return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0);
1735 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1739 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1740 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1744 /* if the flag has been set on the command line, then don't allow override,
1745 but don't report an error */
1746 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1750 parm_ptr = lp_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]);
1752 return set_variable(lp_ctx, parmnum, parm_ptr,
1753 pszParmName, pszParmValue, lp_ctx);
1756 bool lp_do_service_parameter(struct loadparm_context *lp_ctx,
1757 struct loadparm_service *service,
1758 const char *pszParmName, const char *pszParmValue)
1762 int parmnum = map_parameter(pszParmName);
1765 if (strchr(pszParmName, ':')) {
1766 return lp_do_parameter_parametric(lp_ctx, service, pszParmName, pszParmValue, 0);
1768 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1772 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1773 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1777 /* if the flag has been set on the command line, then don't allow override,
1778 but don't report an error */
1779 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1783 if (parm_table[parmnum].class == P_GLOBAL) {
1785 ("Global parameter %s found in service section!\n",
1789 parm_ptr = ((char *)service) + parm_table[parmnum].offset;
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].offset == parm_table[parmnum].offset &&
1798 parm_table[i].class == parm_table[parmnum].class)
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(struct loadparm_context *lp_ctx, const char *pszParmName,
1848 const char *pszParmValue)
1850 int parmnum = map_parameter(pszParmName);
1853 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1856 if (parmnum < 0 && strchr(pszParmName, ':')) {
1857 /* set a parametric option */
1858 return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
1859 pszParmValue, FLAG_CMDLINE);
1863 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1867 /* reset the CMDLINE flag in case this has been called before */
1868 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1870 if (!lp_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
1874 parm_table[parmnum].flags |= FLAG_CMDLINE;
1876 /* we have to also set FLAG_CMDLINE on aliases */
1877 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
1878 parm_table[i].flags |= FLAG_CMDLINE;
1880 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) {
1881 parm_table[i].flags |= FLAG_CMDLINE;
1888 set a option from the commandline in 'a=b' format. Use to support --option
1890 bool lp_set_option(struct loadparm_context *lp_ctx, const char *option)
1908 ret = lp_set_cmdline(lp_ctx, s, p+1);
1914 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1916 /***************************************************************************
1917 Print a parameter of the specified type.
1918 ***************************************************************************/
1920 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1926 for (i = 0; p->enum_list[i].name; i++) {
1927 if (*(int *)ptr == p->enum_list[i].value) {
1929 p->enum_list[i].name);
1936 fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr));
1941 fprintf(f, "%d", *(int *)ptr);
1945 fprintf(f, "0%o", *(int *)ptr);
1949 if ((char ***)ptr && *(char ***)ptr) {
1950 char **list = *(char ***)ptr;
1952 for (; *list; list++)
1953 fprintf(f, "%s%s", *list,
1954 ((*(list+1))?", ":""));
1960 if (*(char **)ptr) {
1961 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));
2001 /***************************************************************************
2002 Process a new section (service). At this stage all sections are services.
2003 Later we'll have special sections that permit server parameters to be set.
2004 Returns True on success, False on failure.
2005 ***************************************************************************/
2007 static bool do_section(const char *pszSectionName, void *userdata)
2009 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2011 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2012 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2015 /* if we've just struck a global section, note the fact. */
2016 lp_ctx->bInGlobalSection = isglobal;
2018 /* check for multiple global sections */
2019 if (lp_ctx->bInGlobalSection) {
2020 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2024 /* if we have a current service, tidy it up before moving on */
2027 if (lp_ctx->currentService != NULL)
2028 bRetval = service_ok(lp_ctx->currentService);
2030 /* if all is still well, move to the next record in the services array */
2032 /* We put this here to avoid an odd message order if messages are */
2033 /* issued by the post-processing of a previous section. */
2034 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2036 if ((lp_ctx->currentService = lp_add_service(lp_ctx, &sDefault,
2039 DEBUG(0, ("Failed to add a new service\n"));
2048 /***************************************************************************
2049 Determine if a partcular base parameter is currentl set to the default value.
2050 ***************************************************************************/
2052 static bool is_default(int i)
2054 void *def_ptr = ((char *)&sDefault) + parm_table[i].offset;
2055 if (!defaults_saved)
2057 switch (parm_table[i].type) {
2059 return str_list_equal((const char **)parm_table[i].def.lvalue,
2060 (const char **)def_ptr);
2063 return strequal(parm_table[i].def.svalue,
2066 return parm_table[i].def.bvalue ==
2072 return parm_table[i].def.ivalue ==
2078 /***************************************************************************
2079 Display the contents of the global structure.
2080 ***************************************************************************/
2082 static void dump_globals(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults)
2085 struct param_opt *data;
2087 fprintf(f, "# Global parameters\n[global]\n");
2089 for (i = 0; parm_table[i].label; i++)
2090 if (parm_table[i].class == P_GLOBAL &&
2091 parm_table[i].offset != -1 &&
2092 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
2093 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2095 fprintf(f, "\t%s = ", parm_table[i].label);
2096 print_parameter(&parm_table[i], lp_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
2099 if (lp_ctx->globals->param_opt != NULL) {
2100 for (data = lp_ctx->globals->param_opt; data;
2101 data = data->next) {
2102 fprintf(f, "\t%s = %s\n", data->key, data->value);
2108 /***************************************************************************
2109 Display the contents of a single services record.
2110 ***************************************************************************/
2112 static void dump_a_service(struct loadparm_service * pService, FILE * f)
2115 struct param_opt *data;
2117 if (pService != &sDefault)
2118 fprintf(f, "\n[%s]\n", pService->szService);
2120 for (i = 0; parm_table[i].label; i++)
2121 if (parm_table[i].class == P_LOCAL &&
2122 parm_table[i].offset != -1 &&
2123 (*parm_table[i].label != '-') &&
2124 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
2125 if (pService == &sDefault) {
2126 if (defaults_saved && is_default(i))
2129 if (equal_parameter(parm_table[i].type,
2130 ((char *)pService) +
2131 parm_table[i].offset,
2132 ((char *)&sDefault) +
2133 parm_table[i].offset))
2137 fprintf(f, "\t%s = ", parm_table[i].label);
2138 print_parameter(&parm_table[i],
2139 ((char *)pService) + parm_table[i].offset, f);
2142 if (pService->param_opt != NULL) {
2143 for (data = pService->param_opt; data; data = data->next) {
2144 fprintf(f, "\t%s = %s\n", data->key, data->value);
2149 bool lp_dump_a_parameter(struct loadparm_context *lp_ctx, int snum, const char *parm_name, FILE * f,
2152 struct loadparm_service * pService = lp_ctx->ServicePtrs[snum];
2153 struct parm_struct *parm;
2156 parm = lp_parm_struct(parm_name);
2162 ptr = ((char *)&sDefault) + parm->offset;
2164 ptr = ((char *)pService) + parm->offset;
2166 print_parameter(parm, ptr, f);
2171 /***************************************************************************
2172 Return info about the next service in a service. snum==-1 gives the globals.
2173 Return NULL when out of parameters.
2174 ***************************************************************************/
2176 struct parm_struct *lp_next_parameter(struct loadparm_context *lp_ctx, int snum, int *i,
2180 /* do the globals */
2181 for (; parm_table[*i].label; (*i)++) {
2182 if (parm_table[*i].offset == -1
2183 || (*parm_table[*i].label == '-'))
2187 && (parm_table[*i].offset ==
2188 parm_table[(*i) - 1].offset))
2191 return &parm_table[(*i)++];
2194 struct loadparm_service *pService = lp_ctx->ServicePtrs[snum];
2196 for (; parm_table[*i].label; (*i)++) {
2197 if (parm_table[*i].class == P_LOCAL &&
2198 parm_table[*i].offset != -1 &&
2199 (*parm_table[*i].label != '-') &&
2201 (parm_table[*i].offset !=
2202 parm_table[(*i) - 1].offset)))
2204 if (allparameters ||
2205 !equal_parameter(parm_table[*i].type,
2206 ((char *)pService) +
2207 parm_table[*i].offset,
2208 ((char *)&sDefault) +
2209 parm_table[*i].offset))
2211 return &parm_table[(*i)++];
2221 /***************************************************************************
2222 Auto-load some home services.
2223 ***************************************************************************/
2225 static void lp_add_auto_services(struct loadparm_context *lp_ctx,
2231 /***************************************************************************
2232 Have we loaded a services file yet?
2233 ***************************************************************************/
2235 bool lp_loaded(void)
2237 return (global_loadparm != NULL);
2240 /***************************************************************************
2241 Unload unused services.
2242 ***************************************************************************/
2244 void lp_killunused(struct loadparm_context *lp_ctx,
2245 struct smbsrv_connection *smb,
2246 bool (*snumused) (struct smbsrv_connection *, int))
2249 for (i = 0; i < lp_ctx->iNumServices; i++) {
2250 if (lp_ctx->ServicePtrs[i] == NULL)
2253 if (!snumused || !snumused(smb, i)) {
2254 talloc_free(lp_ctx->ServicePtrs[i]);
2255 lp_ctx->ServicePtrs[i] = NULL;
2261 static int lp_destructor(struct loadparm_context *lp_ctx)
2263 struct param_opt *data;
2265 if (lp_ctx->globals->param_opt != NULL) {
2266 struct param_opt *next;
2267 for (data = lp_ctx->globals->param_opt; data; data=next) {
2269 if (data->flags & FLAG_CMDLINE) continue;
2270 DLIST_REMOVE(lp_ctx->globals->param_opt, data);
2278 /***************************************************************************
2279 Initialise the global parameter structure.
2280 ***************************************************************************/
2281 struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
2285 struct loadparm_context *lp_ctx;
2287 lp_ctx = talloc_zero(mem_ctx, struct loadparm_context);
2291 talloc_set_destructor(lp_ctx, lp_destructor);
2292 lp_ctx->bInGlobalSection = true;
2293 lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
2295 DEBUG(3, ("Initialising global parameters\n"));
2297 for (i = 0; parm_table[i].label; i++) {
2298 if ((parm_table[i].type == P_STRING ||
2299 parm_table[i].type == P_USTRING) &&
2300 parm_table[i].offset != -1 &&
2301 !(parm_table[i].flags & FLAG_CMDLINE)) {
2302 char **r = ((char *)(parm_table[i].class == P_LOCAL)?&sDefault:lp_ctx->globals) + parm_table[i].offset;
2303 *r = talloc_strdup(lp_ctx, "");
2307 lp_do_global_parameter(lp_ctx, "share backend", "classic");
2309 lp_do_global_parameter(lp_ctx, "server role", "standalone");
2311 /* options that can be set on the command line must be initialised via
2312 the slower lp_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2314 lp_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2316 lp_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2317 myname = get_myname();
2318 lp_do_global_parameter(lp_ctx, "netbios name", myname);
2320 lp_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
2322 lp_do_global_parameter(lp_ctx, "fstype", FSTYPE_STRING);
2323 lp_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2324 lp_do_global_parameter(lp_ctx, "max connections", "-1");
2326 lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo");
2327 lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap web kdc drepl winbind");
2328 lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb");
2329 lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain");
2330 lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind");
2331 lp_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain");
2332 lp_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2333 lp_do_global_parameter(lp_ctx, "sam database", "sam.ldb");
2334 lp_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb");
2335 lp_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb");
2336 lp_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb");
2337 lp_do_global_parameter(lp_ctx, "wins database", "wins.ldb");
2338 lp_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2340 /* This hive should be dynamically generated by Samba using
2341 data from the sam, but for the moment leave it in a tdb to
2342 keep regedt32 from popping up an annoying dialog. */
2343 lp_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2345 /* using UTF8 by default allows us to support all chars */
2346 lp_do_global_parameter(lp_ctx, "unix charset", "UTF8");
2348 /* Use codepage 850 as a default for the dos character set */
2349 lp_do_global_parameter(lp_ctx, "dos charset", "CP850");
2352 * Allow the default PASSWD_CHAT to be overridden in local.h.
2354 lp_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2356 lp_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2357 lp_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2358 lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR);
2359 lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2361 lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0");
2362 lp_do_global_parameter_var(lp_ctx, "server string",
2363 "Samba %s", SAMBA_VERSION_STRING);
2365 lp_do_global_parameter_var(lp_ctx, "announce version", "%d.%d",
2366 DEFAULT_MAJOR_VERSION,
2367 DEFAULT_MINOR_VERSION);
2369 lp_do_global_parameter(lp_ctx, "password server", "*");
2371 lp_do_global_parameter(lp_ctx, "max mux", "50");
2372 lp_do_global_parameter(lp_ctx, "max xmit", "12288");
2373 lp_do_global_parameter(lp_ctx, "password level", "0");
2374 lp_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2375 lp_do_global_parameter(lp_ctx, "server min protocol", "CORE");
2376 lp_do_global_parameter(lp_ctx, "server max protocol", "NT1");
2377 lp_do_global_parameter(lp_ctx, "client min protocol", "CORE");
2378 lp_do_global_parameter(lp_ctx, "client max protocol", "NT1");
2379 lp_do_global_parameter(lp_ctx, "security", "USER");
2380 lp_do_global_parameter(lp_ctx, "paranoid server security", "True");
2381 lp_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2382 lp_do_global_parameter(lp_ctx, "ReadRaw", "True");
2383 lp_do_global_parameter(lp_ctx, "WriteRaw", "True");
2384 lp_do_global_parameter(lp_ctx, "NullPasswords", "False");
2385 lp_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2386 lp_do_global_parameter(lp_ctx, "announce as", "NT SERVER");
2388 lp_do_global_parameter(lp_ctx, "TimeServer", "False");
2389 lp_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2390 lp_do_global_parameter(lp_ctx, "Unicode", "True");
2391 lp_do_global_parameter(lp_ctx, "ClientLanManAuth", "True");
2392 lp_do_global_parameter(lp_ctx, "LanmanAuth", "True");
2393 lp_do_global_parameter(lp_ctx, "NTLMAuth", "True");
2394 lp_do_global_parameter(lp_ctx, "client use spnego principal", "False");
2396 lp_do_global_parameter(lp_ctx, "UnixExtensions", "False");
2398 lp_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2399 lp_do_global_parameter(lp_ctx, "LocalMaster", "True");
2401 lp_do_global_parameter(lp_ctx, "wins support", "False");
2402 lp_do_global_parameter(lp_ctx, "dns proxy", "True");
2404 lp_do_global_parameter(lp_ctx, "winbind separator", "\\");
2405 lp_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2406 lp_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2407 lp_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2408 lp_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
2410 lp_do_global_parameter(lp_ctx, "client signing", "Yes");
2411 lp_do_global_parameter(lp_ctx, "server signing", "auto");
2413 lp_do_global_parameter(lp_ctx, "use spnego", "True");
2415 lp_do_global_parameter(lp_ctx, "smb ports", "445 139");
2416 lp_do_global_parameter(lp_ctx, "nbt port", "137");
2417 lp_do_global_parameter(lp_ctx, "dgram port", "138");
2418 lp_do_global_parameter(lp_ctx, "cldap port", "389");
2419 lp_do_global_parameter(lp_ctx, "krb5 port", "88");
2420 lp_do_global_parameter(lp_ctx, "kpasswd port", "464");
2421 lp_do_global_parameter(lp_ctx, "web port", "901");
2422 lp_do_global_parameter(lp_ctx, "swat directory", dyn_SWATDIR);
2424 lp_do_global_parameter(lp_ctx, "nt status support", "True");
2426 lp_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2427 lp_do_global_parameter(lp_ctx, "min wins ttl", "10");
2429 lp_do_global_parameter(lp_ctx, "tls enabled", "True");
2430 lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2431 lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2432 lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2433 lp_do_global_parameter_var(lp_ctx, "js include", "%s", dyn_JSDIR);
2434 lp_do_global_parameter_var(lp_ctx, "setup directory", "%s",
2437 for (i = 0; parm_table[i].label; i++) {
2438 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
2439 parm_table[i].flags |= FLAG_DEFAULT;
2446 /***************************************************************************
2447 Load the services array from the services file. Return True on success,
2449 ***************************************************************************/
2450 bool lp_load(TALLOC_CTX *mem_ctx, const char *filename, struct loadparm_context **ret_lp)
2454 struct loadparm_context *lp_ctx;
2459 lp_ctx = loadparm_init(mem_ctx);
2463 global_loadparm = lp_ctx;
2465 filename = talloc_strdup(lp_ctx, filename);
2467 lp_ctx->globals->szConfigFile = filename;
2469 lp_ctx->bInGlobalSection = true;
2470 n2 = standard_sub_basic(lp_ctx, lp_ctx->globals->szConfigFile);
2471 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2473 add_to_file_list(lp_ctx, lp_ctx->globals->szConfigFile, n2);
2475 /* We get sections first, so have to start 'behind' to make up */
2476 lp_ctx->currentService = NULL;
2477 bRetval = pm_process(n2, do_section, do_parameter, lp_ctx);
2479 /* finish up the last section */
2480 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2482 if (lp_ctx->currentService != NULL)
2483 bRetval = service_ok(lp_ctx->currentService);
2485 lp_add_auto_services(lp_ctx, lp_auto_services(lp_ctx));
2487 lp_add_hidden(lp_ctx, "IPC$", "IPC");
2488 lp_add_hidden(lp_ctx, "ADMIN$", "DISK");
2490 if (!lp_ctx->globals->szWINSservers && lp_ctx->globals->bWINSsupport) {
2491 lp_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
2494 panic_action = lp_ctx->globals->panic_action;
2504 /***************************************************************************
2505 Return the max number of services.
2506 ***************************************************************************/
2508 int lp_numservices(struct loadparm_context *lp_ctx)
2510 return lp_ctx->iNumServices;
2513 /***************************************************************************
2514 Display the contents of the services array in human-readable form.
2515 ***************************************************************************/
2517 void lp_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
2523 defaults_saved = false;
2525 dump_globals(lp_ctx, f, show_defaults);
2527 dump_a_service(&sDefault, f);
2529 for (iService = 0; iService < maxtoprint; iService++)
2530 lp_dump_one(f, show_defaults, lp_ctx->ServicePtrs[iService]);
2533 /***************************************************************************
2534 Display the contents of one service in human-readable form.
2535 ***************************************************************************/
2537 void lp_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service)
2539 if (service != NULL) {
2540 if (service->szService[0] == '\0')
2542 dump_a_service(service, f);
2546 struct loadparm_service *lp_servicebynum(struct loadparm_context *lp_ctx,
2549 return lp_ctx->ServicePtrs[snum];
2552 struct loadparm_service *lp_service(struct loadparm_context *lp_ctx,
2553 const char *service_name)
2558 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
2559 if (lp_ctx->ServicePtrs[iService] &&
2560 lp_ctx->ServicePtrs[iService]->szService) {
2562 * The substitution here is used to support %U is
2565 serviceName = standard_sub_basic(
2566 lp_ctx->ServicePtrs[iService],
2567 lp_ctx->ServicePtrs[iService]->szService);
2568 if (strequal(serviceName, service_name))
2569 return lp_ctx->ServicePtrs[iService];
2573 DEBUG(7,("lp_servicenumber: couldn't find %s\n", service_name));
2578 /*******************************************************************
2579 A useful volume label function.
2580 ********************************************************************/
2581 const char *volume_label(struct loadparm_service *service)
2583 const char *ret = lp_volume(service);
2585 return lp_servicename(service);
2590 /***********************************************************
2591 If we are PDC then prefer us as DMB
2592 ************************************************************/
2594 bool lp_domain_logons(struct loadparm_context *lp_ctx)
2596 return (lp_server_role(lp_ctx) == ROLE_DOMAIN_CONTROLLER);
2599 const char *lp_printername(struct loadparm_service *service)
2601 const char *ret = _lp_printername(service);
2602 if (ret == NULL || (ret != NULL && *ret == '\0'))
2603 ret = lp_const_servicename(service);
2609 /*******************************************************************
2610 Return the max print jobs per queue.
2611 ********************************************************************/
2613 int lp_maxprintjobs(struct loadparm_service *service)
2615 int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2616 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2617 maxjobs = PRINT_MAX_JOBID - 1;