2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 3 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/locale.h"
60 #include "system/network.h" /* needed for TCP_NODELAY */
61 #include "smb_server/smb_server.h"
62 #include "libcli/raw/signing.h"
63 #include "lib/util/dlinklist.h"
64 #include "param/param.h"
65 #include "param/loadparm.h"
68 static bool bLoaded = false;
70 #define standard_sub_basic talloc_strdup
72 static bool do_parameter(const char *, const char *, void *);
73 static bool defaults_saved = false;
76 struct param_opt *prev, *next;
83 * This structure describes global (ie., server-wide) parameters.
87 enum server_role server_role;
103 char *szWINS_CONFIG_URL;
107 char *jsonrpcServicesDir;
108 char **szPasswordServers;
109 char *szSocketOptions;
111 char **szWINSservers;
113 char *szSocketAddress;
114 char *szAnnounceVersion; /* This is initialised in init_globals */
117 char **szNetbiosAliases;
118 char *szNetbiosScope;
119 char *szDomainOtherSIDs;
120 char **szNameResolveOrder;
121 char **dcerpc_ep_servers;
122 char **server_services;
123 char *ntptr_providor;
124 char *szWinbindSeparator;
125 char *szWinbinddSocketDirectory;
126 char *szTemplateShell;
127 char *szTemplateHomedir;
128 int bWinbindSealedPipes;
129 char *swat_directory;
144 int paranoid_server_security;
147 int announce_as; /* This is initialised in init_globals */
154 char *socket_options;
159 int bPreferredMaster;
160 int bEncryptPasswords;
162 int bObeyPamRestrictions;
167 int bBindInterfacesOnly;
169 int bNTStatusSupport;
175 int bClientPlaintextAuth;
176 int bClientLanManAuth;
177 int bClientNTLMv2Auth;
178 int client_use_spnego_principal;
184 struct param_opt *param_opt;
189 * This structure describes a single service.
191 struct loadparm_service
203 char **ntvfs_handler;
216 int iCreate_force_mode;
223 struct param_opt *param_opt;
225 char dummy[3]; /* for alignment */
229 /* This is a default service used to prime a services structure */
230 static struct loadparm_service sDefault = {
231 NULL, /* szService */
234 NULL, /* szInclude */
235 NULL, /* szPrintername */
236 NULL, /* szHostsallow */
237 NULL, /* szHostsdeny */
241 NULL, /* ntvfs_handler */
242 1000, /* iMaxPrintJobs */
243 0, /* iMaxConnections */
245 true, /* bAvailable */
246 true, /* bBrowseable */
247 true, /* bRead_only */
248 false, /* bPrint_ok */
249 false, /* bMap_system */
250 false, /* bMap_hidden */
251 true, /* bMap_archive */
252 true, /* bStrictLocking */
253 0744, /* iCreate_mask */
254 0000, /* iCreate_force_mode */
255 0755, /* iDir_mask */
256 0000, /* iDir_force_mode */
258 false, /* bMSDfsRoot */
259 false, /* bStrictSync */
260 false, /* bCIFileSystem */
261 NULL, /* Parametric options */
266 /* local variables */
267 static struct loadparm_context {
268 struct global Globals;
269 struct loadparm_service **ServicePtrs;
271 struct loadparm_service *currentService;
272 bool bInGlobalSection;
274 struct file_lists *next;
281 .currentService = NULL,
282 .bInGlobalSection = true,
287 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
289 /* prototypes for the special type handlers */
290 static bool handle_include(struct loadparm_context *lp_ctx,
291 const char *pszParmValue, char **ptr);
292 static bool handle_copy(struct loadparm_context *lp_ctx,
293 const char *pszParmValue, char **ptr);
295 static const struct enum_list enum_protocol[] = {
296 {PROTOCOL_SMB2, "SMB2"},
297 {PROTOCOL_NT1, "NT1"},
298 {PROTOCOL_LANMAN2, "LANMAN2"},
299 {PROTOCOL_LANMAN1, "LANMAN1"},
300 {PROTOCOL_CORE, "CORE"},
301 {PROTOCOL_COREPLUS, "COREPLUS"},
302 {PROTOCOL_COREPLUS, "CORE+"},
306 static const struct enum_list enum_security[] = {
307 {SEC_SHARE, "SHARE"},
312 static const struct enum_list enum_announce_as[] = {
313 {ANNOUNCE_AS_NT_SERVER, "NT"},
314 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
315 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
316 {ANNOUNCE_AS_WIN95, "win95"},
317 {ANNOUNCE_AS_WFW, "WfW"},
321 static const struct enum_list enum_bool_auto[] = {
332 /* Client-side offline caching policy types */
333 #define CSC_POLICY_MANUAL 0
334 #define CSC_POLICY_DOCUMENTS 1
335 #define CSC_POLICY_PROGRAMS 2
336 #define CSC_POLICY_DISABLE 3
338 static const struct enum_list enum_csc_policy[] = {
339 {CSC_POLICY_MANUAL, "manual"},
340 {CSC_POLICY_DOCUMENTS, "documents"},
341 {CSC_POLICY_PROGRAMS, "programs"},
342 {CSC_POLICY_DISABLE, "disable"},
346 /* SMB signing types. */
347 static const struct enum_list enum_smb_signing_vals[] = {
348 {SMB_SIGNING_OFF, "No"},
349 {SMB_SIGNING_OFF, "False"},
350 {SMB_SIGNING_OFF, "0"},
351 {SMB_SIGNING_OFF, "Off"},
352 {SMB_SIGNING_OFF, "disabled"},
353 {SMB_SIGNING_SUPPORTED, "Yes"},
354 {SMB_SIGNING_SUPPORTED, "True"},
355 {SMB_SIGNING_SUPPORTED, "1"},
356 {SMB_SIGNING_SUPPORTED, "On"},
357 {SMB_SIGNING_SUPPORTED, "enabled"},
358 {SMB_SIGNING_REQUIRED, "required"},
359 {SMB_SIGNING_REQUIRED, "mandatory"},
360 {SMB_SIGNING_REQUIRED, "force"},
361 {SMB_SIGNING_REQUIRED, "forced"},
362 {SMB_SIGNING_REQUIRED, "enforced"},
363 {SMB_SIGNING_AUTO, "auto"},
367 static const struct enum_list enum_server_role[] = {
368 {ROLE_STANDALONE, "standalone"},
369 {ROLE_DOMAIN_MEMBER, "member server"},
370 {ROLE_DOMAIN_CONTROLLER, "domain controller"},
375 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
377 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
378 * is implied in current control logic. This may change at some later time. A
379 * flag value of 0 means - show as development option only.
381 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
382 * screen in SWAT. This is used to exclude parameters as well as to squash all
383 * parameters that have been duplicated by pseudonyms.
385 static struct parm_struct parm_table[] = {
386 {"Base Options", P_SEP, P_SEPARATOR},
388 {"server role", P_ENUM, P_GLOBAL, &loadparm.Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
390 {"dos charset", P_STRING, P_GLOBAL, &dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
391 {"unix charset", P_STRING, P_GLOBAL, &unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"ncalrpc dir", P_STRING, P_GLOBAL, &loadparm.Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"display charset", P_STRING, P_GLOBAL, &display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
394 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
395 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
396 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
397 {"workgroup", P_USTRING, P_GLOBAL, &loadparm.Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
398 {"realm", P_STRING, P_GLOBAL, &loadparm.Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"netbios name", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"netbios aliases", P_LIST, P_GLOBAL, &loadparm.Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"netbios scope", P_USTRING, P_GLOBAL, &loadparm.Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
402 {"server string", P_STRING, P_GLOBAL, &loadparm.Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
403 {"interfaces", P_LIST, P_GLOBAL, &loadparm.Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
404 {"bind interfaces only", P_BOOL, P_GLOBAL, &loadparm.Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
406 {"ntptr providor", P_STRING, P_GLOBAL, &loadparm.Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
407 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &loadparm.Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
408 {"server services", P_LIST, P_GLOBAL, &loadparm.Globals.server_services, NULL, NULL, FLAG_ADVANCED},
410 {"Security Options", P_SEP, P_SEPARATOR},
412 {"security", P_ENUM, P_GLOBAL, &loadparm.Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
413 {"encrypt passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
414 {"null passwords", P_BOOL, P_GLOBAL, &loadparm.Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"obey pam restrictions", P_BOOL, P_GLOBAL, &loadparm.Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"password server", P_LIST, P_GLOBAL, &loadparm.Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
417 {"sam database", P_STRING, P_GLOBAL, &loadparm.Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"secrets database", P_STRING, P_GLOBAL, &loadparm.Globals.szSECRETS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"spoolss database", P_STRING, P_GLOBAL, &loadparm.Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"wins config database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"wins database", P_STRING, P_GLOBAL, &loadparm.Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"private dir", P_STRING, P_GLOBAL, &loadparm.Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"passwd chat", P_STRING, P_GLOBAL, &loadparm.Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"password level", P_INTEGER, P_GLOBAL, &loadparm.Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"ntlm auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"client lanman auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"client plaintext auth", P_BOOL, P_GLOBAL, &loadparm.Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
430 {"client use spnego principal", P_BOOL, P_GLOBAL, &loadparm.Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
432 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
434 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
435 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
436 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
437 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
439 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
440 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
442 {"Logging Options", P_SEP, P_SEPARATOR},
444 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
446 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"Protocol Options", P_SEP, P_SEPARATOR},
450 {"smb ports", P_LIST, P_GLOBAL, &loadparm.Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"nbt port", P_INTEGER, P_GLOBAL, &loadparm.Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"dgram port", P_INTEGER, P_GLOBAL, &loadparm.Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"cldap port", P_INTEGER, P_GLOBAL, &loadparm.Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"krb5 port", P_INTEGER, P_GLOBAL, &loadparm.Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"kpasswd port", P_INTEGER, P_GLOBAL, &loadparm.Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"web port", P_INTEGER, P_GLOBAL, &loadparm.Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"tls enabled", P_BOOL, P_GLOBAL, &loadparm.Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"tls keyfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"tls certfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
460 {"tls cafile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
461 {"tls crlfile", P_STRING, P_GLOBAL, &loadparm.Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
462 {"tls dh params file", P_STRING, P_GLOBAL, &loadparm.Globals.tls_dhpfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
463 {"swat directory", P_STRING, P_GLOBAL, &loadparm.Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
464 {"large readwrite", P_BOOL, P_GLOBAL, &loadparm.Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
465 {"server max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
466 {"server min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
467 {"client max protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
468 {"client min protocol", P_ENUM, P_GLOBAL, &loadparm.Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
469 {"unicode", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
470 {"read raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
471 {"write raw", P_BOOL, P_GLOBAL, &loadparm.Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
472 {"disable netbios", P_BOOL, P_GLOBAL, &loadparm.Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"nt status support", P_BOOL, P_GLOBAL, &loadparm.Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"announce version", P_STRING, P_GLOBAL, &loadparm.Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
477 {"announce as", P_ENUM, P_GLOBAL, &loadparm.Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
478 {"max mux", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
479 {"max xmit", P_BYTES, P_GLOBAL, &loadparm.Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
481 {"name resolve order", P_LIST, P_GLOBAL, &loadparm.Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
482 {"max wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
483 {"min wins ttl", P_INTEGER, P_GLOBAL, &loadparm.Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
484 {"time server", P_BOOL, P_GLOBAL, &loadparm.Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
485 {"unix extensions", P_BOOL, P_GLOBAL, &loadparm.Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
486 {"use spnego", P_BOOL, P_GLOBAL, &loadparm.Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
487 {"server signing", P_ENUM, P_GLOBAL, &loadparm.Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
488 {"client signing", P_ENUM, P_GLOBAL, &loadparm.Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
489 {"rpc big endian", P_BOOL, P_GLOBAL, &loadparm.Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
491 {"Tuning Options", P_SEP, P_SEPARATOR},
493 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
494 {"paranoid server security", P_BOOL, P_GLOBAL, &loadparm.Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
495 {"socket options", P_STRING, P_GLOBAL, &loadparm.Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
497 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
498 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
500 {"Printing Options", P_SEP, P_SEPARATOR},
502 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
503 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
504 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
506 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
507 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
509 {"Filename Handling", P_SEP, P_SEPARATOR},
511 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
512 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
513 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
515 {"Domain Options", P_SEP, P_SEPARATOR},
517 {"Logon Options", P_SEP, P_SEPARATOR},
520 {"Browse Options", P_SEP, P_SEPARATOR},
522 {"preferred master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
523 {"prefered master", P_ENUM, P_GLOBAL, &loadparm.Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
524 {"local master", P_BOOL, P_GLOBAL, &loadparm.Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
525 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
526 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
528 {"WINS Options", P_SEP, P_SEPARATOR},
530 {"wins server", P_LIST, P_GLOBAL, &loadparm.Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
531 {"wins support", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
532 {"dns proxy", P_BOOL, P_GLOBAL, &loadparm.Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
533 {"wins hook", P_STRING, P_GLOBAL, &loadparm.Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
535 {"Locking Options", P_SEP, P_SEPARATOR},
537 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
539 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
541 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
543 {"config file", P_STRING, P_GLOBAL, &loadparm.Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
544 {"share backend", P_STRING, P_GLOBAL, &loadparm.Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"preload", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"auto services", P_STRING, P_GLOBAL, &loadparm.Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"lock dir", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_HIDE},
548 {"lock directory", P_STRING, P_GLOBAL, &loadparm.Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"modules dir", P_STRING, P_GLOBAL, &loadparm.Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"pid directory", P_STRING, P_GLOBAL, &loadparm.Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"js include", P_LIST, P_GLOBAL, &loadparm.Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"setup directory", P_STRING, P_GLOBAL, &loadparm.Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"socket address", P_STRING, P_GLOBAL, &loadparm.Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
555 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
556 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
558 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
559 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
560 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
562 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
565 {"host msdfs", P_BOOL, P_GLOBAL, &loadparm.Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"winbind separator", P_STRING, P_GLOBAL, &loadparm.Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
567 {"winbindd socket directory", P_STRING, P_GLOBAL, &loadparm.Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
568 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &loadparm.Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
569 {"template shell", P_STRING, P_GLOBAL, &loadparm.Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
570 {"template homedir", P_STRING, P_GLOBAL, &loadparm.Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
572 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
577 return the parameter table
579 struct parm_struct *lp_parm_table(void)
584 static TALLOC_CTX *lp_talloc;
586 /******************************************************************* a
587 Free up temporary memory - called from the main loop.
588 ********************************************************************/
590 void lp_talloc_free(void)
594 talloc_free(lp_talloc);
598 /*******************************************************************
599 Convenience routine to grab string parameters into temporary memory
600 and run standard_sub_basic on them. The buffers can be written to by
601 callers without affecting the source string.
602 ********************************************************************/
604 static const char *lp_string(const char *s)
606 #if 0 /* until REWRITE done to make thread-safe */
607 size_t len = s ? strlen(s) : 0;
611 /* The follow debug is useful for tracking down memory problems
612 especially if you have an inner loop that is calling a lp_*()
613 function that returns a string. Perhaps this debug should be
614 present all the time? */
617 DEBUG(10, ("lp_string(%s)\n", s));
620 #if 0 /* until REWRITE done to make thread-safe */
622 lp_talloc = talloc_init("lp_talloc");
624 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
632 strlcpy(ret, s, len);
634 if (trim_string(ret, "\"", "\"")) {
635 if (strchr(ret,'"') != NULL)
636 strlcpy(ret, s, len);
639 standard_sub_basic(ret,len+100);
646 In this section all the functions that are used to access the
647 parameters from the rest of the program are defined
650 #define FN_GLOBAL_STRING(fn_name,ptr) \
651 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
652 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
653 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
654 #define FN_GLOBAL_LIST(fn_name,ptr) \
655 const char **fn_name(void) {return(*(const char ***)(ptr));}
656 #define FN_GLOBAL_BOOL(fn_name,ptr) \
657 bool fn_name(void) {return((bool)*(int *)(ptr));}
659 #define FN_GLOBAL_CHAR(fn_name,ptr) \
660 char fn_name(void) {return(*(char *)(ptr));}
662 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
663 int fn_name(void) {return(*(int *)(ptr));}
665 #define FN_LOCAL_STRING(fn_name,val) \
666 const char *fn_name(struct loadparm_service *service) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault.val)));}
667 #define FN_LOCAL_CONST_STRING(fn_name,val) \
668 const char *fn_name(struct loadparm_service *service) {return (const char *)(service != NULL && service->val != NULL) ? service->val : sDefault.val;}
669 #define FN_LOCAL_LIST(fn_name,val) \
670 const char **fn_name(struct loadparm_service *service) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault.val);}
671 #define FN_LOCAL_BOOL(fn_name,val) \
672 bool fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
673 #define FN_LOCAL_INTEGER(fn_name,val) \
674 int fn_name(struct loadparm_service *service) {return((service != NULL)? service->val : sDefault.val);}
676 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &loadparm.Globals.server_role)
677 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &loadparm.Globals.smb_ports)
678 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &loadparm.Globals.nbt_port)
679 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &loadparm.Globals.dgram_port)
680 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &loadparm.Globals.cldap_port)
681 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &loadparm.Globals.krb5_port)
682 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &loadparm.Globals.kpasswd_port)
683 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &loadparm.Globals.web_port)
684 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &dos_charset)
685 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, &loadparm.Globals.swat_directory)
686 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &loadparm.Globals.tls_enabled)
687 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &loadparm.Globals.tls_keyfile)
688 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &loadparm.Globals.tls_certfile)
689 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &loadparm.Globals.tls_cafile)
690 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &loadparm.Globals.tls_crlfile)
691 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_dhpfile, &loadparm.Globals.tls_dhpfile)
692 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &unix_charset)
693 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &display_charset)
694 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &loadparm.Globals.szConfigFile)
695 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, &loadparm.Globals.szShareBackend)
696 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &loadparm.Globals.szSAM_URL)
697 _PUBLIC_ FN_GLOBAL_STRING(lp_secrets_url, &loadparm.Globals.szSECRETS_URL)
698 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &loadparm.Globals.szSPOOLSS_URL)
699 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &loadparm.Globals.szWINS_CONFIG_URL)
700 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &loadparm.Globals.szWINS_URL)
701 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &loadparm.Globals.szWinbindSeparator)
702 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &loadparm.Globals.szWinbinddSocketDirectory)
703 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_shell, &loadparm.Globals.szTemplateShell)
704 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_homedir, &loadparm.Globals.szTemplateHomedir)
705 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &loadparm.Globals.bWinbindSealedPipes)
706 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &loadparm.Globals.szPrivateDir)
707 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &loadparm.Globals.szServerString)
708 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &loadparm.Globals.szLockDir)
709 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &loadparm.Globals.szModulesDir)
710 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &loadparm.Globals.szSetupDir)
711 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &loadparm.Globals.ncalrpc_dir)
712 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &loadparm.Globals.szPidDir)
713 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &loadparm.Globals.dcerpc_ep_servers)
714 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &loadparm.Globals.server_services)
715 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &loadparm.Globals.ntptr_providor)
716 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &loadparm.Globals.szAutoServices)
717 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &loadparm.Globals.szPasswdChat)
718 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &loadparm.Globals.szPasswordServers)
719 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &loadparm.Globals.szNameResolveOrder)
720 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &loadparm.Globals.szRealm)
721 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &loadparm.Globals.socket_options)
722 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &loadparm.Globals.szWorkgroup)
723 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &loadparm.Globals.szNetbiosName)
724 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &loadparm.Globals.szNetbiosScope)
725 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &loadparm.Globals.szWINSservers)
726 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &loadparm.Globals.szInterfaces)
727 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &loadparm.Globals.szSocketAddress)
728 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &loadparm.Globals.szNetbiosAliases)
730 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &loadparm.Globals.bDisableNetbios)
731 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &loadparm.Globals.bWINSsupport)
732 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &loadparm.Globals.bWINSdnsProxy)
733 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &loadparm.Globals.szWINSHook)
734 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &loadparm.Globals.bLocalMaster)
735 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &loadparm.Globals.bReadRaw)
736 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &loadparm.Globals.bLargeReadwrite)
737 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &loadparm.Globals.bWriteRaw)
738 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &loadparm.Globals.bNullPasswords)
739 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &loadparm.Globals.bObeyPamRestrictions)
740 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &loadparm.Globals.bEncryptPasswords)
741 _PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, &loadparm.Globals.bTimeServer)
742 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &loadparm.Globals.bBindInterfacesOnly)
743 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &loadparm.Globals.bUnicode)
744 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &loadparm.Globals.bNTStatusSupport)
745 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &loadparm.Globals.bLanmanAuth)
746 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &loadparm.Globals.bNTLMAuth)
747 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &loadparm.Globals.bClientPlaintextAuth)
748 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &loadparm.Globals.bClientLanManAuth)
749 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &loadparm.Globals.bClientNTLMv2Auth)
750 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &loadparm.Globals.client_use_spnego_principal)
751 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &loadparm.Globals.bHostMSDfs)
752 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &loadparm.Globals.bUnixExtensions)
753 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &loadparm.Globals.bUseSpnego)
754 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &loadparm.Globals.bRpcBigEndian)
755 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &loadparm.Globals.max_wins_ttl)
756 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &loadparm.Globals.min_wins_ttl)
757 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &loadparm.Globals.max_mux)
758 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &loadparm.Globals.max_xmit)
759 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &loadparm.Globals.pwordlevel)
760 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &loadparm.Globals.srv_maxprotocol)
761 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &loadparm.Globals.srv_minprotocol)
762 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &loadparm.Globals.cli_maxprotocol)
763 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &loadparm.Globals.cli_minprotocol)
764 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &loadparm.Globals.security)
765 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &loadparm.Globals.paranoid_server_security)
766 _PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, &loadparm.Globals.announce_as)
767 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &loadparm.Globals.jsInclude)
768 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
769 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
770 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
771 static FN_LOCAL_STRING(_lp_printername, szPrintername)
772 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
773 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
774 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
775 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
776 static FN_LOCAL_STRING(lp_volume, volume)
777 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
778 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
779 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
780 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
781 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
782 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
783 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
784 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
785 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
786 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
787 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
788 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
789 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
790 _PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
791 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
792 _PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
793 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
794 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &loadparm.Globals.server_signing)
795 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &loadparm.Globals.client_signing)
797 /* local prototypes */
798 static int map_parameter(const char *pszParmName);
799 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
800 const char *pszServiceName);
801 static void copy_service(struct loadparm_service *pserviceDest,
802 struct loadparm_service *pserviceSource,
804 static bool service_ok(struct loadparm_service *service);
805 static bool do_section(const char *pszSectionName, void *);
806 static void init_copymap(struct loadparm_service *pservice);
808 /* This is a helper function for parametrical options support. */
809 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
810 /* Actual parametrical functions are quite simple */
811 const char *lp_get_parametric(struct loadparm_service *service,
812 const char *type, const char *option)
815 struct param_opt *data;
817 data = (service == NULL ? loadparm.Globals.param_opt : service->param_opt);
819 asprintf(&vfskey, "%s:%s", type, option);
823 if (strcmp(data->key, vfskey) == 0) {
830 if (service != NULL) {
831 /* Try to fetch the same option but from globals */
832 /* but only if we are not already working with Globals */
833 for (data = loadparm.Globals.param_opt; data;
835 if (strcmp(data->key, vfskey) == 0) {
848 /*******************************************************************
849 convenience routine to return int parameters.
850 ********************************************************************/
851 static int lp_int(const char *s)
855 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
859 return strtol(s, NULL, 0);
862 /*******************************************************************
863 convenience routine to return unsigned long parameters.
864 ********************************************************************/
865 static int lp_ulong(const char *s)
869 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
873 return strtoul(s, NULL, 0);
876 /*******************************************************************
877 convenience routine to return unsigned long parameters.
878 ********************************************************************/
879 static double lp_double(const char *s)
883 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
887 return strtod(s, NULL);
890 /*******************************************************************
891 convenience routine to return boolean parameters.
892 ********************************************************************/
893 static bool lp_bool(const char *s)
898 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
902 if (!set_boolean(s, &ret)) {
903 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
911 /* Return parametric option from a given service. Type is a part of option before ':' */
912 /* Parametric option has following syntax: 'Type: option = value' */
913 /* Returned value is allocated in 'lp_talloc' context */
915 const char *lp_parm_string(struct loadparm_service *service, const char *type,
918 const char *value = lp_get_parametric(service, type, option);
921 return lp_string(value);
926 /* Return parametric option from a given service. Type is a part of option before ':' */
927 /* Parametric option has following syntax: 'Type: option = value' */
928 /* Returned value is allocated in 'lp_talloc' context */
930 const char **lp_parm_string_list(struct loadparm_service *service,
932 const char *option, const char *separator)
934 const char *value = lp_get_parametric(service, type, option);
937 return str_list_make(talloc_autofree_context(), value,
943 /* Return parametric option from a given service. Type is a part of option before ':' */
944 /* Parametric option has following syntax: 'Type: option = value' */
946 int lp_parm_int(struct loadparm_service *service, const char *type,
947 const char *option, int default_v)
949 const char *value = lp_get_parametric(service, type, option);
952 return lp_int(value);
957 /* Return parametric option from a given service. Type is a part of
959 * Parametric option has following syntax: 'Type: option = value'.
962 int lp_parm_bytes(struct loadparm_service *service, const char *type,
963 const char *option, int default_v)
967 const char *value = lp_get_parametric(service, type, option);
969 if (value && conv_str_size(value, &bval)) {
970 if (bval <= INT_MAX) {
978 /* Return parametric option from a given service. Type is a part of option before ':' */
979 /* Parametric option has following syntax: 'Type: option = value' */
981 unsigned long lp_parm_ulong(struct loadparm_service *service, const char *type,
982 const char *option, unsigned long default_v)
984 const char *value = lp_get_parametric(service, type, option);
987 return lp_ulong(value);
993 double lp_parm_double(struct loadparm_service *service, const char *type,
994 const char *option, double default_v)
996 const char *value = lp_get_parametric(service, type, option);
999 return lp_double(value);
1004 /* Return parametric option from a given service. Type is a part of option before ':' */
1005 /* Parametric option has following syntax: 'Type: option = value' */
1007 bool lp_parm_bool(struct loadparm_service *service, const char *type,
1008 const char *option, bool default_v)
1010 const char *value = lp_get_parametric(service, type, option);
1013 return lp_bool(value);
1019 /***************************************************************************
1020 Initialise a service to the defaults.
1021 ***************************************************************************/
1023 static struct loadparm_service *init_service(TALLOC_CTX *mem_ctx)
1025 struct loadparm_service *pservice =
1026 talloc_zero(mem_ctx, struct loadparm_service);
1027 copy_service(pservice, &sDefault, NULL);
1032 Set a string value, deallocating any existing space, and allocing the space
1035 static bool string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
1042 *dest = talloc_strdup(mem_ctx, src);
1043 if ((*dest) == NULL) {
1044 DEBUG(0,("Out of memory in string_init\n"));
1053 /***************************************************************************
1054 Add a new service to the services array initialising it with the given
1056 ***************************************************************************/
1058 static struct loadparm_service *add_a_service(struct loadparm_context *lp_ctx,
1059 const struct loadparm_service *pservice,
1063 struct loadparm_service tservice;
1064 int num_to_alloc = lp_ctx->iNumServices + 1;
1065 struct param_opt *data, *pdata;
1067 tservice = *pservice;
1069 /* it might already exist */
1071 struct loadparm_service *service = getservicebyname(lp_ctx,
1073 if (service != NULL) {
1074 /* Clean all parametric options for service */
1075 /* They will be added during parsing again */
1076 data = service->param_opt;
1082 service->param_opt = NULL;
1087 /* find an invalid one */
1088 for (i = 0; i < lp_ctx->iNumServices; i++)
1089 if (lp_ctx->ServicePtrs[i] == NULL)
1092 /* if not, then create one */
1093 if (i == lp_ctx->iNumServices) {
1094 struct loadparm_service **tsp;
1096 tsp = realloc_p(lp_ctx->ServicePtrs, struct loadparm_service *,
1100 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1104 lp_ctx->ServicePtrs = tsp;
1105 lp_ctx->ServicePtrs[lp_ctx->iNumServices] = NULL;
1108 lp_ctx->iNumServices++;
1111 lp_ctx->ServicePtrs[i] = init_service(talloc_autofree_context());
1112 if (lp_ctx->ServicePtrs[i] == NULL) {
1113 DEBUG(0,("add_a_service: out of memory!\n"));
1116 copy_service(lp_ctx->ServicePtrs[i], &tservice, NULL);
1118 string_set(lp_ctx->ServicePtrs[i], &lp_ctx->ServicePtrs[i]->szService, name);
1119 return lp_ctx->ServicePtrs[i];
1122 /***************************************************************************
1123 Add a new home service, with the specified home directory, defaults coming
1125 ***************************************************************************/
1127 bool lp_add_home(struct loadparm_context *lp_ctx,
1128 const char *pszHomename,
1129 struct loadparm_service *default_service,
1130 const char *user, const char *pszHomedir)
1132 struct loadparm_service *service;
1135 service = add_a_service(lp_ctx, default_service, pszHomename);
1137 if (service == NULL)
1140 if (!(*(default_service->szPath))
1141 || strequal(default_service->szPath, sDefault.szPath)) {
1142 pstrcpy(newHomedir, pszHomedir);
1144 pstrcpy(newHomedir, lp_pathname(default_service));
1145 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1148 string_set(service, &service->szPath, newHomedir);
1150 if (!(*(service->comment))) {
1151 service->comment = talloc_asprintf(service, "Home directory of %s", user);
1153 service->bAvailable = default_service->bAvailable;
1154 service->bBrowseable = default_service->bBrowseable;
1156 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
1157 pszHomename, user, newHomedir));
1162 /***************************************************************************
1163 Add a new service, based on an old one.
1164 ***************************************************************************/
1166 struct loadparm_service *lp_add_service(struct loadparm_context *lp_ctx,
1167 const char *pszService,
1168 struct loadparm_service *default_service)
1170 return add_a_service(lp_ctx, default_service, pszService);
1173 /***************************************************************************
1174 Add the IPC service.
1175 ***************************************************************************/
1177 static bool lp_add_hidden(struct loadparm_context *lp_ctx, const char *name,
1180 struct loadparm_service *service = add_a_service(lp_ctx, &sDefault, name);
1182 if (service == NULL)
1185 string_set(service, &service->szPath, tmpdir());
1187 service->comment = talloc_asprintf(service, "%s Service (%s)",
1188 fstype, loadparm.Globals.szServerString);
1189 string_set(service, &service->fstype, fstype);
1190 service->iMaxConnections = -1;
1191 service->bAvailable = true;
1192 service->bRead_only = true;
1193 service->bPrint_ok = false;
1194 service->bBrowseable = false;
1196 if (strcasecmp(fstype, "IPC") == 0) {
1197 lp_do_service_parameter(lp_ctx, service, "ntvfs handler",
1201 DEBUG(3, ("adding hidden service %s\n", name));
1206 /***************************************************************************
1207 Add a new printer service, with defaults coming from service iFrom.
1208 ***************************************************************************/
1210 bool lp_add_printer(struct loadparm_context *lp_ctx,
1211 const char *pszPrintername,
1212 struct loadparm_service *default_service)
1214 const char *comment = "From Printcap";
1215 struct loadparm_service *service;
1216 service = add_a_service(lp_ctx, default_service, pszPrintername);
1218 if (service == NULL)
1221 /* note that we do NOT default the availability flag to True - */
1222 /* we take it from the default service passed. This allows all */
1223 /* dynamic printers to be disabled by disabling the [printers] */
1224 /* entry (if/when the 'available' keyword is implemented!). */
1226 /* the printer name is set to the service name. */
1227 string_set(service, &service->szPrintername, pszPrintername);
1228 string_set(service, &service->comment, comment);
1229 service->bBrowseable = sDefault.bBrowseable;
1230 /* Printers cannot be read_only. */
1231 service->bRead_only = false;
1232 /* Printer services must be printable. */
1233 service->bPrint_ok = true;
1235 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1240 /***************************************************************************
1241 Map a parameter's string representation to something we can use.
1242 Returns False if the parameter string is not recognised, else TRUE.
1243 ***************************************************************************/
1245 static int map_parameter(const char *pszParmName)
1249 if (*pszParmName == '-')
1252 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1253 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1256 /* Warn only if it isn't parametric option */
1257 if (strchr(pszParmName, ':') == NULL)
1258 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1259 /* We do return 'fail' for parametric options as well because they are
1260 stored in different storage
1267 return the parameter structure for a parameter
1269 struct parm_struct *lp_parm_struct(const char *name)
1271 int parmnum = map_parameter(name);
1272 if (parmnum == -1) return NULL;
1273 return &parm_table[parmnum];
1277 return the parameter pointer for a parameter
1279 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
1281 if (service == NULL)
1284 return ((char *)service) + PTR_DIFF(parm->ptr, &sDefault);
1287 /***************************************************************************
1288 Find a service by name. Otherwise works like get_service.
1289 ***************************************************************************/
1291 static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx,
1292 const char *pszServiceName)
1296 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
1297 if (lp_ctx->ServicePtrs[iService] != NULL &&
1298 strwicmp(lp_ctx->ServicePtrs[iService]->szService, pszServiceName) == 0) {
1299 return lp_ctx->ServicePtrs[iService];
1305 /***************************************************************************
1306 Copy a service structure to another.
1307 If pcopymapDest is NULL then copy all fields
1308 ***************************************************************************/
1310 static void copy_service(struct loadparm_service *pserviceDest,
1311 struct loadparm_service *pserviceSource,
1315 bool bcopyall = (pcopymapDest == NULL);
1316 struct param_opt *data, *pdata, *paramo;
1319 for (i = 0; parm_table[i].label; i++)
1320 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1321 (bcopyall || pcopymapDest[i])) {
1322 void *def_ptr = parm_table[i].ptr;
1324 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1327 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1330 switch (parm_table[i].type) {
1332 *(int *)dest_ptr = *(int *)src_ptr;
1338 *(int *)dest_ptr = *(int *)src_ptr;
1342 string_set(pserviceDest,
1348 string_set(pserviceDest,
1351 strupper(*(char **)dest_ptr);
1354 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1355 *(const char ***)src_ptr);
1363 init_copymap(pserviceDest);
1364 if (pserviceSource->copymap)
1365 memcpy((void *)pserviceDest->copymap,
1366 (void *)pserviceSource->copymap,
1367 sizeof(int) * NUMPARAMETERS);
1370 data = pserviceSource->param_opt;
1373 pdata = pserviceDest->param_opt;
1374 /* Traverse destination */
1376 /* If we already have same option, override it */
1377 if (strcmp(pdata->key, data->key) == 0) {
1378 talloc_free(pdata->value);
1379 pdata->value = talloc_reference(pdata,
1384 pdata = pdata->next;
1387 paramo = talloc(pserviceDest, struct param_opt);
1390 paramo->key = talloc_reference(paramo, data->key);
1391 paramo->value = talloc_reference(paramo, data->value);
1392 DLIST_ADD(pserviceDest->param_opt, paramo);
1398 /***************************************************************************
1399 Check a service for consistency. Return False if the service is in any way
1400 incomplete or faulty, else True.
1401 ***************************************************************************/
1403 static bool service_ok(struct loadparm_service *service)
1408 if (service->szService[0] == '\0') {
1409 DEBUG(0, ("The following message indicates an internal error:\n"));
1410 DEBUG(0, ("No service name in service entry.\n"));
1414 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1415 /* I can't see why you'd want a non-printable printer service... */
1416 if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
1417 if (!service->bPrint_ok) {
1418 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1419 service->szService));
1420 service->bPrint_ok = true;
1422 /* [printers] service must also be non-browsable. */
1423 if (service->bBrowseable)
1424 service->bBrowseable = false;
1427 /* If a service is flagged unavailable, log the fact at level 0. */
1428 if (!service->bAvailable)
1429 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1430 service->szService));
1436 /*******************************************************************
1437 Keep a linked list of all config files so we know when one has changed
1438 it's date and needs to be reloaded.
1439 ********************************************************************/
1441 static void add_to_file_list(struct loadparm_context *lp_ctx,
1442 const char *fname, const char *subfname)
1444 struct file_lists *f = lp_ctx->file_lists;
1447 if (f->name && !strcmp(f->name, fname))
1453 f = talloc(talloc_autofree_context(), struct file_lists);
1456 f->next = lp_ctx->file_lists;
1457 f->name = talloc_strdup(f, fname);
1462 f->subfname = talloc_strdup(f, subfname);
1467 lp_ctx->file_lists = f;
1468 f->modtime = file_modtime(subfname);
1470 time_t t = file_modtime(subfname);
1476 /*******************************************************************
1477 Check if a config file has changed date.
1478 ********************************************************************/
1480 bool lp_file_list_changed(struct loadparm_context *lp_ctx)
1482 struct file_lists *f;
1483 DEBUG(6, ("lp_file_list_changed()\n"));
1485 for (f = lp_ctx->file_lists; f != NULL; f = f->next) {
1489 n2 = standard_sub_basic(talloc_autofree_context(), f->name);
1491 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1492 f->name, n2, ctime(&f->modtime)));
1494 mod_time = file_modtime(n2);
1496 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1497 DEBUGADD(6, ("file %s modified: %s\n", n2,
1499 f->modtime = mod_time;
1500 talloc_free(f->subfname);
1501 f->subfname = talloc_strdup(f, n2);
1508 /***************************************************************************
1509 Handle the include operation.
1510 ***************************************************************************/
1512 static bool handle_include(struct loadparm_context *lp_ctx,
1513 const char *pszParmValue, char **ptr)
1515 char *fname = standard_sub_basic(talloc_autofree_context(),
1518 add_to_file_list(lp_ctx, pszParmValue, fname);
1520 string_set(talloc_autofree_context(), ptr, fname);
1522 if (file_exist(fname))
1523 return pm_process(fname, do_section, do_parameter, lp_ctx);
1525 DEBUG(2, ("Can't find include file %s\n", fname));
1530 /***************************************************************************
1531 Handle the interpretation of the copy parameter.
1532 ***************************************************************************/
1534 static bool handle_copy(struct loadparm_context *lp_ctx,
1535 const char *pszParmValue, char **ptr)
1538 struct loadparm_service *serviceTemp;
1540 string_set(talloc_autofree_context(), ptr, pszParmValue);
1544 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1546 if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) {
1547 if (serviceTemp == lp_ctx->currentService) {
1548 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1550 copy_service(lp_ctx->currentService,
1552 lp_ctx->currentService->copymap);
1556 DEBUG(0, ("Unable to copy service - source not found: %s\n",
1564 /***************************************************************************
1565 Initialise a copymap.
1566 ***************************************************************************/
1568 static void init_copymap(struct loadparm_service *pservice)
1571 talloc_free(pservice->copymap);
1572 pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS);
1573 if (pservice->copymap == NULL) {
1575 ("Couldn't allocate copymap!! (size %d)\n",
1576 (int)NUMPARAMETERS));
1579 for (i = 0; i < NUMPARAMETERS; i++)
1580 pservice->copymap[i] = true;
1583 /***************************************************************************
1584 Process a parametric option
1585 ***************************************************************************/
1586 static bool lp_do_parameter_parametric(struct loadparm_service *service,
1587 const char *pszParmName,
1588 const char *pszParmValue, int flags)
1590 struct param_opt *paramo, *data;
1592 TALLOC_CTX *mem_ctx;
1594 while (isspace((unsigned char)*pszParmName)) {
1598 name = strdup(pszParmName);
1599 if (!name) return false;
1603 if (service == NULL) {
1604 data = loadparm.Globals.param_opt;
1605 mem_ctx = talloc_autofree_context();
1607 data = service->param_opt;
1611 /* Traverse destination */
1612 for (paramo=data; paramo; paramo=paramo->next) {
1613 /* If we already have the option set, override it unless
1614 it was a command line option and the new one isn't */
1615 if (strcmp(paramo->key, name) == 0) {
1616 if ((paramo->flags & FLAG_CMDLINE) &&
1617 !(flags & FLAG_CMDLINE)) {
1621 talloc_free(paramo->value);
1622 paramo->value = talloc_strdup(paramo, pszParmValue);
1623 paramo->flags = flags;
1629 paramo = talloc(mem_ctx, struct param_opt);
1632 paramo->key = talloc_strdup(paramo, name);
1633 paramo->value = talloc_strdup(paramo, pszParmValue);
1634 paramo->flags = flags;
1635 if (service == NULL) {
1636 DLIST_ADD(loadparm.Globals.param_opt, paramo);
1638 DLIST_ADD(service->param_opt, paramo);
1646 static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1647 const char *pszParmName, const char *pszParmValue,
1648 struct loadparm_context *lp_ctx)
1651 /* if it is a special case then go ahead */
1652 if (parm_table[parmnum].special) {
1653 parm_table[parmnum].special(lp_ctx, pszParmValue,
1658 /* now switch on the type of variable it is */
1659 switch (parm_table[parmnum].type)
1663 if (!set_boolean(pszParmValue, &b)) {
1664 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1667 *(int *)parm_ptr = b;
1672 *(int *)parm_ptr = atoi(pszParmValue);
1676 *(int *)parm_ptr = strtol(pszParmValue, NULL, 8);
1682 if (conv_str_size(pszParmValue, &val)) {
1683 if (val <= INT_MAX) {
1684 *(int *)parm_ptr = (int)val;
1689 DEBUG(0,("lp_do_parameter(%s): value is not "
1690 "a valid size specifier!\n", pszParmValue));
1695 *(const char ***)parm_ptr = str_list_make(mem_ctx,
1696 pszParmValue, NULL);
1700 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1704 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1705 strupper(*(char **)parm_ptr);
1709 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1712 parm_table[parmnum].enum_list[i].name)) {
1714 parm_table[parmnum].
1719 if (!parm_table[parmnum].enum_list[i].name) {
1720 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1721 pszParmValue, pszParmName));
1729 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1730 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1731 /* we have to also unset FLAG_DEFAULT on aliases */
1732 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1733 parm_table[i].flags &= ~FLAG_DEFAULT;
1735 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1736 parm_table[i].flags &= ~FLAG_DEFAULT;
1743 bool lp_do_global_parameter(struct loadparm_context *lp_ctx,
1744 const char *pszParmName, const char *pszParmValue)
1746 int parmnum = map_parameter(pszParmName);
1750 if (strchr(pszParmName, ':')) {
1751 return lp_do_parameter_parametric(NULL, pszParmName, pszParmValue, 0);
1753 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1757 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1758 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1762 /* if the flag has been set on the command line, then don't allow override,
1763 but don't report an error */
1764 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1768 parm_ptr = parm_table[parmnum].ptr;
1770 return set_variable(talloc_autofree_context(), parmnum, parm_ptr,
1771 pszParmName, pszParmValue, lp_ctx);
1774 bool lp_do_service_parameter(struct loadparm_context *lp_ctx,
1775 struct loadparm_service *service,
1776 const char *pszParmName, const char *pszParmValue)
1778 void *def_ptr = NULL;
1781 int parmnum = map_parameter(pszParmName);
1784 if (strchr(pszParmName, ':')) {
1785 return lp_do_parameter_parametric(service, pszParmName, pszParmValue, 0);
1787 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1791 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1792 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1796 /* if the flag has been set on the command line, then don't allow override,
1797 but don't report an error */
1798 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1802 def_ptr = parm_table[parmnum].ptr;
1804 if (parm_table[parmnum].class == P_GLOBAL) {
1806 ("Global parameter %s found in service section!\n",
1810 parm_ptr = ((char *)service) + PTR_DIFF(def_ptr, &sDefault);
1812 if (!service->copymap)
1813 init_copymap(service);
1815 /* this handles the aliases - set the copymap for other
1816 * entries with the same data pointer */
1817 for (i = 0; parm_table[i].label; i++)
1818 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1819 service->copymap[i] = false;
1821 return set_variable(service, parmnum, parm_ptr, pszParmName,
1822 pszParmValue, lp_ctx);
1825 /***************************************************************************
1826 Process a parameter.
1827 ***************************************************************************/
1829 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1832 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
1834 if (lp_ctx->bInGlobalSection)
1835 return lp_do_global_parameter(lp_ctx, pszParmName,
1838 return lp_do_service_parameter(lp_ctx, lp_ctx->currentService,
1839 pszParmName, pszParmValue);
1843 variable argument do parameter
1845 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
1846 bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx,
1847 const char *pszParmName, const char *fmt, ...)
1854 s = talloc_vasprintf(NULL, fmt, ap);
1856 ret = lp_do_global_parameter(lp_ctx, pszParmName, s);
1863 set a parameter from the commandline - this is called from command line parameter
1864 parsing code. It sets the parameter then marks the parameter as unable to be modified
1865 by smb.conf processing
1867 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1869 int parmnum = map_parameter(pszParmName);
1872 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1875 if (parmnum < 0 && strchr(pszParmName, ':')) {
1876 /* set a parametric option */
1877 return lp_do_parameter_parametric(NULL, pszParmName, pszParmValue, FLAG_CMDLINE);
1881 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1885 /* reset the CMDLINE flag in case this has been called before */
1886 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1888 if (!lp_do_global_parameter(&loadparm, pszParmName, pszParmValue)) {
1892 parm_table[parmnum].flags |= FLAG_CMDLINE;
1894 /* we have to also set FLAG_CMDLINE on aliases */
1895 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1896 parm_table[i].flags |= FLAG_CMDLINE;
1898 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1899 parm_table[i].flags |= FLAG_CMDLINE;
1906 set a option from the commandline in 'a=b' format. Use to support --option
1908 bool lp_set_option(const char *option)
1926 ret = lp_set_cmdline(s, p+1);
1932 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1934 /***************************************************************************
1935 Print a parameter of the specified type.
1936 ***************************************************************************/
1938 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1944 for (i = 0; p->enum_list[i].name; i++) {
1945 if (*(int *)ptr == p->enum_list[i].value) {
1947 p->enum_list[i].name);
1954 fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr));
1959 fprintf(f, "%d", *(int *)ptr);
1963 fprintf(f, "0%o", *(int *)ptr);
1967 if ((char ***)ptr && *(char ***)ptr) {
1968 char **list = *(char ***)ptr;
1970 for (; *list; list++)
1971 fprintf(f, "%s%s", *list,
1972 ((*(list+1))?", ":""));
1978 if (*(char **)ptr) {
1979 fprintf(f, "%s", *(char **)ptr);
1987 /***************************************************************************
1988 Check if two parameters are equal.
1989 ***************************************************************************/
1991 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
1995 return (*((int *)ptr1) == *((int *)ptr2));
2001 return (*((int *)ptr1) == *((int *)ptr2));
2004 return str_list_equal((const char **)(*(char ***)ptr1),
2005 (const char **)(*(char ***)ptr2));
2010 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2015 return (p1 == p2 || strequal(p1, p2));
2023 /***************************************************************************
2024 Process a new section (service). At this stage all sections are services.
2025 Later we'll have special sections that permit server parameters to be set.
2026 Returns True on success, False on failure.
2027 ***************************************************************************/
2029 static bool do_section(const char *pszSectionName, void *userdata)
2031 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2033 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2034 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2037 /* if we've just struck a global section, note the fact. */
2038 lp_ctx->bInGlobalSection = isglobal;
2040 /* check for multiple global sections */
2041 if (lp_ctx->bInGlobalSection) {
2042 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2046 /* if we have a current service, tidy it up before moving on */
2049 if (lp_ctx->currentService != NULL)
2050 bRetval = service_ok(lp_ctx->currentService);
2052 /* if all is still well, move to the next record in the services array */
2054 /* We put this here to avoid an odd message order if messages are */
2055 /* issued by the post-processing of a previous section. */
2056 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2058 if ((loadparm.currentService = add_a_service(lp_ctx, &sDefault,
2061 DEBUG(0, ("Failed to add a new service\n"));
2070 /***************************************************************************
2071 Determine if a partcular base parameter is currentl set to the default value.
2072 ***************************************************************************/
2074 static bool is_default(int i)
2076 if (!defaults_saved)
2078 switch (parm_table[i].type) {
2080 return str_list_equal((const char **)parm_table[i].def.lvalue,
2081 (const char **)(*(char ***)parm_table[i].ptr));
2084 return strequal(parm_table[i].def.svalue,
2085 *(char **)parm_table[i].ptr);
2087 return parm_table[i].def.bvalue ==
2088 *(int *)parm_table[i].ptr;
2093 return parm_table[i].def.ivalue ==
2094 *(int *)parm_table[i].ptr;
2101 /***************************************************************************
2102 Display the contents of the global structure.
2103 ***************************************************************************/
2105 static void dump_globals(FILE *f, bool show_defaults)
2108 struct param_opt *data;
2110 fprintf(f, "# Global parameters\n[global]\n");
2112 for (i = 0; parm_table[i].label; i++)
2113 if (parm_table[i].class == P_GLOBAL &&
2114 parm_table[i].ptr &&
2115 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2116 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2118 fprintf(f, "\t%s = ", parm_table[i].label);
2119 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2122 if (loadparm.Globals.param_opt != NULL) {
2123 for (data = loadparm.Globals.param_opt; data;
2124 data = data->next) {
2125 fprintf(f, "\t%s = %s\n", data->key, data->value);
2131 /***************************************************************************
2132 Display the contents of a single services record.
2133 ***************************************************************************/
2135 static void dump_a_service(struct loadparm_service * pService, FILE * f)
2138 struct param_opt *data;
2140 if (pService != &sDefault)
2141 fprintf(f, "\n[%s]\n", pService->szService);
2143 for (i = 0; parm_table[i].label; i++)
2144 if (parm_table[i].class == P_LOCAL &&
2145 parm_table[i].ptr &&
2146 (*parm_table[i].label != '-') &&
2147 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2148 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2150 if (pService == &sDefault) {
2151 if (defaults_saved && is_default(i))
2154 if (equal_parameter(parm_table[i].type,
2155 ((char *)pService) +
2157 ((char *)&sDefault) +
2162 fprintf(f, "\t%s = ", parm_table[i].label);
2163 print_parameter(&parm_table[i],
2164 ((char *)pService) + pdiff, f);
2167 if (pService->param_opt != NULL) {
2168 for (data = pService->param_opt; data; data = data->next) {
2169 fprintf(f, "\t%s = %s\n", data->key, data->value);
2174 bool lp_dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2176 struct loadparm_service * pService = loadparm.ServicePtrs[snum];
2177 struct parm_struct *parm;
2180 parm = lp_parm_struct(parm_name);
2188 ptr = ((char *)pService) +
2189 PTR_DIFF(parm->ptr, &sDefault);
2191 print_parameter(parm,
2197 /***************************************************************************
2198 Return info about the next service in a service. snum==-1 gives the globals.
2199 Return NULL when out of parameters.
2200 ***************************************************************************/
2202 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2205 /* do the globals */
2206 for (; parm_table[*i].label; (*i)++) {
2207 if (parm_table[*i].class == P_SEPARATOR)
2208 return &parm_table[(*i)++];
2210 if (!parm_table[*i].ptr
2211 || (*parm_table[*i].label == '-'))
2215 && (parm_table[*i].ptr ==
2216 parm_table[(*i) - 1].ptr))
2219 return &parm_table[(*i)++];
2222 struct loadparm_service *pService = loadparm.ServicePtrs[snum];
2224 for (; parm_table[*i].label; (*i)++) {
2225 if (parm_table[*i].class == P_SEPARATOR)
2226 return &parm_table[(*i)++];
2228 if (parm_table[*i].class == P_LOCAL &&
2229 parm_table[*i].ptr &&
2230 (*parm_table[*i].label != '-') &&
2232 (parm_table[*i].ptr !=
2233 parm_table[(*i) - 1].ptr)))
2236 PTR_DIFF(parm_table[*i].ptr,
2239 if (allparameters ||
2240 !equal_parameter(parm_table[*i].type,
2241 ((char *)pService) +
2243 ((char *)&sDefault) +
2246 return &parm_table[(*i)++];
2256 /***************************************************************************
2257 Auto-load some home services.
2258 ***************************************************************************/
2260 static void lp_add_auto_services(struct loadparm_context *lp_ctx,
2266 /***************************************************************************
2267 Have we loaded a services file yet?
2268 ***************************************************************************/
2270 bool lp_loaded(void)
2275 /***************************************************************************
2276 Unload unused services.
2277 ***************************************************************************/
2279 void lp_killunused(struct smbsrv_connection *smb, bool (*snumused) (struct smbsrv_connection *, int))
2282 for (i = 0; i < loadparm.iNumServices; i++) {
2283 if (loadparm.ServicePtrs[i] == NULL)
2286 if (!snumused || !snumused(smb, i)) {
2287 talloc_free(loadparm.ServicePtrs[i]);
2288 loadparm.ServicePtrs[i] = NULL;
2293 /***************************************************************************
2294 Initialise the global parameter structure.
2295 ***************************************************************************/
2296 bool loadparm_init(struct loadparm_context *lp_ctx)
2301 DEBUG(3, ("Initialising global parameters\n"));
2303 for (i = 0; parm_table[i].label; i++) {
2304 if ((parm_table[i].type == P_STRING ||
2305 parm_table[i].type == P_USTRING) &&
2306 parm_table[i].ptr &&
2307 !(parm_table[i].flags & FLAG_CMDLINE)) {
2308 string_set(talloc_autofree_context(),
2309 (char **)parm_table[i].ptr, "");
2313 lp_do_global_parameter(lp_ctx, "config file", dyn_CONFIGFILE);
2315 lp_do_global_parameter(lp_ctx, "share backend", "classic");
2317 lp_do_global_parameter(lp_ctx, "server role", "standalone");
2319 /* options that can be set on the command line must be initialised via
2320 the slower lp_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2322 lp_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2324 lp_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2325 myname = get_myname();
2326 lp_do_global_parameter(lp_ctx, "netbios name", myname);
2328 lp_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
2330 lp_do_global_parameter(lp_ctx, "fstype", FSTYPE_STRING);
2331 lp_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2332 lp_do_global_parameter(lp_ctx, "max connections", "-1");
2334 lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo");
2335 lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap web kdc drepl winbind");
2336 lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb");
2337 lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain");
2338 lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind");
2339 lp_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain");
2340 lp_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2341 lp_do_global_parameter(lp_ctx, "sam database", "sam.ldb");
2342 lp_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb");
2343 lp_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb");
2344 lp_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb");
2345 lp_do_global_parameter(lp_ctx, "wins database", "wins.ldb");
2346 lp_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2348 /* This hive should be dynamically generated by Samba using
2349 data from the sam, but for the moment leave it in a tdb to
2350 keep regedt32 from popping up an annoying dialog. */
2351 lp_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2353 /* using UTF8 by default allows us to support all chars */
2354 lp_do_global_parameter(lp_ctx, "unix charset", "UTF8");
2356 /* Use codepage 850 as a default for the dos character set */
2357 lp_do_global_parameter(lp_ctx, "dos charset", "CP850");
2360 * Allow the default PASSWD_CHAT to be overridden in local.h.
2362 lp_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2364 lp_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2365 lp_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2366 lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR);
2367 lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2369 lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0");
2370 lp_do_global_parameter_var(lp_ctx, "server string",
2371 "Samba %s", SAMBA_VERSION_STRING);
2373 lp_do_global_parameter_var(lp_ctx, "announce version", "%d.%d",
2374 DEFAULT_MAJOR_VERSION,
2375 DEFAULT_MINOR_VERSION);
2377 lp_do_global_parameter(lp_ctx, "password server", "*");
2379 lp_do_global_parameter(lp_ctx, "max mux", "50");
2380 lp_do_global_parameter(lp_ctx, "max xmit", "12288");
2381 lp_do_global_parameter(lp_ctx, "password level", "0");
2382 lp_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2383 lp_do_global_parameter(lp_ctx, "server min protocol", "CORE");
2384 lp_do_global_parameter(lp_ctx, "server max protocol", "NT1");
2385 lp_do_global_parameter(lp_ctx, "client min protocol", "CORE");
2386 lp_do_global_parameter(lp_ctx, "client max protocol", "NT1");
2387 lp_do_global_parameter(lp_ctx, "security", "USER");
2388 lp_do_global_parameter(lp_ctx, "paranoid server security", "True");
2389 lp_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2390 lp_do_global_parameter(lp_ctx, "ReadRaw", "True");
2391 lp_do_global_parameter(lp_ctx, "WriteRaw", "True");
2392 lp_do_global_parameter(lp_ctx, "NullPasswords", "False");
2393 lp_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2394 lp_do_global_parameter(lp_ctx, "announce as", "NT SERVER");
2396 lp_do_global_parameter(lp_ctx, "TimeServer", "False");
2397 lp_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2398 lp_do_global_parameter(lp_ctx, "Unicode", "True");
2399 lp_do_global_parameter(lp_ctx, "ClientLanManAuth", "True");
2400 lp_do_global_parameter(lp_ctx, "LanmanAuth", "True");
2401 lp_do_global_parameter(lp_ctx, "NTLMAuth", "True");
2402 lp_do_global_parameter(lp_ctx, "client use spnego principal", "False");
2404 lp_do_global_parameter(lp_ctx, "UnixExtensions", "False");
2406 lp_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2407 lp_do_global_parameter(lp_ctx, "LocalMaster", "True");
2409 lp_do_global_parameter(lp_ctx, "wins support", "False");
2410 lp_do_global_parameter(lp_ctx, "dns proxy", "True");
2412 lp_do_global_parameter(lp_ctx, "winbind separator", "\\");
2413 lp_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2414 lp_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2415 lp_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2416 lp_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
2418 lp_do_global_parameter(lp_ctx, "client signing", "Yes");
2419 lp_do_global_parameter(lp_ctx, "server signing", "auto");
2421 lp_do_global_parameter(lp_ctx, "use spnego", "True");
2423 lp_do_global_parameter(lp_ctx, "smb ports", "445 139");
2424 lp_do_global_parameter(lp_ctx, "nbt port", "137");
2425 lp_do_global_parameter(lp_ctx, "dgram port", "138");
2426 lp_do_global_parameter(lp_ctx, "cldap port", "389");
2427 lp_do_global_parameter(lp_ctx, "krb5 port", "88");
2428 lp_do_global_parameter(lp_ctx, "kpasswd port", "464");
2429 lp_do_global_parameter(lp_ctx, "web port", "901");
2430 lp_do_global_parameter(lp_ctx, "swat directory", dyn_SWATDIR);
2432 lp_do_global_parameter(lp_ctx, "nt status support", "True");
2434 lp_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2435 lp_do_global_parameter(lp_ctx, "min wins ttl", "10");
2437 lp_do_global_parameter(lp_ctx, "tls enabled", "True");
2438 lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2439 lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2440 lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2441 lp_do_global_parameter_var(lp_ctx, "js include", "%s", dyn_JSDIR);
2442 lp_do_global_parameter_var(lp_ctx, "setup directory", "%s",
2445 for (i = 0; parm_table[i].label; i++) {
2446 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
2447 parm_table[i].flags |= FLAG_DEFAULT;
2454 /***************************************************************************
2455 Load the services array from the services file. Return True on success,
2457 ***************************************************************************/
2463 struct param_opt *data;
2464 struct loadparm_context *lp_ctx = &loadparm;
2468 if (lp_ctx->Globals.param_opt != NULL) {
2469 struct param_opt *next;
2470 for (data = lp_ctx->Globals.param_opt; data; data=next) {
2472 if (data->flags & FLAG_CMDLINE) continue;
2473 DLIST_REMOVE(lp_ctx->Globals.param_opt, data);
2478 if (!loadparm_init(lp_ctx))
2481 lp_ctx->bInGlobalSection = true;
2482 n2 = standard_sub_basic(talloc_autofree_context(), lp_configfile());
2483 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2485 add_to_file_list(lp_ctx, lp_configfile(), n2);
2487 /* We get sections first, so have to start 'behind' to make up */
2488 lp_ctx->currentService = NULL;
2489 bRetval = pm_process(n2, do_section, do_parameter, lp_ctx);
2491 /* finish up the last section */
2492 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2494 if (lp_ctx->currentService != NULL)
2495 bRetval = service_ok(lp_ctx->currentService);
2497 lp_add_auto_services(lp_ctx, lp_auto_services());
2499 lp_add_hidden(lp_ctx, "IPC$", "IPC");
2500 lp_add_hidden(lp_ctx, "ADMIN$", "DISK");
2504 if (!lp_ctx->Globals.szWINSservers && lp_ctx->Globals.bWINSsupport) {
2505 lp_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
2513 /***************************************************************************
2514 Return the max number of services.
2515 ***************************************************************************/
2517 int lp_numservices(void)
2519 return loadparm.iNumServices;
2522 /***************************************************************************
2523 Display the contents of the services array in human-readable form.
2524 ***************************************************************************/
2526 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
2528 struct loadparm_context *lp_ctx;
2534 defaults_saved = false;
2536 dump_globals(f, show_defaults);
2538 dump_a_service(&sDefault, f);
2540 for (iService = 0; iService < maxtoprint; iService++)
2541 lp_dump_one(f, show_defaults, lp_ctx->ServicePtrs[iService]);
2544 /***************************************************************************
2545 Display the contents of one service in human-readable form.
2546 ***************************************************************************/
2548 void lp_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service)
2550 if (service != NULL) {
2551 if (service->szService[0] == '\0')
2553 dump_a_service(service, f);
2557 struct loadparm_service *lp_servicebynum(int snum)
2559 return loadparm.ServicePtrs[snum];
2562 struct loadparm_service *lp_service(const char *service_name)
2567 for (iService = loadparm.iNumServices - 1; iService >= 0; iService--) {
2568 if (loadparm.ServicePtrs[iService] &&
2569 loadparm.ServicePtrs[iService]->szService) {
2571 * The substitution here is used to support %U is
2574 serviceName = standard_sub_basic(loadparm.ServicePtrs[iService],
2575 loadparm.ServicePtrs[iService]->szService);
2576 if (strequal(serviceName, service_name))
2577 return loadparm.ServicePtrs[iService];
2581 DEBUG(7,("lp_servicenumber: couldn't find %s\n", service_name));
2586 /*******************************************************************
2587 A useful volume label function.
2588 ********************************************************************/
2589 const char *volume_label(struct loadparm_service *service)
2591 const char *ret = lp_volume(service);
2593 return lp_servicename(service);
2598 /***********************************************************
2599 If we are PDC then prefer us as DMB
2600 ************************************************************/
2602 bool lp_domain_logons(void)
2604 return (lp_server_role() == ROLE_DOMAIN_CONTROLLER);
2607 const char *lp_printername(struct loadparm_service *service)
2609 const char *ret = _lp_printername(service);
2610 if (ret == NULL || (ret != NULL && *ret == '\0'))
2611 ret = lp_const_servicename(service);
2617 /*******************************************************************
2618 Return the max print jobs per queue.
2619 ********************************************************************/
2621 int lp_maxprintjobs(struct loadparm_service *service)
2623 int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2624 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2625 maxjobs = PRINT_MAX_JOBID - 1;