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;
187 BOOL client_use_spnego_principal;
190 BOOL bUnixExtensions;
191 BOOL bDisableNetbios;
193 struct param_opt *param_opt;
197 static global Globals;
200 * This structure describes a single service.
215 char **ntvfs_handler;
231 struct param_opt *param_opt;
233 char dummy[3]; /* for alignment */
238 /* This is a default service used to prime a services structure */
239 static service sDefault = {
241 NULL, /* szService */
244 NULL, /* szInclude */
245 NULL, /* szPrintername */
246 NULL, /* szHostsallow */
247 NULL, /* szHostsdeny */
251 NULL, /* ntvfs_handler */
252 1000, /* iMaxPrintJobs */
253 0, /* iMaxConnections */
255 True, /* bAvailable */
256 True, /* bBrowseable */
257 True, /* bRead_only */
258 False, /* bPrint_ok */
259 False, /* bMap_system */
260 False, /* bMap_hidden */
261 True, /* bMap_archive */
262 True, /* bStrictLocking */
264 False, /* bMSDfsRoot */
265 False, /* bStrictSync */
266 False, /* bCIFileSystem */
267 NULL, /* Parametric options */
272 /* local variables */
273 static service **ServicePtrs = NULL;
274 static int iNumServices = 0;
275 static int iServiceIndex = 0;
276 static BOOL bInGlobalSection = True;
277 static int server_role;
278 static int default_server_announce;
280 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
282 /* prototypes for the special type handlers */
283 static BOOL handle_include(const char *pszParmValue, char **ptr);
284 static BOOL handle_copy(const char *pszParmValue, char **ptr);
286 static void set_server_role(void);
287 static void set_default_server_announce_type(void);
289 static const struct enum_list enum_protocol[] = {
290 {PROTOCOL_NT1, "NT1"},
291 {PROTOCOL_LANMAN2, "LANMAN2"},
292 {PROTOCOL_LANMAN1, "LANMAN1"},
293 {PROTOCOL_CORE, "CORE"},
294 {PROTOCOL_COREPLUS, "COREPLUS"},
295 {PROTOCOL_COREPLUS, "CORE+"},
299 static const struct enum_list enum_security[] = {
300 {SEC_SHARE, "SHARE"},
302 {SEC_SERVER, "SERVER"},
303 {SEC_DOMAIN, "DOMAIN"},
310 /* Types of machine we can announce as. */
311 #define ANNOUNCE_AS_NT_SERVER 1
312 #define ANNOUNCE_AS_WIN95 2
313 #define ANNOUNCE_AS_WFW 3
314 #define ANNOUNCE_AS_NT_WORKSTATION 4
316 static const struct enum_list enum_announce_as[] = {
317 {ANNOUNCE_AS_NT_SERVER, "NT"},
318 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
319 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
320 {ANNOUNCE_AS_WIN95, "win95"},
321 {ANNOUNCE_AS_WFW, "WfW"},
325 static const struct enum_list enum_bool_auto[] = {
336 /* Client-side offline caching policy types */
337 #define CSC_POLICY_MANUAL 0
338 #define CSC_POLICY_DOCUMENTS 1
339 #define CSC_POLICY_PROGRAMS 2
340 #define CSC_POLICY_DISABLE 3
342 static const struct enum_list enum_csc_policy[] = {
343 {CSC_POLICY_MANUAL, "manual"},
344 {CSC_POLICY_DOCUMENTS, "documents"},
345 {CSC_POLICY_PROGRAMS, "programs"},
346 {CSC_POLICY_DISABLE, "disable"},
350 /* SMB signing types. */
351 static const struct enum_list enum_smb_signing_vals[] = {
352 {SMB_SIGNING_OFF, "No"},
353 {SMB_SIGNING_OFF, "False"},
354 {SMB_SIGNING_OFF, "0"},
355 {SMB_SIGNING_OFF, "Off"},
356 {SMB_SIGNING_OFF, "disabled"},
357 {SMB_SIGNING_SUPPORTED, "Yes"},
358 {SMB_SIGNING_SUPPORTED, "True"},
359 {SMB_SIGNING_SUPPORTED, "1"},
360 {SMB_SIGNING_SUPPORTED, "On"},
361 {SMB_SIGNING_SUPPORTED, "enabled"},
362 {SMB_SIGNING_REQUIRED, "required"},
363 {SMB_SIGNING_REQUIRED, "mandatory"},
364 {SMB_SIGNING_REQUIRED, "force"},
365 {SMB_SIGNING_REQUIRED, "forced"},
366 {SMB_SIGNING_REQUIRED, "enforced"},
367 {SMB_SIGNING_AUTO, "auto"},
372 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
374 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
375 * is implied in current control logic. This may change at some later time. A
376 * flag value of 0 means - show as development option only.
378 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
379 * screen in SWAT. This is used to exclude parameters as well as to squash all
380 * parameters that have been duplicated by pseudonyms.
382 static struct parm_struct parm_table[] = {
383 {"Base Options", P_SEP, P_SEPARATOR},
385 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
386 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
387 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
388 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
389 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
390 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
391 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
392 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
393 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
394 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
396 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
397 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
398 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
401 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
402 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
403 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
405 {"Security Options", P_SEP, P_SEPARATOR},
407 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
408 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
409 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
410 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
412 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
413 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
430 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
431 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
433 {"Logging Options", P_SEP, P_SEPARATOR},
435 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
436 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
437 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
439 {"Protocol Options", P_SEP, P_SEPARATOR},
441 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
454 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
455 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
456 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
457 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
458 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
459 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
461 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
463 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
464 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
465 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
466 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
468 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
469 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
470 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
471 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
472 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
473 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
474 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
475 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
476 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
478 {"Tuning Options", P_SEP, P_SEPARATOR},
480 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
481 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
482 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
484 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
485 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
487 {"Printing Options", P_SEP, P_SEPARATOR},
489 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
490 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
491 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
493 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
494 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
496 {"Filename Handling", P_SEP, P_SEPARATOR},
498 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
499 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
500 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
502 {"Domain Options", P_SEP, P_SEPARATOR},
504 {"Logon Options", P_SEP, P_SEPARATOR},
506 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
508 {"Browse Options", P_SEP, P_SEPARATOR},
510 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
511 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
512 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
513 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
514 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
515 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
517 {"WINS Options", P_SEP, P_SEPARATOR},
519 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
520 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
522 {"Locking Options", P_SEP, P_SEPARATOR},
524 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
526 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
528 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
530 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
531 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
532 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
533 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
534 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
540 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
542 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
543 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
545 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
546 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
547 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
549 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
552 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
555 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
560 return the parameter table
562 struct parm_struct *lp_parm_table(void)
567 /***************************************************************************
568 Initialise the global parameter structure.
569 ***************************************************************************/
570 static void init_globals(void)
575 DEBUG(3, ("Initialising global parameters\n"));
577 for (i = 0; parm_table[i].label; i++) {
578 if ((parm_table[i].type == P_STRING ||
579 parm_table[i].type == P_USTRING) &&
581 !(parm_table[i].flags & FLAG_CMDLINE)) {
582 string_set(parm_table[i].ptr, "");
586 do_parameter("config file", dyn_CONFIGFILE, NULL);
588 /* options that can be set on the command line must be initialised via
589 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
591 do_parameter("socket options", "TCP_NODELAY", NULL);
593 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
594 myname = get_myname();
595 do_parameter("netbios name", myname, NULL);
597 do_parameter("max protocol", "NT1", NULL);
598 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
600 do_parameter("fstype", FSTYPE_STRING, NULL);
601 do_parameter("ntvfs handler", "unixuid default", NULL);
602 do_parameter("max connections", "-1", NULL);
604 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
605 do_parameter("server services", "smb rpc nbt ldap cldap web kdc", NULL);
606 do_parameter("ntptr providor", "simple_ldb", NULL);
607 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
608 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE, NULL);
609 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
610 do_parameter("sam database", "sam.ldb", NULL);
611 do_parameter("spoolss database", "spoolss.ldb", NULL);
612 do_parameter("wins database", "wins.ldb", NULL);
613 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
615 /* This hive should be dynamically generated by Samba using
616 data from the sam, but for the moment leave it in a tdb to
617 keep regedt32 from popping up an annoying dialog. */
618 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
620 /* using UTF8 by default allows us to support all chars */
621 do_parameter("unix charset", "UTF8", NULL);
623 /* Use codepage 850 as a default for the dos character set */
624 do_parameter("dos charset", "CP850", NULL);
627 * Allow the default PASSWD_CHAT to be overridden in local.h.
629 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
631 do_parameter("pid directory", dyn_PIDDIR, NULL);
632 do_parameter("lock dir", dyn_LOCKDIR, NULL);
633 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
635 do_parameter("socket address", "0.0.0.0", NULL);
636 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
638 do_parameter_var("announce version", "%d.%d",
639 DEFAULT_MAJOR_VERSION,
640 DEFAULT_MINOR_VERSION);
642 do_parameter("password server", "*", NULL);
644 do_parameter("max mux", "50", NULL);
645 do_parameter("max xmit", "12288", NULL);
646 do_parameter("password level", "0", NULL);
647 do_parameter("LargeReadwrite", "True", NULL);
648 do_parameter("minprotocol", "CORE", NULL);
649 do_parameter("security", "USER", NULL);
650 do_parameter("paranoid server security", "True", NULL);
651 do_parameter("EncryptPasswords", "True", NULL);
652 do_parameter("ReadRaw", "True", NULL);
653 do_parameter("WriteRaw", "True", NULL);
654 do_parameter("NullPasswords", "False", NULL);
655 do_parameter("ObeyPamRestrictions", "False", NULL);
656 do_parameter("announce as", "NT SERVER", NULL);
658 do_parameter("TimeServer", "False", NULL);
659 do_parameter("BindInterfacesOnly", "False", NULL);
660 do_parameter("Unicode", "True", NULL);
661 do_parameter("ClientLanManAuth", "True", NULL);
662 do_parameter("LanmanAuth", "True", NULL);
663 do_parameter("NTLMAuth", "True", NULL);
664 do_parameter("client use spnego principal", "False", NULL);
666 do_parameter("UnixExtensions", "False", NULL);
668 do_parameter("PreferredMaster", "Auto", NULL);
669 do_parameter("LocalMaster", "True", NULL);
670 do_parameter("DomainMaster", "Auto", NULL); /* depending on bDomainLogons */
671 do_parameter("DomainLogons", "False", NULL);
672 do_parameter("WINSsupport", "False", NULL);
674 do_parameter("winbind separator", "\\", NULL);
676 do_parameter("client signing", "Yes", NULL);
677 do_parameter("server signing", "auto", NULL);
679 do_parameter("use spnego", "True", NULL);
681 do_parameter("smb ports", SMB_PORTS, NULL);
682 do_parameter("nbt port", "137", NULL);
683 do_parameter("dgram port", "138", NULL);
684 do_parameter("cldap port", "389", NULL);
685 do_parameter("krb5 port", "88", NULL);
686 do_parameter("web port", "901", NULL);
687 do_parameter("swat directory", dyn_SWATDIR, NULL);
689 do_parameter("nt status support", "True", NULL);
691 do_parameter("max wins ttl", "432000", NULL);
692 do_parameter("min wins ttl", "10", NULL);
694 do_parameter("tls enabled", "True", NULL);
695 do_parameter("tls keyfile", "tls/key.pem", NULL);
696 do_parameter("tls certfile", "tls/cert.pem", NULL);
697 do_parameter("tls cafile", "tls/ca.pem", NULL);
698 do_parameter_var("js include", "%s/js", dyn_LIBDIR);
699 do_parameter_var("setup directory", "%s/setup", dyn_LIBDIR);
702 static TALLOC_CTX *lp_talloc;
704 /******************************************************************* a
705 Free up temporary memory - called from the main loop.
706 ********************************************************************/
708 void lp_talloc_free(void)
712 talloc_free(lp_talloc);
716 /*******************************************************************
717 Convenience routine to grab string parameters into temporary memory
718 and run standard_sub_basic on them. The buffers can be written to by
719 callers without affecting the source string.
720 ********************************************************************/
722 static const char *lp_string(const char *s)
724 #if 0 /* until REWRITE done to make thread-safe */
725 size_t len = s ? strlen(s) : 0;
729 /* The follow debug is useful for tracking down memory problems
730 especially if you have an inner loop that is calling a lp_*()
731 function that returns a string. Perhaps this debug should be
732 present all the time? */
735 DEBUG(10, ("lp_string(%s)\n", s));
738 #if 0 /* until REWRITE done to make thread-safe */
740 lp_talloc = talloc_init("lp_talloc");
742 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
750 StrnCpy(ret, s, len);
752 if (trim_string(ret, "\"", "\"")) {
753 if (strchr(ret,'"') != NULL)
754 StrnCpy(ret, s, len);
757 standard_sub_basic(ret,len+100);
764 In this section all the functions that are used to access the
765 parameters from the rest of the program are defined
768 #define FN_GLOBAL_STRING(fn_name,ptr) \
769 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
770 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
771 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
772 #define FN_GLOBAL_LIST(fn_name,ptr) \
773 const char **fn_name(void) {return(*(const char ***)(ptr));}
774 #define FN_GLOBAL_BOOL(fn_name,ptr) \
775 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
776 #define FN_GLOBAL_CHAR(fn_name,ptr) \
777 char fn_name(void) {return(*(char *)(ptr));}
778 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
779 int fn_name(void) {return(*(int *)(ptr));}
781 #define FN_LOCAL_STRING(fn_name,val) \
782 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
783 #define FN_LOCAL_CONST_STRING(fn_name,val) \
784 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
785 #define FN_LOCAL_LIST(fn_name,val) \
786 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
787 #define FN_LOCAL_BOOL(fn_name,val) \
788 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
789 #define FN_LOCAL_CHAR(fn_name,val) \
790 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
791 #define FN_LOCAL_INTEGER(fn_name,val) \
792 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
794 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
795 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
796 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
797 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
798 FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
799 FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
800 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
801 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
802 FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
803 FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
804 FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
805 FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
806 FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
807 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
808 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
809 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
810 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
811 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
812 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
813 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
814 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
815 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
816 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
817 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
818 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
819 FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
820 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
821 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
822 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
823 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
824 FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
825 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
826 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
827 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
828 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
829 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
830 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
831 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
832 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
833 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
834 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
835 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
836 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
837 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
838 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
840 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
841 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
842 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
843 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
844 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
845 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
846 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
847 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
848 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
849 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
850 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
851 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
852 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
853 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
854 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
855 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
856 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
857 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
858 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
859 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
860 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
861 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
862 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
863 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
864 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
865 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
866 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
867 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
868 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
869 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
870 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
871 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
872 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
873 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
874 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
875 FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
878 FN_LOCAL_STRING(lp_servicename, szService)
879 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
880 FN_LOCAL_STRING(lp_pathname, szPath)
881 static FN_LOCAL_STRING(_lp_printername, szPrintername)
882 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
883 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
884 FN_LOCAL_STRING(lp_comment, comment)
885 FN_LOCAL_STRING(lp_fstype, fstype)
886 static FN_LOCAL_STRING(lp_volume, volume)
887 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
888 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
889 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
890 FN_LOCAL_BOOL(lp_readonly, bRead_only)
891 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
892 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
893 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
894 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
895 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
896 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
897 FN_LOCAL_BOOL(lp_map_system, bMap_system)
898 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
899 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
900 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
901 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
903 /* local prototypes */
905 static int map_parameter(const char *pszParmName);
906 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
907 static int getservicebyname(const char *pszServiceName,
908 service * pserviceDest);
909 static void copy_service(service * pserviceDest,
910 service * pserviceSource, BOOL *pcopymapDest);
911 static BOOL service_ok(int iService);
912 static BOOL do_section(const char *pszSectionName, void *);
913 static void init_copymap(service * pservice);
915 /* This is a helper function for parametrical options support. */
916 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
917 /* Actual parametrical functions are quite simple */
918 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
921 struct param_opt *data;
923 if (lookup_service >= iNumServices) return NULL;
925 data = (lookup_service < 0) ?
926 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
928 asprintf(&vfskey, "%s:%s", type, option);
932 if (strcmp(data->key, vfskey) == 0) {
939 if (lookup_service >= 0) {
940 /* Try to fetch the same option but from globals */
941 /* but only if we are not already working with Globals */
942 data = Globals.param_opt;
944 if (strcmp(data->key, vfskey) == 0) {
958 /*******************************************************************
959 convenience routine to return int parameters.
960 ********************************************************************/
961 static int lp_int(const char *s)
965 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
969 return strtol(s, NULL, 0);
972 /*******************************************************************
973 convenience routine to return unsigned long parameters.
974 ********************************************************************/
975 static int lp_ulong(const char *s)
979 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
983 return strtoul(s, NULL, 0);
986 /*******************************************************************
987 convenience routine to return boolean parameters.
988 ********************************************************************/
989 static BOOL lp_bool(const char *s)
994 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
998 if (!set_boolean(&ret,s)) {
999 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1007 /* Return parametric option from a given service. Type is a part of option before ':' */
1008 /* Parametric option has following syntax: 'Type: option = value' */
1009 /* Returned value is allocated in 'lp_talloc' context */
1011 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1013 const char *value = lp_get_parametric(lookup_service, type, option);
1016 return lp_string(value);
1021 /* Return parametric option from a given service. Type is a part of option before ':' */
1022 /* Parametric option has following syntax: 'Type: option = value' */
1023 /* Returned value is allocated in 'lp_talloc' context */
1025 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1026 const char *separator)
1028 const char *value = lp_get_parametric(lookup_service, type, option);
1031 return str_list_make(talloc_autofree_context(), value, separator);
1036 /* Return parametric option from a given service. Type is a part of option before ':' */
1037 /* Parametric option has following syntax: 'Type: option = value' */
1039 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1041 const char *value = lp_get_parametric(lookup_service, type, option);
1044 return lp_int(value);
1049 /* Return parametric option from a given service. Type is a part of option before ':' */
1050 /* Parametric option has following syntax: 'Type: option = value' */
1052 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1054 const char *value = lp_get_parametric(lookup_service, type, option);
1057 return lp_ulong(value);
1062 /* Return parametric option from a given service. Type is a part of option before ':' */
1063 /* Parametric option has following syntax: 'Type: option = value' */
1065 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1067 const char *value = lp_get_parametric(lookup_service, type, option);
1070 return lp_bool(value);
1076 /***************************************************************************
1077 Initialise a service to the defaults.
1078 ***************************************************************************/
1080 static void init_service(service * pservice)
1082 memset((char *)pservice, '\0', sizeof(service));
1083 copy_service(pservice, &sDefault, NULL);
1086 /***************************************************************************
1087 Free the dynamically allocated parts of a service struct.
1088 ***************************************************************************/
1090 static void free_service(service *pservice)
1093 struct param_opt *data, *pdata;
1097 if (pservice->szService)
1098 DEBUG(5, ("free_service: Freeing service %s\n",
1099 pservice->szService));
1101 string_free(&pservice->szService);
1102 SAFE_FREE(pservice->copymap);
1104 for (i = 0; parm_table[i].label; i++) {
1105 if ((parm_table[i].type == P_STRING ||
1106 parm_table[i].type == P_USTRING) &&
1107 parm_table[i].class == P_LOCAL) {
1108 string_free((char **)
1109 (((char *)pservice) +
1110 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1111 } else if (parm_table[i].type == P_LIST &&
1112 parm_table[i].class == P_LOCAL) {
1113 char ***listp = (char ***)(((char *)pservice) +
1114 PTR_DIFF(parm_table[i].ptr, &sDefault));
1115 talloc_free(*listp);
1120 DEBUG(5,("Freeing parametrics:\n"));
1121 data = pservice->param_opt;
1123 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1124 string_free(&data->key);
1125 string_free(&data->value);
1131 ZERO_STRUCTP(pservice);
1134 /***************************************************************************
1135 Add a new service to the services array initialising it with the given
1137 ***************************************************************************/
1139 static int add_a_service(const service *pservice, const char *name)
1143 int num_to_alloc = iNumServices + 1;
1144 struct param_opt *data, *pdata;
1146 tservice = *pservice;
1148 /* it might already exist */
1150 i = getservicebyname(name, NULL);
1152 /* Clean all parametric options for service */
1153 /* They will be added during parsing again */
1154 data = ServicePtrs[i]->param_opt;
1156 string_free(&data->key);
1157 string_free(&data->value);
1162 ServicePtrs[i]->param_opt = NULL;
1167 /* find an invalid one */
1168 for (i = 0; i < iNumServices; i++)
1169 if (!ServicePtrs[i]->valid)
1172 /* if not, then create one */
1173 if (i == iNumServices) {
1176 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1179 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1184 ServicePtrs[iNumServices] = malloc_p(service);
1186 if (!ServicePtrs[iNumServices]) {
1187 DEBUG(0,("add_a_service: out of memory!\n"));
1193 free_service(ServicePtrs[i]);
1195 ServicePtrs[i]->valid = True;
1197 init_service(ServicePtrs[i]);
1198 copy_service(ServicePtrs[i], &tservice, NULL);
1200 string_set(&ServicePtrs[i]->szService, name);
1204 /***************************************************************************
1205 Add a new home service, with the specified home directory, defaults coming
1207 ***************************************************************************/
1209 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1210 const char *user, const char *pszHomedir)
1215 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1220 if (!(*(ServicePtrs[iDefaultService]->szPath))
1221 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1222 pstrcpy(newHomedir, pszHomedir);
1224 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1225 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1228 string_set(&ServicePtrs[i]->szPath, newHomedir);
1230 if (!(*(ServicePtrs[i]->comment))) {
1232 slprintf(comment, sizeof(comment) - 1,
1233 "Home directory of %s", user);
1234 string_set(&ServicePtrs[i]->comment, comment);
1236 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1237 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1239 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1245 /***************************************************************************
1246 Add a new service, based on an old one.
1247 ***************************************************************************/
1249 int lp_add_service(const char *pszService, int iDefaultService)
1251 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1254 /***************************************************************************
1255 Add the IPC service.
1256 ***************************************************************************/
1258 static BOOL lp_add_hidden(const char *name, const char *fstype)
1261 int i = add_a_service(&sDefault, name);
1266 slprintf(comment, sizeof(comment) - 1,
1267 "%s Service (%s)", fstype, Globals.szServerString);
1269 string_set(&ServicePtrs[i]->szPath, tmpdir());
1270 string_set(&ServicePtrs[i]->comment, comment);
1271 string_set(&ServicePtrs[i]->fstype, fstype);
1272 ServicePtrs[i]->iMaxConnections = -1;
1273 ServicePtrs[i]->bAvailable = True;
1274 ServicePtrs[i]->bRead_only = True;
1275 ServicePtrs[i]->bPrint_ok = False;
1276 ServicePtrs[i]->bBrowseable = False;
1278 if (strcasecmp(fstype, "IPC") == 0) {
1279 lp_do_parameter(i, "ntvfs handler", "default");
1282 DEBUG(3, ("adding hidden service %s\n", name));
1287 /***************************************************************************
1288 Add a new printer service, with defaults coming from service iFrom.
1289 ***************************************************************************/
1291 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1293 const char *comment = "From Printcap";
1294 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1299 /* note that we do NOT default the availability flag to True - */
1300 /* we take it from the default service passed. This allows all */
1301 /* dynamic printers to be disabled by disabling the [printers] */
1302 /* entry (if/when the 'available' keyword is implemented!). */
1304 /* the printer name is set to the service name. */
1305 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1306 string_set(&ServicePtrs[i]->comment, comment);
1307 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1308 /* Printers cannot be read_only. */
1309 ServicePtrs[i]->bRead_only = False;
1310 /* Printer services must be printable. */
1311 ServicePtrs[i]->bPrint_ok = True;
1313 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1315 update_server_announce_as_printserver();
1320 /***************************************************************************
1321 Map a parameter's string representation to something we can use.
1322 Returns False if the parameter string is not recognised, else TRUE.
1323 ***************************************************************************/
1325 static int map_parameter(const char *pszParmName)
1329 if (*pszParmName == '-')
1332 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1333 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1336 /* Warn only if it isn't parametric option */
1337 if (strchr(pszParmName, ':') == NULL)
1338 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1339 /* We do return 'fail' for parametric options as well because they are
1340 stored in different storage
1347 return the parameter structure for a parameter
1349 struct parm_struct *lp_parm_struct(const char *name)
1351 int parmnum = map_parameter(name);
1352 if (parmnum == -1) return NULL;
1353 return &parm_table[parmnum];
1357 return the parameter pointer for a parameter
1359 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1364 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1367 /***************************************************************************
1368 Set a boolean variable from the text value stored in the passed string.
1369 Returns True in success, False if the passed string does not correctly
1370 represent a boolean.
1371 ***************************************************************************/
1373 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1378 if (strwicmp(pszParmValue, "yes") == 0 ||
1379 strwicmp(pszParmValue, "true") == 0 ||
1380 strwicmp(pszParmValue, "1") == 0)
1382 else if (strwicmp(pszParmValue, "no") == 0 ||
1383 strwicmp(pszParmValue, "False") == 0 ||
1384 strwicmp(pszParmValue, "0") == 0)
1388 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1395 /***************************************************************************
1396 Find a service by name. Otherwise works like get_service.
1397 ***************************************************************************/
1399 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1403 for (iService = iNumServices - 1; iService >= 0; iService--)
1404 if (VALID(iService) &&
1405 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1406 if (pserviceDest != NULL)
1407 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1414 /***************************************************************************
1415 Copy a service structure to another.
1416 If pcopymapDest is NULL then copy all fields
1417 ***************************************************************************/
1419 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1422 BOOL bcopyall = (pcopymapDest == NULL);
1423 struct param_opt *data, *pdata, *paramo;
1426 for (i = 0; parm_table[i].label; i++)
1427 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1428 (bcopyall || pcopymapDest[i])) {
1429 void *def_ptr = parm_table[i].ptr;
1431 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1434 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1437 switch (parm_table[i].type) {
1439 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1444 *(int *)dest_ptr = *(int *)src_ptr;
1448 string_set(dest_ptr,
1453 string_set(dest_ptr,
1455 strupper(*(char **)dest_ptr);
1458 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1459 *(const char ***)src_ptr);
1467 init_copymap(pserviceDest);
1468 if (pserviceSource->copymap)
1469 memcpy((void *)pserviceDest->copymap,
1470 (void *)pserviceSource->copymap,
1471 sizeof(BOOL) * NUMPARAMETERS);
1474 data = pserviceSource->param_opt;
1477 pdata = pserviceDest->param_opt;
1478 /* Traverse destination */
1480 /* If we already have same option, override it */
1481 if (strcmp(pdata->key, data->key) == 0) {
1482 string_free(&pdata->value);
1483 pdata->value = strdup(data->value);
1487 pdata = pdata->next;
1490 paramo = smb_xmalloc_p(struct param_opt);
1491 paramo->key = strdup(data->key);
1492 paramo->value = strdup(data->value);
1493 DLIST_ADD(pserviceDest->param_opt, paramo);
1499 /***************************************************************************
1500 Check a service for consistency. Return False if the service is in any way
1501 incomplete or faulty, else True.
1502 ***************************************************************************/
1504 static BOOL service_ok(int iService)
1509 if (ServicePtrs[iService]->szService[0] == '\0') {
1510 DEBUG(0, ("The following message indicates an internal error:\n"));
1511 DEBUG(0, ("No service name in service entry.\n"));
1515 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1516 /* I can't see why you'd want a non-printable printer service... */
1517 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1518 if (!ServicePtrs[iService]->bPrint_ok) {
1519 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1520 ServicePtrs[iService]->szService));
1521 ServicePtrs[iService]->bPrint_ok = True;
1522 update_server_announce_as_printserver();
1524 /* [printers] service must also be non-browsable. */
1525 if (ServicePtrs[iService]->bBrowseable)
1526 ServicePtrs[iService]->bBrowseable = False;
1529 /* If a service is flagged unavailable, log the fact at level 0. */
1530 if (!ServicePtrs[iService]->bAvailable)
1531 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1532 ServicePtrs[iService]->szService));
1537 static struct file_lists {
1538 struct file_lists *next;
1542 } *file_lists = NULL;
1544 /*******************************************************************
1545 Keep a linked list of all config files so we know when one has changed
1546 it's date and needs to be reloaded.
1547 ********************************************************************/
1549 static void add_to_file_list(const char *fname, const char *subfname)
1551 struct file_lists *f = file_lists;
1554 if (f->name && !strcmp(f->name, fname))
1560 f = malloc_p(struct file_lists);
1563 f->next = file_lists;
1564 f->name = strdup(fname);
1569 f->subfname = strdup(subfname);
1575 f->modtime = file_modtime(subfname);
1577 time_t t = file_modtime(subfname);
1583 /*******************************************************************
1584 Check if a config file has changed date.
1585 ********************************************************************/
1587 BOOL lp_file_list_changed(void)
1589 struct file_lists *f = file_lists;
1590 DEBUG(6, ("lp_file_list_changed()\n"));
1596 pstrcpy(n2, f->name);
1597 standard_sub_basic(n2,sizeof(n2));
1599 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1600 f->name, n2, ctime(&f->modtime)));
1602 mod_time = file_modtime(n2);
1604 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1606 ("file %s modified: %s\n", n2,
1608 f->modtime = mod_time;
1609 SAFE_FREE(f->subfname);
1610 f->subfname = strdup(n2);
1618 /***************************************************************************
1619 Handle the include operation.
1620 ***************************************************************************/
1622 static BOOL handle_include(const char *pszParmValue, char **ptr)
1625 pstrcpy(fname, pszParmValue);
1627 standard_sub_basic(fname,sizeof(fname));
1629 add_to_file_list(pszParmValue, fname);
1631 string_set(ptr, fname);
1633 if (file_exist(fname))
1634 return (pm_process(fname, do_section, do_parameter, NULL));
1636 DEBUG(2, ("Can't find include file %s\n", fname));
1641 /***************************************************************************
1642 Handle the interpretation of the copy parameter.
1643 ***************************************************************************/
1645 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1649 service serviceTemp;
1651 string_set(ptr, pszParmValue);
1653 init_service(&serviceTemp);
1657 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1659 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1660 if (iTemp == iServiceIndex) {
1661 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1663 copy_service(ServicePtrs[iServiceIndex],
1665 ServicePtrs[iServiceIndex]->copymap);
1669 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1673 free_service(&serviceTemp);
1677 /***************************************************************************
1678 Initialise a copymap.
1679 ***************************************************************************/
1681 static void init_copymap(service * pservice)
1684 SAFE_FREE(pservice->copymap);
1685 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
1686 if (!pservice->copymap)
1688 ("Couldn't allocate copymap!! (size %d)\n",
1689 (int)NUMPARAMETERS));
1691 for (i = 0; i < NUMPARAMETERS; i++)
1692 pservice->copymap[i] = True;
1695 /***************************************************************************
1696 Return the local pointer to a parameter given the service number and the
1697 pointer into the default structure.
1698 ***************************************************************************/
1700 void *lp_local_ptr(int snum, void *ptr)
1702 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1706 /***************************************************************************
1707 Process a parametric option
1708 ***************************************************************************/
1709 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1711 struct param_opt *paramo, *data;
1714 while (isspace((unsigned char)*pszParmName)) {
1718 name = strdup(pszParmName);
1719 if (!name) return False;
1724 data = Globals.param_opt;
1726 data = ServicePtrs[snum]->param_opt;
1729 /* Traverse destination */
1730 for (paramo=data; paramo; paramo=paramo->next) {
1731 /* If we already have the option set, override it unless
1732 it was a command line option and the new one isn't */
1733 if (strcmp(paramo->key, name) == 0) {
1734 if ((paramo->flags & FLAG_CMDLINE) &&
1735 !(flags & FLAG_CMDLINE)) {
1739 free(paramo->value);
1740 paramo->value = strdup(pszParmValue);
1741 paramo->flags = flags;
1747 paramo = smb_xmalloc_p(struct param_opt);
1748 paramo->key = strdup(name);
1749 paramo->value = strdup(pszParmValue);
1750 paramo->flags = flags;
1752 DLIST_ADD(Globals.param_opt, paramo);
1754 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1762 /***************************************************************************
1763 Process a parameter for a particular service number. If snum < 0
1764 then assume we are in the globals.
1765 ***************************************************************************/
1766 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1769 void *parm_ptr = NULL; /* where we are going to store the result */
1770 void *def_ptr = NULL;
1772 parmnum = map_parameter(pszParmName);
1775 if (strchr(pszParmName, ':')) {
1776 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1778 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1782 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1783 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1787 /* if the flag has been set on the command line, then don't allow override,
1788 but don't report an error */
1789 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1793 def_ptr = parm_table[parmnum].ptr;
1795 /* we might point at a service, the default service or a global */
1799 if (parm_table[parmnum].class == P_GLOBAL) {
1801 ("Global parameter %s found in service section!\n",
1806 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1811 if (!ServicePtrs[snum]->copymap)
1812 init_copymap(ServicePtrs[snum]);
1814 /* this handles the aliases - set the copymap for other entries with
1815 the same data pointer */
1816 for (i = 0; parm_table[i].label; i++)
1817 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1818 ServicePtrs[snum]->copymap[i] = False;
1821 /* if it is a special case then go ahead */
1822 if (parm_table[parmnum].special) {
1823 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1827 /* now switch on the type of variable it is */
1828 switch (parm_table[parmnum].type)
1831 set_boolean(parm_ptr, pszParmValue);
1835 *(int *)parm_ptr = atoi(pszParmValue);
1839 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1840 pszParmValue, NULL);
1844 string_set(parm_ptr, pszParmValue);
1848 string_set(parm_ptr, pszParmValue);
1849 strupper(*(char **)parm_ptr);
1853 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1856 parm_table[parmnum].enum_list[i].name)) {
1858 parm_table[parmnum].
1863 if (!parm_table[parmnum].enum_list[i].name) {
1864 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1865 pszParmValue, pszParmName));
1876 /***************************************************************************
1877 Process a parameter.
1878 ***************************************************************************/
1880 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1882 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1883 pszParmName, pszParmValue));
1887 variable argument do parameter
1889 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1891 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1898 s = talloc_vasprintf(NULL, fmt, ap);
1900 ret = do_parameter(pszParmName, s, NULL);
1907 set a parameter from the commandline - this is called from command line parameter
1908 parsing code. It sets the parameter then marks the parameter as unable to be modified
1909 by smb.conf processing
1911 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1913 int parmnum = map_parameter(pszParmName);
1916 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1919 if (parmnum < 0 && strchr(pszParmName, ':')) {
1920 /* set a parametric option */
1921 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1925 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1929 /* reset the CMDLINE flag in case this has been called before */
1930 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1932 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1936 parm_table[parmnum].flags |= FLAG_CMDLINE;
1938 /* we have to also set FLAG_CMDLINE on aliases */
1939 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1940 parm_table[i].flags |= FLAG_CMDLINE;
1942 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1943 parm_table[i].flags |= FLAG_CMDLINE;
1950 set a option from the commandline in 'a=b' format. Use to support --option
1952 BOOL lp_set_option(const char *option)
1970 ret = lp_set_cmdline(s, p+1);
1976 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1978 /***************************************************************************
1979 Print a parameter of the specified type.
1980 ***************************************************************************/
1982 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1988 for (i = 0; p->enum_list[i].name; i++) {
1989 if (*(int *)ptr == p->enum_list[i].value) {
1991 p->enum_list[i].name);
1998 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2002 fprintf(f, "%d", *(int *)ptr);
2006 if ((char ***)ptr && *(char ***)ptr) {
2007 char **list = *(char ***)ptr;
2009 for (; *list; list++)
2010 fprintf(f, "%s%s", *list,
2011 ((*(list+1))?", ":""));
2017 if (*(char **)ptr) {
2018 fprintf(f, "%s", *(char **)ptr);
2026 /***************************************************************************
2027 Check if two parameters are equal.
2028 ***************************************************************************/
2030 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2034 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2038 return (*((int *)ptr1) == *((int *)ptr2));
2041 return str_list_equal((const char **)(*(char ***)ptr1),
2042 (const char **)(*(char ***)ptr2));
2047 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2052 return (p1 == p2 || strequal(p1, p2));
2060 /***************************************************************************
2061 Process a new section (service). At this stage all sections are services.
2062 Later we'll have special sections that permit server parameters to be set.
2063 Returns True on success, False on failure.
2064 ***************************************************************************/
2066 static BOOL do_section(const char *pszSectionName, void *userdata)
2069 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2070 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2073 /* if we've just struck a global section, note the fact. */
2074 bInGlobalSection = isglobal;
2076 /* check for multiple global sections */
2077 if (bInGlobalSection) {
2078 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2082 /* if we have a current service, tidy it up before moving on */
2085 if (iServiceIndex >= 0)
2086 bRetval = service_ok(iServiceIndex);
2088 /* if all is still well, move to the next record in the services array */
2090 /* We put this here to avoid an odd message order if messages are */
2091 /* issued by the post-processing of a previous section. */
2092 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2094 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2096 DEBUG(0, ("Failed to add a new service\n"));
2105 /***************************************************************************
2106 Determine if a partcular base parameter is currentl set to the default value.
2107 ***************************************************************************/
2109 static BOOL is_default(int i)
2111 if (!defaults_saved)
2113 switch (parm_table[i].type) {
2115 return str_list_equal((const char **)parm_table[i].def.lvalue,
2116 (const char **)(*(char ***)parm_table[i].ptr));
2119 return strequal(parm_table[i].def.svalue,
2120 *(char **)parm_table[i].ptr);
2122 return parm_table[i].def.bvalue ==
2123 *(BOOL *)parm_table[i].ptr;
2126 return parm_table[i].def.ivalue ==
2127 *(int *)parm_table[i].ptr;
2134 /***************************************************************************
2135 Display the contents of the global structure.
2136 ***************************************************************************/
2138 static void dump_globals(FILE *f)
2141 struct param_opt *data;
2143 fprintf(f, "# Global parameters\n[global]\n");
2145 for (i = 0; parm_table[i].label; i++)
2146 if (parm_table[i].class == P_GLOBAL &&
2147 parm_table[i].ptr &&
2148 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2149 if (defaults_saved && is_default(i))
2151 fprintf(f, "\t%s = ", parm_table[i].label);
2152 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2155 if (Globals.param_opt != NULL) {
2156 data = Globals.param_opt;
2158 fprintf(f, "\t%s = %s\n", data->key, data->value);
2165 /***************************************************************************
2166 Display the contents of a single services record.
2167 ***************************************************************************/
2169 static void dump_a_service(service * pService, FILE * f)
2172 struct param_opt *data;
2174 if (pService != &sDefault)
2175 fprintf(f, "\n[%s]\n", pService->szService);
2177 for (i = 0; parm_table[i].label; i++)
2178 if (parm_table[i].class == P_LOCAL &&
2179 parm_table[i].ptr &&
2180 (*parm_table[i].label != '-') &&
2181 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2182 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2184 if (pService == &sDefault) {
2185 if (defaults_saved && is_default(i))
2188 if (equal_parameter(parm_table[i].type,
2189 ((char *)pService) +
2191 ((char *)&sDefault) +
2196 fprintf(f, "\t%s = ", parm_table[i].label);
2197 print_parameter(&parm_table[i],
2198 ((char *)pService) + pdiff, f);
2201 if (pService->param_opt != NULL) {
2202 data = pService->param_opt;
2204 fprintf(f, "\t%s = %s\n", data->key, data->value);
2211 /***************************************************************************
2212 Return info about the next service in a service. snum==-1 gives the globals.
2213 Return NULL when out of parameters.
2214 ***************************************************************************/
2216 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2219 /* do the globals */
2220 for (; parm_table[*i].label; (*i)++) {
2221 if (parm_table[*i].class == P_SEPARATOR)
2222 return &parm_table[(*i)++];
2224 if (!parm_table[*i].ptr
2225 || (*parm_table[*i].label == '-'))
2229 && (parm_table[*i].ptr ==
2230 parm_table[(*i) - 1].ptr))
2233 return &parm_table[(*i)++];
2236 service *pService = ServicePtrs[snum];
2238 for (; parm_table[*i].label; (*i)++) {
2239 if (parm_table[*i].class == P_SEPARATOR)
2240 return &parm_table[(*i)++];
2242 if (parm_table[*i].class == P_LOCAL &&
2243 parm_table[*i].ptr &&
2244 (*parm_table[*i].label != '-') &&
2246 (parm_table[*i].ptr !=
2247 parm_table[(*i) - 1].ptr)))
2250 PTR_DIFF(parm_table[*i].ptr,
2253 if (allparameters ||
2254 !equal_parameter(parm_table[*i].type,
2255 ((char *)pService) +
2257 ((char *)&sDefault) +
2260 return &parm_table[(*i)++];
2270 /***************************************************************************
2271 Return TRUE if the passed service number is within range.
2272 ***************************************************************************/
2274 BOOL lp_snum_ok(int iService)
2276 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2279 /***************************************************************************
2280 Auto-load some home services.
2281 ***************************************************************************/
2283 static void lp_add_auto_services(const char *str)
2288 /***************************************************************************
2289 Announce ourselves as a print server.
2290 ***************************************************************************/
2292 void update_server_announce_as_printserver(void)
2294 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2297 /***************************************************************************
2298 Have we loaded a services file yet?
2299 ***************************************************************************/
2301 BOOL lp_loaded(void)
2306 /***************************************************************************
2307 Unload unused services.
2308 ***************************************************************************/
2310 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2313 for (i = 0; i < iNumServices; i++) {
2317 if (!snumused || !snumused(smb, i)) {
2318 ServicePtrs[i]->valid = False;
2319 free_service(ServicePtrs[i]);
2324 /***************************************************************************
2326 ***************************************************************************/
2328 void lp_killservice(int iServiceIn)
2330 if (VALID(iServiceIn)) {
2331 ServicePtrs[iServiceIn]->valid = False;
2332 free_service(ServicePtrs[iServiceIn]);
2336 /*******************************************************************
2337 Set the server type we will announce as via nmbd.
2338 ********************************************************************/
2340 static void set_server_role(void)
2342 server_role = ROLE_STANDALONE;
2344 switch (lp_security()) {
2346 if (lp_domain_logons())
2347 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2352 if (lp_domain_logons()) {
2353 if (Globals.bDomainMaster) /* auto or yes */
2354 server_role = ROLE_DOMAIN_PDC;
2356 server_role = ROLE_DOMAIN_BDC;
2359 server_role = ROLE_DOMAIN_MEMBER;
2362 if (lp_domain_logons()) {
2364 if (Globals.bDomainMaster) /* auto or yes */
2365 server_role = ROLE_DOMAIN_PDC;
2367 server_role = ROLE_DOMAIN_BDC;
2371 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2375 DEBUG(10, ("set_server_role: role = "));
2377 switch(server_role) {
2378 case ROLE_STANDALONE:
2379 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2381 case ROLE_DOMAIN_MEMBER:
2382 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2384 case ROLE_DOMAIN_BDC:
2385 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2387 case ROLE_DOMAIN_PDC:
2388 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
2393 /***************************************************************************
2394 Load the services array from the services file. Return True on success,
2396 ***************************************************************************/
2402 struct param_opt *data;
2406 bInGlobalSection = True;
2408 if (Globals.param_opt != NULL) {
2409 struct param_opt *next;
2410 for (data=Globals.param_opt; data; data=next) {
2412 if (data->flags & FLAG_CMDLINE) continue;
2415 DLIST_REMOVE(Globals.param_opt, data);
2422 pstrcpy(n2, lp_configfile());
2423 standard_sub_basic(n2,sizeof(n2));
2424 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2426 add_to_file_list(lp_configfile(), n2);
2428 /* We get sections first, so have to start 'behind' to make up */
2430 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2432 /* finish up the last section */
2433 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2435 if (iServiceIndex >= 0)
2436 bRetval = service_ok(iServiceIndex);
2438 lp_add_auto_services(lp_auto_services());
2440 lp_add_hidden("IPC$", "IPC");
2441 lp_add_hidden("ADMIN$", "DISK");
2444 set_default_server_announce_type();
2448 if (Globals.bWINSsupport) {
2449 lp_do_parameter(-1, "wins server", "127.0.0.1");
2457 /***************************************************************************
2458 Reset the max number of services.
2459 ***************************************************************************/
2461 void lp_resetnumservices(void)
2466 /***************************************************************************
2467 Return the max number of services.
2468 ***************************************************************************/
2470 int lp_numservices(void)
2472 return (iNumServices);
2475 /***************************************************************************
2476 Display the contents of the services array in human-readable form.
2477 ***************************************************************************/
2479 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2484 defaults_saved = False;
2488 dump_a_service(&sDefault, f);
2490 for (iService = 0; iService < maxtoprint; iService++)
2491 lp_dump_one(f, show_defaults, iService);
2494 /***************************************************************************
2495 Display the contents of one service in human-readable form.
2496 ***************************************************************************/
2498 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2501 if (ServicePtrs[snum]->szService[0] == '\0')
2503 dump_a_service(ServicePtrs[snum], f);
2507 /***************************************************************************
2508 Return the number of the service with the given name, or -1 if it doesn't
2509 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2510 getservicebyname()! This works ONLY if all services have been loaded, and
2511 does not copy the found service.
2512 ***************************************************************************/
2514 int lp_servicenumber(const char *pszServiceName)
2517 fstring serviceName;
2520 for (iService = iNumServices - 1; iService >= 0; iService--) {
2521 if (VALID(iService) && ServicePtrs[iService]->szService) {
2523 * The substitution here is used to support %U is
2526 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2527 standard_sub_basic(serviceName,sizeof(serviceName));
2528 if (strequal(serviceName, pszServiceName))
2534 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2539 /*******************************************************************
2540 A useful volume label function.
2541 ********************************************************************/
2542 const char *volume_label(int snum)
2544 const char *ret = lp_volume(snum);
2546 return lp_servicename(snum);
2551 /*******************************************************************
2552 Set the server type we will announce as via nmbd.
2553 ********************************************************************/
2555 static void set_default_server_announce_type(void)
2557 default_server_announce = 0;
2558 default_server_announce |= SV_TYPE_WORKSTATION;
2559 default_server_announce |= SV_TYPE_SERVER;
2560 default_server_announce |= SV_TYPE_SERVER_UNIX;
2562 switch (lp_announce_as()) {
2563 case ANNOUNCE_AS_NT_SERVER:
2564 default_server_announce |= SV_TYPE_SERVER_NT;
2565 /* fall through... */
2566 case ANNOUNCE_AS_NT_WORKSTATION:
2567 default_server_announce |= SV_TYPE_NT;
2569 case ANNOUNCE_AS_WIN95:
2570 default_server_announce |= SV_TYPE_WIN95_PLUS;
2572 case ANNOUNCE_AS_WFW:
2573 default_server_announce |= SV_TYPE_WFW;
2579 switch (lp_server_role()) {
2580 case ROLE_DOMAIN_MEMBER:
2581 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2583 case ROLE_DOMAIN_PDC:
2584 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2586 case ROLE_DOMAIN_BDC:
2587 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2589 case ROLE_STANDALONE:
2593 if (lp_time_server())
2594 default_server_announce |= SV_TYPE_TIME_SOURCE;
2596 if (lp_host_msdfs())
2597 default_server_announce |= SV_TYPE_DFS_SERVER;
2599 /* TODO: only announce us as print server when we are a print server */
2600 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2603 /***********************************************************
2604 returns role of Samba server
2605 ************************************************************/
2607 int lp_server_role(void)
2612 /***********************************************************
2613 If we are PDC then prefer us as DMB
2614 ************************************************************/
2616 BOOL lp_domain_master(void)
2618 if (Globals.bDomainMaster == Auto)
2619 return (lp_server_role() == ROLE_DOMAIN_PDC);
2621 return Globals.bDomainMaster;
2624 /***********************************************************
2625 If we are DMB then prefer us as LMB
2626 ************************************************************/
2628 BOOL lp_preferred_master(void)
2630 if (Globals.bPreferredMaster == Auto)
2631 return (lp_local_master() && lp_domain_master());
2633 return Globals.bPreferredMaster;
2636 /*******************************************************************
2638 ********************************************************************/
2640 void lp_remove_service(int snum)
2642 ServicePtrs[snum]->valid = False;
2645 /*******************************************************************
2647 ********************************************************************/
2649 void lp_copy_service(int snum, const char *new_name)
2651 const char *oldname = lp_servicename(snum);
2652 do_section(new_name, NULL);
2654 snum = lp_servicenumber(new_name);
2656 lp_do_parameter(snum, "copy", oldname);
2661 /*******************************************************************
2662 Get the default server type we will announce as via nmbd.
2663 ********************************************************************/
2664 int lp_default_server_announce(void)
2666 return default_server_announce;
2669 const char *lp_printername(int snum)
2671 const char *ret = _lp_printername(snum);
2672 if (ret == NULL || (ret != NULL && *ret == '\0'))
2673 ret = lp_const_servicename(snum);
2679 /*******************************************************************
2680 Return the max print jobs per queue.
2681 ********************************************************************/
2683 int lp_maxprintjobs(int snum)
2685 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2686 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2687 maxjobs = PRINT_MAX_JOBID - 1;