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
58 #include "dynconfig.h"
60 #include "system/time.h"
61 #include "system/iconv.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "dlinklist.h"
65 #include "param/loadparm.h"
67 static BOOL bLoaded = False;
69 /* some helpful bits */
70 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
71 #define VALID(i) ServicePtrs[i]->valid
73 static BOOL do_parameter(const char *, const char *, void *);
74 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
76 static BOOL defaults_saved = False;
80 struct param_opt *prev, *next;
87 * This structure describes global (ie., server-wide) parameters.
97 char *display_charset;
101 char *szServerString;
102 char *szAutoServices;
108 char *szWINS_CONFIG_URL;
112 char **szPasswordServers;
113 char *szSocketOptions;
115 char **szWINSservers;
117 char *szSocketAddress;
118 char *szAnnounceVersion; /* This is initialised in init_globals */
121 char **szNetbiosAliases;
122 char *szNetbiosScope;
123 char *szDomainOtherSIDs;
124 char **szNameResolveOrder;
126 char **dcerpc_ep_servers;
127 char **server_services;
128 char *ntptr_providor;
129 char *szWinbindSeparator;
130 char *szWinbinddSocketDirectory;
131 BOOL bWinbindSealedPipes;
132 char *swat_directory;
145 BOOL paranoid_server_security;
148 int announce_as; /* This is initialised in init_globals */
155 char *socket_options;
160 BOOL bPreferredMaster;
161 BOOL bEncryptPasswords;
163 BOOL bObeyPamRestrictions;
164 BOOL bLargeReadwrite;
168 BOOL bBindInterfacesOnly;
170 BOOL bNTStatusSupport;
176 BOOL bClientPlaintextAuth;
177 BOOL bClientLanManAuth;
178 BOOL bClientNTLMv2Auth;
179 BOOL client_use_spnego_principal;
182 BOOL bUnixExtensions;
183 BOOL bDisableNetbios;
185 struct param_opt *param_opt;
189 static global Globals;
192 * This structure describes a single service.
207 char **ntvfs_handler;
223 struct param_opt *param_opt;
225 char dummy[3]; /* for alignment */
230 /* This is a default service used to prime a services structure */
231 static service sDefault = {
233 NULL, /* szService */
236 NULL, /* szInclude */
237 NULL, /* szPrintername */
238 NULL, /* szHostsallow */
239 NULL, /* szHostsdeny */
243 NULL, /* ntvfs_handler */
244 1000, /* iMaxPrintJobs */
245 0, /* iMaxConnections */
247 True, /* bAvailable */
248 True, /* bBrowseable */
249 True, /* bRead_only */
250 False, /* bPrint_ok */
251 False, /* bMap_system */
252 False, /* bMap_hidden */
253 True, /* bMap_archive */
254 True, /* bStrictLocking */
256 False, /* bMSDfsRoot */
257 False, /* bStrictSync */
258 False, /* bCIFileSystem */
259 NULL, /* Parametric options */
264 /* local variables */
265 static service **ServicePtrs = NULL;
266 static int iNumServices = 0;
267 static int iServiceIndex = 0;
268 static BOOL bInGlobalSection = True;
269 static int default_server_announce;
271 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
273 /* prototypes for the special type handlers */
274 static BOOL handle_include(const char *pszParmValue, char **ptr);
275 static BOOL handle_copy(const char *pszParmValue, char **ptr);
277 static void set_default_server_announce_type(void);
279 static const struct enum_list enum_protocol[] = {
280 {PROTOCOL_NT1, "NT1"},
281 {PROTOCOL_LANMAN2, "LANMAN2"},
282 {PROTOCOL_LANMAN1, "LANMAN1"},
283 {PROTOCOL_CORE, "CORE"},
284 {PROTOCOL_COREPLUS, "COREPLUS"},
285 {PROTOCOL_COREPLUS, "CORE+"},
289 static const struct enum_list enum_security[] = {
290 {SEC_SHARE, "SHARE"},
295 /* Types of machine we can announce as. */
296 #define ANNOUNCE_AS_NT_SERVER 1
297 #define ANNOUNCE_AS_WIN95 2
298 #define ANNOUNCE_AS_WFW 3
299 #define ANNOUNCE_AS_NT_WORKSTATION 4
301 static const struct enum_list enum_announce_as[] = {
302 {ANNOUNCE_AS_NT_SERVER, "NT"},
303 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
304 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
305 {ANNOUNCE_AS_WIN95, "win95"},
306 {ANNOUNCE_AS_WFW, "WfW"},
310 static const struct enum_list enum_bool_auto[] = {
321 /* Client-side offline caching policy types */
322 #define CSC_POLICY_MANUAL 0
323 #define CSC_POLICY_DOCUMENTS 1
324 #define CSC_POLICY_PROGRAMS 2
325 #define CSC_POLICY_DISABLE 3
327 static const struct enum_list enum_csc_policy[] = {
328 {CSC_POLICY_MANUAL, "manual"},
329 {CSC_POLICY_DOCUMENTS, "documents"},
330 {CSC_POLICY_PROGRAMS, "programs"},
331 {CSC_POLICY_DISABLE, "disable"},
335 /* SMB signing types. */
336 static const struct enum_list enum_smb_signing_vals[] = {
337 {SMB_SIGNING_OFF, "No"},
338 {SMB_SIGNING_OFF, "False"},
339 {SMB_SIGNING_OFF, "0"},
340 {SMB_SIGNING_OFF, "Off"},
341 {SMB_SIGNING_OFF, "disabled"},
342 {SMB_SIGNING_SUPPORTED, "Yes"},
343 {SMB_SIGNING_SUPPORTED, "True"},
344 {SMB_SIGNING_SUPPORTED, "1"},
345 {SMB_SIGNING_SUPPORTED, "On"},
346 {SMB_SIGNING_SUPPORTED, "enabled"},
347 {SMB_SIGNING_REQUIRED, "required"},
348 {SMB_SIGNING_REQUIRED, "mandatory"},
349 {SMB_SIGNING_REQUIRED, "force"},
350 {SMB_SIGNING_REQUIRED, "forced"},
351 {SMB_SIGNING_REQUIRED, "enforced"},
352 {SMB_SIGNING_AUTO, "auto"},
356 static const struct enum_list enum_server_role[] = {
357 {ROLE_STANDALONE, "standalone"},
358 {ROLE_DOMAIN_MEMBER, "member server"},
359 {ROLE_DOMAIN_BDC, "bdc"},
360 {ROLE_DOMAIN_PDC, "pdc"},
365 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
367 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
368 * is implied in current control logic. This may change at some later time. A
369 * flag value of 0 means - show as development option only.
371 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
372 * screen in SWAT. This is used to exclude parameters as well as to squash all
373 * parameters that have been duplicated by pseudonyms.
375 static struct parm_struct parm_table[] = {
376 {"Base Options", P_SEP, P_SEPARATOR},
378 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
380 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
381 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
382 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
383 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
384 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
385 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
386 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
387 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
388 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
389 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
390 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
391 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
394 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
396 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
397 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
398 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
400 {"Security Options", P_SEP, P_SEPARATOR},
402 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
403 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
404 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
406 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
407 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
408 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
409 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
410 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
412 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
424 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
425 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
427 {"Logging Options", P_SEP, P_SEPARATOR},
429 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
430 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
431 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
433 {"Protocol Options", P_SEP, P_SEPARATOR},
435 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
436 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
437 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
438 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
439 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
449 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
450 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
451 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
452 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
453 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
454 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
459 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
460 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
461 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
463 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
464 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
465 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
466 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
467 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
468 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
469 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
470 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
471 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
473 {"Tuning Options", P_SEP, P_SEPARATOR},
475 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
476 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
477 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
479 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
480 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
482 {"Printing Options", P_SEP, P_SEPARATOR},
484 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
485 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
486 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
488 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
489 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
491 {"Filename Handling", P_SEP, P_SEPARATOR},
493 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
494 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
495 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
497 {"Domain Options", P_SEP, P_SEPARATOR},
499 {"Logon Options", P_SEP, P_SEPARATOR},
502 {"Browse Options", P_SEP, P_SEPARATOR},
504 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
505 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
506 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
507 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
508 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
510 {"WINS Options", P_SEP, P_SEPARATOR},
512 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
513 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
514 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
515 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
517 {"Locking Options", P_SEP, P_SEPARATOR},
519 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
521 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
523 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
525 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
526 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
527 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
528 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
529 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
530 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
531 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
532 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
535 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
537 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
538 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
540 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
541 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
542 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
544 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
547 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
549 {"winbindd socket directory", P_STRING, P_GLOBAL, &Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
550 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
552 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
557 return the parameter table
559 struct parm_struct *lp_parm_table(void)
564 /***************************************************************************
565 Initialise the global parameter structure.
566 ***************************************************************************/
567 static void init_globals(void)
572 DEBUG(3, ("Initialising global parameters\n"));
574 for (i = 0; parm_table[i].label; i++) {
575 if ((parm_table[i].type == P_STRING ||
576 parm_table[i].type == P_USTRING) &&
578 !(parm_table[i].flags & FLAG_CMDLINE)) {
579 string_set(parm_table[i].ptr, "");
583 do_parameter("config file", dyn_CONFIGFILE, NULL);
585 do_parameter("server role", "standalone", NULL);
587 /* options that can be set on the command line must be initialised via
588 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
590 do_parameter("socket options", "TCP_NODELAY", NULL);
592 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
593 myname = get_myname();
594 do_parameter("netbios name", myname, NULL);
596 do_parameter("max protocol", "NT1", NULL);
597 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
599 do_parameter("fstype", FSTYPE_STRING, NULL);
600 do_parameter("ntvfs handler", "unixuid default", NULL);
601 do_parameter("max connections", "-1", NULL);
603 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
604 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc winbind", NULL);
605 do_parameter("ntptr providor", "simple_ldb", NULL);
606 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
607 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
608 do_parameter("sam database", "sam.ldb", NULL);
609 do_parameter("spoolss database", "spoolss.ldb", NULL);
610 do_parameter("wins config database", "wins_config.ldb", NULL);
611 do_parameter("wins database", "wins.ldb", NULL);
612 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
614 /* This hive should be dynamically generated by Samba using
615 data from the sam, but for the moment leave it in a tdb to
616 keep regedt32 from popping up an annoying dialog. */
617 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
619 /* using UTF8 by default allows us to support all chars */
620 do_parameter("unix charset", "UTF8", NULL);
622 /* Use codepage 850 as a default for the dos character set */
623 do_parameter("dos charset", "CP850", NULL);
626 * Allow the default PASSWD_CHAT to be overridden in local.h.
628 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
630 do_parameter("pid directory", dyn_PIDDIR, NULL);
631 do_parameter("lock dir", dyn_LOCKDIR, NULL);
632 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
634 do_parameter("socket address", "0.0.0.0", NULL);
635 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
637 do_parameter_var("announce version", "%d.%d",
638 DEFAULT_MAJOR_VERSION,
639 DEFAULT_MINOR_VERSION);
641 do_parameter("password server", "*", NULL);
643 do_parameter("max mux", "50", NULL);
644 do_parameter("max xmit", "12288", NULL);
645 do_parameter("password level", "0", NULL);
646 do_parameter("LargeReadwrite", "True", NULL);
647 do_parameter("minprotocol", "CORE", NULL);
648 do_parameter("security", "USER", NULL);
649 do_parameter("paranoid server security", "True", NULL);
650 do_parameter("EncryptPasswords", "True", NULL);
651 do_parameter("ReadRaw", "True", NULL);
652 do_parameter("WriteRaw", "True", NULL);
653 do_parameter("NullPasswords", "False", NULL);
654 do_parameter("ObeyPamRestrictions", "False", NULL);
655 do_parameter("announce as", "NT SERVER", NULL);
657 do_parameter("TimeServer", "False", NULL);
658 do_parameter("BindInterfacesOnly", "False", NULL);
659 do_parameter("Unicode", "True", NULL);
660 do_parameter("ClientLanManAuth", "True", NULL);
661 do_parameter("LanmanAuth", "True", NULL);
662 do_parameter("NTLMAuth", "True", NULL);
663 do_parameter("client use spnego principal", "False", NULL);
665 do_parameter("UnixExtensions", "False", NULL);
667 do_parameter("PreferredMaster", "Auto", NULL);
668 do_parameter("LocalMaster", "True", NULL);
670 do_parameter("wins support", "False", NULL);
671 do_parameter("dns proxy", "True", NULL);
673 do_parameter("winbind separator", "\\", NULL);
674 do_parameter("winbind sealed pipes", "True", NULL);
675 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR, NULL);
677 do_parameter("client signing", "Yes", NULL);
678 do_parameter("server signing", "auto", NULL);
680 do_parameter("use spnego", "True", NULL);
682 do_parameter("smb ports", SMB_PORTS, NULL);
683 do_parameter("nbt port", "137", NULL);
684 do_parameter("dgram port", "138", NULL);
685 do_parameter("cldap port", "389", NULL);
686 do_parameter("krb5 port", "88", NULL);
687 do_parameter("kpasswd port", "464", NULL);
688 do_parameter("web port", "901", NULL);
689 do_parameter("swat directory", dyn_SWATDIR, NULL);
691 do_parameter("nt status support", "True", NULL);
693 do_parameter("max wins ttl", "518400", NULL); /* 6 days */
694 do_parameter("min wins ttl", "10", NULL);
696 do_parameter("tls enabled", "True", NULL);
697 do_parameter("tls keyfile", "tls/key.pem", NULL);
698 do_parameter("tls certfile", "tls/cert.pem", NULL);
699 do_parameter("tls cafile", "tls/ca.pem", NULL);
700 do_parameter_var("js include", "%s", dyn_JSDIR);
701 do_parameter_var("setup directory", "%s", dyn_SETUPDIR);
703 for (i = 0; parm_table[i].label; i++) {
704 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
705 parm_table[i].flags |= FLAG_DEFAULT;
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_CONST_STRING(lp_winbindd_socket_directory, &Globals.szWinbinddSocketDirectory)
827 FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
828 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
829 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
830 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
831 FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
832 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
833 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
834 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
835 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
836 FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
837 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
838 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
839 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
840 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
841 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
842 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
843 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
844 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
845 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
846 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
847 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
848 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
849 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
850 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
852 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
853 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
854 FN_GLOBAL_BOOL(lp_wins_dns_proxy, &Globals.bWINSdnsProxy)
855 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
856 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
857 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
858 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
859 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
860 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
861 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
862 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
863 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
864 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
865 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
866 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
867 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
868 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
869 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
870 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
871 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
872 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
873 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
874 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
875 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
876 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
877 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
878 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
879 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
880 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
881 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
882 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
883 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
884 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
885 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
886 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
887 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
888 FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
891 FN_LOCAL_STRING(lp_servicename, szService)
892 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
893 FN_LOCAL_STRING(lp_pathname, szPath)
894 static FN_LOCAL_STRING(_lp_printername, szPrintername)
895 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
896 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
897 FN_LOCAL_STRING(lp_comment, comment)
898 FN_LOCAL_STRING(lp_fstype, fstype)
899 static FN_LOCAL_STRING(lp_volume, volume)
900 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
901 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
902 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
903 FN_LOCAL_BOOL(lp_readonly, bRead_only)
904 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
905 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
906 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
907 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
908 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
909 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
910 FN_LOCAL_BOOL(lp_map_system, bMap_system)
911 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
912 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
913 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
914 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
916 /* local prototypes */
918 static int map_parameter(const char *pszParmName);
919 static int getservicebyname(const char *pszServiceName,
920 service * pserviceDest);
921 static void copy_service(service * pserviceDest,
922 service * pserviceSource, BOOL *pcopymapDest);
923 static BOOL service_ok(int iService);
924 static BOOL do_section(const char *pszSectionName, void *);
925 static void init_copymap(service * pservice);
927 /* This is a helper function for parametrical options support. */
928 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
929 /* Actual parametrical functions are quite simple */
930 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
933 struct param_opt *data;
935 if (lookup_service >= iNumServices) return NULL;
937 data = (lookup_service < 0) ?
938 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
940 asprintf(&vfskey, "%s:%s", type, option);
944 if (strcmp(data->key, vfskey) == 0) {
951 if (lookup_service >= 0) {
952 /* Try to fetch the same option but from globals */
953 /* but only if we are not already working with Globals */
954 data = Globals.param_opt;
956 if (strcmp(data->key, vfskey) == 0) {
970 /*******************************************************************
971 convenience routine to return int parameters.
972 ********************************************************************/
973 static int lp_int(const char *s)
977 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
981 return strtol(s, NULL, 0);
984 /*******************************************************************
985 convenience routine to return unsigned long parameters.
986 ********************************************************************/
987 static int lp_ulong(const char *s)
991 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
995 return strtoul(s, NULL, 0);
998 /*******************************************************************
999 convenience routine to return boolean parameters.
1000 ********************************************************************/
1001 static BOOL lp_bool(const char *s)
1006 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1010 if (!set_boolean(s, &ret)) {
1011 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1019 /* Return parametric option from a given service. Type is a part of option before ':' */
1020 /* Parametric option has following syntax: 'Type: option = value' */
1021 /* Returned value is allocated in 'lp_talloc' context */
1023 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1025 const char *value = lp_get_parametric(lookup_service, type, option);
1028 return lp_string(value);
1033 /* Return parametric option from a given service. Type is a part of option before ':' */
1034 /* Parametric option has following syntax: 'Type: option = value' */
1035 /* Returned value is allocated in 'lp_talloc' context */
1037 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1038 const char *separator)
1040 const char *value = lp_get_parametric(lookup_service, type, option);
1043 return str_list_make(talloc_autofree_context(), value, separator);
1048 /* Return parametric option from a given service. Type is a part of option before ':' */
1049 /* Parametric option has following syntax: 'Type: option = value' */
1051 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1053 const char *value = lp_get_parametric(lookup_service, type, option);
1056 return lp_int(value);
1061 /* Return parametric option from a given service. Type is a part of option before ':' */
1062 /* Parametric option has following syntax: 'Type: option = value' */
1064 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1066 const char *value = lp_get_parametric(lookup_service, type, option);
1069 return lp_ulong(value);
1074 /* Return parametric option from a given service. Type is a part of option before ':' */
1075 /* Parametric option has following syntax: 'Type: option = value' */
1077 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1079 const char *value = lp_get_parametric(lookup_service, type, option);
1082 return lp_bool(value);
1088 /***************************************************************************
1089 Initialise a service to the defaults.
1090 ***************************************************************************/
1092 static void init_service(service * pservice)
1094 memset((char *)pservice, '\0', sizeof(service));
1095 copy_service(pservice, &sDefault, NULL);
1098 /***************************************************************************
1099 Free the dynamically allocated parts of a service struct.
1100 ***************************************************************************/
1102 static void free_service(service *pservice)
1105 struct param_opt *data, *pdata;
1109 if (pservice->szService)
1110 DEBUG(5, ("free_service: Freeing service %s\n",
1111 pservice->szService));
1113 string_free(&pservice->szService);
1114 SAFE_FREE(pservice->copymap);
1116 for (i = 0; parm_table[i].label; i++) {
1117 if ((parm_table[i].type == P_STRING ||
1118 parm_table[i].type == P_USTRING) &&
1119 parm_table[i].class == P_LOCAL) {
1120 string_free((char **)
1121 (((char *)pservice) +
1122 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1123 } else if (parm_table[i].type == P_LIST &&
1124 parm_table[i].class == P_LOCAL) {
1125 char ***listp = (char ***)(((char *)pservice) +
1126 PTR_DIFF(parm_table[i].ptr, &sDefault));
1127 talloc_free(*listp);
1132 DEBUG(5,("Freeing parametrics:\n"));
1133 data = pservice->param_opt;
1135 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1136 string_free(&data->key);
1137 string_free(&data->value);
1143 ZERO_STRUCTP(pservice);
1146 /***************************************************************************
1147 Add a new service to the services array initialising it with the given
1149 ***************************************************************************/
1151 static int add_a_service(const service *pservice, const char *name)
1155 int num_to_alloc = iNumServices + 1;
1156 struct param_opt *data, *pdata;
1158 tservice = *pservice;
1160 /* it might already exist */
1162 i = getservicebyname(name, NULL);
1164 /* Clean all parametric options for service */
1165 /* They will be added during parsing again */
1166 data = ServicePtrs[i]->param_opt;
1168 string_free(&data->key);
1169 string_free(&data->value);
1174 ServicePtrs[i]->param_opt = NULL;
1179 /* find an invalid one */
1180 for (i = 0; i < iNumServices; i++)
1181 if (!ServicePtrs[i]->valid)
1184 /* if not, then create one */
1185 if (i == iNumServices) {
1188 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1191 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1196 ServicePtrs[iNumServices] = malloc_p(service);
1198 if (!ServicePtrs[iNumServices]) {
1199 DEBUG(0,("add_a_service: out of memory!\n"));
1205 free_service(ServicePtrs[i]);
1207 ServicePtrs[i]->valid = True;
1209 init_service(ServicePtrs[i]);
1210 copy_service(ServicePtrs[i], &tservice, NULL);
1212 string_set(&ServicePtrs[i]->szService, name);
1216 /***************************************************************************
1217 Add a new home service, with the specified home directory, defaults coming
1219 ***************************************************************************/
1221 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1222 const char *user, const char *pszHomedir)
1227 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1232 if (!(*(ServicePtrs[iDefaultService]->szPath))
1233 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1234 pstrcpy(newHomedir, pszHomedir);
1236 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1237 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1240 string_set(&ServicePtrs[i]->szPath, newHomedir);
1242 if (!(*(ServicePtrs[i]->comment))) {
1244 slprintf(comment, sizeof(comment) - 1,
1245 "Home directory of %s", user);
1246 string_set(&ServicePtrs[i]->comment, comment);
1248 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1249 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1251 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1257 /***************************************************************************
1258 Add a new service, based on an old one.
1259 ***************************************************************************/
1261 int lp_add_service(const char *pszService, int iDefaultService)
1263 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1266 /***************************************************************************
1267 Add the IPC service.
1268 ***************************************************************************/
1270 static BOOL lp_add_hidden(const char *name, const char *fstype)
1273 int i = add_a_service(&sDefault, name);
1278 slprintf(comment, sizeof(comment) - 1,
1279 "%s Service (%s)", fstype, Globals.szServerString);
1281 string_set(&ServicePtrs[i]->szPath, tmpdir());
1282 string_set(&ServicePtrs[i]->comment, comment);
1283 string_set(&ServicePtrs[i]->fstype, fstype);
1284 ServicePtrs[i]->iMaxConnections = -1;
1285 ServicePtrs[i]->bAvailable = True;
1286 ServicePtrs[i]->bRead_only = True;
1287 ServicePtrs[i]->bPrint_ok = False;
1288 ServicePtrs[i]->bBrowseable = False;
1290 if (strcasecmp(fstype, "IPC") == 0) {
1291 lp_do_parameter(i, "ntvfs handler", "default");
1294 DEBUG(3, ("adding hidden service %s\n", name));
1299 /***************************************************************************
1300 Add a new printer service, with defaults coming from service iFrom.
1301 ***************************************************************************/
1303 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1305 const char *comment = "From Printcap";
1306 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1311 /* note that we do NOT default the availability flag to True - */
1312 /* we take it from the default service passed. This allows all */
1313 /* dynamic printers to be disabled by disabling the [printers] */
1314 /* entry (if/when the 'available' keyword is implemented!). */
1316 /* the printer name is set to the service name. */
1317 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1318 string_set(&ServicePtrs[i]->comment, comment);
1319 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1320 /* Printers cannot be read_only. */
1321 ServicePtrs[i]->bRead_only = False;
1322 /* Printer services must be printable. */
1323 ServicePtrs[i]->bPrint_ok = True;
1325 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1327 update_server_announce_as_printserver();
1332 /***************************************************************************
1333 Map a parameter's string representation to something we can use.
1334 Returns False if the parameter string is not recognised, else TRUE.
1335 ***************************************************************************/
1337 static int map_parameter(const char *pszParmName)
1341 if (*pszParmName == '-')
1344 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1345 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1348 /* Warn only if it isn't parametric option */
1349 if (strchr(pszParmName, ':') == NULL)
1350 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1351 /* We do return 'fail' for parametric options as well because they are
1352 stored in different storage
1359 return the parameter structure for a parameter
1361 struct parm_struct *lp_parm_struct(const char *name)
1363 int parmnum = map_parameter(name);
1364 if (parmnum == -1) return NULL;
1365 return &parm_table[parmnum];
1369 return the parameter pointer for a parameter
1371 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1376 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1379 /***************************************************************************
1380 Find a service by name. Otherwise works like get_service.
1381 ***************************************************************************/
1383 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1387 for (iService = iNumServices - 1; iService >= 0; iService--)
1388 if (VALID(iService) &&
1389 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1390 if (pserviceDest != NULL)
1391 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1398 /***************************************************************************
1399 Copy a service structure to another.
1400 If pcopymapDest is NULL then copy all fields
1401 ***************************************************************************/
1403 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1406 BOOL bcopyall = (pcopymapDest == NULL);
1407 struct param_opt *data, *pdata, *paramo;
1410 for (i = 0; parm_table[i].label; i++)
1411 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1412 (bcopyall || pcopymapDest[i])) {
1413 void *def_ptr = parm_table[i].ptr;
1415 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1418 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1421 switch (parm_table[i].type) {
1423 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1428 *(int *)dest_ptr = *(int *)src_ptr;
1432 string_set(dest_ptr,
1437 string_set(dest_ptr,
1439 strupper(*(char **)dest_ptr);
1442 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1443 *(const char ***)src_ptr);
1451 init_copymap(pserviceDest);
1452 if (pserviceSource->copymap)
1453 memcpy((void *)pserviceDest->copymap,
1454 (void *)pserviceSource->copymap,
1455 sizeof(BOOL) * NUMPARAMETERS);
1458 data = pserviceSource->param_opt;
1461 pdata = pserviceDest->param_opt;
1462 /* Traverse destination */
1464 /* If we already have same option, override it */
1465 if (strcmp(pdata->key, data->key) == 0) {
1466 string_free(&pdata->value);
1467 pdata->value = strdup(data->value);
1471 pdata = pdata->next;
1474 paramo = malloc_p(struct param_opt);
1477 paramo->key = strdup(data->key);
1478 paramo->value = strdup(data->value);
1479 DLIST_ADD(pserviceDest->param_opt, paramo);
1485 /***************************************************************************
1486 Check a service for consistency. Return False if the service is in any way
1487 incomplete or faulty, else True.
1488 ***************************************************************************/
1490 static BOOL service_ok(int iService)
1495 if (ServicePtrs[iService]->szService[0] == '\0') {
1496 DEBUG(0, ("The following message indicates an internal error:\n"));
1497 DEBUG(0, ("No service name in service entry.\n"));
1501 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1502 /* I can't see why you'd want a non-printable printer service... */
1503 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1504 if (!ServicePtrs[iService]->bPrint_ok) {
1505 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1506 ServicePtrs[iService]->szService));
1507 ServicePtrs[iService]->bPrint_ok = True;
1508 update_server_announce_as_printserver();
1510 /* [printers] service must also be non-browsable. */
1511 if (ServicePtrs[iService]->bBrowseable)
1512 ServicePtrs[iService]->bBrowseable = False;
1515 /* If a service is flagged unavailable, log the fact at level 0. */
1516 if (!ServicePtrs[iService]->bAvailable)
1517 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1518 ServicePtrs[iService]->szService));
1523 static struct file_lists {
1524 struct file_lists *next;
1528 } *file_lists = NULL;
1530 /*******************************************************************
1531 Keep a linked list of all config files so we know when one has changed
1532 it's date and needs to be reloaded.
1533 ********************************************************************/
1535 static void add_to_file_list(const char *fname, const char *subfname)
1537 struct file_lists *f = file_lists;
1540 if (f->name && !strcmp(f->name, fname))
1546 f = malloc_p(struct file_lists);
1549 f->next = file_lists;
1550 f->name = strdup(fname);
1555 f->subfname = strdup(subfname);
1561 f->modtime = file_modtime(subfname);
1563 time_t t = file_modtime(subfname);
1569 /*******************************************************************
1570 Check if a config file has changed date.
1571 ********************************************************************/
1573 BOOL lp_file_list_changed(void)
1575 struct file_lists *f = file_lists;
1576 DEBUG(6, ("lp_file_list_changed()\n"));
1582 pstrcpy(n2, f->name);
1583 standard_sub_basic(n2,sizeof(n2));
1585 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1586 f->name, n2, ctime(&f->modtime)));
1588 mod_time = file_modtime(n2);
1590 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1592 ("file %s modified: %s\n", n2,
1594 f->modtime = mod_time;
1595 SAFE_FREE(f->subfname);
1596 f->subfname = strdup(n2);
1604 /***************************************************************************
1605 Handle the include operation.
1606 ***************************************************************************/
1608 static BOOL handle_include(const char *pszParmValue, char **ptr)
1611 pstrcpy(fname, pszParmValue);
1613 standard_sub_basic(fname,sizeof(fname));
1615 add_to_file_list(pszParmValue, fname);
1617 string_set(ptr, fname);
1619 if (file_exist(fname))
1620 return (pm_process(fname, do_section, do_parameter, NULL));
1622 DEBUG(2, ("Can't find include file %s\n", fname));
1627 /***************************************************************************
1628 Handle the interpretation of the copy parameter.
1629 ***************************************************************************/
1631 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1635 service serviceTemp;
1637 string_set(ptr, pszParmValue);
1639 init_service(&serviceTemp);
1643 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1645 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1646 if (iTemp == iServiceIndex) {
1647 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1649 copy_service(ServicePtrs[iServiceIndex],
1651 ServicePtrs[iServiceIndex]->copymap);
1655 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1659 free_service(&serviceTemp);
1663 /***************************************************************************
1664 Initialise a copymap.
1665 ***************************************************************************/
1667 static void init_copymap(service * pservice)
1670 SAFE_FREE(pservice->copymap);
1671 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
1672 if (!pservice->copymap)
1674 ("Couldn't allocate copymap!! (size %d)\n",
1675 (int)NUMPARAMETERS));
1677 for (i = 0; i < NUMPARAMETERS; i++)
1678 pservice->copymap[i] = True;
1681 /***************************************************************************
1682 Return the local pointer to a parameter given the service number and the
1683 pointer into the default structure.
1684 ***************************************************************************/
1686 void *lp_local_ptr(int snum, void *ptr)
1688 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1692 /***************************************************************************
1693 Process a parametric option
1694 ***************************************************************************/
1695 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1697 struct param_opt *paramo, *data;
1700 while (isspace((unsigned char)*pszParmName)) {
1704 name = strdup(pszParmName);
1705 if (!name) return False;
1710 data = Globals.param_opt;
1712 data = ServicePtrs[snum]->param_opt;
1715 /* Traverse destination */
1716 for (paramo=data; paramo; paramo=paramo->next) {
1717 /* If we already have the option set, override it unless
1718 it was a command line option and the new one isn't */
1719 if (strcmp(paramo->key, name) == 0) {
1720 if ((paramo->flags & FLAG_CMDLINE) &&
1721 !(flags & FLAG_CMDLINE)) {
1725 free(paramo->value);
1726 paramo->value = strdup(pszParmValue);
1727 paramo->flags = flags;
1733 paramo = malloc_p(struct param_opt);
1736 paramo->key = strdup(name);
1737 paramo->value = strdup(pszParmValue);
1738 paramo->flags = flags;
1740 DLIST_ADD(Globals.param_opt, paramo);
1742 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1750 /***************************************************************************
1751 Process a parameter for a particular service number. If snum < 0
1752 then assume we are in the globals.
1753 ***************************************************************************/
1754 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1757 void *parm_ptr = NULL; /* where we are going to store the result */
1758 void *def_ptr = NULL;
1760 parmnum = map_parameter(pszParmName);
1763 if (strchr(pszParmName, ':')) {
1764 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1766 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1770 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1771 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1775 /* if the flag has been set on the command line, then don't allow override,
1776 but don't report an error */
1777 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1781 def_ptr = parm_table[parmnum].ptr;
1783 /* we might point at a service, the default service or a global */
1787 if (parm_table[parmnum].class == P_GLOBAL) {
1789 ("Global parameter %s found in service section!\n",
1794 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1799 if (!ServicePtrs[snum]->copymap)
1800 init_copymap(ServicePtrs[snum]);
1802 /* this handles the aliases - set the copymap for other entries with
1803 the same data pointer */
1804 for (i = 0; parm_table[i].label; i++)
1805 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1806 ServicePtrs[snum]->copymap[i] = False;
1809 /* if it is a special case then go ahead */
1810 if (parm_table[parmnum].special) {
1811 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1815 /* now switch on the type of variable it is */
1816 switch (parm_table[parmnum].type)
1819 if (!set_boolean(pszParmValue, parm_ptr)) {
1820 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1826 *(int *)parm_ptr = atoi(pszParmValue);
1830 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1831 pszParmValue, NULL);
1835 string_set(parm_ptr, pszParmValue);
1839 string_set(parm_ptr, pszParmValue);
1840 strupper(*(char **)parm_ptr);
1844 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1847 parm_table[parmnum].enum_list[i].name)) {
1849 parm_table[parmnum].
1854 if (!parm_table[parmnum].enum_list[i].name) {
1855 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1856 pszParmValue, pszParmName));
1864 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1865 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1866 /* we have to also unset FLAG_DEFAULT on aliases */
1867 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1868 parm_table[i].flags &= ~FLAG_DEFAULT;
1870 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1871 parm_table[i].flags &= ~FLAG_DEFAULT;
1878 /***************************************************************************
1879 Process a parameter.
1880 ***************************************************************************/
1882 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1884 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1885 pszParmName, pszParmValue));
1889 variable argument do parameter
1891 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1893 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1900 s = talloc_vasprintf(NULL, fmt, ap);
1902 ret = do_parameter(pszParmName, s, NULL);
1909 set a parameter from the commandline - this is called from command line parameter
1910 parsing code. It sets the parameter then marks the parameter as unable to be modified
1911 by smb.conf processing
1913 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1915 int parmnum = map_parameter(pszParmName);
1918 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1921 if (parmnum < 0 && strchr(pszParmName, ':')) {
1922 /* set a parametric option */
1923 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1927 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1931 /* reset the CMDLINE flag in case this has been called before */
1932 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1934 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1938 parm_table[parmnum].flags |= FLAG_CMDLINE;
1940 /* we have to also set FLAG_CMDLINE on aliases */
1941 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1942 parm_table[i].flags |= FLAG_CMDLINE;
1944 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1945 parm_table[i].flags |= FLAG_CMDLINE;
1952 set a option from the commandline in 'a=b' format. Use to support --option
1954 BOOL lp_set_option(const char *option)
1972 ret = lp_set_cmdline(s, p+1);
1978 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1980 /***************************************************************************
1981 Print a parameter of the specified type.
1982 ***************************************************************************/
1984 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1990 for (i = 0; p->enum_list[i].name; i++) {
1991 if (*(int *)ptr == p->enum_list[i].value) {
1993 p->enum_list[i].name);
2000 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2004 fprintf(f, "%d", *(int *)ptr);
2008 if ((char ***)ptr && *(char ***)ptr) {
2009 char **list = *(char ***)ptr;
2011 for (; *list; list++)
2012 fprintf(f, "%s%s", *list,
2013 ((*(list+1))?", ":""));
2019 if (*(char **)ptr) {
2020 fprintf(f, "%s", *(char **)ptr);
2028 /***************************************************************************
2029 Check if two parameters are equal.
2030 ***************************************************************************/
2032 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2036 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2040 return (*((int *)ptr1) == *((int *)ptr2));
2043 return str_list_equal((const char **)(*(char ***)ptr1),
2044 (const char **)(*(char ***)ptr2));
2049 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2054 return (p1 == p2 || strequal(p1, p2));
2062 /***************************************************************************
2063 Process a new section (service). At this stage all sections are services.
2064 Later we'll have special sections that permit server parameters to be set.
2065 Returns True on success, False on failure.
2066 ***************************************************************************/
2068 static BOOL do_section(const char *pszSectionName, void *userdata)
2071 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2072 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2075 /* if we've just struck a global section, note the fact. */
2076 bInGlobalSection = isglobal;
2078 /* check for multiple global sections */
2079 if (bInGlobalSection) {
2080 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2084 /* if we have a current service, tidy it up before moving on */
2087 if (iServiceIndex >= 0)
2088 bRetval = service_ok(iServiceIndex);
2090 /* if all is still well, move to the next record in the services array */
2092 /* We put this here to avoid an odd message order if messages are */
2093 /* issued by the post-processing of a previous section. */
2094 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2096 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2098 DEBUG(0, ("Failed to add a new service\n"));
2107 /***************************************************************************
2108 Determine if a partcular base parameter is currentl set to the default value.
2109 ***************************************************************************/
2111 static BOOL is_default(int i)
2113 if (!defaults_saved)
2115 switch (parm_table[i].type) {
2117 return str_list_equal((const char **)parm_table[i].def.lvalue,
2118 (const char **)(*(char ***)parm_table[i].ptr));
2121 return strequal(parm_table[i].def.svalue,
2122 *(char **)parm_table[i].ptr);
2124 return parm_table[i].def.bvalue ==
2125 *(BOOL *)parm_table[i].ptr;
2128 return parm_table[i].def.ivalue ==
2129 *(int *)parm_table[i].ptr;
2136 /***************************************************************************
2137 Display the contents of the global structure.
2138 ***************************************************************************/
2140 static void dump_globals(FILE *f, BOOL show_defaults)
2143 struct param_opt *data;
2145 fprintf(f, "# Global parameters\n[global]\n");
2147 for (i = 0; parm_table[i].label; i++)
2148 if (parm_table[i].class == P_GLOBAL &&
2149 parm_table[i].ptr &&
2150 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2151 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2153 fprintf(f, "\t%s = ", parm_table[i].label);
2154 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2157 if (Globals.param_opt != NULL) {
2158 data = Globals.param_opt;
2160 fprintf(f, "\t%s = %s\n", data->key, data->value);
2167 /***************************************************************************
2168 Display the contents of a single services record.
2169 ***************************************************************************/
2171 static void dump_a_service(service * pService, FILE * f)
2174 struct param_opt *data;
2176 if (pService != &sDefault)
2177 fprintf(f, "\n[%s]\n", pService->szService);
2179 for (i = 0; parm_table[i].label; i++)
2180 if (parm_table[i].class == P_LOCAL &&
2181 parm_table[i].ptr &&
2182 (*parm_table[i].label != '-') &&
2183 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2184 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2186 if (pService == &sDefault) {
2187 if (defaults_saved && is_default(i))
2190 if (equal_parameter(parm_table[i].type,
2191 ((char *)pService) +
2193 ((char *)&sDefault) +
2198 fprintf(f, "\t%s = ", parm_table[i].label);
2199 print_parameter(&parm_table[i],
2200 ((char *)pService) + pdiff, f);
2203 if (pService->param_opt != NULL) {
2204 data = pService->param_opt;
2206 fprintf(f, "\t%s = %s\n", data->key, data->value);
2212 BOOL lp_dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
2214 service * pService = ServicePtrs[snum];
2217 struct parm_struct *parm;
2225 parm = lp_parm_struct(parm_name);
2233 ptr = ((char *)pService) +
2234 PTR_DIFF(parm->ptr, &sDefault);
2236 print_parameter(parm,
2242 /***************************************************************************
2243 Return info about the next service in a service. snum==-1 gives the globals.
2244 Return NULL when out of parameters.
2245 ***************************************************************************/
2247 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2250 /* do the globals */
2251 for (; parm_table[*i].label; (*i)++) {
2252 if (parm_table[*i].class == P_SEPARATOR)
2253 return &parm_table[(*i)++];
2255 if (!parm_table[*i].ptr
2256 || (*parm_table[*i].label == '-'))
2260 && (parm_table[*i].ptr ==
2261 parm_table[(*i) - 1].ptr))
2264 return &parm_table[(*i)++];
2267 service *pService = ServicePtrs[snum];
2269 for (; parm_table[*i].label; (*i)++) {
2270 if (parm_table[*i].class == P_SEPARATOR)
2271 return &parm_table[(*i)++];
2273 if (parm_table[*i].class == P_LOCAL &&
2274 parm_table[*i].ptr &&
2275 (*parm_table[*i].label != '-') &&
2277 (parm_table[*i].ptr !=
2278 parm_table[(*i) - 1].ptr)))
2281 PTR_DIFF(parm_table[*i].ptr,
2284 if (allparameters ||
2285 !equal_parameter(parm_table[*i].type,
2286 ((char *)pService) +
2288 ((char *)&sDefault) +
2291 return &parm_table[(*i)++];
2301 /***************************************************************************
2302 Return TRUE if the passed service number is within range.
2303 ***************************************************************************/
2305 BOOL lp_snum_ok(int iService)
2307 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2310 /***************************************************************************
2311 Auto-load some home services.
2312 ***************************************************************************/
2314 static void lp_add_auto_services(const char *str)
2319 /***************************************************************************
2320 Announce ourselves as a print server.
2321 ***************************************************************************/
2323 void update_server_announce_as_printserver(void)
2325 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2328 /***************************************************************************
2329 Have we loaded a services file yet?
2330 ***************************************************************************/
2332 BOOL lp_loaded(void)
2337 /***************************************************************************
2338 Unload unused services.
2339 ***************************************************************************/
2341 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2344 for (i = 0; i < iNumServices; i++) {
2348 if (!snumused || !snumused(smb, i)) {
2349 ServicePtrs[i]->valid = False;
2350 free_service(ServicePtrs[i]);
2355 /***************************************************************************
2357 ***************************************************************************/
2359 void lp_killservice(int iServiceIn)
2361 if (VALID(iServiceIn)) {
2362 ServicePtrs[iServiceIn]->valid = False;
2363 free_service(ServicePtrs[iServiceIn]);
2367 /***************************************************************************
2368 Load the services array from the services file. Return True on success,
2370 ***************************************************************************/
2376 struct param_opt *data;
2380 bInGlobalSection = True;
2382 if (Globals.param_opt != NULL) {
2383 struct param_opt *next;
2384 for (data=Globals.param_opt; data; data=next) {
2386 if (data->flags & FLAG_CMDLINE) continue;
2389 DLIST_REMOVE(Globals.param_opt, data);
2396 pstrcpy(n2, lp_configfile());
2397 standard_sub_basic(n2,sizeof(n2));
2398 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2400 add_to_file_list(lp_configfile(), n2);
2402 /* We get sections first, so have to start 'behind' to make up */
2404 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2406 /* finish up the last section */
2407 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2409 if (iServiceIndex >= 0)
2410 bRetval = service_ok(iServiceIndex);
2412 lp_add_auto_services(lp_auto_services());
2414 lp_add_hidden("IPC$", "IPC");
2415 lp_add_hidden("ADMIN$", "DISK");
2417 set_default_server_announce_type();
2421 if (!Globals.szWINSservers && Globals.bWINSsupport) {
2422 lp_do_parameter(-1, "wins server", "127.0.0.1");
2430 /***************************************************************************
2431 Reset the max number of services.
2432 ***************************************************************************/
2434 void lp_resetnumservices(void)
2439 /***************************************************************************
2440 Return the max number of services.
2441 ***************************************************************************/
2443 int lp_numservices(void)
2445 return (iNumServices);
2448 /***************************************************************************
2449 Display the contents of the services array in human-readable form.
2450 ***************************************************************************/
2452 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2457 defaults_saved = False;
2459 dump_globals(f, show_defaults);
2461 dump_a_service(&sDefault, f);
2463 for (iService = 0; iService < maxtoprint; iService++)
2464 lp_dump_one(f, show_defaults, iService);
2467 /***************************************************************************
2468 Display the contents of one service in human-readable form.
2469 ***************************************************************************/
2471 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2474 if (ServicePtrs[snum]->szService[0] == '\0')
2476 dump_a_service(ServicePtrs[snum], f);
2480 /***************************************************************************
2481 Return the number of the service with the given name, or -1 if it doesn't
2482 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2483 getservicebyname()! This works ONLY if all services have been loaded, and
2484 does not copy the found service.
2485 ***************************************************************************/
2487 int lp_servicenumber(const char *pszServiceName)
2490 fstring serviceName;
2493 for (iService = iNumServices - 1; iService >= 0; iService--) {
2494 if (VALID(iService) && ServicePtrs[iService]->szService) {
2496 * The substitution here is used to support %U is
2499 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2500 standard_sub_basic(serviceName,sizeof(serviceName));
2501 if (strequal(serviceName, pszServiceName))
2507 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2512 /*******************************************************************
2513 A useful volume label function.
2514 ********************************************************************/
2515 const char *volume_label(int snum)
2517 const char *ret = lp_volume(snum);
2519 return lp_servicename(snum);
2524 /*******************************************************************
2525 Set the server type we will announce as via nmbd.
2526 ********************************************************************/
2528 static void set_default_server_announce_type(void)
2530 default_server_announce = 0;
2531 default_server_announce |= SV_TYPE_WORKSTATION;
2532 default_server_announce |= SV_TYPE_SERVER;
2533 default_server_announce |= SV_TYPE_SERVER_UNIX;
2535 switch (lp_announce_as()) {
2536 case ANNOUNCE_AS_NT_SERVER:
2537 default_server_announce |= SV_TYPE_SERVER_NT;
2538 /* fall through... */
2539 case ANNOUNCE_AS_NT_WORKSTATION:
2540 default_server_announce |= SV_TYPE_NT;
2542 case ANNOUNCE_AS_WIN95:
2543 default_server_announce |= SV_TYPE_WIN95_PLUS;
2545 case ANNOUNCE_AS_WFW:
2546 default_server_announce |= SV_TYPE_WFW;
2552 switch (lp_server_role()) {
2553 case ROLE_DOMAIN_MEMBER:
2554 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2556 case ROLE_DOMAIN_PDC:
2557 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2559 case ROLE_DOMAIN_BDC:
2560 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2562 case ROLE_STANDALONE:
2566 if (lp_time_server())
2567 default_server_announce |= SV_TYPE_TIME_SOURCE;
2569 if (lp_host_msdfs())
2570 default_server_announce |= SV_TYPE_DFS_SERVER;
2572 /* TODO: only announce us as print server when we are a print server */
2573 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2576 /***********************************************************
2577 If we are PDC then prefer us as DMB
2578 ************************************************************/
2580 BOOL lp_domain_master(void)
2582 return (lp_server_role() == ROLE_DOMAIN_PDC);
2585 /***********************************************************
2586 If we are PDC then prefer us as DMB
2587 ************************************************************/
2589 BOOL lp_domain_logons(void)
2591 return (lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC);
2594 /***********************************************************
2595 If we are DMB then prefer us as LMB
2596 ************************************************************/
2598 BOOL lp_preferred_master(void)
2600 return (lp_local_master() && lp_domain_master());
2603 /*******************************************************************
2605 ********************************************************************/
2607 void lp_remove_service(int snum)
2609 ServicePtrs[snum]->valid = False;
2612 /*******************************************************************
2614 ********************************************************************/
2616 void lp_copy_service(int snum, const char *new_name)
2618 const char *oldname = lp_servicename(snum);
2619 do_section(new_name, NULL);
2621 snum = lp_servicenumber(new_name);
2623 lp_do_parameter(snum, "copy", oldname);
2628 /*******************************************************************
2629 Get the default server type we will announce as via nmbd.
2630 ********************************************************************/
2631 int lp_default_server_announce(void)
2633 return default_server_announce;
2636 const char *lp_printername(int snum)
2638 const char *ret = _lp_printername(snum);
2639 if (ret == NULL || (ret != NULL && *ret == '\0'))
2640 ret = lp_const_servicename(snum);
2646 /*******************************************************************
2647 Return the max print jobs per queue.
2648 ********************************************************************/
2650 int lp_maxprintjobs(int snum)
2652 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2653 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2654 maxjobs = PRINT_MAX_JOBID - 1;