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"
59 #include "system/time.h"
60 #include "system/iconv.h"
61 #include "system/network.h"
62 #include "system/printing.h"
63 #include "librpc/gen_ndr/ndr_svcctl.h"
64 #include "librpc/gen_ndr/ndr_samr.h"
65 #include "librpc/gen_ndr/ndr_nbt.h"
66 #include "dlinklist.h"
67 #include "param/loadparm.h"
69 static BOOL bLoaded = False;
72 #define GLOBAL_NAME "global"
76 #define PRINTERS_NAME "printers"
80 #define HOMES_NAME "homes"
83 /* some helpful bits */
84 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
85 #define VALID(i) ServicePtrs[i]->valid
87 static BOOL do_parameter(const char *, const char *, void *);
88 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
90 static BOOL defaults_saved = False;
94 struct param_opt *prev, *next;
101 * This structure describes global (ie., server-wide) parameters.
111 char *display_charset;
115 char *szServerString;
116 char *szAutoServices;
122 char *szWINS_CONFIG_URL;
126 char **szPasswordServers;
127 char *szSocketOptions;
129 char **szWINSservers;
131 char *szSocketAddress;
132 char *szAnnounceVersion; /* This is initialised in init_globals */
135 char **szNetbiosAliases;
136 char *szNetbiosScope;
137 char *szDomainOtherSIDs;
138 char **szNameResolveOrder;
140 char **dcerpc_ep_servers;
141 char **server_services;
142 char *ntptr_providor;
143 char *szWinbindSeparator;
144 BOOL bWinbindSealedPipes;
145 char *swat_directory;
158 BOOL paranoid_server_security;
161 int announce_as; /* This is initialised in init_globals */
168 char *socket_options;
171 BOOL bPreferredMaster;
172 BOOL bEncryptPasswords;
174 BOOL bObeyPamRestrictions;
175 BOOL bLargeReadwrite;
179 BOOL bBindInterfacesOnly;
181 BOOL bNTStatusSupport;
187 BOOL bClientPlaintextAuth;
188 BOOL bClientLanManAuth;
189 BOOL bClientNTLMv2Auth;
190 BOOL client_use_spnego_principal;
193 BOOL bUnixExtensions;
194 BOOL bDisableNetbios;
196 struct param_opt *param_opt;
200 static global Globals;
203 * This structure describes a single service.
218 char **ntvfs_handler;
234 struct param_opt *param_opt;
236 char dummy[3]; /* for alignment */
241 /* This is a default service used to prime a services structure */
242 static service sDefault = {
244 NULL, /* szService */
247 NULL, /* szInclude */
248 NULL, /* szPrintername */
249 NULL, /* szHostsallow */
250 NULL, /* szHostsdeny */
254 NULL, /* ntvfs_handler */
255 1000, /* iMaxPrintJobs */
256 0, /* iMaxConnections */
258 True, /* bAvailable */
259 True, /* bBrowseable */
260 True, /* bRead_only */
261 False, /* bPrint_ok */
262 False, /* bMap_system */
263 False, /* bMap_hidden */
264 True, /* bMap_archive */
265 True, /* bStrictLocking */
267 False, /* bMSDfsRoot */
268 False, /* bStrictSync */
269 False, /* bCIFileSystem */
270 NULL, /* Parametric options */
275 /* local variables */
276 static service **ServicePtrs = NULL;
277 static int iNumServices = 0;
278 static int iServiceIndex = 0;
279 static BOOL bInGlobalSection = True;
280 static int default_server_announce;
282 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
284 /* prototypes for the special type handlers */
285 static BOOL handle_include(const char *pszParmValue, char **ptr);
286 static BOOL handle_copy(const char *pszParmValue, char **ptr);
288 static void set_default_server_announce_type(void);
290 static const struct enum_list enum_protocol[] = {
291 {PROTOCOL_NT1, "NT1"},
292 {PROTOCOL_LANMAN2, "LANMAN2"},
293 {PROTOCOL_LANMAN1, "LANMAN1"},
294 {PROTOCOL_CORE, "CORE"},
295 {PROTOCOL_COREPLUS, "COREPLUS"},
296 {PROTOCOL_COREPLUS, "CORE+"},
300 static const struct enum_list enum_security[] = {
301 {SEC_SHARE, "SHARE"},
306 /* Types of machine we can announce as. */
307 #define ANNOUNCE_AS_NT_SERVER 1
308 #define ANNOUNCE_AS_WIN95 2
309 #define ANNOUNCE_AS_WFW 3
310 #define ANNOUNCE_AS_NT_WORKSTATION 4
312 static const struct enum_list enum_announce_as[] = {
313 {ANNOUNCE_AS_NT_SERVER, "NT"},
314 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
315 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
316 {ANNOUNCE_AS_WIN95, "win95"},
317 {ANNOUNCE_AS_WFW, "WfW"},
321 static const struct enum_list enum_bool_auto[] = {
332 /* Client-side offline caching policy types */
333 #define CSC_POLICY_MANUAL 0
334 #define CSC_POLICY_DOCUMENTS 1
335 #define CSC_POLICY_PROGRAMS 2
336 #define CSC_POLICY_DISABLE 3
338 static const struct enum_list enum_csc_policy[] = {
339 {CSC_POLICY_MANUAL, "manual"},
340 {CSC_POLICY_DOCUMENTS, "documents"},
341 {CSC_POLICY_PROGRAMS, "programs"},
342 {CSC_POLICY_DISABLE, "disable"},
346 /* SMB signing types. */
347 static const struct enum_list enum_smb_signing_vals[] = {
348 {SMB_SIGNING_OFF, "No"},
349 {SMB_SIGNING_OFF, "False"},
350 {SMB_SIGNING_OFF, "0"},
351 {SMB_SIGNING_OFF, "Off"},
352 {SMB_SIGNING_OFF, "disabled"},
353 {SMB_SIGNING_SUPPORTED, "Yes"},
354 {SMB_SIGNING_SUPPORTED, "True"},
355 {SMB_SIGNING_SUPPORTED, "1"},
356 {SMB_SIGNING_SUPPORTED, "On"},
357 {SMB_SIGNING_SUPPORTED, "enabled"},
358 {SMB_SIGNING_REQUIRED, "required"},
359 {SMB_SIGNING_REQUIRED, "mandatory"},
360 {SMB_SIGNING_REQUIRED, "force"},
361 {SMB_SIGNING_REQUIRED, "forced"},
362 {SMB_SIGNING_REQUIRED, "enforced"},
363 {SMB_SIGNING_AUTO, "auto"},
367 static const struct enum_list enum_server_role[] = {
368 {ROLE_STANDALONE, "standalone"},
369 {ROLE_DOMAIN_MEMBER, "member server"},
370 {ROLE_DOMAIN_BDC, "bdc"},
371 {ROLE_DOMAIN_PDC, "pdc"},
376 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
378 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
379 * is implied in current control logic. This may change at some later time. A
380 * flag value of 0 means - show as development option only.
382 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
383 * screen in SWAT. This is used to exclude parameters as well as to squash all
384 * parameters that have been duplicated by pseudonyms.
386 static struct parm_struct parm_table[] = {
387 {"Base Options", P_SEP, P_SEPARATOR},
389 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
391 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
394 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
395 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
396 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
397 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
398 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
402 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
403 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
404 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
406 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
407 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
408 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
409 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
411 {"Security Options", P_SEP, P_SEPARATOR},
413 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
414 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
415 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
416 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
419 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
430 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
431 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
433 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
435 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
436 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
438 {"Logging Options", P_SEP, P_SEPARATOR},
440 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
442 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"Protocol Options", P_SEP, P_SEPARATOR},
446 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
460 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
461 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
462 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
463 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
464 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
465 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
467 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
470 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
471 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
472 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
475 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
477 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
478 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
479 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
480 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
481 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
482 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
484 {"Tuning Options", P_SEP, P_SEPARATOR},
486 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
487 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
488 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
490 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
491 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
493 {"Printing Options", P_SEP, P_SEPARATOR},
495 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
496 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
497 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
499 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
500 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
502 {"Filename Handling", P_SEP, P_SEPARATOR},
504 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
505 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
506 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
508 {"Domain Options", P_SEP, P_SEPARATOR},
510 {"Logon Options", P_SEP, P_SEPARATOR},
513 {"Browse Options", P_SEP, P_SEPARATOR},
515 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
516 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
517 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
518 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
519 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
521 {"WINS Options", P_SEP, P_SEPARATOR},
523 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
524 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
526 {"Locking Options", P_SEP, P_SEPARATOR},
528 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
530 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
532 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
534 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
535 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
538 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
544 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
546 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
547 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
549 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
550 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
551 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
553 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
556 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
558 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
560 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
565 return the parameter table
567 struct parm_struct *lp_parm_table(void)
572 /***************************************************************************
573 Initialise the global parameter structure.
574 ***************************************************************************/
575 static void init_globals(void)
580 DEBUG(3, ("Initialising global parameters\n"));
582 for (i = 0; parm_table[i].label; i++) {
583 if ((parm_table[i].type == P_STRING ||
584 parm_table[i].type == P_USTRING) &&
586 !(parm_table[i].flags & FLAG_CMDLINE)) {
587 string_set(parm_table[i].ptr, "");
591 do_parameter("config file", dyn_CONFIGFILE, NULL);
593 do_parameter("server role", "standalone", NULL);
595 /* options that can be set on the command line must be initialised via
596 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
598 do_parameter("socket options", "TCP_NODELAY", NULL);
600 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
601 myname = get_myname();
602 do_parameter("netbios name", myname, NULL);
604 do_parameter("max protocol", "NT1", NULL);
605 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
607 do_parameter("fstype", FSTYPE_STRING, NULL);
608 do_parameter("ntvfs handler", "unixuid default", NULL);
609 do_parameter("max connections", "-1", NULL);
611 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
612 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc", NULL);
613 do_parameter("ntptr providor", "simple_ldb", NULL);
614 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
615 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
616 do_parameter("sam database", "sam.ldb", NULL);
617 do_parameter("spoolss database", "spoolss.ldb", NULL);
618 do_parameter("wins config database", "wins_config.ldb", NULL);
619 do_parameter("wins database", "wins.ldb", NULL);
620 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
622 /* This hive should be dynamically generated by Samba using
623 data from the sam, but for the moment leave it in a tdb to
624 keep regedt32 from popping up an annoying dialog. */
625 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
627 /* using UTF8 by default allows us to support all chars */
628 do_parameter("unix charset", "UTF8", NULL);
630 /* Use codepage 850 as a default for the dos character set */
631 do_parameter("dos charset", "CP850", NULL);
634 * Allow the default PASSWD_CHAT to be overridden in local.h.
636 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
638 do_parameter("pid directory", dyn_PIDDIR, NULL);
639 do_parameter("lock dir", dyn_LOCKDIR, NULL);
640 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
642 do_parameter("socket address", "0.0.0.0", NULL);
643 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
645 do_parameter_var("announce version", "%d.%d",
646 DEFAULT_MAJOR_VERSION,
647 DEFAULT_MINOR_VERSION);
649 do_parameter("password server", "*", NULL);
651 do_parameter("max mux", "50", NULL);
652 do_parameter("max xmit", "12288", NULL);
653 do_parameter("password level", "0", NULL);
654 do_parameter("LargeReadwrite", "True", NULL);
655 do_parameter("minprotocol", "CORE", NULL);
656 do_parameter("security", "USER", NULL);
657 do_parameter("paranoid server security", "True", NULL);
658 do_parameter("EncryptPasswords", "True", NULL);
659 do_parameter("ReadRaw", "True", NULL);
660 do_parameter("WriteRaw", "True", NULL);
661 do_parameter("NullPasswords", "False", NULL);
662 do_parameter("ObeyPamRestrictions", "False", NULL);
663 do_parameter("announce as", "NT SERVER", NULL);
665 do_parameter("TimeServer", "False", NULL);
666 do_parameter("BindInterfacesOnly", "False", NULL);
667 do_parameter("Unicode", "True", NULL);
668 do_parameter("ClientLanManAuth", "True", NULL);
669 do_parameter("LanmanAuth", "True", NULL);
670 do_parameter("NTLMAuth", "True", NULL);
671 do_parameter("client use spnego principal", "False", NULL);
673 do_parameter("UnixExtensions", "False", NULL);
675 do_parameter("PreferredMaster", "Auto", NULL);
676 do_parameter("LocalMaster", "True", NULL);
678 do_parameter("WINSsupport", "False", NULL);
680 do_parameter("winbind separator", "\\", NULL);
681 do_parameter("winbind sealed pipes", "True", NULL);
683 do_parameter("client signing", "Yes", NULL);
684 do_parameter("server signing", "auto", NULL);
686 do_parameter("use spnego", "True", NULL);
688 do_parameter("smb ports", SMB_PORTS, NULL);
689 do_parameter("nbt port", "137", NULL);
690 do_parameter("dgram port", "138", NULL);
691 do_parameter("cldap port", "389", NULL);
692 do_parameter("krb5 port", "88", NULL);
693 do_parameter("kpasswd port", "464", NULL);
694 do_parameter("web port", "901", NULL);
695 do_parameter("swat directory", dyn_SWATDIR, NULL);
697 do_parameter("nt status support", "True", NULL);
699 do_parameter("max wins ttl", "432000", NULL);
700 do_parameter("min wins ttl", "10", NULL);
702 do_parameter("tls enabled", "True", NULL);
703 do_parameter("tls keyfile", "tls/key.pem", NULL);
704 do_parameter("tls certfile", "tls/cert.pem", NULL);
705 do_parameter("tls cafile", "tls/ca.pem", NULL);
706 do_parameter_var("js include", "%s/js", dyn_LIBDIR);
707 do_parameter_var("setup directory", "%s/setup", dyn_LIBDIR);
710 static TALLOC_CTX *lp_talloc;
712 /******************************************************************* a
713 Free up temporary memory - called from the main loop.
714 ********************************************************************/
716 void lp_talloc_free(void)
720 talloc_free(lp_talloc);
724 /*******************************************************************
725 Convenience routine to grab string parameters into temporary memory
726 and run standard_sub_basic on them. The buffers can be written to by
727 callers without affecting the source string.
728 ********************************************************************/
730 static const char *lp_string(const char *s)
732 #if 0 /* until REWRITE done to make thread-safe */
733 size_t len = s ? strlen(s) : 0;
737 /* The follow debug is useful for tracking down memory problems
738 especially if you have an inner loop that is calling a lp_*()
739 function that returns a string. Perhaps this debug should be
740 present all the time? */
743 DEBUG(10, ("lp_string(%s)\n", s));
746 #if 0 /* until REWRITE done to make thread-safe */
748 lp_talloc = talloc_init("lp_talloc");
750 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
758 StrnCpy(ret, s, len);
760 if (trim_string(ret, "\"", "\"")) {
761 if (strchr(ret,'"') != NULL)
762 StrnCpy(ret, s, len);
765 standard_sub_basic(ret,len+100);
772 In this section all the functions that are used to access the
773 parameters from the rest of the program are defined
776 #define FN_GLOBAL_STRING(fn_name,ptr) \
777 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
778 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
779 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
780 #define FN_GLOBAL_LIST(fn_name,ptr) \
781 const char **fn_name(void) {return(*(const char ***)(ptr));}
782 #define FN_GLOBAL_BOOL(fn_name,ptr) \
783 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
784 #define FN_GLOBAL_CHAR(fn_name,ptr) \
785 char fn_name(void) {return(*(char *)(ptr));}
786 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
787 int fn_name(void) {return(*(int *)(ptr));}
789 #define FN_LOCAL_STRING(fn_name,val) \
790 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
791 #define FN_LOCAL_CONST_STRING(fn_name,val) \
792 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
793 #define FN_LOCAL_LIST(fn_name,val) \
794 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
795 #define FN_LOCAL_BOOL(fn_name,val) \
796 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
797 #define FN_LOCAL_CHAR(fn_name,val) \
798 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
799 #define FN_LOCAL_INTEGER(fn_name,val) \
800 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
802 FN_GLOBAL_INTEGER(lp_server_role, &Globals.server_role)
803 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
804 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
805 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
806 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
807 FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
808 FN_GLOBAL_INTEGER(lp_kpasswd_port, &Globals.kpasswd_port)
809 FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
810 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
811 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
812 FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
813 FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
814 FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
815 FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
816 FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
817 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
818 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
819 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
820 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
821 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
822 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
823 FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL)
824 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
825 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
826 FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
827 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
828 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
829 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
830 FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
831 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
832 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
833 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
834 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
835 FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
836 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
837 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
838 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
839 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
840 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
841 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
842 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
843 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
844 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
845 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
846 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
847 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
848 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
849 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
851 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
852 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
853 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
854 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
855 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
856 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
857 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
858 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
859 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
860 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
861 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
862 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
863 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
864 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
865 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
866 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
867 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
868 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
869 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
870 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
871 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
872 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
873 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
874 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
875 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
876 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
877 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
878 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
879 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
880 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
881 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
882 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
883 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
884 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
885 FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
888 FN_LOCAL_STRING(lp_servicename, szService)
889 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
890 FN_LOCAL_STRING(lp_pathname, szPath)
891 static FN_LOCAL_STRING(_lp_printername, szPrintername)
892 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
893 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
894 FN_LOCAL_STRING(lp_comment, comment)
895 FN_LOCAL_STRING(lp_fstype, fstype)
896 static FN_LOCAL_STRING(lp_volume, volume)
897 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
898 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
899 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
900 FN_LOCAL_BOOL(lp_readonly, bRead_only)
901 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
902 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
903 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
904 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
905 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
906 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
907 FN_LOCAL_BOOL(lp_map_system, bMap_system)
908 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
909 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
910 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
911 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
913 /* local prototypes */
915 static int map_parameter(const char *pszParmName);
916 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
917 static int getservicebyname(const char *pszServiceName,
918 service * pserviceDest);
919 static void copy_service(service * pserviceDest,
920 service * pserviceSource, BOOL *pcopymapDest);
921 static BOOL service_ok(int iService);
922 static BOOL do_section(const char *pszSectionName, void *);
923 static void init_copymap(service * pservice);
925 /* This is a helper function for parametrical options support. */
926 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
927 /* Actual parametrical functions are quite simple */
928 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
931 struct param_opt *data;
933 if (lookup_service >= iNumServices) return NULL;
935 data = (lookup_service < 0) ?
936 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
938 asprintf(&vfskey, "%s:%s", type, option);
942 if (strcmp(data->key, vfskey) == 0) {
949 if (lookup_service >= 0) {
950 /* Try to fetch the same option but from globals */
951 /* but only if we are not already working with Globals */
952 data = Globals.param_opt;
954 if (strcmp(data->key, vfskey) == 0) {
968 /*******************************************************************
969 convenience routine to return int parameters.
970 ********************************************************************/
971 static int lp_int(const char *s)
975 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
979 return strtol(s, NULL, 0);
982 /*******************************************************************
983 convenience routine to return unsigned long parameters.
984 ********************************************************************/
985 static int lp_ulong(const char *s)
989 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
993 return strtoul(s, NULL, 0);
996 /*******************************************************************
997 convenience routine to return boolean parameters.
998 ********************************************************************/
999 static BOOL lp_bool(const char *s)
1004 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1008 if (!set_boolean(&ret,s)) {
1009 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
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(int lookup_service, const char *type, const char *option)
1023 const char *value = lp_get_parametric(lookup_service, type, option);
1026 return lp_string(value);
1031 /* Return parametric option from a given service. Type is a part of option before ':' */
1032 /* Parametric option has following syntax: 'Type: option = value' */
1033 /* Returned value is allocated in 'lp_talloc' context */
1035 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1036 const char *separator)
1038 const char *value = lp_get_parametric(lookup_service, type, option);
1041 return str_list_make(talloc_autofree_context(), value, separator);
1046 /* Return parametric option from a given service. Type is a part of option before ':' */
1047 /* Parametric option has following syntax: 'Type: option = value' */
1049 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1051 const char *value = lp_get_parametric(lookup_service, type, option);
1054 return lp_int(value);
1059 /* Return parametric option from a given service. Type is a part of option before ':' */
1060 /* Parametric option has following syntax: 'Type: option = value' */
1062 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1064 const char *value = lp_get_parametric(lookup_service, type, option);
1067 return lp_ulong(value);
1072 /* Return parametric option from a given service. Type is a part of option before ':' */
1073 /* Parametric option has following syntax: 'Type: option = value' */
1075 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1077 const char *value = lp_get_parametric(lookup_service, type, option);
1080 return lp_bool(value);
1086 /***************************************************************************
1087 Initialise a service to the defaults.
1088 ***************************************************************************/
1090 static void init_service(service * pservice)
1092 memset((char *)pservice, '\0', sizeof(service));
1093 copy_service(pservice, &sDefault, NULL);
1096 /***************************************************************************
1097 Free the dynamically allocated parts of a service struct.
1098 ***************************************************************************/
1100 static void free_service(service *pservice)
1103 struct param_opt *data, *pdata;
1107 if (pservice->szService)
1108 DEBUG(5, ("free_service: Freeing service %s\n",
1109 pservice->szService));
1111 string_free(&pservice->szService);
1112 SAFE_FREE(pservice->copymap);
1114 for (i = 0; parm_table[i].label; i++) {
1115 if ((parm_table[i].type == P_STRING ||
1116 parm_table[i].type == P_USTRING) &&
1117 parm_table[i].class == P_LOCAL) {
1118 string_free((char **)
1119 (((char *)pservice) +
1120 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1121 } else if (parm_table[i].type == P_LIST &&
1122 parm_table[i].class == P_LOCAL) {
1123 char ***listp = (char ***)(((char *)pservice) +
1124 PTR_DIFF(parm_table[i].ptr, &sDefault));
1125 talloc_free(*listp);
1130 DEBUG(5,("Freeing parametrics:\n"));
1131 data = pservice->param_opt;
1133 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1134 string_free(&data->key);
1135 string_free(&data->value);
1141 ZERO_STRUCTP(pservice);
1144 /***************************************************************************
1145 Add a new service to the services array initialising it with the given
1147 ***************************************************************************/
1149 static int add_a_service(const service *pservice, const char *name)
1153 int num_to_alloc = iNumServices + 1;
1154 struct param_opt *data, *pdata;
1156 tservice = *pservice;
1158 /* it might already exist */
1160 i = getservicebyname(name, NULL);
1162 /* Clean all parametric options for service */
1163 /* They will be added during parsing again */
1164 data = ServicePtrs[i]->param_opt;
1166 string_free(&data->key);
1167 string_free(&data->value);
1172 ServicePtrs[i]->param_opt = NULL;
1177 /* find an invalid one */
1178 for (i = 0; i < iNumServices; i++)
1179 if (!ServicePtrs[i]->valid)
1182 /* if not, then create one */
1183 if (i == iNumServices) {
1186 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1189 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1194 ServicePtrs[iNumServices] = malloc_p(service);
1196 if (!ServicePtrs[iNumServices]) {
1197 DEBUG(0,("add_a_service: out of memory!\n"));
1203 free_service(ServicePtrs[i]);
1205 ServicePtrs[i]->valid = True;
1207 init_service(ServicePtrs[i]);
1208 copy_service(ServicePtrs[i], &tservice, NULL);
1210 string_set(&ServicePtrs[i]->szService, name);
1214 /***************************************************************************
1215 Add a new home service, with the specified home directory, defaults coming
1217 ***************************************************************************/
1219 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1220 const char *user, const char *pszHomedir)
1225 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1230 if (!(*(ServicePtrs[iDefaultService]->szPath))
1231 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1232 pstrcpy(newHomedir, pszHomedir);
1234 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1235 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1238 string_set(&ServicePtrs[i]->szPath, newHomedir);
1240 if (!(*(ServicePtrs[i]->comment))) {
1242 slprintf(comment, sizeof(comment) - 1,
1243 "Home directory of %s", user);
1244 string_set(&ServicePtrs[i]->comment, comment);
1246 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1247 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1249 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1255 /***************************************************************************
1256 Add a new service, based on an old one.
1257 ***************************************************************************/
1259 int lp_add_service(const char *pszService, int iDefaultService)
1261 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1264 /***************************************************************************
1265 Add the IPC service.
1266 ***************************************************************************/
1268 static BOOL lp_add_hidden(const char *name, const char *fstype)
1271 int i = add_a_service(&sDefault, name);
1276 slprintf(comment, sizeof(comment) - 1,
1277 "%s Service (%s)", fstype, Globals.szServerString);
1279 string_set(&ServicePtrs[i]->szPath, tmpdir());
1280 string_set(&ServicePtrs[i]->comment, comment);
1281 string_set(&ServicePtrs[i]->fstype, fstype);
1282 ServicePtrs[i]->iMaxConnections = -1;
1283 ServicePtrs[i]->bAvailable = True;
1284 ServicePtrs[i]->bRead_only = True;
1285 ServicePtrs[i]->bPrint_ok = False;
1286 ServicePtrs[i]->bBrowseable = False;
1288 if (strcasecmp(fstype, "IPC") == 0) {
1289 lp_do_parameter(i, "ntvfs handler", "default");
1292 DEBUG(3, ("adding hidden service %s\n", name));
1297 /***************************************************************************
1298 Add a new printer service, with defaults coming from service iFrom.
1299 ***************************************************************************/
1301 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1303 const char *comment = "From Printcap";
1304 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1309 /* note that we do NOT default the availability flag to True - */
1310 /* we take it from the default service passed. This allows all */
1311 /* dynamic printers to be disabled by disabling the [printers] */
1312 /* entry (if/when the 'available' keyword is implemented!). */
1314 /* the printer name is set to the service name. */
1315 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1316 string_set(&ServicePtrs[i]->comment, comment);
1317 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1318 /* Printers cannot be read_only. */
1319 ServicePtrs[i]->bRead_only = False;
1320 /* Printer services must be printable. */
1321 ServicePtrs[i]->bPrint_ok = True;
1323 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1325 update_server_announce_as_printserver();
1330 /***************************************************************************
1331 Map a parameter's string representation to something we can use.
1332 Returns False if the parameter string is not recognised, else TRUE.
1333 ***************************************************************************/
1335 static int map_parameter(const char *pszParmName)
1339 if (*pszParmName == '-')
1342 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1343 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1346 /* Warn only if it isn't parametric option */
1347 if (strchr(pszParmName, ':') == NULL)
1348 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1349 /* We do return 'fail' for parametric options as well because they are
1350 stored in different storage
1357 return the parameter structure for a parameter
1359 struct parm_struct *lp_parm_struct(const char *name)
1361 int parmnum = map_parameter(name);
1362 if (parmnum == -1) return NULL;
1363 return &parm_table[parmnum];
1367 return the parameter pointer for a parameter
1369 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1374 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1377 /***************************************************************************
1378 Set a boolean variable from the text value stored in the passed string.
1379 Returns True in success, False if the passed string does not correctly
1380 represent a boolean.
1381 ***************************************************************************/
1383 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1388 if (strwicmp(pszParmValue, "yes") == 0 ||
1389 strwicmp(pszParmValue, "true") == 0 ||
1390 strwicmp(pszParmValue, "1") == 0)
1392 else if (strwicmp(pszParmValue, "no") == 0 ||
1393 strwicmp(pszParmValue, "False") == 0 ||
1394 strwicmp(pszParmValue, "0") == 0)
1398 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1405 /***************************************************************************
1406 Find a service by name. Otherwise works like get_service.
1407 ***************************************************************************/
1409 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1413 for (iService = iNumServices - 1; iService >= 0; iService--)
1414 if (VALID(iService) &&
1415 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1416 if (pserviceDest != NULL)
1417 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1424 /***************************************************************************
1425 Copy a service structure to another.
1426 If pcopymapDest is NULL then copy all fields
1427 ***************************************************************************/
1429 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1432 BOOL bcopyall = (pcopymapDest == NULL);
1433 struct param_opt *data, *pdata, *paramo;
1436 for (i = 0; parm_table[i].label; i++)
1437 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1438 (bcopyall || pcopymapDest[i])) {
1439 void *def_ptr = parm_table[i].ptr;
1441 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1444 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1447 switch (parm_table[i].type) {
1449 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1454 *(int *)dest_ptr = *(int *)src_ptr;
1458 string_set(dest_ptr,
1463 string_set(dest_ptr,
1465 strupper(*(char **)dest_ptr);
1468 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1469 *(const char ***)src_ptr);
1477 init_copymap(pserviceDest);
1478 if (pserviceSource->copymap)
1479 memcpy((void *)pserviceDest->copymap,
1480 (void *)pserviceSource->copymap,
1481 sizeof(BOOL) * NUMPARAMETERS);
1484 data = pserviceSource->param_opt;
1487 pdata = pserviceDest->param_opt;
1488 /* Traverse destination */
1490 /* If we already have same option, override it */
1491 if (strcmp(pdata->key, data->key) == 0) {
1492 string_free(&pdata->value);
1493 pdata->value = strdup(data->value);
1497 pdata = pdata->next;
1500 paramo = malloc_p(struct param_opt);
1503 paramo->key = strdup(data->key);
1504 paramo->value = strdup(data->value);
1505 DLIST_ADD(pserviceDest->param_opt, paramo);
1511 /***************************************************************************
1512 Check a service for consistency. Return False if the service is in any way
1513 incomplete or faulty, else True.
1514 ***************************************************************************/
1516 static BOOL service_ok(int iService)
1521 if (ServicePtrs[iService]->szService[0] == '\0') {
1522 DEBUG(0, ("The following message indicates an internal error:\n"));
1523 DEBUG(0, ("No service name in service entry.\n"));
1527 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1528 /* I can't see why you'd want a non-printable printer service... */
1529 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1530 if (!ServicePtrs[iService]->bPrint_ok) {
1531 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1532 ServicePtrs[iService]->szService));
1533 ServicePtrs[iService]->bPrint_ok = True;
1534 update_server_announce_as_printserver();
1536 /* [printers] service must also be non-browsable. */
1537 if (ServicePtrs[iService]->bBrowseable)
1538 ServicePtrs[iService]->bBrowseable = False;
1541 /* If a service is flagged unavailable, log the fact at level 0. */
1542 if (!ServicePtrs[iService]->bAvailable)
1543 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1544 ServicePtrs[iService]->szService));
1549 static struct file_lists {
1550 struct file_lists *next;
1554 } *file_lists = NULL;
1556 /*******************************************************************
1557 Keep a linked list of all config files so we know when one has changed
1558 it's date and needs to be reloaded.
1559 ********************************************************************/
1561 static void add_to_file_list(const char *fname, const char *subfname)
1563 struct file_lists *f = file_lists;
1566 if (f->name && !strcmp(f->name, fname))
1572 f = malloc_p(struct file_lists);
1575 f->next = file_lists;
1576 f->name = strdup(fname);
1581 f->subfname = strdup(subfname);
1587 f->modtime = file_modtime(subfname);
1589 time_t t = file_modtime(subfname);
1595 /*******************************************************************
1596 Check if a config file has changed date.
1597 ********************************************************************/
1599 BOOL lp_file_list_changed(void)
1601 struct file_lists *f = file_lists;
1602 DEBUG(6, ("lp_file_list_changed()\n"));
1608 pstrcpy(n2, f->name);
1609 standard_sub_basic(n2,sizeof(n2));
1611 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1612 f->name, n2, ctime(&f->modtime)));
1614 mod_time = file_modtime(n2);
1616 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1618 ("file %s modified: %s\n", n2,
1620 f->modtime = mod_time;
1621 SAFE_FREE(f->subfname);
1622 f->subfname = strdup(n2);
1630 /***************************************************************************
1631 Handle the include operation.
1632 ***************************************************************************/
1634 static BOOL handle_include(const char *pszParmValue, char **ptr)
1637 pstrcpy(fname, pszParmValue);
1639 standard_sub_basic(fname,sizeof(fname));
1641 add_to_file_list(pszParmValue, fname);
1643 string_set(ptr, fname);
1645 if (file_exist(fname))
1646 return (pm_process(fname, do_section, do_parameter, NULL));
1648 DEBUG(2, ("Can't find include file %s\n", fname));
1653 /***************************************************************************
1654 Handle the interpretation of the copy parameter.
1655 ***************************************************************************/
1657 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1661 service serviceTemp;
1663 string_set(ptr, pszParmValue);
1665 init_service(&serviceTemp);
1669 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1671 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1672 if (iTemp == iServiceIndex) {
1673 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1675 copy_service(ServicePtrs[iServiceIndex],
1677 ServicePtrs[iServiceIndex]->copymap);
1681 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1685 free_service(&serviceTemp);
1689 /***************************************************************************
1690 Initialise a copymap.
1691 ***************************************************************************/
1693 static void init_copymap(service * pservice)
1696 SAFE_FREE(pservice->copymap);
1697 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
1698 if (!pservice->copymap)
1700 ("Couldn't allocate copymap!! (size %d)\n",
1701 (int)NUMPARAMETERS));
1703 for (i = 0; i < NUMPARAMETERS; i++)
1704 pservice->copymap[i] = True;
1707 /***************************************************************************
1708 Return the local pointer to a parameter given the service number and the
1709 pointer into the default structure.
1710 ***************************************************************************/
1712 void *lp_local_ptr(int snum, void *ptr)
1714 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1718 /***************************************************************************
1719 Process a parametric option
1720 ***************************************************************************/
1721 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1723 struct param_opt *paramo, *data;
1726 while (isspace((unsigned char)*pszParmName)) {
1730 name = strdup(pszParmName);
1731 if (!name) return False;
1736 data = Globals.param_opt;
1738 data = ServicePtrs[snum]->param_opt;
1741 /* Traverse destination */
1742 for (paramo=data; paramo; paramo=paramo->next) {
1743 /* If we already have the option set, override it unless
1744 it was a command line option and the new one isn't */
1745 if (strcmp(paramo->key, name) == 0) {
1746 if ((paramo->flags & FLAG_CMDLINE) &&
1747 !(flags & FLAG_CMDLINE)) {
1751 free(paramo->value);
1752 paramo->value = strdup(pszParmValue);
1753 paramo->flags = flags;
1759 paramo = malloc_p(struct param_opt);
1762 paramo->key = strdup(name);
1763 paramo->value = strdup(pszParmValue);
1764 paramo->flags = flags;
1766 DLIST_ADD(Globals.param_opt, paramo);
1768 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1776 /***************************************************************************
1777 Process a parameter for a particular service number. If snum < 0
1778 then assume we are in the globals.
1779 ***************************************************************************/
1780 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1783 void *parm_ptr = NULL; /* where we are going to store the result */
1784 void *def_ptr = NULL;
1786 parmnum = map_parameter(pszParmName);
1789 if (strchr(pszParmName, ':')) {
1790 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1792 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1796 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1797 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1801 /* if the flag has been set on the command line, then don't allow override,
1802 but don't report an error */
1803 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1807 def_ptr = parm_table[parmnum].ptr;
1809 /* we might point at a service, the default service or a global */
1813 if (parm_table[parmnum].class == P_GLOBAL) {
1815 ("Global parameter %s found in service section!\n",
1820 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1825 if (!ServicePtrs[snum]->copymap)
1826 init_copymap(ServicePtrs[snum]);
1828 /* this handles the aliases - set the copymap for other entries with
1829 the same data pointer */
1830 for (i = 0; parm_table[i].label; i++)
1831 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1832 ServicePtrs[snum]->copymap[i] = False;
1835 /* if it is a special case then go ahead */
1836 if (parm_table[parmnum].special) {
1837 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1841 /* now switch on the type of variable it is */
1842 switch (parm_table[parmnum].type)
1845 set_boolean(parm_ptr, pszParmValue);
1849 *(int *)parm_ptr = atoi(pszParmValue);
1853 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1854 pszParmValue, NULL);
1858 string_set(parm_ptr, pszParmValue);
1862 string_set(parm_ptr, pszParmValue);
1863 strupper(*(char **)parm_ptr);
1867 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1870 parm_table[parmnum].enum_list[i].name)) {
1872 parm_table[parmnum].
1877 if (!parm_table[parmnum].enum_list[i].name) {
1878 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1879 pszParmValue, pszParmName));
1890 /***************************************************************************
1891 Process a parameter.
1892 ***************************************************************************/
1894 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1896 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1897 pszParmName, pszParmValue));
1901 variable argument do parameter
1903 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1905 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1912 s = talloc_vasprintf(NULL, fmt, ap);
1914 ret = do_parameter(pszParmName, s, NULL);
1921 set a parameter from the commandline - this is called from command line parameter
1922 parsing code. It sets the parameter then marks the parameter as unable to be modified
1923 by smb.conf processing
1925 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1927 int parmnum = map_parameter(pszParmName);
1930 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1933 if (parmnum < 0 && strchr(pszParmName, ':')) {
1934 /* set a parametric option */
1935 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1939 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1943 /* reset the CMDLINE flag in case this has been called before */
1944 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1946 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1950 parm_table[parmnum].flags |= FLAG_CMDLINE;
1952 /* we have to also set FLAG_CMDLINE on aliases */
1953 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1954 parm_table[i].flags |= FLAG_CMDLINE;
1956 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1957 parm_table[i].flags |= FLAG_CMDLINE;
1964 set a option from the commandline in 'a=b' format. Use to support --option
1966 BOOL lp_set_option(const char *option)
1984 ret = lp_set_cmdline(s, p+1);
1990 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1992 /***************************************************************************
1993 Print a parameter of the specified type.
1994 ***************************************************************************/
1996 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2002 for (i = 0; p->enum_list[i].name; i++) {
2003 if (*(int *)ptr == p->enum_list[i].value) {
2005 p->enum_list[i].name);
2012 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2016 fprintf(f, "%d", *(int *)ptr);
2020 if ((char ***)ptr && *(char ***)ptr) {
2021 char **list = *(char ***)ptr;
2023 for (; *list; list++)
2024 fprintf(f, "%s%s", *list,
2025 ((*(list+1))?", ":""));
2031 if (*(char **)ptr) {
2032 fprintf(f, "%s", *(char **)ptr);
2040 /***************************************************************************
2041 Check if two parameters are equal.
2042 ***************************************************************************/
2044 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2048 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2052 return (*((int *)ptr1) == *((int *)ptr2));
2055 return str_list_equal((const char **)(*(char ***)ptr1),
2056 (const char **)(*(char ***)ptr2));
2061 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2066 return (p1 == p2 || strequal(p1, p2));
2074 /***************************************************************************
2075 Process a new section (service). At this stage all sections are services.
2076 Later we'll have special sections that permit server parameters to be set.
2077 Returns True on success, False on failure.
2078 ***************************************************************************/
2080 static BOOL do_section(const char *pszSectionName, void *userdata)
2083 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2084 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2087 /* if we've just struck a global section, note the fact. */
2088 bInGlobalSection = isglobal;
2090 /* check for multiple global sections */
2091 if (bInGlobalSection) {
2092 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2096 /* if we have a current service, tidy it up before moving on */
2099 if (iServiceIndex >= 0)
2100 bRetval = service_ok(iServiceIndex);
2102 /* if all is still well, move to the next record in the services array */
2104 /* We put this here to avoid an odd message order if messages are */
2105 /* issued by the post-processing of a previous section. */
2106 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2108 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2110 DEBUG(0, ("Failed to add a new service\n"));
2119 /***************************************************************************
2120 Determine if a partcular base parameter is currentl set to the default value.
2121 ***************************************************************************/
2123 static BOOL is_default(int i)
2125 if (!defaults_saved)
2127 switch (parm_table[i].type) {
2129 return str_list_equal((const char **)parm_table[i].def.lvalue,
2130 (const char **)(*(char ***)parm_table[i].ptr));
2133 return strequal(parm_table[i].def.svalue,
2134 *(char **)parm_table[i].ptr);
2136 return parm_table[i].def.bvalue ==
2137 *(BOOL *)parm_table[i].ptr;
2140 return parm_table[i].def.ivalue ==
2141 *(int *)parm_table[i].ptr;
2148 /***************************************************************************
2149 Display the contents of the global structure.
2150 ***************************************************************************/
2152 static void dump_globals(FILE *f)
2155 struct param_opt *data;
2157 fprintf(f, "# Global parameters\n[global]\n");
2159 for (i = 0; parm_table[i].label; i++)
2160 if (parm_table[i].class == P_GLOBAL &&
2161 parm_table[i].ptr &&
2162 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2163 if (defaults_saved && is_default(i))
2165 fprintf(f, "\t%s = ", parm_table[i].label);
2166 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2169 if (Globals.param_opt != NULL) {
2170 data = Globals.param_opt;
2172 fprintf(f, "\t%s = %s\n", data->key, data->value);
2179 /***************************************************************************
2180 Display the contents of a single services record.
2181 ***************************************************************************/
2183 static void dump_a_service(service * pService, FILE * f)
2186 struct param_opt *data;
2188 if (pService != &sDefault)
2189 fprintf(f, "\n[%s]\n", pService->szService);
2191 for (i = 0; parm_table[i].label; i++)
2192 if (parm_table[i].class == P_LOCAL &&
2193 parm_table[i].ptr &&
2194 (*parm_table[i].label != '-') &&
2195 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2196 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2198 if (pService == &sDefault) {
2199 if (defaults_saved && is_default(i))
2202 if (equal_parameter(parm_table[i].type,
2203 ((char *)pService) +
2205 ((char *)&sDefault) +
2210 fprintf(f, "\t%s = ", parm_table[i].label);
2211 print_parameter(&parm_table[i],
2212 ((char *)pService) + pdiff, f);
2215 if (pService->param_opt != NULL) {
2216 data = pService->param_opt;
2218 fprintf(f, "\t%s = %s\n", data->key, data->value);
2225 /***************************************************************************
2226 Return info about the next service in a service. snum==-1 gives the globals.
2227 Return NULL when out of parameters.
2228 ***************************************************************************/
2230 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2233 /* do the globals */
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].ptr
2239 || (*parm_table[*i].label == '-'))
2243 && (parm_table[*i].ptr ==
2244 parm_table[(*i) - 1].ptr))
2247 return &parm_table[(*i)++];
2250 service *pService = ServicePtrs[snum];
2252 for (; parm_table[*i].label; (*i)++) {
2253 if (parm_table[*i].class == P_SEPARATOR)
2254 return &parm_table[(*i)++];
2256 if (parm_table[*i].class == P_LOCAL &&
2257 parm_table[*i].ptr &&
2258 (*parm_table[*i].label != '-') &&
2260 (parm_table[*i].ptr !=
2261 parm_table[(*i) - 1].ptr)))
2264 PTR_DIFF(parm_table[*i].ptr,
2267 if (allparameters ||
2268 !equal_parameter(parm_table[*i].type,
2269 ((char *)pService) +
2271 ((char *)&sDefault) +
2274 return &parm_table[(*i)++];
2284 /***************************************************************************
2285 Return TRUE if the passed service number is within range.
2286 ***************************************************************************/
2288 BOOL lp_snum_ok(int iService)
2290 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2293 /***************************************************************************
2294 Auto-load some home services.
2295 ***************************************************************************/
2297 static void lp_add_auto_services(const char *str)
2302 /***************************************************************************
2303 Announce ourselves as a print server.
2304 ***************************************************************************/
2306 void update_server_announce_as_printserver(void)
2308 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2311 /***************************************************************************
2312 Have we loaded a services file yet?
2313 ***************************************************************************/
2315 BOOL lp_loaded(void)
2320 /***************************************************************************
2321 Unload unused services.
2322 ***************************************************************************/
2324 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2327 for (i = 0; i < iNumServices; i++) {
2331 if (!snumused || !snumused(smb, i)) {
2332 ServicePtrs[i]->valid = False;
2333 free_service(ServicePtrs[i]);
2338 /***************************************************************************
2340 ***************************************************************************/
2342 void lp_killservice(int iServiceIn)
2344 if (VALID(iServiceIn)) {
2345 ServicePtrs[iServiceIn]->valid = False;
2346 free_service(ServicePtrs[iServiceIn]);
2350 /***************************************************************************
2351 Load the services array from the services file. Return True on success,
2353 ***************************************************************************/
2359 struct param_opt *data;
2363 bInGlobalSection = True;
2365 if (Globals.param_opt != NULL) {
2366 struct param_opt *next;
2367 for (data=Globals.param_opt; data; data=next) {
2369 if (data->flags & FLAG_CMDLINE) continue;
2372 DLIST_REMOVE(Globals.param_opt, data);
2379 pstrcpy(n2, lp_configfile());
2380 standard_sub_basic(n2,sizeof(n2));
2381 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2383 add_to_file_list(lp_configfile(), n2);
2385 /* We get sections first, so have to start 'behind' to make up */
2387 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2389 /* finish up the last section */
2390 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2392 if (iServiceIndex >= 0)
2393 bRetval = service_ok(iServiceIndex);
2395 lp_add_auto_services(lp_auto_services());
2397 lp_add_hidden("IPC$", "IPC");
2398 lp_add_hidden("ADMIN$", "DISK");
2400 set_default_server_announce_type();
2404 if (Globals.bWINSsupport) {
2405 lp_do_parameter(-1, "wins server", "127.0.0.1");
2413 /***************************************************************************
2414 Reset the max number of services.
2415 ***************************************************************************/
2417 void lp_resetnumservices(void)
2422 /***************************************************************************
2423 Return the max number of services.
2424 ***************************************************************************/
2426 int lp_numservices(void)
2428 return (iNumServices);
2431 /***************************************************************************
2432 Display the contents of the services array in human-readable form.
2433 ***************************************************************************/
2435 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2440 defaults_saved = False;
2444 dump_a_service(&sDefault, f);
2446 for (iService = 0; iService < maxtoprint; iService++)
2447 lp_dump_one(f, show_defaults, iService);
2450 /***************************************************************************
2451 Display the contents of one service in human-readable form.
2452 ***************************************************************************/
2454 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2457 if (ServicePtrs[snum]->szService[0] == '\0')
2459 dump_a_service(ServicePtrs[snum], f);
2463 /***************************************************************************
2464 Return the number of the service with the given name, or -1 if it doesn't
2465 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2466 getservicebyname()! This works ONLY if all services have been loaded, and
2467 does not copy the found service.
2468 ***************************************************************************/
2470 int lp_servicenumber(const char *pszServiceName)
2473 fstring serviceName;
2476 for (iService = iNumServices - 1; iService >= 0; iService--) {
2477 if (VALID(iService) && ServicePtrs[iService]->szService) {
2479 * The substitution here is used to support %U is
2482 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2483 standard_sub_basic(serviceName,sizeof(serviceName));
2484 if (strequal(serviceName, pszServiceName))
2490 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2495 /*******************************************************************
2496 A useful volume label function.
2497 ********************************************************************/
2498 const char *volume_label(int snum)
2500 const char *ret = lp_volume(snum);
2502 return lp_servicename(snum);
2507 /*******************************************************************
2508 Set the server type we will announce as via nmbd.
2509 ********************************************************************/
2511 static void set_default_server_announce_type(void)
2513 default_server_announce = 0;
2514 default_server_announce |= SV_TYPE_WORKSTATION;
2515 default_server_announce |= SV_TYPE_SERVER;
2516 default_server_announce |= SV_TYPE_SERVER_UNIX;
2518 switch (lp_announce_as()) {
2519 case ANNOUNCE_AS_NT_SERVER:
2520 default_server_announce |= SV_TYPE_SERVER_NT;
2521 /* fall through... */
2522 case ANNOUNCE_AS_NT_WORKSTATION:
2523 default_server_announce |= SV_TYPE_NT;
2525 case ANNOUNCE_AS_WIN95:
2526 default_server_announce |= SV_TYPE_WIN95_PLUS;
2528 case ANNOUNCE_AS_WFW:
2529 default_server_announce |= SV_TYPE_WFW;
2535 switch (lp_server_role()) {
2536 case ROLE_DOMAIN_MEMBER:
2537 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2539 case ROLE_DOMAIN_PDC:
2540 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2542 case ROLE_DOMAIN_BDC:
2543 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2545 case ROLE_STANDALONE:
2549 if (lp_time_server())
2550 default_server_announce |= SV_TYPE_TIME_SOURCE;
2552 if (lp_host_msdfs())
2553 default_server_announce |= SV_TYPE_DFS_SERVER;
2555 /* TODO: only announce us as print server when we are a print server */
2556 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2559 /***********************************************************
2560 If we are PDC then prefer us as DMB
2561 ************************************************************/
2563 BOOL lp_domain_master(void)
2565 return (lp_server_role() == ROLE_DOMAIN_PDC);
2568 /***********************************************************
2569 If we are PDC then prefer us as DMB
2570 ************************************************************/
2572 BOOL lp_domain_logons(void)
2574 return (lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC);
2577 /***********************************************************
2578 If we are DMB then prefer us as LMB
2579 ************************************************************/
2581 BOOL lp_preferred_master(void)
2583 return (lp_local_master() && lp_domain_master());
2586 /*******************************************************************
2588 ********************************************************************/
2590 void lp_remove_service(int snum)
2592 ServicePtrs[snum]->valid = False;
2595 /*******************************************************************
2597 ********************************************************************/
2599 void lp_copy_service(int snum, const char *new_name)
2601 const char *oldname = lp_servicename(snum);
2602 do_section(new_name, NULL);
2604 snum = lp_servicenumber(new_name);
2606 lp_do_parameter(snum, "copy", oldname);
2611 /*******************************************************************
2612 Get the default server type we will announce as via nmbd.
2613 ********************************************************************/
2614 int lp_default_server_announce(void)
2616 return default_server_announce;
2619 const char *lp_printername(int snum)
2621 const char *ret = _lp_printername(snum);
2622 if (ret == NULL || (ret != NULL && *ret == '\0'))
2623 ret = lp_const_servicename(snum);
2629 /*******************************************************************
2630 Return the max print jobs per queue.
2631 ********************************************************************/
2633 int lp_maxprintjobs(int snum)
2635 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2636 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2637 maxjobs = PRINT_MAX_JOBID - 1;