2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 3 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/locale.h"
60 #include "system/network.h" /* needed for TCP_NODELAY */
61 #include "smb_server/smb_server.h"
62 #include "libcli/raw/signing.h"
63 #include "lib/util/dlinklist.h"
64 #include "param/param.h"
65 #include "param/loadparm.h"
67 static bool bLoaded = false;
69 #define standard_sub_basic talloc_strdup
71 static bool do_parameter(const char *, const char *, void *);
72 static bool defaults_saved = false;
75 * This structure describes global (ie., server-wide) parameters.
77 struct loadparm_global
79 enum server_role server_role;
81 const char **smb_ports;
85 char *display_charset;
93 const char *szConfigFile;
98 char *szWINS_CONFIG_URL;
101 const char **jsInclude;
102 char *jsonrpcServicesDir;
103 const char **szPasswordServers;
104 char *szSocketOptions;
106 const char **szWINSservers;
107 const char **szInterfaces;
108 char *szSocketAddress;
109 char *szAnnounceVersion; /* This is initialised in init_globals */
112 const char **szNetbiosAliases;
113 char *szNetbiosScope;
114 char *szDomainOtherSIDs;
115 const char **szNameResolveOrder;
116 const char **dcerpc_ep_servers;
117 const char **server_services;
118 char *ntptr_providor;
119 char *szWinbindSeparator;
120 char *szWinbinddSocketDirectory;
121 char *szTemplateShell;
122 char *szTemplateHomedir;
123 int bWinbindSealedPipes;
124 char *swat_directory;
142 int paranoid_server_security;
145 int announce_as; /* This is initialised in init_globals */
152 char *socket_options;
157 int bPreferredMaster;
158 int bEncryptPasswords;
160 int bObeyPamRestrictions;
165 int bBindInterfacesOnly;
167 int bNTStatusSupport;
173 int bClientPlaintextAuth;
174 int bClientLanManAuth;
175 int bClientNTLMv2Auth;
176 int client_use_spnego_principal;
182 struct param_opt *param_opt;
187 * This structure describes a single service.
189 struct loadparm_service
201 char **ntvfs_handler;
214 int iCreate_force_mode;
221 struct param_opt *param_opt;
223 char dummy[3]; /* for alignment */
227 /* This is a default service used to prime a services structure */
228 struct loadparm_service sDefault = {
233 .szPrintername = NULL,
234 .szHostsallow = NULL,
239 .ntvfs_handler = NULL,
240 .iMaxPrintJobs = 1000,
241 .iMaxConnections = 0,
247 .bMap_system = false,
248 .bMap_hidden = false,
249 .bMap_archive = true,
250 .bStrictLocking = true,
251 .iCreate_mask = 0744,
252 .iCreate_force_mode = 0000,
254 .iDir_force_mode = 0000,
257 .bStrictSync = false,
258 .bCIFileSystem = false,
261 /* local variables */
262 struct loadparm_context {
263 struct loadparm_global Globals;
264 struct loadparm_service **ServicePtrs;
266 struct loadparm_service *currentService;
267 bool bInGlobalSection;
269 struct file_lists *next;
276 struct loadparm_context *global_loadparm = NULL;
278 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
280 /* prototypes for the special type handlers */
281 static bool handle_include(struct loadparm_context *lp_ctx,
282 const char *pszParmValue, char **ptr);
283 static bool handle_copy(struct loadparm_context *lp_ctx,
284 const char *pszParmValue, char **ptr);
285 static bool handle_debuglevel(struct loadparm_context *lp_ctx,
286 const char *pszParmValue, char **ptr);
287 static bool handle_logfile(struct loadparm_context *lp_ctx,
288 const char *pszParmValue, char **ptr);
290 static const struct enum_list enum_protocol[] = {
291 {PROTOCOL_SMB2, "SMB2"},
292 {PROTOCOL_NT1, "NT1"},
293 {PROTOCOL_LANMAN2, "LANMAN2"},
294 {PROTOCOL_LANMAN1, "LANMAN1"},
295 {PROTOCOL_CORE, "CORE"},
296 {PROTOCOL_COREPLUS, "COREPLUS"},
297 {PROTOCOL_COREPLUS, "CORE+"},
301 static const struct enum_list enum_security[] = {
302 {SEC_SHARE, "SHARE"},
307 static const struct enum_list enum_announce_as[] = {
308 {ANNOUNCE_AS_NT_SERVER, "NT"},
309 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
310 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
311 {ANNOUNCE_AS_WIN95, "win95"},
312 {ANNOUNCE_AS_WFW, "WfW"},
316 static const struct enum_list enum_bool_auto[] = {
327 /* Client-side offline caching policy types */
330 CSC_POLICY_DOCUMENTS=1,
331 CSC_POLICY_PROGRAMS=2,
335 static const struct enum_list enum_csc_policy[] = {
336 {CSC_POLICY_MANUAL, "manual"},
337 {CSC_POLICY_DOCUMENTS, "documents"},
338 {CSC_POLICY_PROGRAMS, "programs"},
339 {CSC_POLICY_DISABLE, "disable"},
343 /* SMB signing types. */
344 static const struct enum_list enum_smb_signing_vals[] = {
345 {SMB_SIGNING_OFF, "No"},
346 {SMB_SIGNING_OFF, "False"},
347 {SMB_SIGNING_OFF, "0"},
348 {SMB_SIGNING_OFF, "Off"},
349 {SMB_SIGNING_OFF, "disabled"},
350 {SMB_SIGNING_SUPPORTED, "Yes"},
351 {SMB_SIGNING_SUPPORTED, "True"},
352 {SMB_SIGNING_SUPPORTED, "1"},
353 {SMB_SIGNING_SUPPORTED, "On"},
354 {SMB_SIGNING_SUPPORTED, "enabled"},
355 {SMB_SIGNING_REQUIRED, "required"},
356 {SMB_SIGNING_REQUIRED, "mandatory"},
357 {SMB_SIGNING_REQUIRED, "force"},
358 {SMB_SIGNING_REQUIRED, "forced"},
359 {SMB_SIGNING_REQUIRED, "enforced"},
360 {SMB_SIGNING_AUTO, "auto"},
364 static const struct enum_list enum_server_role[] = {
365 {ROLE_STANDALONE, "standalone"},
366 {ROLE_DOMAIN_MEMBER, "member server"},
367 {ROLE_DOMAIN_CONTROLLER, "domain controller"},
372 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
374 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
375 * is implied in current control logic. This may change at some later time. A
376 * flag value of 0 means - show as development option only.
378 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
379 * screen in SWAT. This is used to exclude parameters as well as to squash all
380 * parameters that have been duplicated by pseudonyms.
383 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
384 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
386 static struct parm_struct parm_table[] = {
387 {"config file", P_STRING, P_GLOBAL, GLOBAL_VAR(szConfigFile), NULL, NULL, FLAG_HIDE},
389 {"server role", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_role), NULL, enum_server_role, FLAG_BASIC},
391 {"dos charset", P_STRING, P_GLOBAL, GLOBAL_VAR(dos_charset), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"unix charset", P_STRING, P_GLOBAL, GLOBAL_VAR(unix_charset), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"ncalrpc dir", P_STRING, P_GLOBAL, GLOBAL_VAR(ncalrpc_dir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
394 {"display charset", P_STRING, P_GLOBAL, GLOBAL_VAR(display_charset), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
395 {"comment", P_STRING, P_LOCAL, LOCAL_VAR(comment), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
396 {"path", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
397 {"directory", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL, FLAG_HIDE},
398 {"workgroup", P_USTRING, P_GLOBAL, GLOBAL_VAR(szWorkgroup), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"realm", P_STRING, P_GLOBAL, GLOBAL_VAR(szRealm), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"netbios name", P_USTRING, P_GLOBAL, GLOBAL_VAR(szNetbiosName), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"netbios aliases", P_LIST, P_GLOBAL, GLOBAL_VAR(szNetbiosAliases), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
402 {"netbios scope", P_USTRING, P_GLOBAL, GLOBAL_VAR(szNetbiosScope), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
403 {"server string", P_STRING, P_GLOBAL, GLOBAL_VAR(szServerString), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
404 {"interfaces", P_LIST, P_GLOBAL, GLOBAL_VAR(szInterfaces), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"bind interfaces only", P_BOOL, P_GLOBAL, GLOBAL_VAR(bBindInterfacesOnly), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
406 {"ntvfs handler", P_LIST, P_LOCAL, LOCAL_VAR(ntvfs_handler), NULL, NULL, FLAG_ADVANCED},
407 {"ntptr providor", P_STRING, P_GLOBAL, GLOBAL_VAR(ntptr_providor), NULL, NULL, FLAG_ADVANCED},
408 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, GLOBAL_VAR(dcerpc_ep_servers), NULL, NULL, FLAG_ADVANCED},
409 {"server services", P_LIST, P_GLOBAL, GLOBAL_VAR(server_services), NULL, NULL, FLAG_ADVANCED},
411 {"security", P_ENUM, P_GLOBAL, GLOBAL_VAR(security), NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
412 {"encrypt passwords", P_BOOL, P_GLOBAL, GLOBAL_VAR(bEncryptPasswords), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
413 {"null passwords", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNullPasswords), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"obey pam restrictions", P_BOOL, P_GLOBAL, GLOBAL_VAR(bObeyPamRestrictions), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"password server", P_LIST, P_GLOBAL, GLOBAL_VAR(szPasswordServers), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
416 {"sam database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSAM_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"secrets database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSECRETS_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"spoolss database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSPOOLSS_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"wins config database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_CONFIG_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"wins database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_URL), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"private dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szPrivateDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"passwd chat", P_STRING, P_GLOBAL, GLOBAL_VAR(szPasswdChat), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"password level", P_INTEGER, P_GLOBAL, GLOBAL_VAR(pwordlevel), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"lanman auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLanmanAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"ntlm auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNTLMAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientNTLMv2Auth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"client lanman auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientLanManAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"client plaintext auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientPlaintextAuth), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"client use spnego principal", P_BOOL, P_GLOBAL, GLOBAL_VAR(client_use_spnego_principal), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
431 {"read only", P_BOOL, P_LOCAL, LOCAL_VAR(bRead_only), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
433 {"create mask", P_OCTAL, P_LOCAL, LOCAL_VAR(iCreate_mask), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
434 {"force create mode", P_OCTAL, P_LOCAL, LOCAL_VAR(iCreate_force_mode), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
435 {"directory mask", P_OCTAL, P_LOCAL, LOCAL_VAR(iDir_mask), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
436 {"force directory mode", P_OCTAL, P_LOCAL, LOCAL_VAR(iDir_force_mode), NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
438 {"hosts allow", P_LIST, P_LOCAL, LOCAL_VAR(szHostsallow), NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
439 {"hosts deny", P_LIST, P_LOCAL, LOCAL_VAR(szHostsdeny), NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
441 {"log level", P_INTEGER, P_GLOBAL, GLOBAL_VAR(debuglevel), handle_debuglevel, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"debuglevel", P_INTEGER, P_GLOBAL, GLOBAL_VAR(debuglevel), handle_debuglevel, NULL, FLAG_HIDE},
443 {"log file", P_STRING, P_GLOBAL, GLOBAL_VAR(logfile), handle_logfile, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"smb ports", P_LIST, P_GLOBAL, GLOBAL_VAR(smb_ports), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"nbt port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(nbt_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"dgram port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(dgram_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"cldap port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(cldap_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"krb5 port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(krb5_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"kpasswd port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(kpasswd_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"web port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(web_port), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"tls enabled", P_BOOL, P_GLOBAL, GLOBAL_VAR(tls_enabled), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"tls keyfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_keyfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"tls certfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_certfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"tls cafile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_cafile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"tls crlfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_crlfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"tls dh params file", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_dhpfile), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"swat directory", P_STRING, P_GLOBAL, GLOBAL_VAR(swat_directory), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"large readwrite", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLargeReadwrite), NULL, NULL, FLAG_DEVELOPER},
460 {"server max protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(srv_maxprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
461 {"server min protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(srv_minprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
462 {"client max protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(cli_maxprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
463 {"client min protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(cli_minprotocol), NULL, enum_protocol, FLAG_DEVELOPER},
464 {"unicode", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUnicode), NULL, NULL, FLAG_DEVELOPER},
465 {"read raw", P_BOOL, P_GLOBAL, GLOBAL_VAR(bReadRaw), NULL, NULL, FLAG_DEVELOPER},
466 {"write raw", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWriteRaw), NULL, NULL, FLAG_DEVELOPER},
467 {"disable netbios", P_BOOL, P_GLOBAL, GLOBAL_VAR(bDisableNetbios), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"nt status support", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNTStatusSupport), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
471 {"announce version", P_STRING, P_GLOBAL, GLOBAL_VAR(szAnnounceVersion), NULL, NULL, FLAG_DEVELOPER},
472 {"announce as", P_ENUM, P_GLOBAL, GLOBAL_VAR(announce_as), NULL, enum_announce_as, FLAG_DEVELOPER},
473 {"max mux", P_INTEGER, P_GLOBAL, GLOBAL_VAR(max_mux), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"max xmit", P_BYTES, P_GLOBAL, GLOBAL_VAR(max_xmit), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"name resolve order", P_LIST, P_GLOBAL, GLOBAL_VAR(szNameResolveOrder), NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
477 {"max wins ttl", P_INTEGER, P_GLOBAL, GLOBAL_VAR(max_wins_ttl), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
478 {"min wins ttl", P_INTEGER, P_GLOBAL, GLOBAL_VAR(min_wins_ttl), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
479 {"time server", P_BOOL, P_GLOBAL, GLOBAL_VAR(bTimeServer), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
480 {"unix extensions", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUnixExtensions), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
481 {"use spnego", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUseSpnego), NULL, NULL, FLAG_DEVELOPER},
482 {"server signing", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_signing), NULL, enum_smb_signing_vals, FLAG_ADVANCED},
483 {"client signing", P_ENUM, P_GLOBAL, GLOBAL_VAR(client_signing), NULL, enum_smb_signing_vals, FLAG_ADVANCED},
484 {"rpc big endian", P_BOOL, P_GLOBAL, GLOBAL_VAR(bRpcBigEndian), NULL, NULL, FLAG_DEVELOPER},
486 {"max connections", P_INTEGER, P_LOCAL, LOCAL_VAR(iMaxConnections), NULL, NULL, FLAG_SHARE},
487 {"paranoid server security", P_BOOL, P_GLOBAL, GLOBAL_VAR(paranoid_server_security), NULL, NULL, FLAG_DEVELOPER},
488 {"socket options", P_STRING, P_GLOBAL, GLOBAL_VAR(socket_options), NULL, NULL, FLAG_DEVELOPER},
490 {"strict sync", P_BOOL, P_LOCAL, LOCAL_VAR(bStrictSync), NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
491 {"case insensitive filesystem", P_BOOL, P_LOCAL, LOCAL_VAR(bCIFileSystem), NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
493 {"max print jobs", P_INTEGER, P_LOCAL, LOCAL_VAR(iMaxPrintJobs), NULL, NULL, FLAG_PRINT},
494 {"printable", P_BOOL, P_LOCAL, LOCAL_VAR(bPrint_ok), NULL, NULL, FLAG_PRINT},
495 {"print ok", P_BOOL, P_LOCAL, LOCAL_VAR(bPrint_ok), NULL, NULL, FLAG_HIDE},
497 {"printer name", P_STRING, P_LOCAL, LOCAL_VAR(szPrintername), NULL, NULL, FLAG_PRINT},
498 {"printer", P_STRING, P_LOCAL, LOCAL_VAR(szPrintername), NULL, NULL, FLAG_HIDE},
500 {"map system", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_system), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
501 {"map hidden", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_hidden), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
502 {"map archive", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_archive), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
504 {"preferred master", P_ENUM, P_GLOBAL, GLOBAL_VAR(bPreferredMaster), NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
505 {"prefered master", P_ENUM, P_GLOBAL, GLOBAL_VAR(bPreferredMaster), NULL, enum_bool_auto, FLAG_HIDE},
506 {"local master", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLocalMaster), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
507 {"browseable", P_BOOL, P_LOCAL, LOCAL_VAR(bBrowseable), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
508 {"browsable", P_BOOL, P_LOCAL, LOCAL_VAR(bBrowseable), NULL, NULL, FLAG_HIDE},
510 {"wins server", P_LIST, P_GLOBAL, GLOBAL_VAR(szWINSservers), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
511 {"wins support", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWINSsupport), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
512 {"dns proxy", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWINSdnsProxy), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
513 {"wins hook", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINSHook), NULL, NULL, FLAG_ADVANCED},
515 {"csc policy", P_ENUM, P_LOCAL, LOCAL_VAR(iCSCPolicy), NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
517 {"strict locking", P_BOOL, P_LOCAL, LOCAL_VAR(bStrictLocking), NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
519 {"share backend", P_STRING, P_GLOBAL, GLOBAL_VAR(szShareBackend), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
520 {"preload", P_STRING, P_GLOBAL, GLOBAL_VAR(szAutoServices), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
521 {"auto services", P_STRING, P_GLOBAL, GLOBAL_VAR(szAutoServices), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
522 {"lock dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL, FLAG_HIDE},
523 {"lock directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
524 {"modules dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szModulesDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
525 {"pid directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szPidDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
526 {"js include", P_LIST, P_GLOBAL, GLOBAL_VAR(jsInclude), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
527 {"setup directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szSetupDir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
529 {"socket address", P_STRING, P_GLOBAL, GLOBAL_VAR(szSocketAddress), NULL, NULL, FLAG_DEVELOPER},
530 {"copy", P_STRING, P_LOCAL, LOCAL_VAR(szCopy), handle_copy, NULL, FLAG_HIDE},
531 {"include", P_STRING, P_LOCAL, LOCAL_VAR(szInclude), handle_include, NULL, FLAG_HIDE},
533 {"available", P_BOOL, P_LOCAL, LOCAL_VAR(bAvailable), NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
534 {"volume", P_STRING, P_LOCAL, LOCAL_VAR(volume), NULL, NULL, FLAG_SHARE },
535 {"fstype", P_STRING, P_LOCAL, LOCAL_VAR(fstype), NULL, NULL, FLAG_SHARE},
537 {"panic action", P_STRING, P_GLOBAL, GLOBAL_VAR(panic_action), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"msdfs root", P_BOOL, P_LOCAL, LOCAL_VAR(bMSDfsRoot), NULL, NULL, FLAG_SHARE},
540 {"host msdfs", P_BOOL, P_GLOBAL, GLOBAL_VAR(bHostMSDfs), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"winbind separator", P_STRING, P_GLOBAL, GLOBAL_VAR(szWinbindSeparator), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
542 {"winbindd socket directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szWinbinddSocketDirectory), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
543 {"winbind sealed pipes", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWinbindSealedPipes), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
544 {"template shell", P_STRING, P_GLOBAL, GLOBAL_VAR(szTemplateShell), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
545 {"template homedir", P_STRING, P_GLOBAL, GLOBAL_VAR(szTemplateHomedir), NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
547 {NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
552 return the parameter table
554 struct parm_struct *lp_parm_table(void)
559 static TALLOC_CTX *lp_talloc;
561 /******************************************************************* a
562 Free up temporary memory - called from the main loop.
563 ********************************************************************/
565 void lp_talloc_free(void)
569 talloc_free(lp_talloc);
573 /*******************************************************************
574 Convenience routine to grab string parameters into temporary memory
575 and run standard_sub_basic on them. The buffers can be written to by
576 callers without affecting the source string.
577 ********************************************************************/
579 static const char *lp_string(const char *s)
581 #if 0 /* until REWRITE done to make thread-safe */
582 size_t len = s ? strlen(s) : 0;
586 /* The follow debug is useful for tracking down memory problems
587 especially if you have an inner loop that is calling a lp_*()
588 function that returns a string. Perhaps this debug should be
589 present all the time? */
592 DEBUG(10, ("lp_string(%s)\n", s));
595 #if 0 /* until REWRITE done to make thread-safe */
597 lp_talloc = talloc_init("lp_talloc");
599 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
607 strlcpy(ret, s, len);
609 if (trim_string(ret, "\"", "\"")) {
610 if (strchr(ret,'"') != NULL)
611 strlcpy(ret, s, len);
614 standard_sub_basic(ret,len+100);
621 In this section all the functions that are used to access the
622 parameters from the rest of the program are defined
625 #define FN_GLOBAL_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_string(lp_ctx->Globals.var_name) : "";}
627 #define FN_GLOBAL_CONST_STRING(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 ? lp_ctx->Globals.var_name : "";}
629 #define FN_GLOBAL_LIST(fn_name,var_name) \
630 const char **fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->Globals.var_name;}
631 #define FN_GLOBAL_BOOL(fn_name,var_name) \
632 bool fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return false; return lp_ctx->Globals.var_name;}
634 #define FN_GLOBAL_CHAR(fn_name,ptr) \
635 char fn_name(void) {return(*(char *)(ptr));}
637 #define FN_GLOBAL_INTEGER(fn_name,var_name) \
638 int fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return 0; return lp_ctx->Globals.var_name;}
640 #define FN_LOCAL_STRING(fn_name,val) \
641 const char *fn_name(struct loadparm_service *service) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault.val)));}
642 #define FN_LOCAL_CONST_STRING(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_LIST(fn_name,val) \
645 const char **fn_name(struct loadparm_service *service) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault.val);}
646 #define FN_LOCAL_BOOL(fn_name,val) \
647 bool fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
648 #define FN_LOCAL_INTEGER(fn_name,val) \
649 int fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
651 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, server_role)
652 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, smb_ports)
653 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, nbt_port)
654 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, dgram_port)
655 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, cldap_port)
656 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, krb5_port)
657 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, kpasswd_port)
658 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, web_port)
659 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, swat_directory)
660 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, tls_enabled)
661 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, tls_keyfile)
662 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, tls_certfile)
663 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, tls_cafile)
664 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, tls_crlfile)
665 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_dhpfile, tls_dhpfile)
666 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, szShareBackend)
667 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, szSAM_URL)
668 _PUBLIC_ FN_GLOBAL_STRING(lp_secrets_url, szSECRETS_URL)
669 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, szSPOOLSS_URL)
670 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, szWINS_CONFIG_URL)
671 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, szWINS_URL)
672 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator)
673 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, szWinbinddSocketDirectory)
674 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell)
675 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir)
676 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, bWinbindSealedPipes)
677 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, szPrivateDir)
678 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, szServerString)
679 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, szLockDir)
680 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, szModulesDir)
681 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, szSetupDir)
682 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, ncalrpc_dir)
683 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, dos_charset)
684 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, unix_charset)
685 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, display_charset)
686 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, szPidDir)
687 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, dcerpc_ep_servers)
688 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, server_services)
689 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, ntptr_providor)
690 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, szAutoServices)
691 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat)
692 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, szPasswordServers)
693 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, szNameResolveOrder)
694 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, szRealm)
695 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, socket_options)
696 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, szWorkgroup)
697 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, szNetbiosName)
698 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, szNetbiosScope)
699 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers)
700 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, szInterfaces)
701 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, szSocketAddress)
702 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases)
704 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios)
705 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, bWINSsupport)
706 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, bWINSdnsProxy)
707 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, szWINSHook)
708 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, szConfigFile)
709 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, bLocalMaster)
710 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, bReadRaw)
711 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite)
712 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, bWriteRaw)
713 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords)
714 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions)
715 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords)
716 _PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, bTimeServer)
717 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly)
718 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, bUnicode)
719 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport)
720 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth)
721 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth)
722 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth)
723 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth)
724 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth)
725 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal)
726 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs)
727 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions)
728 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego)
729 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, bRpcBigEndian)
730 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl)
731 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl)
732 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, max_mux)
733 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, max_xmit)
734 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel)
735 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, srv_maxprotocol)
736 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, srv_minprotocol)
737 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, cli_maxprotocol)
738 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, cli_minprotocol)
739 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, security)
740 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
741 _PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, announce_as)
742 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, jsInclude)
743 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
744 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
745 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
746 static FN_LOCAL_STRING(_lp_printername, szPrintername)
747 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
748 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
749 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
750 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
751 static FN_LOCAL_STRING(lp_volume, volume)
752 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
753 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
754 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
755 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
756 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
757 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
758 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
759 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
760 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
761 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
762 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
763 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
764 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
765 _PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
766 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
767 _PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
768 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
769 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, server_signing)
770 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, client_signing)
772 /* local prototypes */
773 static int map_parameter(const char *pszParmName);
774 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
775 const char *pszServiceName);
776 static void copy_service(struct loadparm_service *pserviceDest,
777 struct loadparm_service *pserviceSource,
779 static bool service_ok(struct loadparm_service *service);
780 static bool do_section(const char *pszSectionName, void *);
781 static void init_copymap(struct loadparm_service *pservice);
783 /* This is a helper function for parametrical options support. */
784 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
785 /* Actual parametrical functions are quite simple */
786 const char *lp_get_parametric(struct loadparm_context *lp_ctx,
787 struct loadparm_service *service,
788 const char *type, const char *option)
791 struct param_opt *data;
793 data = (service == NULL ? lp_ctx->Globals.param_opt : service->param_opt);
795 asprintf(&vfskey, "%s:%s", type, option);
799 if (strcmp(data->key, vfskey) == 0) {
806 if (service != NULL) {
807 /* Try to fetch the same option but from globals */
808 /* but only if we are not already working with Globals */
809 for (data = lp_ctx->Globals.param_opt; data;
811 if (strcmp(data->key, vfskey) == 0) {
824 /*******************************************************************
825 convenience routine to return int parameters.
826 ********************************************************************/
827 static int lp_int(const char *s)
831 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
835 return strtol(s, NULL, 0);
838 /*******************************************************************
839 convenience routine to return unsigned long parameters.
840 ********************************************************************/
841 static int lp_ulong(const char *s)
845 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
849 return strtoul(s, NULL, 0);
852 /*******************************************************************
853 convenience routine to return unsigned long parameters.
854 ********************************************************************/
855 static double lp_double(const char *s)
859 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
863 return strtod(s, NULL);
866 /*******************************************************************
867 convenience routine to return boolean parameters.
868 ********************************************************************/
869 static bool lp_bool(const char *s)
874 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
878 if (!set_boolean(s, &ret)) {
879 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
887 /* Return parametric option from a given service. Type is a part of option before ':' */
888 /* Parametric option has following syntax: 'Type: option = value' */
889 /* Returned value is allocated in 'lp_talloc' context */
891 const char *lp_parm_string(struct loadparm_context *lp_ctx,
892 struct loadparm_service *service, const char *type,
895 const char *value = lp_get_parametric(lp_ctx, service, type, option);
898 return lp_string(value);
903 /* Return parametric option from a given service. Type is a part of option before ':' */
904 /* Parametric option has following syntax: 'Type: option = value' */
905 /* Returned value is allocated in 'lp_talloc' context */
907 const char **lp_parm_string_list(struct loadparm_context *lp_ctx,
908 struct loadparm_service *service,
910 const char *option, const char *separator)
912 const char *value = lp_get_parametric(lp_ctx, service, type, option);
915 return str_list_make(talloc_autofree_context(), value,
921 /* Return parametric option from a given service. Type is a part of option before ':' */
922 /* Parametric option has following syntax: 'Type: option = value' */
924 int lp_parm_int(struct loadparm_context *lp_ctx,
925 struct loadparm_service *service, const char *type,
926 const char *option, int default_v)
928 const char *value = lp_get_parametric(lp_ctx, service, type, option);
931 return lp_int(value);
936 /* Return parametric option from a given service. Type is a part of
938 * Parametric option has following syntax: 'Type: option = value'.
941 int lp_parm_bytes(struct loadparm_context *lp_ctx,
942 struct loadparm_service *service, const char *type,
943 const char *option, int default_v)
947 const char *value = lp_get_parametric(lp_ctx, service, type, option);
949 if (value && conv_str_size(value, &bval)) {
950 if (bval <= INT_MAX) {
958 /* Return parametric option from a given service. Type is a part of option before ':' */
959 /* Parametric option has following syntax: 'Type: option = value' */
961 unsigned long lp_parm_ulong(struct loadparm_context *lp_ctx,
962 struct loadparm_service *service, const char *type,
963 const char *option, unsigned long default_v)
965 const char *value = lp_get_parametric(lp_ctx, service, type, option);
968 return lp_ulong(value);
974 double lp_parm_double(struct loadparm_context *lp_ctx,
975 struct loadparm_service *service, const char *type,
976 const char *option, double default_v)
978 const char *value = lp_get_parametric(lp_ctx, service, type, option);
981 return lp_double(value);
986 /* Return parametric option from a given service. Type is a part of option before ':' */
987 /* Parametric option has following syntax: 'Type: option = value' */
989 bool lp_parm_bool(struct loadparm_context *lp_ctx,
990 struct loadparm_service *service, const char *type,
991 const char *option, bool default_v)
993 const char *value = lp_get_parametric(lp_ctx, service, type, option);
996 return lp_bool(value);
1002 /***************************************************************************
1003 Initialise a service to the defaults.
1004 ***************************************************************************/
1006 static struct loadparm_service *init_service(TALLOC_CTX *mem_ctx)
1008 struct loadparm_service *pservice =
1009 talloc_zero(mem_ctx, struct loadparm_service);
1010 copy_service(pservice, &sDefault, NULL);
1015 Set a string value, deallocating any existing space, and allocing the space
1018 static bool string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
1025 *dest = talloc_strdup(mem_ctx, src);
1026 if ((*dest) == NULL) {
1027 DEBUG(0,("Out of memory in string_init\n"));
1036 /***************************************************************************
1037 Add a new service to the services array initialising it with the given
1039 ***************************************************************************/
1041 struct loadparm_service *lp_add_service(struct loadparm_context *lp_ctx,
1042 const struct loadparm_service *pservice,
1046 struct loadparm_service tservice;
1047 int num_to_alloc = lp_ctx->iNumServices + 1;
1048 struct param_opt *data, *pdata;
1050 tservice = *pservice;
1052 /* it might already exist */
1054 struct loadparm_service *service = getservicebyname(lp_ctx,
1056 if (service != NULL) {
1057 /* Clean all parametric options for service */
1058 /* They will be added during parsing again */
1059 data = service->param_opt;
1065 service->param_opt = NULL;
1070 /* find an invalid one */
1071 for (i = 0; i < lp_ctx->iNumServices; i++)
1072 if (lp_ctx->ServicePtrs[i] == NULL)
1075 /* if not, then create one */
1076 if (i == lp_ctx->iNumServices) {
1077 struct loadparm_service **tsp;
1079 tsp = talloc_realloc(lp_ctx, lp_ctx->ServicePtrs, struct loadparm_service *,
1083 DEBUG(0,("lp_add_service: failed to enlarge ServicePtrs!\n"));
1087 lp_ctx->ServicePtrs = tsp;
1088 lp_ctx->ServicePtrs[lp_ctx->iNumServices] = NULL;
1091 lp_ctx->iNumServices++;
1094 lp_ctx->ServicePtrs[i] = init_service(lp_ctx);
1095 if (lp_ctx->ServicePtrs[i] == NULL) {
1096 DEBUG(0,("lp_add_service: out of memory!\n"));
1099 copy_service(lp_ctx->ServicePtrs[i], &tservice, NULL);
1101 string_set(lp_ctx->ServicePtrs[i], &lp_ctx->ServicePtrs[i]->szService, name);
1102 return lp_ctx->ServicePtrs[i];
1105 /***************************************************************************
1106 Add a new home service, with the specified home directory, defaults coming
1108 ***************************************************************************/
1110 bool lp_add_home(struct loadparm_context *lp_ctx,
1111 const char *pszHomename,
1112 struct loadparm_service *default_service,
1113 const char *user, const char *pszHomedir)
1115 struct loadparm_service *service;
1117 service = lp_add_service(lp_ctx, default_service, pszHomename);
1119 if (service == NULL)
1122 if (!(*(default_service->szPath))
1123 || strequal(default_service->szPath, sDefault.szPath)) {
1124 service->szPath = talloc_strdup(service, pszHomedir);
1126 service->szPath = string_sub_talloc(service, lp_pathname(default_service),"%H", pszHomedir);
1129 if (!(*(service->comment))) {
1130 service->comment = talloc_asprintf(service, "Home directory of %s", user);
1132 service->bAvailable = default_service->bAvailable;
1133 service->bBrowseable = default_service->bBrowseable;
1135 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
1136 pszHomename, user, service->szPath));
1141 /***************************************************************************
1142 Add the IPC service.
1143 ***************************************************************************/
1145 static bool lp_add_hidden(struct loadparm_context *lp_ctx, const char *name,
1148 struct loadparm_service *service = lp_add_service(lp_ctx, &sDefault, name);
1150 if (service == NULL)
1153 string_set(service, &service->szPath, tmpdir());
1155 service->comment = talloc_asprintf(service, "%s Service (%s)",
1156 fstype, lp_ctx->Globals.szServerString);
1157 string_set(service, &service->fstype, fstype);
1158 service->iMaxConnections = -1;
1159 service->bAvailable = true;
1160 service->bRead_only = true;
1161 service->bPrint_ok = false;
1162 service->bBrowseable = false;
1164 if (strcasecmp(fstype, "IPC") == 0) {
1165 lp_do_service_parameter(lp_ctx, service, "ntvfs handler",
1169 DEBUG(3, ("adding hidden service %s\n", name));
1174 /***************************************************************************
1175 Add a new printer service, with defaults coming from service iFrom.
1176 ***************************************************************************/
1178 bool lp_add_printer(struct loadparm_context *lp_ctx,
1179 const char *pszPrintername,
1180 struct loadparm_service *default_service)
1182 const char *comment = "From Printcap";
1183 struct loadparm_service *service;
1184 service = lp_add_service(lp_ctx, default_service, pszPrintername);
1186 if (service == NULL)
1189 /* note that we do NOT default the availability flag to True - */
1190 /* we take it from the default service passed. This allows all */
1191 /* dynamic printers to be disabled by disabling the [printers] */
1192 /* entry (if/when the 'available' keyword is implemented!). */
1194 /* the printer name is set to the service name. */
1195 string_set(service, &service->szPrintername, pszPrintername);
1196 string_set(service, &service->comment, comment);
1197 service->bBrowseable = sDefault.bBrowseable;
1198 /* Printers cannot be read_only. */
1199 service->bRead_only = false;
1200 /* Printer services must be printable. */
1201 service->bPrint_ok = true;
1203 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1208 /***************************************************************************
1209 Map a parameter's string representation to something we can use.
1210 Returns False if the parameter string is not recognised, else TRUE.
1211 ***************************************************************************/
1213 static int map_parameter(const char *pszParmName)
1217 if (*pszParmName == '-')
1220 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1221 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1224 /* Warn only if it isn't parametric option */
1225 if (strchr(pszParmName, ':') == NULL)
1226 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1227 /* We do return 'fail' for parametric options as well because they are
1228 stored in different storage
1235 return the parameter structure for a parameter
1237 struct parm_struct *lp_parm_struct(const char *name)
1239 int parmnum = map_parameter(name);
1240 if (parmnum == -1) return NULL;
1241 return &parm_table[parmnum];
1245 return the parameter pointer for a parameter
1247 void *lp_parm_ptr(struct loadparm_context *lp_ctx,
1248 struct loadparm_service *service, struct parm_struct *parm)
1250 if (service == NULL) {
1251 if (parm->class == P_LOCAL)
1252 return ((char *)&sDefault)+parm->offset;
1253 else if (parm->class == P_GLOBAL)
1254 return ((char *)&(lp_ctx->Globals))+parm->offset;
1257 return ((char *)service) + parm->offset;
1261 /***************************************************************************
1262 Find a service by name. Otherwise works like get_service.
1263 ***************************************************************************/
1265 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
1266 const char *pszServiceName)
1270 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
1271 if (lp_ctx->ServicePtrs[iService] != NULL &&
1272 strwicmp(lp_ctx->ServicePtrs[iService]->szService, pszServiceName) == 0) {
1273 return lp_ctx->ServicePtrs[iService];
1279 /***************************************************************************
1280 Copy a service structure to another.
1281 If pcopymapDest is NULL then copy all fields
1282 ***************************************************************************/
1284 static void copy_service(struct loadparm_service *pserviceDest,
1285 struct loadparm_service *pserviceSource,
1289 bool bcopyall = (pcopymapDest == NULL);
1290 struct param_opt *data, *pdata, *paramo;
1293 for (i = 0; parm_table[i].label; i++)
1294 if (parm_table[i].offset != -1 && parm_table[i].class == P_LOCAL &&
1295 (bcopyall || pcopymapDest[i])) {
1297 ((char *)pserviceSource) + parm_table[i].offset;
1299 ((char *)pserviceDest) + parm_table[i].offset;
1301 switch (parm_table[i].type) {
1303 *(int *)dest_ptr = *(int *)src_ptr;
1309 *(int *)dest_ptr = *(int *)src_ptr;
1313 string_set(pserviceDest,
1319 string_set(pserviceDest,
1322 strupper(*(char **)dest_ptr);
1325 *(const char ***)dest_ptr = str_list_copy(pserviceDest,
1326 *(const char ***)src_ptr);
1334 init_copymap(pserviceDest);
1335 if (pserviceSource->copymap)
1336 memcpy((void *)pserviceDest->copymap,
1337 (void *)pserviceSource->copymap,
1338 sizeof(int) * NUMPARAMETERS);
1341 data = pserviceSource->param_opt;
1344 pdata = pserviceDest->param_opt;
1345 /* Traverse destination */
1347 /* If we already have same option, override it */
1348 if (strcmp(pdata->key, data->key) == 0) {
1349 talloc_free(pdata->value);
1350 pdata->value = talloc_reference(pdata,
1355 pdata = pdata->next;
1358 paramo = talloc(pserviceDest, struct param_opt);
1361 paramo->key = talloc_reference(paramo, data->key);
1362 paramo->value = talloc_reference(paramo, data->value);
1363 DLIST_ADD(pserviceDest->param_opt, paramo);
1369 /***************************************************************************
1370 Check a service for consistency. Return False if the service is in any way
1371 incomplete or faulty, else True.
1372 ***************************************************************************/
1374 static bool service_ok(struct loadparm_service *service)
1379 if (service->szService[0] == '\0') {
1380 DEBUG(0, ("The following message indicates an internal error:\n"));
1381 DEBUG(0, ("No service name in service entry.\n"));
1385 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1386 /* I can't see why you'd want a non-printable printer service... */
1387 if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
1388 if (!service->bPrint_ok) {
1389 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1390 service->szService));
1391 service->bPrint_ok = true;
1393 /* [printers] service must also be non-browsable. */
1394 if (service->bBrowseable)
1395 service->bBrowseable = false;
1398 /* If a service is flagged unavailable, log the fact at level 0. */
1399 if (!service->bAvailable)
1400 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1401 service->szService));
1407 /*******************************************************************
1408 Keep a linked list of all config files so we know when one has changed
1409 it's date and needs to be reloaded.
1410 ********************************************************************/
1412 static void add_to_file_list(struct loadparm_context *lp_ctx,
1413 const char *fname, const char *subfname)
1415 struct file_lists *f = lp_ctx->file_lists;
1418 if (f->name && !strcmp(f->name, fname))
1424 f = talloc(lp_ctx, struct file_lists);
1427 f->next = lp_ctx->file_lists;
1428 f->name = talloc_strdup(f, fname);
1433 f->subfname = talloc_strdup(f, subfname);
1438 lp_ctx->file_lists = f;
1439 f->modtime = file_modtime(subfname);
1441 time_t t = file_modtime(subfname);
1447 /*******************************************************************
1448 Check if a config file has changed date.
1449 ********************************************************************/
1451 bool lp_file_list_changed(struct loadparm_context *lp_ctx)
1453 struct file_lists *f;
1454 DEBUG(6, ("lp_file_list_changed()\n"));
1456 for (f = lp_ctx->file_lists; f != NULL; f = f->next) {
1460 n2 = standard_sub_basic(lp_ctx, f->name);
1462 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1463 f->name, n2, ctime(&f->modtime)));
1465 mod_time = file_modtime(n2);
1467 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1468 DEBUGADD(6, ("file %s modified: %s\n", n2,
1470 f->modtime = mod_time;
1471 talloc_free(f->subfname);
1472 f->subfname = talloc_strdup(f, n2);
1479 /***************************************************************************
1480 Handle the include operation.
1481 ***************************************************************************/
1483 static bool handle_include(struct loadparm_context *lp_ctx,
1484 const char *pszParmValue, char **ptr)
1486 char *fname = standard_sub_basic(lp_ctx, pszParmValue);
1488 add_to_file_list(lp_ctx, pszParmValue, fname);
1490 string_set(lp_ctx, ptr, fname);
1492 if (file_exist(fname))
1493 return pm_process(fname, do_section, do_parameter, lp_ctx);
1495 DEBUG(2, ("Can't find include file %s\n", fname));
1500 /***************************************************************************
1501 Handle the interpretation of the copy parameter.
1502 ***************************************************************************/
1504 static bool handle_copy(struct loadparm_context *lp_ctx,
1505 const char *pszParmValue, char **ptr)
1508 struct loadparm_service *serviceTemp;
1510 string_set(lp_ctx, ptr, pszParmValue);
1514 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1516 if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) {
1517 if (serviceTemp == lp_ctx->currentService) {
1518 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1520 copy_service(lp_ctx->currentService,
1522 lp_ctx->currentService->copymap);
1526 DEBUG(0, ("Unable to copy service - source not found: %s\n",
1534 static bool handle_debuglevel(struct loadparm_context *lp_ctx,
1535 const char *pszParmValue, char **ptr)
1537 DEBUGLEVEL = atoi(pszParmValue);
1542 static bool handle_logfile(struct loadparm_context *lp_ctx,
1543 const char *pszParmValue, char **ptr)
1545 logfile = pszParmValue;
1549 /***************************************************************************
1550 Initialise a copymap.
1551 ***************************************************************************/
1553 static void init_copymap(struct loadparm_service *pservice)
1556 talloc_free(pservice->copymap);
1557 pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS);
1558 if (pservice->copymap == NULL) {
1560 ("Couldn't allocate copymap!! (size %d)\n",
1561 (int)NUMPARAMETERS));
1564 for (i = 0; i < NUMPARAMETERS; i++)
1565 pservice->copymap[i] = true;
1568 /***************************************************************************
1569 Process a parametric option
1570 ***************************************************************************/
1571 static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
1572 struct loadparm_service *service,
1573 const char *pszParmName,
1574 const char *pszParmValue, int flags)
1576 struct param_opt *paramo, *data;
1578 TALLOC_CTX *mem_ctx;
1580 while (isspace((unsigned char)*pszParmName)) {
1584 name = strdup(pszParmName);
1585 if (!name) return false;
1589 if (service == NULL) {
1590 data = lp_ctx->Globals.param_opt;
1593 data = service->param_opt;
1597 /* Traverse destination */
1598 for (paramo=data; paramo; paramo=paramo->next) {
1599 /* If we already have the option set, override it unless
1600 it was a command line option and the new one isn't */
1601 if (strcmp(paramo->key, name) == 0) {
1602 if ((paramo->flags & FLAG_CMDLINE) &&
1603 !(flags & FLAG_CMDLINE)) {
1607 talloc_free(paramo->value);
1608 paramo->value = talloc_strdup(paramo, pszParmValue);
1609 paramo->flags = flags;
1615 paramo = talloc(mem_ctx, struct param_opt);
1618 paramo->key = talloc_strdup(paramo, name);
1619 paramo->value = talloc_strdup(paramo, pszParmValue);
1620 paramo->flags = flags;
1621 if (service == NULL) {
1622 DLIST_ADD(lp_ctx->Globals.param_opt, paramo);
1624 DLIST_ADD(service->param_opt, paramo);
1632 static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1633 const char *pszParmName, const char *pszParmValue,
1634 struct loadparm_context *lp_ctx)
1637 /* if it is a special case then go ahead */
1638 if (parm_table[parmnum].special) {
1639 parm_table[parmnum].special(lp_ctx, pszParmValue,
1644 /* now switch on the type of variable it is */
1645 switch (parm_table[parmnum].type)
1649 if (!set_boolean(pszParmValue, &b)) {
1650 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1653 *(int *)parm_ptr = b;
1658 *(int *)parm_ptr = atoi(pszParmValue);
1662 *(int *)parm_ptr = strtol(pszParmValue, NULL, 8);
1668 if (conv_str_size(pszParmValue, &val)) {
1669 if (val <= INT_MAX) {
1670 *(int *)parm_ptr = (int)val;
1675 DEBUG(0,("lp_do_parameter(%s): value is not "
1676 "a valid size specifier!\n", pszParmValue));
1681 *(const char ***)parm_ptr = str_list_make(mem_ctx,
1682 pszParmValue, NULL);
1686 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1690 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1691 strupper(*(char **)parm_ptr);
1695 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1698 parm_table[parmnum].enum_list[i].name)) {
1700 parm_table[parmnum].
1705 if (!parm_table[parmnum].enum_list[i].name) {
1706 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1707 pszParmValue, pszParmName));
1713 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1714 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1715 /* we have to also unset FLAG_DEFAULT on aliases */
1716 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
1717 parm_table[i].flags &= ~FLAG_DEFAULT;
1719 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) {
1720 parm_table[i].flags &= ~FLAG_DEFAULT;
1727 bool lp_do_global_parameter(struct loadparm_context *lp_ctx,
1728 const char *pszParmName, const char *pszParmValue)
1730 int parmnum = map_parameter(pszParmName);
1734 if (strchr(pszParmName, ':')) {
1735 return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0);
1737 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1741 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1742 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1746 /* if the flag has been set on the command line, then don't allow override,
1747 but don't report an error */
1748 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1752 parm_ptr = lp_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]);
1754 return set_variable(lp_ctx, parmnum, parm_ptr,
1755 pszParmName, pszParmValue, lp_ctx);
1758 bool lp_do_service_parameter(struct loadparm_context *lp_ctx,
1759 struct loadparm_service *service,
1760 const char *pszParmName, const char *pszParmValue)
1764 int parmnum = map_parameter(pszParmName);
1767 if (strchr(pszParmName, ':')) {
1768 return lp_do_parameter_parametric(lp_ctx, service, pszParmName, pszParmValue, 0);
1770 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1774 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1775 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1779 /* if the flag has been set on the command line, then don't allow override,
1780 but don't report an error */
1781 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1785 if (parm_table[parmnum].class == P_GLOBAL) {
1787 ("Global parameter %s found in service section!\n",
1791 parm_ptr = ((char *)service) + parm_table[parmnum].offset;
1793 if (!service->copymap)
1794 init_copymap(service);
1796 /* this handles the aliases - set the copymap for other
1797 * entries with the same data pointer */
1798 for (i = 0; parm_table[i].label; i++)
1799 if (parm_table[i].offset == parm_table[parmnum].offset &&
1800 parm_table[i].class == parm_table[parmnum].class)
1801 service->copymap[i] = false;
1803 return set_variable(service, parmnum, parm_ptr, pszParmName,
1804 pszParmValue, lp_ctx);
1807 /***************************************************************************
1808 Process a parameter.
1809 ***************************************************************************/
1811 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1814 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
1816 if (lp_ctx->bInGlobalSection)
1817 return lp_do_global_parameter(lp_ctx, pszParmName,
1820 return lp_do_service_parameter(lp_ctx, lp_ctx->currentService,
1821 pszParmName, pszParmValue);
1825 variable argument do parameter
1827 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
1828 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx,
1829 const char *pszParmName, const char *fmt, ...)
1836 s = talloc_vasprintf(NULL, fmt, ap);
1838 ret = lp_do_global_parameter(lp_ctx, pszParmName, s);
1845 set a parameter from the commandline - this is called from command line parameter
1846 parsing code. It sets the parameter then marks the parameter as unable to be modified
1847 by smb.conf processing
1849 bool lp_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName,
1850 const char *pszParmValue)
1852 int parmnum = map_parameter(pszParmName);
1855 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1858 if (parmnum < 0 && strchr(pszParmName, ':')) {
1859 /* set a parametric option */
1860 return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
1861 pszParmValue, FLAG_CMDLINE);
1865 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1869 /* reset the CMDLINE flag in case this has been called before */
1870 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1872 if (!lp_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
1876 parm_table[parmnum].flags |= FLAG_CMDLINE;
1878 /* we have to also set FLAG_CMDLINE on aliases */
1879 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
1880 parm_table[i].flags |= FLAG_CMDLINE;
1882 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) {
1883 parm_table[i].flags |= FLAG_CMDLINE;
1890 set a option from the commandline in 'a=b' format. Use to support --option
1892 bool lp_set_option(struct loadparm_context *lp_ctx, const char *option)
1910 ret = lp_set_cmdline(lp_ctx, s, p+1);
1916 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1918 /***************************************************************************
1919 Print a parameter of the specified type.
1920 ***************************************************************************/
1922 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1928 for (i = 0; p->enum_list[i].name; i++) {
1929 if (*(int *)ptr == p->enum_list[i].value) {
1931 p->enum_list[i].name);
1938 fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr));
1943 fprintf(f, "%d", *(int *)ptr);
1947 fprintf(f, "0%o", *(int *)ptr);
1951 if ((char ***)ptr && *(char ***)ptr) {
1952 char **list = *(char ***)ptr;
1954 for (; *list; list++)
1955 fprintf(f, "%s%s", *list,
1956 ((*(list+1))?", ":""));
1962 if (*(char **)ptr) {
1963 fprintf(f, "%s", *(char **)ptr);
1969 /***************************************************************************
1970 Check if two parameters are equal.
1971 ***************************************************************************/
1973 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
1977 return (*((int *)ptr1) == *((int *)ptr2));
1983 return (*((int *)ptr1) == *((int *)ptr2));
1986 return str_list_equal((const char **)(*(char ***)ptr1),
1987 (const char **)(*(char ***)ptr2));
1992 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1997 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 ((lp_ctx->currentService = lp_add_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 void *def_ptr = ((char *)&sDefault) + parm_table[i].offset;
2057 if (!defaults_saved)
2059 switch (parm_table[i].type) {
2061 return str_list_equal((const char **)parm_table[i].def.lvalue,
2062 (const char **)def_ptr);
2065 return strequal(parm_table[i].def.svalue,
2068 return parm_table[i].def.bvalue ==
2074 return parm_table[i].def.ivalue ==
2080 /***************************************************************************
2081 Display the contents of the global structure.
2082 ***************************************************************************/
2084 static void dump_globals(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults)
2087 struct param_opt *data;
2089 fprintf(f, "# Global parameters\n[global]\n");
2091 for (i = 0; parm_table[i].label; i++)
2092 if (parm_table[i].class == P_GLOBAL &&
2093 parm_table[i].offset != -1 &&
2094 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
2095 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2097 fprintf(f, "\t%s = ", parm_table[i].label);
2098 print_parameter(&parm_table[i], lp_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
2101 if (lp_ctx->Globals.param_opt != NULL) {
2102 for (data = lp_ctx->Globals.param_opt; data;
2103 data = data->next) {
2104 fprintf(f, "\t%s = %s\n", data->key, data->value);
2110 /***************************************************************************
2111 Display the contents of a single services record.
2112 ***************************************************************************/
2114 static void dump_a_service(struct loadparm_service * pService, FILE * f)
2117 struct param_opt *data;
2119 if (pService != &sDefault)
2120 fprintf(f, "\n[%s]\n", pService->szService);
2122 for (i = 0; parm_table[i].label; i++)
2123 if (parm_table[i].class == P_LOCAL &&
2124 parm_table[i].offset != -1 &&
2125 (*parm_table[i].label != '-') &&
2126 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
2127 if (pService == &sDefault) {
2128 if (defaults_saved && is_default(i))
2131 if (equal_parameter(parm_table[i].type,
2132 ((char *)pService) +
2133 parm_table[i].offset,
2134 ((char *)&sDefault) +
2135 parm_table[i].offset))
2139 fprintf(f, "\t%s = ", parm_table[i].label);
2140 print_parameter(&parm_table[i],
2141 ((char *)pService) + parm_table[i].offset, f);
2144 if (pService->param_opt != NULL) {
2145 for (data = pService->param_opt; data; data = data->next) {
2146 fprintf(f, "\t%s = %s\n", data->key, data->value);
2151 bool lp_dump_a_parameter(struct loadparm_context *lp_ctx, int snum, const char *parm_name, FILE * f,
2154 struct loadparm_service * pService = lp_ctx->ServicePtrs[snum];
2155 struct parm_struct *parm;
2158 parm = lp_parm_struct(parm_name);
2164 ptr = ((char *)&sDefault) + parm->offset;
2166 ptr = ((char *)pService) + parm->offset;
2168 print_parameter(parm, ptr, f);
2173 /***************************************************************************
2174 Return info about the next service in a service. snum==-1 gives the globals.
2175 Return NULL when out of parameters.
2176 ***************************************************************************/
2178 struct parm_struct *lp_next_parameter(struct loadparm_context *lp_ctx, int snum, int *i,
2182 /* do the globals */
2183 for (; parm_table[*i].label; (*i)++) {
2184 if (parm_table[*i].offset == -1
2185 || (*parm_table[*i].label == '-'))
2189 && (parm_table[*i].offset ==
2190 parm_table[(*i) - 1].offset))
2193 return &parm_table[(*i)++];
2196 struct loadparm_service *pService = lp_ctx->ServicePtrs[snum];
2198 for (; parm_table[*i].label; (*i)++) {
2199 if (parm_table[*i].class == P_LOCAL &&
2200 parm_table[*i].offset != -1 &&
2201 (*parm_table[*i].label != '-') &&
2203 (parm_table[*i].offset !=
2204 parm_table[(*i) - 1].offset)))
2206 if (allparameters ||
2207 !equal_parameter(parm_table[*i].type,
2208 ((char *)pService) +
2209 parm_table[*i].offset,
2210 ((char *)&sDefault) +
2211 parm_table[*i].offset))
2213 return &parm_table[(*i)++];
2223 /***************************************************************************
2224 Auto-load some home services.
2225 ***************************************************************************/
2227 static void lp_add_auto_services(struct loadparm_context *lp_ctx,
2233 /***************************************************************************
2234 Have we loaded a services file yet?
2235 ***************************************************************************/
2237 bool lp_loaded(void)
2242 /***************************************************************************
2243 Unload unused services.
2244 ***************************************************************************/
2246 void lp_killunused(struct loadparm_context *lp_ctx,
2247 struct smbsrv_connection *smb,
2248 bool (*snumused) (struct smbsrv_connection *, int))
2251 for (i = 0; i < lp_ctx->iNumServices; i++) {
2252 if (lp_ctx->ServicePtrs[i] == NULL)
2255 if (!snumused || !snumused(smb, i)) {
2256 talloc_free(lp_ctx->ServicePtrs[i]);
2257 lp_ctx->ServicePtrs[i] = NULL;
2263 static int lp_destructor(struct loadparm_context *lp_ctx)
2265 struct param_opt *data;
2267 if (lp_ctx->Globals.param_opt != NULL) {
2268 struct param_opt *next;
2269 for (data = lp_ctx->Globals.param_opt; data; data=next) {
2271 if (data->flags & FLAG_CMDLINE) continue;
2272 DLIST_REMOVE(lp_ctx->Globals.param_opt, data);
2280 /***************************************************************************
2281 Initialise the global parameter structure.
2282 ***************************************************************************/
2283 struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
2287 struct loadparm_context *lp_ctx;
2289 lp_ctx = talloc(mem_ctx, struct loadparm_context);
2293 talloc_set_destructor(lp_ctx, lp_destructor);
2294 lp_ctx->bInGlobalSection = true;
2296 DEBUG(3, ("Initialising global parameters\n"));
2298 for (i = 0; parm_table[i].label; i++) {
2299 if ((parm_table[i].type == P_STRING ||
2300 parm_table[i].type == P_USTRING) &&
2301 parm_table[i].offset != -1 &&
2302 !(parm_table[i].flags & FLAG_CMDLINE)) {
2303 char **r = ((char *)(parm_table[i].class == P_LOCAL)?&sDefault:&(lp_ctx->Globals)) + parm_table[i].offset;
2304 *r = talloc_strdup(lp_ctx, "");
2308 lp_do_global_parameter(lp_ctx, "share backend", "classic");
2310 lp_do_global_parameter(lp_ctx, "server role", "standalone");
2312 /* options that can be set on the command line must be initialised via
2313 the slower lp_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2315 lp_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2317 lp_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2318 myname = get_myname();
2319 lp_do_global_parameter(lp_ctx, "netbios name", myname);
2321 lp_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
2323 lp_do_global_parameter(lp_ctx, "fstype", FSTYPE_STRING);
2324 lp_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2325 lp_do_global_parameter(lp_ctx, "max connections", "-1");
2327 lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo");
2328 lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap web kdc drepl winbind");
2329 lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb");
2330 lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain");
2331 lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind");
2332 lp_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain");
2333 lp_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2334 lp_do_global_parameter(lp_ctx, "sam database", "sam.ldb");
2335 lp_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb");
2336 lp_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb");
2337 lp_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb");
2338 lp_do_global_parameter(lp_ctx, "wins database", "wins.ldb");
2339 lp_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2341 /* This hive should be dynamically generated by Samba using
2342 data from the sam, but for the moment leave it in a tdb to
2343 keep regedt32 from popping up an annoying dialog. */
2344 lp_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2346 /* using UTF8 by default allows us to support all chars */
2347 lp_do_global_parameter(lp_ctx, "unix charset", "UTF8");
2349 /* Use codepage 850 as a default for the dos character set */
2350 lp_do_global_parameter(lp_ctx, "dos charset", "CP850");
2353 * Allow the default PASSWD_CHAT to be overridden in local.h.
2355 lp_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2357 lp_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2358 lp_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2359 lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR);
2360 lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2362 lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0");
2363 lp_do_global_parameter_var(lp_ctx, "server string",
2364 "Samba %s", SAMBA_VERSION_STRING);
2366 lp_do_global_parameter_var(lp_ctx, "announce version", "%d.%d",
2367 DEFAULT_MAJOR_VERSION,
2368 DEFAULT_MINOR_VERSION);
2370 lp_do_global_parameter(lp_ctx, "password server", "*");
2372 lp_do_global_parameter(lp_ctx, "max mux", "50");
2373 lp_do_global_parameter(lp_ctx, "max xmit", "12288");
2374 lp_do_global_parameter(lp_ctx, "password level", "0");
2375 lp_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2376 lp_do_global_parameter(lp_ctx, "server min protocol", "CORE");
2377 lp_do_global_parameter(lp_ctx, "server max protocol", "NT1");
2378 lp_do_global_parameter(lp_ctx, "client min protocol", "CORE");
2379 lp_do_global_parameter(lp_ctx, "client max protocol", "NT1");
2380 lp_do_global_parameter(lp_ctx, "security", "USER");
2381 lp_do_global_parameter(lp_ctx, "paranoid server security", "True");
2382 lp_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2383 lp_do_global_parameter(lp_ctx, "ReadRaw", "True");
2384 lp_do_global_parameter(lp_ctx, "WriteRaw", "True");
2385 lp_do_global_parameter(lp_ctx, "NullPasswords", "False");
2386 lp_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2387 lp_do_global_parameter(lp_ctx, "announce as", "NT SERVER");
2389 lp_do_global_parameter(lp_ctx, "TimeServer", "False");
2390 lp_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2391 lp_do_global_parameter(lp_ctx, "Unicode", "True");
2392 lp_do_global_parameter(lp_ctx, "ClientLanManAuth", "True");
2393 lp_do_global_parameter(lp_ctx, "LanmanAuth", "True");
2394 lp_do_global_parameter(lp_ctx, "NTLMAuth", "True");
2395 lp_do_global_parameter(lp_ctx, "client use spnego principal", "False");
2397 lp_do_global_parameter(lp_ctx, "UnixExtensions", "False");
2399 lp_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2400 lp_do_global_parameter(lp_ctx, "LocalMaster", "True");
2402 lp_do_global_parameter(lp_ctx, "wins support", "False");
2403 lp_do_global_parameter(lp_ctx, "dns proxy", "True");
2405 lp_do_global_parameter(lp_ctx, "winbind separator", "\\");
2406 lp_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2407 lp_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2408 lp_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2409 lp_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
2411 lp_do_global_parameter(lp_ctx, "client signing", "Yes");
2412 lp_do_global_parameter(lp_ctx, "server signing", "auto");
2414 lp_do_global_parameter(lp_ctx, "use spnego", "True");
2416 lp_do_global_parameter(lp_ctx, "smb ports", "445 139");
2417 lp_do_global_parameter(lp_ctx, "nbt port", "137");
2418 lp_do_global_parameter(lp_ctx, "dgram port", "138");
2419 lp_do_global_parameter(lp_ctx, "cldap port", "389");
2420 lp_do_global_parameter(lp_ctx, "krb5 port", "88");
2421 lp_do_global_parameter(lp_ctx, "kpasswd port", "464");
2422 lp_do_global_parameter(lp_ctx, "web port", "901");
2423 lp_do_global_parameter(lp_ctx, "swat directory", dyn_SWATDIR);
2425 lp_do_global_parameter(lp_ctx, "nt status support", "True");
2427 lp_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2428 lp_do_global_parameter(lp_ctx, "min wins ttl", "10");
2430 lp_do_global_parameter(lp_ctx, "tls enabled", "True");
2431 lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2432 lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2433 lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2434 lp_do_global_parameter_var(lp_ctx, "js include", "%s", dyn_JSDIR);
2435 lp_do_global_parameter_var(lp_ctx, "setup directory", "%s",
2438 for (i = 0; parm_table[i].label; i++) {
2439 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
2440 parm_table[i].flags |= FLAG_DEFAULT;
2447 /***************************************************************************
2448 Load the services array from the services file. Return True on success,
2450 ***************************************************************************/
2451 bool lp_load(TALLOC_CTX *mem_ctx, const char *filename, struct loadparm_context **ret_lp)
2455 struct loadparm_context *lp_ctx;
2460 lp_ctx = loadparm_init(mem_ctx);
2464 global_loadparm = lp_ctx;
2466 filename = talloc_strdup(lp_ctx, filename);
2468 lp_ctx->Globals.szConfigFile = filename;
2470 lp_ctx->bInGlobalSection = true;
2471 n2 = standard_sub_basic(lp_ctx, lp_ctx->Globals.szConfigFile);
2472 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2474 add_to_file_list(lp_ctx, lp_ctx->Globals.szConfigFile, n2);
2476 /* We get sections first, so have to start 'behind' to make up */
2477 lp_ctx->currentService = NULL;
2478 bRetval = pm_process(n2, do_section, do_parameter, lp_ctx);
2480 /* finish up the last section */
2481 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2483 if (lp_ctx->currentService != NULL)
2484 bRetval = service_ok(lp_ctx->currentService);
2486 lp_add_auto_services(lp_ctx, lp_auto_services(lp_ctx));
2488 lp_add_hidden(lp_ctx, "IPC$", "IPC");
2489 lp_add_hidden(lp_ctx, "ADMIN$", "DISK");
2493 if (!lp_ctx->Globals.szWINSservers && lp_ctx->Globals.bWINSsupport) {
2494 lp_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
2497 panic_action = lp_ctx->Globals.panic_action;
2507 /***************************************************************************
2508 Return the max number of services.
2509 ***************************************************************************/
2511 int lp_numservices(struct loadparm_context *lp_ctx)
2513 return lp_ctx->iNumServices;
2516 /***************************************************************************
2517 Display the contents of the services array in human-readable form.
2518 ***************************************************************************/
2520 void lp_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
2526 defaults_saved = false;
2528 dump_globals(lp_ctx, f, show_defaults);
2530 dump_a_service(&sDefault, f);
2532 for (iService = 0; iService < maxtoprint; iService++)
2533 lp_dump_one(f, show_defaults, lp_ctx->ServicePtrs[iService]);
2536 /***************************************************************************
2537 Display the contents of one service in human-readable form.
2538 ***************************************************************************/
2540 void lp_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service)
2542 if (service != NULL) {
2543 if (service->szService[0] == '\0')
2545 dump_a_service(service, f);
2549 struct loadparm_service *lp_servicebynum(struct loadparm_context *lp_ctx,
2552 return lp_ctx->ServicePtrs[snum];
2555 struct loadparm_service *lp_service(struct loadparm_context *lp_ctx,
2556 const char *service_name)
2561 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
2562 if (lp_ctx->ServicePtrs[iService] &&
2563 lp_ctx->ServicePtrs[iService]->szService) {
2565 * The substitution here is used to support %U is
2568 serviceName = standard_sub_basic(
2569 lp_ctx->ServicePtrs[iService],
2570 lp_ctx->ServicePtrs[iService]->szService);
2571 if (strequal(serviceName, service_name))
2572 return lp_ctx->ServicePtrs[iService];
2576 DEBUG(7,("lp_servicenumber: couldn't find %s\n", service_name));
2581 /*******************************************************************
2582 A useful volume label function.
2583 ********************************************************************/
2584 const char *volume_label(struct loadparm_service *service)
2586 const char *ret = lp_volume(service);
2588 return lp_servicename(service);
2593 /***********************************************************
2594 If we are PDC then prefer us as DMB
2595 ************************************************************/
2597 bool lp_domain_logons(struct loadparm_context *lp_ctx)
2599 return (lp_server_role(lp_ctx) == ROLE_DOMAIN_CONTROLLER);
2602 const char *lp_printername(struct loadparm_service *service)
2604 const char *ret = _lp_printername(service);
2605 if (ret == NULL || (ret != NULL && *ret == '\0'))
2606 ret = lp_const_servicename(service);
2612 /*******************************************************************
2613 Return the max print jobs per queue.
2614 ********************************************************************/
2616 int lp_maxprintjobs(struct loadparm_service *service)
2618 int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2619 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2620 maxjobs = PRINT_MAX_JOBID - 1;