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>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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/iconv.h"
60 #include "system/network.h"
61 #include "system/printing.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "librpc/gen_ndr/ndr_nbt.h"
65 #include "dlinklist.h"
66 #include "param/loadparm.h"
68 static BOOL bLoaded = False;
71 #define GLOBAL_NAME "global"
75 #define PRINTERS_NAME "printers"
79 #define HOMES_NAME "homes"
82 /* some helpful bits */
83 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
84 #define VALID(i) ServicePtrs[i]->valid
86 static BOOL do_parameter(const char *, const char *, void *);
87 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
89 static BOOL defaults_saved = False;
93 struct param_opt *prev, *next;
100 * This structure describes global (ie., server-wide) parameters.
108 char *display_charset;
112 char *szServerString;
113 char *szAutoServices;
117 char *szSMBPasswdFile;
123 char **szPasswordServers;
124 char *szSocketOptions;
126 char **szWINSservers;
128 char *szSocketAddress;
129 char *szAnnounceVersion; /* This is initialised in init_globals */
132 char **szNetbiosAliases;
133 char *szNetbiosScope;
134 char *szDomainOtherSIDs;
135 char **szNameResolveOrder;
137 char **dcerpc_ep_servers;
138 char **server_services;
139 char *ntptr_providor;
140 char *szWinbindSeparator;
141 char *swat_directory;
154 BOOL paranoid_server_security;
157 int announce_as; /* This is initialised in init_globals */
163 char *socket_options;
166 BOOL bPreferredMaster;
169 BOOL bEncryptPasswords;
171 BOOL bObeyPamRestrictions;
172 BOOL bLargeReadwrite;
176 BOOL bBindInterfacesOnly;
178 BOOL bNTStatusSupport;
184 BOOL bClientPlaintextAuth;
185 BOOL bClientLanManAuth;
186 BOOL bClientNTLMv2Auth;
189 BOOL bUnixExtensions;
190 BOOL bDisableNetbios;
192 struct param_opt *param_opt;
196 static global Globals;
199 * This structure describes a single service.
214 char **ntvfs_handler;
230 struct param_opt *param_opt;
232 char dummy[3]; /* for alignment */
237 /* This is a default service used to prime a services structure */
238 static service sDefault = {
240 NULL, /* szService */
243 NULL, /* szInclude */
244 NULL, /* szPrintername */
245 NULL, /* szHostsallow */
246 NULL, /* szHostsdeny */
250 NULL, /* ntvfs_handler */
251 1000, /* iMaxPrintJobs */
252 0, /* iMaxConnections */
254 True, /* bAvailable */
255 True, /* bBrowseable */
256 True, /* bRead_only */
257 False, /* bPrint_ok */
258 False, /* bMap_system */
259 False, /* bMap_hidden */
260 True, /* bMap_archive */
261 True, /* bStrictLocking */
263 False, /* bMSDfsRoot */
264 False, /* bStrictSync */
265 False, /* bCIFileSystem */
266 NULL, /* Parametric options */
271 /* local variables */
272 static service **ServicePtrs = NULL;
273 static int iNumServices = 0;
274 static int iServiceIndex = 0;
275 static BOOL bInGlobalSection = True;
276 static int server_role;
277 static int default_server_announce;
279 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
281 /* prototypes for the special type handlers */
282 static BOOL handle_include(const char *pszParmValue, char **ptr);
283 static BOOL handle_copy(const char *pszParmValue, char **ptr);
285 static void set_server_role(void);
286 static void set_default_server_announce_type(void);
288 static const struct enum_list enum_protocol[] = {
289 {PROTOCOL_NT1, "NT1"},
290 {PROTOCOL_LANMAN2, "LANMAN2"},
291 {PROTOCOL_LANMAN1, "LANMAN1"},
292 {PROTOCOL_CORE, "CORE"},
293 {PROTOCOL_COREPLUS, "COREPLUS"},
294 {PROTOCOL_COREPLUS, "CORE+"},
298 static const struct enum_list enum_security[] = {
299 {SEC_SHARE, "SHARE"},
301 {SEC_SERVER, "SERVER"},
302 {SEC_DOMAIN, "DOMAIN"},
309 /* Types of machine we can announce as. */
310 #define ANNOUNCE_AS_NT_SERVER 1
311 #define ANNOUNCE_AS_WIN95 2
312 #define ANNOUNCE_AS_WFW 3
313 #define ANNOUNCE_AS_NT_WORKSTATION 4
315 static const struct enum_list enum_announce_as[] = {
316 {ANNOUNCE_AS_NT_SERVER, "NT"},
317 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
318 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
319 {ANNOUNCE_AS_WIN95, "win95"},
320 {ANNOUNCE_AS_WFW, "WfW"},
324 static const struct enum_list enum_bool_auto[] = {
335 /* Client-side offline caching policy types */
336 #define CSC_POLICY_MANUAL 0
337 #define CSC_POLICY_DOCUMENTS 1
338 #define CSC_POLICY_PROGRAMS 2
339 #define CSC_POLICY_DISABLE 3
341 static const struct enum_list enum_csc_policy[] = {
342 {CSC_POLICY_MANUAL, "manual"},
343 {CSC_POLICY_DOCUMENTS, "documents"},
344 {CSC_POLICY_PROGRAMS, "programs"},
345 {CSC_POLICY_DISABLE, "disable"},
349 /* SMB signing types. */
350 static const struct enum_list enum_smb_signing_vals[] = {
351 {SMB_SIGNING_OFF, "No"},
352 {SMB_SIGNING_OFF, "False"},
353 {SMB_SIGNING_OFF, "0"},
354 {SMB_SIGNING_OFF, "Off"},
355 {SMB_SIGNING_OFF, "disabled"},
356 {SMB_SIGNING_SUPPORTED, "Yes"},
357 {SMB_SIGNING_SUPPORTED, "True"},
358 {SMB_SIGNING_SUPPORTED, "1"},
359 {SMB_SIGNING_SUPPORTED, "On"},
360 {SMB_SIGNING_SUPPORTED, "enabled"},
361 {SMB_SIGNING_REQUIRED, "required"},
362 {SMB_SIGNING_REQUIRED, "mandatory"},
363 {SMB_SIGNING_REQUIRED, "force"},
364 {SMB_SIGNING_REQUIRED, "forced"},
365 {SMB_SIGNING_REQUIRED, "enforced"},
366 {SMB_SIGNING_AUTO, "auto"},
371 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
373 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
374 * is implied in current control logic. This may change at some later time. A
375 * flag value of 0 means - show as development option only.
377 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
378 * screen in SWAT. This is used to exclude parameters as well as to squash all
379 * parameters that have been duplicated by pseudonyms.
381 static struct parm_struct parm_table[] = {
382 {"Base Options", P_SEP, P_SEPARATOR},
384 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
385 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
386 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
387 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
388 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
389 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
390 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
391 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
392 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
393 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
394 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
396 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
397 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
398 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
400 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
401 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
402 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
404 {"Security Options", P_SEP, P_SEPARATOR},
406 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
407 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
408 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
409 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
410 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
412 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
428 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
429 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
431 {"Logging Options", P_SEP, P_SEPARATOR},
433 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
434 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
435 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
437 {"Protocol Options", P_SEP, P_SEPARATOR},
439 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
452 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
453 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
454 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
455 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
456 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
457 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
461 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
462 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
463 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
464 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
466 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
467 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
468 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
470 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
471 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
472 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
473 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
474 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
476 {"Tuning Options", P_SEP, P_SEPARATOR},
478 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
479 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
480 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
482 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
483 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
485 {"Printing Options", P_SEP, P_SEPARATOR},
487 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
488 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
489 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
491 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
492 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
494 {"Filename Handling", P_SEP, P_SEPARATOR},
496 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
497 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
498 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
500 {"Domain Options", P_SEP, P_SEPARATOR},
502 {"Logon Options", P_SEP, P_SEPARATOR},
504 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
506 {"Browse Options", P_SEP, P_SEPARATOR},
508 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
509 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
510 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
511 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
512 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
513 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
515 {"WINS Options", P_SEP, P_SEPARATOR},
517 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
518 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
520 {"Locking Options", P_SEP, P_SEPARATOR},
522 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
524 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
526 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
528 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
529 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
530 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
531 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
532 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
533 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
538 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
540 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
541 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
543 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
544 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
545 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
547 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
550 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
553 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
558 return the parameter table
560 struct parm_struct *lp_parm_table(void)
565 /***************************************************************************
566 Initialise the global parameter structure.
567 ***************************************************************************/
568 static void init_globals(void)
573 DEBUG(3, ("Initialising global parameters\n"));
575 for (i = 0; parm_table[i].label; i++) {
576 if ((parm_table[i].type == P_STRING ||
577 parm_table[i].type == P_USTRING) &&
579 !(parm_table[i].flags & FLAG_CMDLINE)) {
580 string_set(parm_table[i].ptr, "");
584 do_parameter("config file", dyn_CONFIGFILE, NULL);
586 /* options that can be set on the command line must be initialised via
587 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
589 do_parameter("socket options", "TCP_NODELAY", NULL);
591 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
592 myname = get_myname();
593 do_parameter("netbios name", myname, NULL);
595 do_parameter("max protocol", "NT1", NULL);
596 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
598 do_parameter("fstype", FSTYPE_STRING, NULL);
599 do_parameter("ntvfs handler", "unixuid default", NULL);
600 do_parameter("max connections", "-1", NULL);
602 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
603 do_parameter("server services", "smb rpc nbt ldap cldap web kdc", NULL);
604 do_parameter("ntptr providor", "simple_ldb", NULL);
605 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
606 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE, NULL);
607 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
608 do_parameter("sam database", "sam.ldb", NULL);
609 do_parameter("spoolss database", "spoolss.ldb", NULL);
610 do_parameter("wins database", "wins.ldb", NULL);
611 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
613 /* This hive should be dynamically generated by Samba using
614 data from the sam, but for the moment leave it in a tdb to
615 keep regedt32 from popping up an annoying dialog. */
616 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
618 /* using UTF8 by default allows us to support all chars */
619 do_parameter("unix charset", "UTF8", NULL);
621 /* Use codepage 850 as a default for the dos character set */
622 do_parameter("dos charset", "CP850", NULL);
625 * Allow the default PASSWD_CHAT to be overridden in local.h.
627 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
629 do_parameter("pid directory", dyn_PIDDIR, NULL);
630 do_parameter("lock dir", dyn_LOCKDIR, NULL);
631 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
633 do_parameter("socket address", "0.0.0.0", NULL);
634 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
636 do_parameter_var("announce version", "%d.%d",
637 DEFAULT_MAJOR_VERSION,
638 DEFAULT_MINOR_VERSION);
640 do_parameter("password server", "*", NULL);
642 do_parameter("max mux", "50", NULL);
643 do_parameter("max xmit", "12288", NULL);
644 do_parameter("password level", "0", NULL);
645 do_parameter("LargeReadwrite", "True", NULL);
646 do_parameter("minprotocol", "CORE", NULL);
647 do_parameter("security", "USER", NULL);
648 do_parameter("paranoid server security", "True", NULL);
649 do_parameter("EncryptPasswords", "True", NULL);
650 do_parameter("ReadRaw", "True", NULL);
651 do_parameter("WriteRaw", "True", NULL);
652 do_parameter("NullPasswords", "False", NULL);
653 do_parameter("ObeyPamRestrictions", "False", NULL);
654 do_parameter("announce as", "NT SERVER", NULL);
656 do_parameter("TimeServer", "False", NULL);
657 do_parameter("BindInterfacesOnly", "False", NULL);
658 do_parameter("Unicode", "True", NULL);
659 do_parameter("ClientLanManAuth", "True", NULL);
660 do_parameter("LanmanAuth", "True", NULL);
661 do_parameter("NTLMAuth", "True", NULL);
663 do_parameter("UnixExtensions", "False", NULL);
665 do_parameter("PreferredMaster", "Auto", NULL);
666 do_parameter("LocalMaster", "True", NULL);
667 do_parameter("DomainMaster", "Auto", NULL); /* depending on bDomainLogons */
668 do_parameter("DomainLogons", "False", NULL);
669 do_parameter("WINSsupport", "False", NULL);
671 do_parameter("winbind separator", "\\", NULL);
673 do_parameter("client signing", "Yes", NULL);
674 do_parameter("server signing", "auto", NULL);
676 do_parameter("use spnego", "True", NULL);
678 do_parameter("smb ports", SMB_PORTS, NULL);
679 do_parameter("nbt port", "137", NULL);
680 do_parameter("dgram port", "138", NULL);
681 do_parameter("cldap port", "389", NULL);
682 do_parameter("krb5 port", "88", NULL);
683 do_parameter("web port", "901", NULL);
684 do_parameter("swat directory", dyn_SWATDIR, NULL);
686 do_parameter("nt status support", "True", NULL);
688 do_parameter("max wins ttl", "432000", NULL);
689 do_parameter("min wins ttl", "10", NULL);
691 do_parameter("tls enabled", "True", NULL);
692 do_parameter("tls keyfile", "tls/key.pem", NULL);
693 do_parameter("tls certfile", "tls/cert.pem", NULL);
694 do_parameter("tls cafile", "tls/ca.pem", NULL);
695 do_parameter_var("js include", "%s/js", dyn_LIBDIR);
696 do_parameter_var("setup directory", "%s/setup", dyn_LIBDIR);
699 static TALLOC_CTX *lp_talloc;
701 /******************************************************************* a
702 Free up temporary memory - called from the main loop.
703 ********************************************************************/
705 void lp_talloc_free(void)
709 talloc_free(lp_talloc);
713 /*******************************************************************
714 Convenience routine to grab string parameters into temporary memory
715 and run standard_sub_basic on them. The buffers can be written to by
716 callers without affecting the source string.
717 ********************************************************************/
719 static const char *lp_string(const char *s)
721 #if 0 /* until REWRITE done to make thread-safe */
722 size_t len = s ? strlen(s) : 0;
726 /* The follow debug is useful for tracking down memory problems
727 especially if you have an inner loop that is calling a lp_*()
728 function that returns a string. Perhaps this debug should be
729 present all the time? */
732 DEBUG(10, ("lp_string(%s)\n", s));
735 #if 0 /* until REWRITE done to make thread-safe */
737 lp_talloc = talloc_init("lp_talloc");
739 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
747 StrnCpy(ret, s, len);
749 if (trim_string(ret, "\"", "\"")) {
750 if (strchr(ret,'"') != NULL)
751 StrnCpy(ret, s, len);
754 standard_sub_basic(ret,len+100);
761 In this section all the functions that are used to access the
762 parameters from the rest of the program are defined
765 #define FN_GLOBAL_STRING(fn_name,ptr) \
766 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
767 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
768 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
769 #define FN_GLOBAL_LIST(fn_name,ptr) \
770 const char **fn_name(void) {return(*(const char ***)(ptr));}
771 #define FN_GLOBAL_BOOL(fn_name,ptr) \
772 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
773 #define FN_GLOBAL_CHAR(fn_name,ptr) \
774 char fn_name(void) {return(*(char *)(ptr));}
775 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
776 int fn_name(void) {return(*(int *)(ptr));}
778 #define FN_LOCAL_STRING(fn_name,val) \
779 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
780 #define FN_LOCAL_CONST_STRING(fn_name,val) \
781 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
782 #define FN_LOCAL_LIST(fn_name,val) \
783 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
784 #define FN_LOCAL_BOOL(fn_name,val) \
785 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
786 #define FN_LOCAL_CHAR(fn_name,val) \
787 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
788 #define FN_LOCAL_INTEGER(fn_name,val) \
789 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
791 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
792 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
793 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
794 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
795 FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
796 FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
797 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
798 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
799 FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
800 FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
801 FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
802 FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
803 FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
804 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
805 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
806 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
807 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
808 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
809 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
810 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
811 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
812 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
813 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
814 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
815 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
816 FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
817 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
818 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
819 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
820 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
821 FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
822 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
823 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
824 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
825 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
826 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
827 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
828 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
829 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
830 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
831 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
832 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
833 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
834 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
835 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
837 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
838 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
839 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
840 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
841 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
842 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
843 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
844 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
845 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
846 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
847 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
848 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
849 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
850 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
851 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
852 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
853 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
854 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
855 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
856 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
857 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
858 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
859 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
860 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
861 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
862 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
863 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
864 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
865 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
866 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
867 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
868 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
869 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
870 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
871 FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
874 FN_LOCAL_STRING(lp_servicename, szService)
875 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
876 FN_LOCAL_STRING(lp_pathname, szPath)
877 static FN_LOCAL_STRING(_lp_printername, szPrintername)
878 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
879 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
880 FN_LOCAL_STRING(lp_comment, comment)
881 FN_LOCAL_STRING(lp_fstype, fstype)
882 static FN_LOCAL_STRING(lp_volume, volume)
883 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
884 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
885 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
886 FN_LOCAL_BOOL(lp_readonly, bRead_only)
887 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
888 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
889 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
890 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
891 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
892 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
893 FN_LOCAL_BOOL(lp_map_system, bMap_system)
894 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
895 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
896 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
897 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
899 /* local prototypes */
901 static int map_parameter(const char *pszParmName);
902 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
903 static int getservicebyname(const char *pszServiceName,
904 service * pserviceDest);
905 static void copy_service(service * pserviceDest,
906 service * pserviceSource, BOOL *pcopymapDest);
907 static BOOL service_ok(int iService);
908 static BOOL do_section(const char *pszSectionName, void *);
909 static void init_copymap(service * pservice);
911 /* This is a helper function for parametrical options support. */
912 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
913 /* Actual parametrical functions are quite simple */
914 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
917 struct param_opt *data;
919 if (lookup_service >= iNumServices) return NULL;
921 data = (lookup_service < 0) ?
922 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
924 asprintf(&vfskey, "%s:%s", type, option);
928 if (strcmp(data->key, vfskey) == 0) {
935 if (lookup_service >= 0) {
936 /* Try to fetch the same option but from globals */
937 /* but only if we are not already working with Globals */
938 data = Globals.param_opt;
940 if (strcmp(data->key, vfskey) == 0) {
954 /*******************************************************************
955 convenience routine to return int parameters.
956 ********************************************************************/
957 static int lp_int(const char *s)
961 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
965 return strtol(s, NULL, 0);
968 /*******************************************************************
969 convenience routine to return unsigned long parameters.
970 ********************************************************************/
971 static int lp_ulong(const char *s)
975 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
979 return strtoul(s, NULL, 0);
982 /*******************************************************************
983 convenience routine to return boolean parameters.
984 ********************************************************************/
985 static BOOL lp_bool(const char *s)
990 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
994 if (!set_boolean(&ret,s)) {
995 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1003 /* Return parametric option from a given service. Type is a part of option before ':' */
1004 /* Parametric option has following syntax: 'Type: option = value' */
1005 /* Returned value is allocated in 'lp_talloc' context */
1007 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1009 const char *value = lp_get_parametric(lookup_service, type, option);
1012 return lp_string(value);
1017 /* Return parametric option from a given service. Type is a part of option before ':' */
1018 /* Parametric option has following syntax: 'Type: option = value' */
1019 /* Returned value is allocated in 'lp_talloc' context */
1021 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1022 const char *separator)
1024 const char *value = lp_get_parametric(lookup_service, type, option);
1027 return str_list_make(talloc_autofree_context(), value, separator);
1032 /* Return parametric option from a given service. Type is a part of option before ':' */
1033 /* Parametric option has following syntax: 'Type: option = value' */
1035 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1037 const char *value = lp_get_parametric(lookup_service, type, option);
1040 return lp_int(value);
1045 /* Return parametric option from a given service. Type is a part of option before ':' */
1046 /* Parametric option has following syntax: 'Type: option = value' */
1048 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1050 const char *value = lp_get_parametric(lookup_service, type, option);
1053 return lp_ulong(value);
1058 /* Return parametric option from a given service. Type is a part of option before ':' */
1059 /* Parametric option has following syntax: 'Type: option = value' */
1061 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1063 const char *value = lp_get_parametric(lookup_service, type, option);
1066 return lp_bool(value);
1072 /***************************************************************************
1073 Initialise a service to the defaults.
1074 ***************************************************************************/
1076 static void init_service(service * pservice)
1078 memset((char *)pservice, '\0', sizeof(service));
1079 copy_service(pservice, &sDefault, NULL);
1082 /***************************************************************************
1083 Free the dynamically allocated parts of a service struct.
1084 ***************************************************************************/
1086 static void free_service(service *pservice)
1089 struct param_opt *data, *pdata;
1093 if (pservice->szService)
1094 DEBUG(5, ("free_service: Freeing service %s\n",
1095 pservice->szService));
1097 string_free(&pservice->szService);
1098 SAFE_FREE(pservice->copymap);
1100 for (i = 0; parm_table[i].label; i++) {
1101 if ((parm_table[i].type == P_STRING ||
1102 parm_table[i].type == P_USTRING) &&
1103 parm_table[i].class == P_LOCAL) {
1104 string_free((char **)
1105 (((char *)pservice) +
1106 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1107 } else if (parm_table[i].type == P_LIST &&
1108 parm_table[i].class == P_LOCAL) {
1109 char ***listp = (char ***)(((char *)pservice) +
1110 PTR_DIFF(parm_table[i].ptr, &sDefault));
1111 talloc_free(*listp);
1116 DEBUG(5,("Freeing parametrics:\n"));
1117 data = pservice->param_opt;
1119 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1120 string_free(&data->key);
1121 string_free(&data->value);
1127 ZERO_STRUCTP(pservice);
1130 /***************************************************************************
1131 Add a new service to the services array initialising it with the given
1133 ***************************************************************************/
1135 static int add_a_service(const service *pservice, const char *name)
1139 int num_to_alloc = iNumServices + 1;
1140 struct param_opt *data, *pdata;
1142 tservice = *pservice;
1144 /* it might already exist */
1146 i = getservicebyname(name, NULL);
1148 /* Clean all parametric options for service */
1149 /* They will be added during parsing again */
1150 data = ServicePtrs[i]->param_opt;
1152 string_free(&data->key);
1153 string_free(&data->value);
1158 ServicePtrs[i]->param_opt = NULL;
1163 /* find an invalid one */
1164 for (i = 0; i < iNumServices; i++)
1165 if (!ServicePtrs[i]->valid)
1168 /* if not, then create one */
1169 if (i == iNumServices) {
1172 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1175 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1180 ServicePtrs[iNumServices] = malloc_p(service);
1182 if (!ServicePtrs[iNumServices]) {
1183 DEBUG(0,("add_a_service: out of memory!\n"));
1189 free_service(ServicePtrs[i]);
1191 ServicePtrs[i]->valid = True;
1193 init_service(ServicePtrs[i]);
1194 copy_service(ServicePtrs[i], &tservice, NULL);
1196 string_set(&ServicePtrs[i]->szService, name);
1200 /***************************************************************************
1201 Add a new home service, with the specified home directory, defaults coming
1203 ***************************************************************************/
1205 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1206 const char *user, const char *pszHomedir)
1211 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1216 if (!(*(ServicePtrs[iDefaultService]->szPath))
1217 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1218 pstrcpy(newHomedir, pszHomedir);
1220 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1221 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1224 string_set(&ServicePtrs[i]->szPath, newHomedir);
1226 if (!(*(ServicePtrs[i]->comment))) {
1228 slprintf(comment, sizeof(comment) - 1,
1229 "Home directory of %s", user);
1230 string_set(&ServicePtrs[i]->comment, comment);
1232 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1233 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1235 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1241 /***************************************************************************
1242 Add a new service, based on an old one.
1243 ***************************************************************************/
1245 int lp_add_service(const char *pszService, int iDefaultService)
1247 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1250 /***************************************************************************
1251 Add the IPC service.
1252 ***************************************************************************/
1254 static BOOL lp_add_hidden(const char *name, const char *fstype)
1257 int i = add_a_service(&sDefault, name);
1262 slprintf(comment, sizeof(comment) - 1,
1263 "%s Service (%s)", fstype, Globals.szServerString);
1265 string_set(&ServicePtrs[i]->szPath, tmpdir());
1266 string_set(&ServicePtrs[i]->comment, comment);
1267 string_set(&ServicePtrs[i]->fstype, fstype);
1268 ServicePtrs[i]->iMaxConnections = -1;
1269 ServicePtrs[i]->bAvailable = True;
1270 ServicePtrs[i]->bRead_only = True;
1271 ServicePtrs[i]->bPrint_ok = False;
1272 ServicePtrs[i]->bBrowseable = False;
1274 if (strcasecmp(fstype, "IPC") == 0) {
1275 lp_do_parameter(i, "ntvfs handler", "default");
1278 DEBUG(3, ("adding hidden service %s\n", name));
1283 /***************************************************************************
1284 Add a new printer service, with defaults coming from service iFrom.
1285 ***************************************************************************/
1287 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1289 const char *comment = "From Printcap";
1290 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1295 /* note that we do NOT default the availability flag to True - */
1296 /* we take it from the default service passed. This allows all */
1297 /* dynamic printers to be disabled by disabling the [printers] */
1298 /* entry (if/when the 'available' keyword is implemented!). */
1300 /* the printer name is set to the service name. */
1301 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1302 string_set(&ServicePtrs[i]->comment, comment);
1303 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1304 /* Printers cannot be read_only. */
1305 ServicePtrs[i]->bRead_only = False;
1306 /* Printer services must be printable. */
1307 ServicePtrs[i]->bPrint_ok = True;
1309 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1311 update_server_announce_as_printserver();
1316 /***************************************************************************
1317 Map a parameter's string representation to something we can use.
1318 Returns False if the parameter string is not recognised, else TRUE.
1319 ***************************************************************************/
1321 static int map_parameter(const char *pszParmName)
1325 if (*pszParmName == '-')
1328 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1329 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1332 /* Warn only if it isn't parametric option */
1333 if (strchr(pszParmName, ':') == NULL)
1334 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1335 /* We do return 'fail' for parametric options as well because they are
1336 stored in different storage
1343 return the parameter structure for a parameter
1345 struct parm_struct *lp_parm_struct(const char *name)
1347 int parmnum = map_parameter(name);
1348 if (parmnum == -1) return NULL;
1349 return &parm_table[parmnum];
1353 return the parameter pointer for a parameter
1355 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1360 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1363 /***************************************************************************
1364 Set a boolean variable from the text value stored in the passed string.
1365 Returns True in success, False if the passed string does not correctly
1366 represent a boolean.
1367 ***************************************************************************/
1369 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1374 if (strwicmp(pszParmValue, "yes") == 0 ||
1375 strwicmp(pszParmValue, "true") == 0 ||
1376 strwicmp(pszParmValue, "1") == 0)
1378 else if (strwicmp(pszParmValue, "no") == 0 ||
1379 strwicmp(pszParmValue, "False") == 0 ||
1380 strwicmp(pszParmValue, "0") == 0)
1384 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1391 /***************************************************************************
1392 Find a service by name. Otherwise works like get_service.
1393 ***************************************************************************/
1395 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1399 for (iService = iNumServices - 1; iService >= 0; iService--)
1400 if (VALID(iService) &&
1401 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1402 if (pserviceDest != NULL)
1403 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1410 /***************************************************************************
1411 Copy a service structure to another.
1412 If pcopymapDest is NULL then copy all fields
1413 ***************************************************************************/
1415 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1418 BOOL bcopyall = (pcopymapDest == NULL);
1419 struct param_opt *data, *pdata, *paramo;
1422 for (i = 0; parm_table[i].label; i++)
1423 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1424 (bcopyall || pcopymapDest[i])) {
1425 void *def_ptr = parm_table[i].ptr;
1427 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1430 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1433 switch (parm_table[i].type) {
1435 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1440 *(int *)dest_ptr = *(int *)src_ptr;
1444 string_set(dest_ptr,
1449 string_set(dest_ptr,
1451 strupper(*(char **)dest_ptr);
1454 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1455 *(const char ***)src_ptr);
1463 init_copymap(pserviceDest);
1464 if (pserviceSource->copymap)
1465 memcpy((void *)pserviceDest->copymap,
1466 (void *)pserviceSource->copymap,
1467 sizeof(BOOL) * NUMPARAMETERS);
1470 data = pserviceSource->param_opt;
1473 pdata = pserviceDest->param_opt;
1474 /* Traverse destination */
1476 /* If we already have same option, override it */
1477 if (strcmp(pdata->key, data->key) == 0) {
1478 string_free(&pdata->value);
1479 pdata->value = strdup(data->value);
1483 pdata = pdata->next;
1486 paramo = smb_xmalloc_p(struct param_opt);
1487 paramo->key = strdup(data->key);
1488 paramo->value = strdup(data->value);
1489 DLIST_ADD(pserviceDest->param_opt, paramo);
1495 /***************************************************************************
1496 Check a service for consistency. Return False if the service is in any way
1497 incomplete or faulty, else True.
1498 ***************************************************************************/
1500 static BOOL service_ok(int iService)
1505 if (ServicePtrs[iService]->szService[0] == '\0') {
1506 DEBUG(0, ("The following message indicates an internal error:\n"));
1507 DEBUG(0, ("No service name in service entry.\n"));
1511 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1512 /* I can't see why you'd want a non-printable printer service... */
1513 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1514 if (!ServicePtrs[iService]->bPrint_ok) {
1515 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1516 ServicePtrs[iService]->szService));
1517 ServicePtrs[iService]->bPrint_ok = True;
1518 update_server_announce_as_printserver();
1520 /* [printers] service must also be non-browsable. */
1521 if (ServicePtrs[iService]->bBrowseable)
1522 ServicePtrs[iService]->bBrowseable = False;
1525 /* If a service is flagged unavailable, log the fact at level 0. */
1526 if (!ServicePtrs[iService]->bAvailable)
1527 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1528 ServicePtrs[iService]->szService));
1533 static struct file_lists {
1534 struct file_lists *next;
1538 } *file_lists = NULL;
1540 /*******************************************************************
1541 Keep a linked list of all config files so we know when one has changed
1542 it's date and needs to be reloaded.
1543 ********************************************************************/
1545 static void add_to_file_list(const char *fname, const char *subfname)
1547 struct file_lists *f = file_lists;
1550 if (f->name && !strcmp(f->name, fname))
1556 f = malloc_p(struct file_lists);
1559 f->next = file_lists;
1560 f->name = strdup(fname);
1565 f->subfname = strdup(subfname);
1571 f->modtime = file_modtime(subfname);
1573 time_t t = file_modtime(subfname);
1579 /*******************************************************************
1580 Check if a config file has changed date.
1581 ********************************************************************/
1583 BOOL lp_file_list_changed(void)
1585 struct file_lists *f = file_lists;
1586 DEBUG(6, ("lp_file_list_changed()\n"));
1592 pstrcpy(n2, f->name);
1593 standard_sub_basic(n2,sizeof(n2));
1595 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1596 f->name, n2, ctime(&f->modtime)));
1598 mod_time = file_modtime(n2);
1600 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1602 ("file %s modified: %s\n", n2,
1604 f->modtime = mod_time;
1605 SAFE_FREE(f->subfname);
1606 f->subfname = strdup(n2);
1614 /***************************************************************************
1615 Handle the include operation.
1616 ***************************************************************************/
1618 static BOOL handle_include(const char *pszParmValue, char **ptr)
1621 pstrcpy(fname, pszParmValue);
1623 standard_sub_basic(fname,sizeof(fname));
1625 add_to_file_list(pszParmValue, fname);
1627 string_set(ptr, fname);
1629 if (file_exist(fname))
1630 return (pm_process(fname, do_section, do_parameter, NULL));
1632 DEBUG(2, ("Can't find include file %s\n", fname));
1637 /***************************************************************************
1638 Handle the interpretation of the copy parameter.
1639 ***************************************************************************/
1641 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1645 service serviceTemp;
1647 string_set(ptr, pszParmValue);
1649 init_service(&serviceTemp);
1653 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1655 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1656 if (iTemp == iServiceIndex) {
1657 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1659 copy_service(ServicePtrs[iServiceIndex],
1661 ServicePtrs[iServiceIndex]->copymap);
1665 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1669 free_service(&serviceTemp);
1673 /***************************************************************************
1674 Initialise a copymap.
1675 ***************************************************************************/
1677 static void init_copymap(service * pservice)
1680 SAFE_FREE(pservice->copymap);
1681 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
1682 if (!pservice->copymap)
1684 ("Couldn't allocate copymap!! (size %d)\n",
1685 (int)NUMPARAMETERS));
1687 for (i = 0; i < NUMPARAMETERS; i++)
1688 pservice->copymap[i] = True;
1691 /***************************************************************************
1692 Return the local pointer to a parameter given the service number and the
1693 pointer into the default structure.
1694 ***************************************************************************/
1696 void *lp_local_ptr(int snum, void *ptr)
1698 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1702 /***************************************************************************
1703 Process a parametric option
1704 ***************************************************************************/
1705 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1707 struct param_opt *paramo, *data;
1710 while (isspace((unsigned char)*pszParmName)) {
1714 name = strdup(pszParmName);
1715 if (!name) return False;
1720 data = Globals.param_opt;
1722 data = ServicePtrs[snum]->param_opt;
1725 /* Traverse destination */
1726 for (paramo=data; paramo; paramo=paramo->next) {
1727 /* If we already have the option set, override it unless
1728 it was a command line option and the new one isn't */
1729 if (strcmp(paramo->key, name) == 0) {
1730 if ((paramo->flags & FLAG_CMDLINE) &&
1731 !(flags & FLAG_CMDLINE)) {
1735 free(paramo->value);
1736 paramo->value = strdup(pszParmValue);
1737 paramo->flags = flags;
1743 paramo = smb_xmalloc_p(struct param_opt);
1744 paramo->key = strdup(name);
1745 paramo->value = strdup(pszParmValue);
1746 paramo->flags = flags;
1748 DLIST_ADD(Globals.param_opt, paramo);
1750 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1758 /***************************************************************************
1759 Process a parameter for a particular service number. If snum < 0
1760 then assume we are in the globals.
1761 ***************************************************************************/
1762 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1765 void *parm_ptr = NULL; /* where we are going to store the result */
1766 void *def_ptr = NULL;
1768 parmnum = map_parameter(pszParmName);
1771 if (strchr(pszParmName, ':')) {
1772 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1774 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1778 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1779 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1783 /* if the flag has been set on the command line, then don't allow override,
1784 but don't report an error */
1785 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1789 def_ptr = parm_table[parmnum].ptr;
1791 /* we might point at a service, the default service or a global */
1795 if (parm_table[parmnum].class == P_GLOBAL) {
1797 ("Global parameter %s found in service section!\n",
1802 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1807 if (!ServicePtrs[snum]->copymap)
1808 init_copymap(ServicePtrs[snum]);
1810 /* this handles the aliases - set the copymap for other entries with
1811 the same data pointer */
1812 for (i = 0; parm_table[i].label; i++)
1813 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1814 ServicePtrs[snum]->copymap[i] = False;
1817 /* if it is a special case then go ahead */
1818 if (parm_table[parmnum].special) {
1819 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1823 /* now switch on the type of variable it is */
1824 switch (parm_table[parmnum].type)
1827 set_boolean(parm_ptr, pszParmValue);
1831 *(int *)parm_ptr = atoi(pszParmValue);
1835 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1836 pszParmValue, NULL);
1840 string_set(parm_ptr, pszParmValue);
1844 string_set(parm_ptr, pszParmValue);
1845 strupper(*(char **)parm_ptr);
1849 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1852 parm_table[parmnum].enum_list[i].name)) {
1854 parm_table[parmnum].
1859 if (!parm_table[parmnum].enum_list[i].name) {
1860 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1861 pszParmValue, pszParmName));
1872 /***************************************************************************
1873 Process a parameter.
1874 ***************************************************************************/
1876 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1878 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1879 pszParmName, pszParmValue));
1883 variable argument do parameter
1885 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1887 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1894 s = talloc_vasprintf(NULL, fmt, ap);
1896 ret = do_parameter(pszParmName, s, NULL);
1903 set a parameter from the commandline - this is called from command line parameter
1904 parsing code. It sets the parameter then marks the parameter as unable to be modified
1905 by smb.conf processing
1907 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1909 int parmnum = map_parameter(pszParmName);
1912 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1915 if (parmnum < 0 && strchr(pszParmName, ':')) {
1916 /* set a parametric option */
1917 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1921 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1925 /* reset the CMDLINE flag in case this has been called before */
1926 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1928 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1932 parm_table[parmnum].flags |= FLAG_CMDLINE;
1934 /* we have to also set FLAG_CMDLINE on aliases */
1935 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1936 parm_table[i].flags |= FLAG_CMDLINE;
1938 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1939 parm_table[i].flags |= FLAG_CMDLINE;
1946 set a option from the commandline in 'a=b' format. Use to support --option
1948 BOOL lp_set_option(const char *option)
1966 ret = lp_set_cmdline(s, p+1);
1972 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1974 /***************************************************************************
1975 Print a parameter of the specified type.
1976 ***************************************************************************/
1978 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1984 for (i = 0; p->enum_list[i].name; i++) {
1985 if (*(int *)ptr == p->enum_list[i].value) {
1987 p->enum_list[i].name);
1994 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
1998 fprintf(f, "%d", *(int *)ptr);
2002 if ((char ***)ptr && *(char ***)ptr) {
2003 char **list = *(char ***)ptr;
2005 for (; *list; list++)
2006 fprintf(f, "%s%s", *list,
2007 ((*(list+1))?", ":""));
2013 if (*(char **)ptr) {
2014 fprintf(f, "%s", *(char **)ptr);
2022 /***************************************************************************
2023 Check if two parameters are equal.
2024 ***************************************************************************/
2026 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2030 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2034 return (*((int *)ptr1) == *((int *)ptr2));
2037 return str_list_equal((const char **)(*(char ***)ptr1),
2038 (const char **)(*(char ***)ptr2));
2043 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2048 return (p1 == p2 || strequal(p1, p2));
2056 /***************************************************************************
2057 Process a new section (service). At this stage all sections are services.
2058 Later we'll have special sections that permit server parameters to be set.
2059 Returns True on success, False on failure.
2060 ***************************************************************************/
2062 static BOOL do_section(const char *pszSectionName, void *userdata)
2065 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2066 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2069 /* if we've just struck a global section, note the fact. */
2070 bInGlobalSection = isglobal;
2072 /* check for multiple global sections */
2073 if (bInGlobalSection) {
2074 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2078 /* if we have a current service, tidy it up before moving on */
2081 if (iServiceIndex >= 0)
2082 bRetval = service_ok(iServiceIndex);
2084 /* if all is still well, move to the next record in the services array */
2086 /* We put this here to avoid an odd message order if messages are */
2087 /* issued by the post-processing of a previous section. */
2088 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2090 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2092 DEBUG(0, ("Failed to add a new service\n"));
2101 /***************************************************************************
2102 Determine if a partcular base parameter is currentl set to the default value.
2103 ***************************************************************************/
2105 static BOOL is_default(int i)
2107 if (!defaults_saved)
2109 switch (parm_table[i].type) {
2111 return str_list_equal((const char **)parm_table[i].def.lvalue,
2112 (const char **)(*(char ***)parm_table[i].ptr));
2115 return strequal(parm_table[i].def.svalue,
2116 *(char **)parm_table[i].ptr);
2118 return parm_table[i].def.bvalue ==
2119 *(BOOL *)parm_table[i].ptr;
2122 return parm_table[i].def.ivalue ==
2123 *(int *)parm_table[i].ptr;
2130 /***************************************************************************
2131 Display the contents of the global structure.
2132 ***************************************************************************/
2134 static void dump_globals(FILE *f)
2137 struct param_opt *data;
2139 fprintf(f, "# Global parameters\n[global]\n");
2141 for (i = 0; parm_table[i].label; i++)
2142 if (parm_table[i].class == P_GLOBAL &&
2143 parm_table[i].ptr &&
2144 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2145 if (defaults_saved && is_default(i))
2147 fprintf(f, "\t%s = ", parm_table[i].label);
2148 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2151 if (Globals.param_opt != NULL) {
2152 data = Globals.param_opt;
2154 fprintf(f, "\t%s = %s\n", data->key, data->value);
2161 /***************************************************************************
2162 Display the contents of a single services record.
2163 ***************************************************************************/
2165 static void dump_a_service(service * pService, FILE * f)
2168 struct param_opt *data;
2170 if (pService != &sDefault)
2171 fprintf(f, "\n[%s]\n", pService->szService);
2173 for (i = 0; parm_table[i].label; i++)
2174 if (parm_table[i].class == P_LOCAL &&
2175 parm_table[i].ptr &&
2176 (*parm_table[i].label != '-') &&
2177 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2178 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2180 if (pService == &sDefault) {
2181 if (defaults_saved && is_default(i))
2184 if (equal_parameter(parm_table[i].type,
2185 ((char *)pService) +
2187 ((char *)&sDefault) +
2192 fprintf(f, "\t%s = ", parm_table[i].label);
2193 print_parameter(&parm_table[i],
2194 ((char *)pService) + pdiff, f);
2197 if (pService->param_opt != NULL) {
2198 data = pService->param_opt;
2200 fprintf(f, "\t%s = %s\n", data->key, data->value);
2207 /***************************************************************************
2208 Return info about the next service in a service. snum==-1 gives the globals.
2209 Return NULL when out of parameters.
2210 ***************************************************************************/
2212 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2215 /* do the globals */
2216 for (; parm_table[*i].label; (*i)++) {
2217 if (parm_table[*i].class == P_SEPARATOR)
2218 return &parm_table[(*i)++];
2220 if (!parm_table[*i].ptr
2221 || (*parm_table[*i].label == '-'))
2225 && (parm_table[*i].ptr ==
2226 parm_table[(*i) - 1].ptr))
2229 return &parm_table[(*i)++];
2232 service *pService = ServicePtrs[snum];
2234 for (; parm_table[*i].label; (*i)++) {
2235 if (parm_table[*i].class == P_SEPARATOR)
2236 return &parm_table[(*i)++];
2238 if (parm_table[*i].class == P_LOCAL &&
2239 parm_table[*i].ptr &&
2240 (*parm_table[*i].label != '-') &&
2242 (parm_table[*i].ptr !=
2243 parm_table[(*i) - 1].ptr)))
2246 PTR_DIFF(parm_table[*i].ptr,
2249 if (allparameters ||
2250 !equal_parameter(parm_table[*i].type,
2251 ((char *)pService) +
2253 ((char *)&sDefault) +
2256 return &parm_table[(*i)++];
2266 /***************************************************************************
2267 Return TRUE if the passed service number is within range.
2268 ***************************************************************************/
2270 BOOL lp_snum_ok(int iService)
2272 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2275 /***************************************************************************
2276 Auto-load some home services.
2277 ***************************************************************************/
2279 static void lp_add_auto_services(const char *str)
2284 /***************************************************************************
2285 Announce ourselves as a print server.
2286 ***************************************************************************/
2288 void update_server_announce_as_printserver(void)
2290 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2293 /***************************************************************************
2294 Have we loaded a services file yet?
2295 ***************************************************************************/
2297 BOOL lp_loaded(void)
2302 /***************************************************************************
2303 Unload unused services.
2304 ***************************************************************************/
2306 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2309 for (i = 0; i < iNumServices; i++) {
2313 if (!snumused || !snumused(smb, i)) {
2314 ServicePtrs[i]->valid = False;
2315 free_service(ServicePtrs[i]);
2320 /***************************************************************************
2322 ***************************************************************************/
2324 void lp_killservice(int iServiceIn)
2326 if (VALID(iServiceIn)) {
2327 ServicePtrs[iServiceIn]->valid = False;
2328 free_service(ServicePtrs[iServiceIn]);
2332 /*******************************************************************
2333 Set the server type we will announce as via nmbd.
2334 ********************************************************************/
2336 static void set_server_role(void)
2338 server_role = ROLE_STANDALONE;
2340 switch (lp_security()) {
2342 if (lp_domain_logons())
2343 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2348 if (lp_domain_logons()) {
2349 if (Globals.bDomainMaster) /* auto or yes */
2350 server_role = ROLE_DOMAIN_PDC;
2352 server_role = ROLE_DOMAIN_BDC;
2355 server_role = ROLE_DOMAIN_MEMBER;
2358 if (lp_domain_logons()) {
2360 if (Globals.bDomainMaster) /* auto or yes */
2361 server_role = ROLE_DOMAIN_PDC;
2363 server_role = ROLE_DOMAIN_BDC;
2367 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2371 DEBUG(10, ("set_server_role: role = "));
2373 switch(server_role) {
2374 case ROLE_STANDALONE:
2375 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2377 case ROLE_DOMAIN_MEMBER:
2378 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2380 case ROLE_DOMAIN_BDC:
2381 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2383 case ROLE_DOMAIN_PDC:
2384 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
2389 /***************************************************************************
2390 Load the services array from the services file. Return True on success,
2392 ***************************************************************************/
2398 struct param_opt *data;
2402 bInGlobalSection = True;
2404 if (Globals.param_opt != NULL) {
2405 struct param_opt *next;
2406 for (data=Globals.param_opt; data; data=next) {
2408 if (data->flags & FLAG_CMDLINE) continue;
2411 DLIST_REMOVE(Globals.param_opt, data);
2418 pstrcpy(n2, lp_configfile());
2419 standard_sub_basic(n2,sizeof(n2));
2420 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2422 add_to_file_list(lp_configfile(), n2);
2424 /* We get sections first, so have to start 'behind' to make up */
2426 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2428 /* finish up the last section */
2429 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2431 if (iServiceIndex >= 0)
2432 bRetval = service_ok(iServiceIndex);
2434 lp_add_auto_services(lp_auto_services());
2436 lp_add_hidden("IPC$", "IPC");
2437 lp_add_hidden("ADMIN$", "DISK");
2440 set_default_server_announce_type();
2444 if (Globals.bWINSsupport) {
2445 lp_do_parameter(-1, "wins server", "127.0.0.1");
2453 /***************************************************************************
2454 Reset the max number of services.
2455 ***************************************************************************/
2457 void lp_resetnumservices(void)
2462 /***************************************************************************
2463 Return the max number of services.
2464 ***************************************************************************/
2466 int lp_numservices(void)
2468 return (iNumServices);
2471 /***************************************************************************
2472 Display the contents of the services array in human-readable form.
2473 ***************************************************************************/
2475 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2480 defaults_saved = False;
2484 dump_a_service(&sDefault, f);
2486 for (iService = 0; iService < maxtoprint; iService++)
2487 lp_dump_one(f, show_defaults, iService);
2490 /***************************************************************************
2491 Display the contents of one service in human-readable form.
2492 ***************************************************************************/
2494 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2497 if (ServicePtrs[snum]->szService[0] == '\0')
2499 dump_a_service(ServicePtrs[snum], f);
2503 /***************************************************************************
2504 Return the number of the service with the given name, or -1 if it doesn't
2505 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2506 getservicebyname()! This works ONLY if all services have been loaded, and
2507 does not copy the found service.
2508 ***************************************************************************/
2510 int lp_servicenumber(const char *pszServiceName)
2513 fstring serviceName;
2516 for (iService = iNumServices - 1; iService >= 0; iService--) {
2517 if (VALID(iService) && ServicePtrs[iService]->szService) {
2519 * The substitution here is used to support %U is
2522 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2523 standard_sub_basic(serviceName,sizeof(serviceName));
2524 if (strequal(serviceName, pszServiceName))
2530 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2535 /*******************************************************************
2536 A useful volume label function.
2537 ********************************************************************/
2538 const char *volume_label(int snum)
2540 const char *ret = lp_volume(snum);
2542 return lp_servicename(snum);
2547 /*******************************************************************
2548 Set the server type we will announce as via nmbd.
2549 ********************************************************************/
2551 static void set_default_server_announce_type(void)
2553 default_server_announce = 0;
2554 default_server_announce |= SV_TYPE_WORKSTATION;
2555 default_server_announce |= SV_TYPE_SERVER;
2556 default_server_announce |= SV_TYPE_SERVER_UNIX;
2558 switch (lp_announce_as()) {
2559 case ANNOUNCE_AS_NT_SERVER:
2560 default_server_announce |= SV_TYPE_SERVER_NT;
2561 /* fall through... */
2562 case ANNOUNCE_AS_NT_WORKSTATION:
2563 default_server_announce |= SV_TYPE_NT;
2565 case ANNOUNCE_AS_WIN95:
2566 default_server_announce |= SV_TYPE_WIN95_PLUS;
2568 case ANNOUNCE_AS_WFW:
2569 default_server_announce |= SV_TYPE_WFW;
2575 switch (lp_server_role()) {
2576 case ROLE_DOMAIN_MEMBER:
2577 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2579 case ROLE_DOMAIN_PDC:
2580 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2582 case ROLE_DOMAIN_BDC:
2583 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2585 case ROLE_STANDALONE:
2589 if (lp_time_server())
2590 default_server_announce |= SV_TYPE_TIME_SOURCE;
2592 if (lp_host_msdfs())
2593 default_server_announce |= SV_TYPE_DFS_SERVER;
2595 /* TODO: only announce us as print server when we are a print server */
2596 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2599 /***********************************************************
2600 returns role of Samba server
2601 ************************************************************/
2603 int lp_server_role(void)
2608 /***********************************************************
2609 If we are PDC then prefer us as DMB
2610 ************************************************************/
2612 BOOL lp_domain_master(void)
2614 if (Globals.bDomainMaster == Auto)
2615 return (lp_server_role() == ROLE_DOMAIN_PDC);
2617 return Globals.bDomainMaster;
2620 /***********************************************************
2621 If we are DMB then prefer us as LMB
2622 ************************************************************/
2624 BOOL lp_preferred_master(void)
2626 if (Globals.bPreferredMaster == Auto)
2627 return (lp_local_master() && lp_domain_master());
2629 return Globals.bPreferredMaster;
2632 /*******************************************************************
2634 ********************************************************************/
2636 void lp_remove_service(int snum)
2638 ServicePtrs[snum]->valid = False;
2641 /*******************************************************************
2643 ********************************************************************/
2645 void lp_copy_service(int snum, const char *new_name)
2647 const char *oldname = lp_servicename(snum);
2648 do_section(new_name, NULL);
2650 snum = lp_servicenumber(new_name);
2652 lp_do_parameter(snum, "copy", oldname);
2657 /*******************************************************************
2658 Get the default server type we will announce as via nmbd.
2659 ********************************************************************/
2660 int lp_default_server_announce(void)
2662 return default_server_announce;
2665 const char *lp_printername(int snum)
2667 const char *ret = _lp_printername(snum);
2668 if (ret == NULL || (ret != NULL && *ret == '\0'))
2669 ret = lp_const_servicename(snum);
2675 /*******************************************************************
2676 Return the max print jobs per queue.
2677 ********************************************************************/
2679 int lp_maxprintjobs(int snum)
2681 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2682 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2683 maxjobs = PRINT_MAX_JOBID - 1;