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/locale.h"
62 #include "librpc/gen_ndr/svcctl.h"
63 #include "librpc/gen_ndr/samr.h"
64 #include "smb_server/smb_server.h"
65 #include "libcli/raw/signing.h"
66 #include "dlinklist.h"
67 #include "param/loadparm.h"
69 static BOOL bLoaded = False;
71 /* some helpful bits */
72 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
73 #define VALID(i) ServicePtrs[i]->valid
75 static BOOL do_parameter(const char *, const char *, void *);
76 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
78 static BOOL defaults_saved = False;
82 struct param_opt *prev, *next;
89 * This structure describes global (ie., server-wide) parameters.
99 char *display_charset;
104 char *szServerString;
105 char *szAutoServices;
110 char *szWINS_CONFIG_URL;
114 char **szPasswordServers;
115 char *szSocketOptions;
117 char **szWINSservers;
119 char *szSocketAddress;
120 char *szAnnounceVersion; /* This is initialised in init_globals */
123 char **szNetbiosAliases;
124 char *szNetbiosScope;
125 char *szDomainOtherSIDs;
126 char **szNameResolveOrder;
127 char **dcerpc_ep_servers;
128 char **server_services;
129 char *ntptr_providor;
130 char *szWinbindSeparator;
131 char *szWinbinddSocketDirectory;
132 int bWinbindSealedPipes;
133 char *swat_directory;
148 int paranoid_server_security;
151 int announce_as; /* This is initialised in init_globals */
158 char *socket_options;
163 int bPreferredMaster;
164 int bEncryptPasswords;
166 int bObeyPamRestrictions;
171 int bBindInterfacesOnly;
173 int bNTStatusSupport;
179 int bClientPlaintextAuth;
180 int bClientLanManAuth;
181 int bClientNTLMv2Auth;
182 int client_use_spnego_principal;
188 struct param_opt *param_opt;
192 static global Globals;
195 * This structure describes a single service.
210 char **ntvfs_handler;
226 struct param_opt *param_opt;
228 char dummy[3]; /* for alignment */
233 /* This is a default service used to prime a services structure */
234 static service sDefault = {
236 NULL, /* szService */
239 NULL, /* szInclude */
240 NULL, /* szPrintername */
241 NULL, /* szHostsallow */
242 NULL, /* szHostsdeny */
246 NULL, /* ntvfs_handler */
247 1000, /* iMaxPrintJobs */
248 0, /* iMaxConnections */
250 True, /* bAvailable */
251 True, /* bBrowseable */
252 True, /* bRead_only */
253 False, /* bPrint_ok */
254 False, /* bMap_system */
255 False, /* bMap_hidden */
256 True, /* bMap_archive */
257 True, /* bStrictLocking */
259 False, /* bMSDfsRoot */
260 False, /* bStrictSync */
261 False, /* bCIFileSystem */
262 NULL, /* Parametric options */
267 /* local variables */
268 static service **ServicePtrs = NULL;
269 static int iNumServices = 0;
270 static int iServiceIndex = 0;
271 static BOOL bInGlobalSection = True;
272 static int default_server_announce;
274 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
276 /* prototypes for the special type handlers */
277 static BOOL handle_include(const char *pszParmValue, char **ptr);
278 static BOOL handle_copy(const char *pszParmValue, char **ptr);
280 static void set_default_server_announce_type(void);
282 static const struct enum_list enum_protocol[] = {
283 {PROTOCOL_SMB2, "SMB2"},
284 {PROTOCOL_NT1, "NT1"},
285 {PROTOCOL_LANMAN2, "LANMAN2"},
286 {PROTOCOL_LANMAN1, "LANMAN1"},
287 {PROTOCOL_CORE, "CORE"},
288 {PROTOCOL_COREPLUS, "COREPLUS"},
289 {PROTOCOL_COREPLUS, "CORE+"},
293 static const struct enum_list enum_security[] = {
294 {SEC_SHARE, "SHARE"},
299 /* Types of machine we can announce as. */
300 #define ANNOUNCE_AS_NT_SERVER 1
301 #define ANNOUNCE_AS_WIN95 2
302 #define ANNOUNCE_AS_WFW 3
303 #define ANNOUNCE_AS_NT_WORKSTATION 4
305 static const struct enum_list enum_announce_as[] = {
306 {ANNOUNCE_AS_NT_SERVER, "NT"},
307 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
308 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
309 {ANNOUNCE_AS_WIN95, "win95"},
310 {ANNOUNCE_AS_WFW, "WfW"},
314 static const struct enum_list enum_bool_auto[] = {
325 /* Client-side offline caching policy types */
326 #define CSC_POLICY_MANUAL 0
327 #define CSC_POLICY_DOCUMENTS 1
328 #define CSC_POLICY_PROGRAMS 2
329 #define CSC_POLICY_DISABLE 3
331 static const struct enum_list enum_csc_policy[] = {
332 {CSC_POLICY_MANUAL, "manual"},
333 {CSC_POLICY_DOCUMENTS, "documents"},
334 {CSC_POLICY_PROGRAMS, "programs"},
335 {CSC_POLICY_DISABLE, "disable"},
339 /* SMB signing types. */
340 static const struct enum_list enum_smb_signing_vals[] = {
341 {SMB_SIGNING_OFF, "No"},
342 {SMB_SIGNING_OFF, "False"},
343 {SMB_SIGNING_OFF, "0"},
344 {SMB_SIGNING_OFF, "Off"},
345 {SMB_SIGNING_OFF, "disabled"},
346 {SMB_SIGNING_SUPPORTED, "Yes"},
347 {SMB_SIGNING_SUPPORTED, "True"},
348 {SMB_SIGNING_SUPPORTED, "1"},
349 {SMB_SIGNING_SUPPORTED, "On"},
350 {SMB_SIGNING_SUPPORTED, "enabled"},
351 {SMB_SIGNING_REQUIRED, "required"},
352 {SMB_SIGNING_REQUIRED, "mandatory"},
353 {SMB_SIGNING_REQUIRED, "force"},
354 {SMB_SIGNING_REQUIRED, "forced"},
355 {SMB_SIGNING_REQUIRED, "enforced"},
356 {SMB_SIGNING_AUTO, "auto"},
360 static const struct enum_list enum_server_role[] = {
361 {ROLE_STANDALONE, "standalone"},
362 {ROLE_DOMAIN_MEMBER, "member server"},
363 {ROLE_DOMAIN_BDC, "bdc"},
364 {ROLE_DOMAIN_PDC, "pdc"},
369 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
371 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
372 * is implied in current control logic. This may change at some later time. A
373 * flag value of 0 means - show as development option only.
375 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
376 * screen in SWAT. This is used to exclude parameters as well as to squash all
377 * parameters that have been duplicated by pseudonyms.
379 static struct parm_struct parm_table[] = {
380 {"Base Options", P_SEP, P_SEPARATOR},
382 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
384 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
385 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
386 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
387 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
388 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
389 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
390 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
391 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
392 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
393 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
394 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
396 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
397 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
398 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
400 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
401 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
402 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
404 {"Security Options", P_SEP, P_SEPARATOR},
406 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
407 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
408 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
409 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
410 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
412 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
428 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
429 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
431 {"Logging Options", P_SEP, P_SEPARATOR},
433 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
434 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
435 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
437 {"Protocol Options", P_SEP, P_SEPARATOR},
439 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
453 {"server max protocol", P_ENUM, P_GLOBAL, &Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
454 {"server min protocol", P_ENUM, P_GLOBAL, &Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
455 {"client max protocol", P_ENUM, P_GLOBAL, &Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
456 {"client min protocol", P_ENUM, P_GLOBAL, &Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
457 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
458 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
459 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
460 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
462 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
464 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
465 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
466 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
467 {"max xmit", P_BYTES, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
470 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
471 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
472 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
473 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
475 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
476 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
477 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
479 {"Tuning Options", P_SEP, P_SEPARATOR},
481 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
482 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
483 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
485 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
486 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
488 {"Printing Options", P_SEP, P_SEPARATOR},
490 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
491 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
492 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
494 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
495 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
497 {"Filename Handling", P_SEP, P_SEPARATOR},
499 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
500 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
501 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
503 {"Domain Options", P_SEP, P_SEPARATOR},
505 {"Logon Options", P_SEP, P_SEPARATOR},
508 {"Browse Options", P_SEP, P_SEPARATOR},
510 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
511 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
512 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
513 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
514 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
516 {"WINS Options", P_SEP, P_SEPARATOR},
518 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
519 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
520 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
521 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
523 {"Locking Options", P_SEP, P_SEPARATOR},
525 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
527 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
529 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
531 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
532 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
533 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
535 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"modules dir", P_STRING, P_GLOBAL, &Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
542 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
544 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
545 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
547 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
548 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
549 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
551 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
554 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
556 {"winbindd socket directory", P_STRING, P_GLOBAL, &Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
557 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
559 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
564 return the parameter table
566 struct parm_struct *lp_parm_table(void)
571 /***************************************************************************
572 Initialise the global parameter structure.
573 ***************************************************************************/
574 static void init_globals(void)
579 DEBUG(3, ("Initialising global parameters\n"));
581 for (i = 0; parm_table[i].label; i++) {
582 if ((parm_table[i].type == P_STRING ||
583 parm_table[i].type == P_USTRING) &&
585 !(parm_table[i].flags & FLAG_CMDLINE)) {
586 string_set(parm_table[i].ptr, "");
590 do_parameter("config file", dyn_CONFIGFILE, NULL);
592 do_parameter("server role", "standalone", NULL);
594 /* options that can be set on the command line must be initialised via
595 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
597 do_parameter("socket options", "TCP_NODELAY", NULL);
599 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
600 myname = get_myname();
601 do_parameter("netbios name", myname, NULL);
603 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
605 do_parameter("fstype", FSTYPE_STRING, NULL);
606 do_parameter("ntvfs handler", "unixuid default", NULL);
607 do_parameter("max connections", "-1", NULL);
609 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
610 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc winbind", NULL);
611 do_parameter("ntptr providor", "simple_ldb", NULL);
612 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
613 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
614 do_parameter("sam database", "sam.ldb", NULL);
615 do_parameter("spoolss database", "spoolss.ldb", NULL);
616 do_parameter("wins config database", "wins_config.ldb", NULL);
617 do_parameter("wins database", "wins.ldb", NULL);
618 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
620 /* This hive should be dynamically generated by Samba using
621 data from the sam, but for the moment leave it in a tdb to
622 keep regedt32 from popping up an annoying dialog. */
623 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
625 /* using UTF8 by default allows us to support all chars */
626 do_parameter("unix charset", "UTF8", NULL);
628 /* Use codepage 850 as a default for the dos character set */
629 do_parameter("dos charset", "CP850", NULL);
632 * Allow the default PASSWD_CHAT to be overridden in local.h.
634 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
636 do_parameter("pid directory", dyn_PIDDIR, NULL);
637 do_parameter("lock dir", dyn_LOCKDIR, NULL);
638 do_parameter("modules dir", dyn_MODULESDIR, NULL);
639 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
641 do_parameter("socket address", "0.0.0.0", NULL);
642 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
644 do_parameter_var("announce version", "%d.%d",
645 DEFAULT_MAJOR_VERSION,
646 DEFAULT_MINOR_VERSION);
648 do_parameter("password server", "*", NULL);
650 do_parameter("max mux", "50", NULL);
651 do_parameter("max xmit", "12288", NULL);
652 do_parameter("password level", "0", NULL);
653 do_parameter("LargeReadwrite", "True", NULL);
654 do_parameter("server min protocol", "CORE", NULL);
655 do_parameter("server max protocol", "NT1", NULL);
656 do_parameter("client min protocol", "CORE", NULL);
657 do_parameter("client max protocol", "NT1", NULL);
658 do_parameter("security", "USER", NULL);
659 do_parameter("paranoid server security", "True", NULL);
660 do_parameter("EncryptPasswords", "True", NULL);
661 do_parameter("ReadRaw", "True", NULL);
662 do_parameter("WriteRaw", "True", NULL);
663 do_parameter("NullPasswords", "False", NULL);
664 do_parameter("ObeyPamRestrictions", "False", NULL);
665 do_parameter("announce as", "NT SERVER", NULL);
667 do_parameter("TimeServer", "False", NULL);
668 do_parameter("BindInterfacesOnly", "False", NULL);
669 do_parameter("Unicode", "True", NULL);
670 do_parameter("ClientLanManAuth", "True", NULL);
671 do_parameter("LanmanAuth", "True", NULL);
672 do_parameter("NTLMAuth", "True", NULL);
673 do_parameter("client use spnego principal", "False", NULL);
675 do_parameter("UnixExtensions", "False", NULL);
677 do_parameter("PreferredMaster", "Auto", NULL);
678 do_parameter("LocalMaster", "True", NULL);
680 do_parameter("wins support", "False", NULL);
681 do_parameter("dns proxy", "True", NULL);
683 do_parameter("winbind separator", "\\", NULL);
684 do_parameter("winbind sealed pipes", "True", NULL);
685 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR, NULL);
687 do_parameter("client signing", "Yes", NULL);
688 do_parameter("server signing", "auto", NULL);
690 do_parameter("use spnego", "True", NULL);
692 do_parameter("smb ports", SMB_PORTS, NULL);
693 do_parameter("nbt port", "137", NULL);
694 do_parameter("dgram port", "138", NULL);
695 do_parameter("cldap port", "389", NULL);
696 do_parameter("krb5 port", "88", NULL);
697 do_parameter("kpasswd port", "464", NULL);
698 do_parameter("web port", "901", NULL);
699 do_parameter("swat directory", dyn_SWATDIR, NULL);
701 do_parameter("nt status support", "True", NULL);
703 do_parameter("max wins ttl", "518400", NULL); /* 6 days */
704 do_parameter("min wins ttl", "10", NULL);
706 do_parameter("tls enabled", "True", NULL);
707 do_parameter("tls keyfile", "tls/key.pem", NULL);
708 do_parameter("tls certfile", "tls/cert.pem", NULL);
709 do_parameter("tls cafile", "tls/ca.pem", NULL);
710 do_parameter_var("js include", "%s", dyn_JSDIR);
711 do_parameter_var("setup directory", "%s", dyn_SETUPDIR);
713 for (i = 0; parm_table[i].label; i++) {
714 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
715 parm_table[i].flags |= FLAG_DEFAULT;
720 static TALLOC_CTX *lp_talloc;
722 /******************************************************************* a
723 Free up temporary memory - called from the main loop.
724 ********************************************************************/
726 void lp_talloc_free(void)
730 talloc_free(lp_talloc);
734 /*******************************************************************
735 Convenience routine to grab string parameters into temporary memory
736 and run standard_sub_basic on them. The buffers can be written to by
737 callers without affecting the source string.
738 ********************************************************************/
740 static const char *lp_string(const char *s)
742 #if 0 /* until REWRITE done to make thread-safe */
743 size_t len = s ? strlen(s) : 0;
747 /* The follow debug is useful for tracking down memory problems
748 especially if you have an inner loop that is calling a lp_*()
749 function that returns a string. Perhaps this debug should be
750 present all the time? */
753 DEBUG(10, ("lp_string(%s)\n", s));
756 #if 0 /* until REWRITE done to make thread-safe */
758 lp_talloc = talloc_init("lp_talloc");
760 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
768 strlcpy(ret, s, len);
770 if (trim_string(ret, "\"", "\"")) {
771 if (strchr(ret,'"') != NULL)
772 strlcpy(ret, s, len);
775 standard_sub_basic(ret,len+100);
782 In this section all the functions that are used to access the
783 parameters from the rest of the program are defined
786 #define FN_GLOBAL_STRING(fn_name,ptr) \
787 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
788 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
789 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
790 #define FN_GLOBAL_LIST(fn_name,ptr) \
791 const char **fn_name(void) {return(*(const char ***)(ptr));}
792 #define FN_GLOBAL_BOOL(fn_name,ptr) \
793 BOOL fn_name(void) {return((BOOL)*(int *)(ptr));}
794 #define FN_GLOBAL_CHAR(fn_name,ptr) \
795 char fn_name(void) {return(*(char *)(ptr));}
796 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
797 int fn_name(void) {return(*(int *)(ptr));}
799 #define FN_LOCAL_STRING(fn_name,val) \
800 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
801 #define FN_LOCAL_CONST_STRING(fn_name,val) \
802 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
803 #define FN_LOCAL_LIST(fn_name,val) \
804 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
805 #define FN_LOCAL_BOOL(fn_name,val) \
806 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
807 #define FN_LOCAL_CHAR(fn_name,val) \
808 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
809 #define FN_LOCAL_INTEGER(fn_name,val) \
810 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
812 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &Globals.server_role)
813 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
814 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
815 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
816 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
817 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
818 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &Globals.kpasswd_port)
819 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
820 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
821 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
822 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
823 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
824 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
825 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
826 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
827 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
828 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
829 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
830 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
831 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
832 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL)
833 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
834 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
835 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &Globals.szWinbinddSocketDirectory)
836 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
837 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
838 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
839 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
840 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &Globals.szModulesDir)
841 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
842 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
843 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
844 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
845 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
846 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
847 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
848 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
849 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
850 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
851 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
852 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
853 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
854 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
855 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
856 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
857 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
858 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
859 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
861 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
862 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
863 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &Globals.bWINSdnsProxy)
864 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
865 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
866 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
867 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
868 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
869 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
870 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
871 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
872 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
873 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
874 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
875 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
876 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
877 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
878 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
879 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
880 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
881 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
882 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
883 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
884 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
885 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
886 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
887 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
888 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
889 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
890 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
891 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &Globals.srv_maxprotocol)
892 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &Globals.srv_minprotocol)
893 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &Globals.cli_maxprotocol)
894 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &Globals.cli_minprotocol)
895 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
896 _PUBLIC_ FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
897 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
898 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
899 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
902 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
903 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
904 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
905 static FN_LOCAL_STRING(_lp_printername, szPrintername)
906 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
907 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
908 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
909 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
910 static FN_LOCAL_STRING(lp_volume, volume)
911 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
912 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
913 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
914 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
915 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
916 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
917 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
918 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
919 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
920 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
921 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
922 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
923 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
924 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
925 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
927 /* local prototypes */
929 static int map_parameter(const char *pszParmName);
930 static int getservicebyname(const char *pszServiceName,
931 service * pserviceDest);
932 static void copy_service(service * pserviceDest,
933 service * pserviceSource, int *pcopymapDest);
934 static BOOL service_ok(int iService);
935 static BOOL do_section(const char *pszSectionName, void *);
936 static void init_copymap(service * pservice);
938 /* This is a helper function for parametrical options support. */
939 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
940 /* Actual parametrical functions are quite simple */
941 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
944 struct param_opt *data;
946 if (lookup_service >= iNumServices) return NULL;
948 data = (lookup_service < 0) ?
949 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
951 asprintf(&vfskey, "%s:%s", type, option);
955 if (strcmp(data->key, vfskey) == 0) {
962 if (lookup_service >= 0) {
963 /* Try to fetch the same option but from globals */
964 /* but only if we are not already working with Globals */
965 data = Globals.param_opt;
967 if (strcmp(data->key, vfskey) == 0) {
981 /*******************************************************************
982 convenience routine to return int parameters.
983 ********************************************************************/
984 static int lp_int(const char *s)
988 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
992 return strtol(s, NULL, 0);
995 /*******************************************************************
996 convenience routine to return unsigned long parameters.
997 ********************************************************************/
998 static int lp_ulong(const char *s)
1002 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1006 return strtoul(s, NULL, 0);
1009 /*******************************************************************
1010 convenience routine to return boolean parameters.
1011 ********************************************************************/
1012 static BOOL lp_bool(const char *s)
1017 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1021 if (!set_boolean(s, &ret)) {
1022 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1030 /* Return parametric option from a given service. Type is a part of option before ':' */
1031 /* Parametric option has following syntax: 'Type: option = value' */
1032 /* Returned value is allocated in 'lp_talloc' context */
1034 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1036 const char *value = lp_get_parametric(lookup_service, type, option);
1039 return lp_string(value);
1044 /* Return parametric option from a given service. Type is a part of option before ':' */
1045 /* Parametric option has following syntax: 'Type: option = value' */
1046 /* Returned value is allocated in 'lp_talloc' context */
1048 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1049 const char *separator)
1051 const char *value = lp_get_parametric(lookup_service, type, option);
1054 return str_list_make(talloc_autofree_context(), value, separator);
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 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1064 const char *value = lp_get_parametric(lookup_service, type, option);
1067 return lp_int(value);
1072 /* Return parametric option from a given service. Type is a part of
1073 * option before ':'.
1074 * Parametric option has following syntax: 'Type: option = value'.
1077 int lp_parm_bytes(int lookup_service, const char *type, const char *option, int default_v)
1081 const char *value = lp_get_parametric(lookup_service, type, option);
1083 if (value && conv_str_size(value, &bval)) {
1084 if (bval <= INT_MAX) {
1092 /* Return parametric option from a given service. Type is a part of option before ':' */
1093 /* Parametric option has following syntax: 'Type: option = value' */
1095 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1097 const char *value = lp_get_parametric(lookup_service, type, option);
1100 return lp_ulong(value);
1105 /* Return parametric option from a given service. Type is a part of option before ':' */
1106 /* Parametric option has following syntax: 'Type: option = value' */
1108 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1110 const char *value = lp_get_parametric(lookup_service, type, option);
1113 return lp_bool(value);
1119 /***************************************************************************
1120 Initialise a service to the defaults.
1121 ***************************************************************************/
1123 static void init_service(service * pservice)
1125 memset((char *)pservice, '\0', sizeof(service));
1126 copy_service(pservice, &sDefault, NULL);
1129 /***************************************************************************
1130 Free the dynamically allocated parts of a service struct.
1131 ***************************************************************************/
1133 static void free_service(service *pservice)
1136 struct param_opt *data, *pdata;
1140 if (pservice->szService)
1141 DEBUG(5, ("free_service: Freeing service %s\n",
1142 pservice->szService));
1144 string_free(&pservice->szService);
1145 SAFE_FREE(pservice->copymap);
1147 for (i = 0; parm_table[i].label; i++) {
1148 if ((parm_table[i].type == P_STRING ||
1149 parm_table[i].type == P_USTRING) &&
1150 parm_table[i].class == P_LOCAL) {
1151 string_free((char **)
1152 (((char *)pservice) +
1153 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1154 } else if (parm_table[i].type == P_LIST &&
1155 parm_table[i].class == P_LOCAL) {
1156 char ***listp = (char ***)(((char *)pservice) +
1157 PTR_DIFF(parm_table[i].ptr, &sDefault));
1158 talloc_free(*listp);
1163 DEBUG(5,("Freeing parametrics:\n"));
1164 data = pservice->param_opt;
1166 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1167 string_free(&data->key);
1168 string_free(&data->value);
1174 ZERO_STRUCTP(pservice);
1177 /***************************************************************************
1178 Add a new service to the services array initialising it with the given
1180 ***************************************************************************/
1182 static int add_a_service(const service *pservice, const char *name)
1186 int num_to_alloc = iNumServices + 1;
1187 struct param_opt *data, *pdata;
1189 tservice = *pservice;
1191 /* it might already exist */
1193 i = getservicebyname(name, NULL);
1195 /* Clean all parametric options for service */
1196 /* They will be added during parsing again */
1197 data = ServicePtrs[i]->param_opt;
1199 string_free(&data->key);
1200 string_free(&data->value);
1205 ServicePtrs[i]->param_opt = NULL;
1210 /* find an invalid one */
1211 for (i = 0; i < iNumServices; i++)
1212 if (!ServicePtrs[i]->valid)
1215 /* if not, then create one */
1216 if (i == iNumServices) {
1219 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1222 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1227 ServicePtrs[iNumServices] = malloc_p(service);
1229 if (!ServicePtrs[iNumServices]) {
1230 DEBUG(0,("add_a_service: out of memory!\n"));
1236 free_service(ServicePtrs[i]);
1238 ServicePtrs[i]->valid = True;
1240 init_service(ServicePtrs[i]);
1241 copy_service(ServicePtrs[i], &tservice, NULL);
1243 string_set(&ServicePtrs[i]->szService, name);
1247 /***************************************************************************
1248 Add a new home service, with the specified home directory, defaults coming
1250 ***************************************************************************/
1252 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1253 const char *user, const char *pszHomedir)
1258 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1263 if (!(*(ServicePtrs[iDefaultService]->szPath))
1264 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1265 pstrcpy(newHomedir, pszHomedir);
1267 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1268 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1271 string_set(&ServicePtrs[i]->szPath, newHomedir);
1273 if (!(*(ServicePtrs[i]->comment))) {
1275 slprintf(comment, sizeof(comment) - 1,
1276 "Home directory of %s", user);
1277 string_set(&ServicePtrs[i]->comment, comment);
1279 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1280 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1282 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1288 /***************************************************************************
1289 Add a new service, based on an old one.
1290 ***************************************************************************/
1292 int lp_add_service(const char *pszService, int iDefaultService)
1294 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1297 /***************************************************************************
1298 Add the IPC service.
1299 ***************************************************************************/
1301 static BOOL lp_add_hidden(const char *name, const char *fstype)
1304 int i = add_a_service(&sDefault, name);
1309 slprintf(comment, sizeof(comment) - 1,
1310 "%s Service (%s)", fstype, Globals.szServerString);
1312 string_set(&ServicePtrs[i]->szPath, tmpdir());
1313 string_set(&ServicePtrs[i]->comment, comment);
1314 string_set(&ServicePtrs[i]->fstype, fstype);
1315 ServicePtrs[i]->iMaxConnections = -1;
1316 ServicePtrs[i]->bAvailable = True;
1317 ServicePtrs[i]->bRead_only = True;
1318 ServicePtrs[i]->bPrint_ok = False;
1319 ServicePtrs[i]->bBrowseable = False;
1321 if (strcasecmp(fstype, "IPC") == 0) {
1322 lp_do_parameter(i, "ntvfs handler", "default");
1325 DEBUG(3, ("adding hidden service %s\n", name));
1330 /***************************************************************************
1331 Add a new printer service, with defaults coming from service iFrom.
1332 ***************************************************************************/
1334 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1336 const char *comment = "From Printcap";
1337 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1342 /* note that we do NOT default the availability flag to True - */
1343 /* we take it from the default service passed. This allows all */
1344 /* dynamic printers to be disabled by disabling the [printers] */
1345 /* entry (if/when the 'available' keyword is implemented!). */
1347 /* the printer name is set to the service name. */
1348 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1349 string_set(&ServicePtrs[i]->comment, comment);
1350 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1351 /* Printers cannot be read_only. */
1352 ServicePtrs[i]->bRead_only = False;
1353 /* Printer services must be printable. */
1354 ServicePtrs[i]->bPrint_ok = True;
1356 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1358 update_server_announce_as_printserver();
1363 /***************************************************************************
1364 Map a parameter's string representation to something we can use.
1365 Returns False if the parameter string is not recognised, else TRUE.
1366 ***************************************************************************/
1368 static int map_parameter(const char *pszParmName)
1372 if (*pszParmName == '-')
1375 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1376 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1379 /* Warn only if it isn't parametric option */
1380 if (strchr(pszParmName, ':') == NULL)
1381 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1382 /* We do return 'fail' for parametric options as well because they are
1383 stored in different storage
1390 return the parameter structure for a parameter
1392 struct parm_struct *lp_parm_struct(const char *name)
1394 int parmnum = map_parameter(name);
1395 if (parmnum == -1) return NULL;
1396 return &parm_table[parmnum];
1400 return the parameter pointer for a parameter
1402 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1407 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1410 /***************************************************************************
1411 Find a service by name. Otherwise works like get_service.
1412 ***************************************************************************/
1414 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1418 for (iService = iNumServices - 1; iService >= 0; iService--)
1419 if (VALID(iService) &&
1420 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1421 if (pserviceDest != NULL)
1422 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1429 /***************************************************************************
1430 Copy a service structure to another.
1431 If pcopymapDest is NULL then copy all fields
1432 ***************************************************************************/
1434 static void copy_service(service * pserviceDest, service * pserviceSource, int *pcopymapDest)
1437 BOOL bcopyall = (pcopymapDest == NULL);
1438 struct param_opt *data, *pdata, *paramo;
1441 for (i = 0; parm_table[i].label; i++)
1442 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1443 (bcopyall || pcopymapDest[i])) {
1444 void *def_ptr = parm_table[i].ptr;
1446 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1449 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1452 switch (parm_table[i].type) {
1454 *(int *)dest_ptr = *(int *)src_ptr;
1459 *(int *)dest_ptr = *(int *)src_ptr;
1463 string_set(dest_ptr,
1468 string_set(dest_ptr,
1470 strupper(*(char **)dest_ptr);
1473 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1474 *(const char ***)src_ptr);
1482 init_copymap(pserviceDest);
1483 if (pserviceSource->copymap)
1484 memcpy((void *)pserviceDest->copymap,
1485 (void *)pserviceSource->copymap,
1486 sizeof(int) * NUMPARAMETERS);
1489 data = pserviceSource->param_opt;
1492 pdata = pserviceDest->param_opt;
1493 /* Traverse destination */
1495 /* If we already have same option, override it */
1496 if (strcmp(pdata->key, data->key) == 0) {
1497 string_free(&pdata->value);
1498 pdata->value = strdup(data->value);
1502 pdata = pdata->next;
1505 paramo = malloc_p(struct param_opt);
1508 paramo->key = strdup(data->key);
1509 paramo->value = strdup(data->value);
1510 DLIST_ADD(pserviceDest->param_opt, paramo);
1516 /***************************************************************************
1517 Check a service for consistency. Return False if the service is in any way
1518 incomplete or faulty, else True.
1519 ***************************************************************************/
1521 static BOOL service_ok(int iService)
1526 if (ServicePtrs[iService]->szService[0] == '\0') {
1527 DEBUG(0, ("The following message indicates an internal error:\n"));
1528 DEBUG(0, ("No service name in service entry.\n"));
1532 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1533 /* I can't see why you'd want a non-printable printer service... */
1534 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1535 if (!ServicePtrs[iService]->bPrint_ok) {
1536 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1537 ServicePtrs[iService]->szService));
1538 ServicePtrs[iService]->bPrint_ok = True;
1539 update_server_announce_as_printserver();
1541 /* [printers] service must also be non-browsable. */
1542 if (ServicePtrs[iService]->bBrowseable)
1543 ServicePtrs[iService]->bBrowseable = False;
1546 /* If a service is flagged unavailable, log the fact at level 0. */
1547 if (!ServicePtrs[iService]->bAvailable)
1548 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1549 ServicePtrs[iService]->szService));
1554 static struct file_lists {
1555 struct file_lists *next;
1559 } *file_lists = NULL;
1561 /*******************************************************************
1562 Keep a linked list of all config files so we know when one has changed
1563 it's date and needs to be reloaded.
1564 ********************************************************************/
1566 static void add_to_file_list(const char *fname, const char *subfname)
1568 struct file_lists *f = file_lists;
1571 if (f->name && !strcmp(f->name, fname))
1577 f = malloc_p(struct file_lists);
1580 f->next = file_lists;
1581 f->name = strdup(fname);
1586 f->subfname = strdup(subfname);
1592 f->modtime = file_modtime(subfname);
1594 time_t t = file_modtime(subfname);
1600 /*******************************************************************
1601 Check if a config file has changed date.
1602 ********************************************************************/
1604 BOOL lp_file_list_changed(void)
1606 struct file_lists *f = file_lists;
1607 DEBUG(6, ("lp_file_list_changed()\n"));
1613 pstrcpy(n2, f->name);
1614 standard_sub_basic(n2,sizeof(n2));
1616 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1617 f->name, n2, ctime(&f->modtime)));
1619 mod_time = file_modtime(n2);
1621 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1623 ("file %s modified: %s\n", n2,
1625 f->modtime = mod_time;
1626 SAFE_FREE(f->subfname);
1627 f->subfname = strdup(n2);
1635 /***************************************************************************
1636 Handle the include operation.
1637 ***************************************************************************/
1639 static BOOL handle_include(const char *pszParmValue, char **ptr)
1642 pstrcpy(fname, pszParmValue);
1644 standard_sub_basic(fname,sizeof(fname));
1646 add_to_file_list(pszParmValue, fname);
1648 string_set(ptr, fname);
1650 if (file_exist(fname))
1651 return (pm_process(fname, do_section, do_parameter, NULL));
1653 DEBUG(2, ("Can't find include file %s\n", fname));
1658 /***************************************************************************
1659 Handle the interpretation of the copy parameter.
1660 ***************************************************************************/
1662 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1666 service serviceTemp;
1668 string_set(ptr, pszParmValue);
1670 init_service(&serviceTemp);
1674 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1676 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1677 if (iTemp == iServiceIndex) {
1678 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1680 copy_service(ServicePtrs[iServiceIndex],
1682 ServicePtrs[iServiceIndex]->copymap);
1686 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1690 free_service(&serviceTemp);
1694 /***************************************************************************
1695 Initialise a copymap.
1696 ***************************************************************************/
1698 static void init_copymap(service * pservice)
1701 SAFE_FREE(pservice->copymap);
1702 pservice->copymap = malloc_array_p(int, NUMPARAMETERS);
1703 if (!pservice->copymap)
1705 ("Couldn't allocate copymap!! (size %d)\n",
1706 (int)NUMPARAMETERS));
1708 for (i = 0; i < NUMPARAMETERS; i++)
1709 pservice->copymap[i] = True;
1712 /***************************************************************************
1713 Return the local pointer to a parameter given the service number and the
1714 pointer into the default structure.
1715 ***************************************************************************/
1717 void *lp_local_ptr(int snum, void *ptr)
1719 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1723 /***************************************************************************
1724 Process a parametric option
1725 ***************************************************************************/
1726 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1728 struct param_opt *paramo, *data;
1731 while (isspace((unsigned char)*pszParmName)) {
1735 name = strdup(pszParmName);
1736 if (!name) return False;
1741 data = Globals.param_opt;
1743 data = ServicePtrs[snum]->param_opt;
1746 /* Traverse destination */
1747 for (paramo=data; paramo; paramo=paramo->next) {
1748 /* If we already have the option set, override it unless
1749 it was a command line option and the new one isn't */
1750 if (strcmp(paramo->key, name) == 0) {
1751 if ((paramo->flags & FLAG_CMDLINE) &&
1752 !(flags & FLAG_CMDLINE)) {
1756 free(paramo->value);
1757 paramo->value = strdup(pszParmValue);
1758 paramo->flags = flags;
1764 paramo = malloc_p(struct param_opt);
1767 paramo->key = strdup(name);
1768 paramo->value = strdup(pszParmValue);
1769 paramo->flags = flags;
1771 DLIST_ADD(Globals.param_opt, paramo);
1773 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1781 /***************************************************************************
1782 Process a parameter for a particular service number. If snum < 0
1783 then assume we are in the globals.
1784 ***************************************************************************/
1785 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1788 void *parm_ptr = NULL; /* where we are going to store the result */
1789 void *def_ptr = NULL;
1791 parmnum = map_parameter(pszParmName);
1794 if (strchr(pszParmName, ':')) {
1795 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1797 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1801 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1802 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1806 /* if the flag has been set on the command line, then don't allow override,
1807 but don't report an error */
1808 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1812 def_ptr = parm_table[parmnum].ptr;
1814 /* we might point at a service, the default service or a global */
1818 if (parm_table[parmnum].class == P_GLOBAL) {
1820 ("Global parameter %s found in service section!\n",
1825 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1830 if (!ServicePtrs[snum]->copymap)
1831 init_copymap(ServicePtrs[snum]);
1833 /* this handles the aliases - set the copymap for other entries with
1834 the same data pointer */
1835 for (i = 0; parm_table[i].label; i++)
1836 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1837 ServicePtrs[snum]->copymap[i] = False;
1840 /* if it is a special case then go ahead */
1841 if (parm_table[parmnum].special) {
1842 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1846 /* now switch on the type of variable it is */
1847 switch (parm_table[parmnum].type)
1850 if (!set_boolean(pszParmValue, parm_ptr)) {
1851 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1857 *(int *)parm_ptr = atoi(pszParmValue);
1863 if (conv_str_size(pszParmValue, &val)) {
1864 if (val <= INT_MAX) {
1865 *(int *)parm_ptr = (int)val;
1870 DEBUG(0,("lp_do_parameter(%s): value is not "
1871 "a valid size specifier!\n", pszParmValue));
1876 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1877 pszParmValue, NULL);
1881 string_set(parm_ptr, pszParmValue);
1885 string_set(parm_ptr, pszParmValue);
1886 strupper(*(char **)parm_ptr);
1890 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1893 parm_table[parmnum].enum_list[i].name)) {
1895 parm_table[parmnum].
1900 if (!parm_table[parmnum].enum_list[i].name) {
1901 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1902 pszParmValue, pszParmName));
1910 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1911 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1912 /* we have to also unset FLAG_DEFAULT on aliases */
1913 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1914 parm_table[i].flags &= ~FLAG_DEFAULT;
1916 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1917 parm_table[i].flags &= ~FLAG_DEFAULT;
1924 /***************************************************************************
1925 Process a parameter.
1926 ***************************************************************************/
1928 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1930 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1931 pszParmName, pszParmValue));
1935 variable argument do parameter
1937 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1939 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1946 s = talloc_vasprintf(NULL, fmt, ap);
1948 ret = do_parameter(pszParmName, s, NULL);
1955 set a parameter from the commandline - this is called from command line parameter
1956 parsing code. It sets the parameter then marks the parameter as unable to be modified
1957 by smb.conf processing
1959 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1961 int parmnum = map_parameter(pszParmName);
1964 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1967 if (parmnum < 0 && strchr(pszParmName, ':')) {
1968 /* set a parametric option */
1969 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1973 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1977 /* reset the CMDLINE flag in case this has been called before */
1978 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1980 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1984 parm_table[parmnum].flags |= FLAG_CMDLINE;
1986 /* we have to also set FLAG_CMDLINE on aliases */
1987 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1988 parm_table[i].flags |= FLAG_CMDLINE;
1990 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1991 parm_table[i].flags |= FLAG_CMDLINE;
1998 set a option from the commandline in 'a=b' format. Use to support --option
2000 BOOL lp_set_option(const char *option)
2018 ret = lp_set_cmdline(s, p+1);
2024 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2026 /***************************************************************************
2027 Print a parameter of the specified type.
2028 ***************************************************************************/
2030 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2036 for (i = 0; p->enum_list[i].name; i++) {
2037 if (*(int *)ptr == p->enum_list[i].value) {
2039 p->enum_list[i].name);
2046 fprintf(f, "%s", BOOLSTR((BOOL)*(int *)ptr));
2051 fprintf(f, "%d", *(int *)ptr);
2055 if ((char ***)ptr && *(char ***)ptr) {
2056 char **list = *(char ***)ptr;
2058 for (; *list; list++)
2059 fprintf(f, "%s%s", *list,
2060 ((*(list+1))?", ":""));
2066 if (*(char **)ptr) {
2067 fprintf(f, "%s", *(char **)ptr);
2075 /***************************************************************************
2076 Check if two parameters are equal.
2077 ***************************************************************************/
2079 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2083 return (*((int *)ptr1) == *((int *)ptr2));
2088 return (*((int *)ptr1) == *((int *)ptr2));
2091 return str_list_equal((const char **)(*(char ***)ptr1),
2092 (const char **)(*(char ***)ptr2));
2097 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2102 return (p1 == p2 || strequal(p1, p2));
2110 /***************************************************************************
2111 Process a new section (service). At this stage all sections are services.
2112 Later we'll have special sections that permit server parameters to be set.
2113 Returns True on success, False on failure.
2114 ***************************************************************************/
2116 static BOOL do_section(const char *pszSectionName, void *userdata)
2119 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2120 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2123 /* if we've just struck a global section, note the fact. */
2124 bInGlobalSection = isglobal;
2126 /* check for multiple global sections */
2127 if (bInGlobalSection) {
2128 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2132 /* if we have a current service, tidy it up before moving on */
2135 if (iServiceIndex >= 0)
2136 bRetval = service_ok(iServiceIndex);
2138 /* if all is still well, move to the next record in the services array */
2140 /* We put this here to avoid an odd message order if messages are */
2141 /* issued by the post-processing of a previous section. */
2142 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2144 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2146 DEBUG(0, ("Failed to add a new service\n"));
2155 /***************************************************************************
2156 Determine if a partcular base parameter is currentl set to the default value.
2157 ***************************************************************************/
2159 static BOOL is_default(int i)
2161 if (!defaults_saved)
2163 switch (parm_table[i].type) {
2165 return str_list_equal((const char **)parm_table[i].def.lvalue,
2166 (const char **)(*(char ***)parm_table[i].ptr));
2169 return strequal(parm_table[i].def.svalue,
2170 *(char **)parm_table[i].ptr);
2172 return parm_table[i].def.bvalue ==
2173 *(int *)parm_table[i].ptr;
2177 return parm_table[i].def.ivalue ==
2178 *(int *)parm_table[i].ptr;
2185 /***************************************************************************
2186 Display the contents of the global structure.
2187 ***************************************************************************/
2189 static void dump_globals(FILE *f, BOOL show_defaults)
2192 struct param_opt *data;
2194 fprintf(f, "# Global parameters\n[global]\n");
2196 for (i = 0; parm_table[i].label; i++)
2197 if (parm_table[i].class == P_GLOBAL &&
2198 parm_table[i].ptr &&
2199 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2200 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2202 fprintf(f, "\t%s = ", parm_table[i].label);
2203 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2206 if (Globals.param_opt != NULL) {
2207 data = Globals.param_opt;
2209 fprintf(f, "\t%s = %s\n", data->key, data->value);
2216 /***************************************************************************
2217 Display the contents of a single services record.
2218 ***************************************************************************/
2220 static void dump_a_service(service * pService, FILE * f)
2223 struct param_opt *data;
2225 if (pService != &sDefault)
2226 fprintf(f, "\n[%s]\n", pService->szService);
2228 for (i = 0; parm_table[i].label; i++)
2229 if (parm_table[i].class == P_LOCAL &&
2230 parm_table[i].ptr &&
2231 (*parm_table[i].label != '-') &&
2232 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2233 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2235 if (pService == &sDefault) {
2236 if (defaults_saved && is_default(i))
2239 if (equal_parameter(parm_table[i].type,
2240 ((char *)pService) +
2242 ((char *)&sDefault) +
2247 fprintf(f, "\t%s = ", parm_table[i].label);
2248 print_parameter(&parm_table[i],
2249 ((char *)pService) + pdiff, f);
2252 if (pService->param_opt != NULL) {
2253 data = pService->param_opt;
2255 fprintf(f, "\t%s = %s\n", data->key, data->value);
2261 BOOL lp_dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
2263 service * pService = ServicePtrs[snum];
2264 struct parm_struct *parm;
2267 parm = lp_parm_struct(parm_name);
2275 ptr = ((char *)pService) +
2276 PTR_DIFF(parm->ptr, &sDefault);
2278 print_parameter(parm,
2284 /***************************************************************************
2285 Return info about the next service in a service. snum==-1 gives the globals.
2286 Return NULL when out of parameters.
2287 ***************************************************************************/
2289 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2292 /* do the globals */
2293 for (; parm_table[*i].label; (*i)++) {
2294 if (parm_table[*i].class == P_SEPARATOR)
2295 return &parm_table[(*i)++];
2297 if (!parm_table[*i].ptr
2298 || (*parm_table[*i].label == '-'))
2302 && (parm_table[*i].ptr ==
2303 parm_table[(*i) - 1].ptr))
2306 return &parm_table[(*i)++];
2309 service *pService = ServicePtrs[snum];
2311 for (; parm_table[*i].label; (*i)++) {
2312 if (parm_table[*i].class == P_SEPARATOR)
2313 return &parm_table[(*i)++];
2315 if (parm_table[*i].class == P_LOCAL &&
2316 parm_table[*i].ptr &&
2317 (*parm_table[*i].label != '-') &&
2319 (parm_table[*i].ptr !=
2320 parm_table[(*i) - 1].ptr)))
2323 PTR_DIFF(parm_table[*i].ptr,
2326 if (allparameters ||
2327 !equal_parameter(parm_table[*i].type,
2328 ((char *)pService) +
2330 ((char *)&sDefault) +
2333 return &parm_table[(*i)++];
2343 /***************************************************************************
2344 Return TRUE if the passed service number is within range.
2345 ***************************************************************************/
2347 BOOL lp_snum_ok(int iService)
2349 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2352 /***************************************************************************
2353 Auto-load some home services.
2354 ***************************************************************************/
2356 static void lp_add_auto_services(const char *str)
2361 /***************************************************************************
2362 Announce ourselves as a print server.
2363 ***************************************************************************/
2365 void update_server_announce_as_printserver(void)
2367 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2370 /***************************************************************************
2371 Have we loaded a services file yet?
2372 ***************************************************************************/
2374 BOOL lp_loaded(void)
2379 /***************************************************************************
2380 Unload unused services.
2381 ***************************************************************************/
2383 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2386 for (i = 0; i < iNumServices; i++) {
2390 if (!snumused || !snumused(smb, i)) {
2391 ServicePtrs[i]->valid = False;
2392 free_service(ServicePtrs[i]);
2397 /***************************************************************************
2399 ***************************************************************************/
2401 void lp_killservice(int iServiceIn)
2403 if (VALID(iServiceIn)) {
2404 ServicePtrs[iServiceIn]->valid = False;
2405 free_service(ServicePtrs[iServiceIn]);
2409 /***************************************************************************
2410 Load the services array from the services file. Return True on success,
2412 ***************************************************************************/
2418 struct param_opt *data;
2422 bInGlobalSection = True;
2424 if (Globals.param_opt != NULL) {
2425 struct param_opt *next;
2426 for (data=Globals.param_opt; data; data=next) {
2428 if (data->flags & FLAG_CMDLINE) continue;
2431 DLIST_REMOVE(Globals.param_opt, data);
2438 pstrcpy(n2, lp_configfile());
2439 standard_sub_basic(n2,sizeof(n2));
2440 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2442 add_to_file_list(lp_configfile(), n2);
2444 /* We get sections first, so have to start 'behind' to make up */
2446 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2448 /* finish up the last section */
2449 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2451 if (iServiceIndex >= 0)
2452 bRetval = service_ok(iServiceIndex);
2454 lp_add_auto_services(lp_auto_services());
2456 lp_add_hidden("IPC$", "IPC");
2457 lp_add_hidden("ADMIN$", "DISK");
2459 set_default_server_announce_type();
2463 if (!Globals.szWINSservers && Globals.bWINSsupport) {
2464 lp_do_parameter(-1, "wins server", "127.0.0.1");
2472 /***************************************************************************
2473 Reset the max number of services.
2474 ***************************************************************************/
2476 void lp_resetnumservices(void)
2481 /***************************************************************************
2482 Return the max number of services.
2483 ***************************************************************************/
2485 int lp_numservices(void)
2487 return (iNumServices);
2490 /***************************************************************************
2491 Display the contents of the services array in human-readable form.
2492 ***************************************************************************/
2494 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2499 defaults_saved = False;
2501 dump_globals(f, show_defaults);
2503 dump_a_service(&sDefault, f);
2505 for (iService = 0; iService < maxtoprint; iService++)
2506 lp_dump_one(f, show_defaults, iService);
2509 /***************************************************************************
2510 Display the contents of one service in human-readable form.
2511 ***************************************************************************/
2513 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2516 if (ServicePtrs[snum]->szService[0] == '\0')
2518 dump_a_service(ServicePtrs[snum], f);
2522 /***************************************************************************
2523 Return the number of the service with the given name, or -1 if it doesn't
2524 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2525 getservicebyname()! This works ONLY if all services have been loaded, and
2526 does not copy the found service.
2527 ***************************************************************************/
2529 int lp_servicenumber(const char *pszServiceName)
2532 fstring serviceName;
2535 for (iService = iNumServices - 1; iService >= 0; iService--) {
2536 if (VALID(iService) && ServicePtrs[iService]->szService) {
2538 * The substitution here is used to support %U is
2541 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2542 standard_sub_basic(serviceName,sizeof(serviceName));
2543 if (strequal(serviceName, pszServiceName))
2549 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2554 int lp_find_valid_service(const char *pszServiceName)
2558 iService = lp_servicenumber(pszServiceName);
2560 if (iService >= 0 && !lp_snum_ok(iService)) {
2561 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService, pszServiceName));
2565 if (iService == -1) {
2566 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName));
2572 /*******************************************************************
2573 A useful volume label function.
2574 ********************************************************************/
2575 const char *volume_label(int snum)
2577 const char *ret = lp_volume(snum);
2579 return lp_servicename(snum);
2584 /*******************************************************************
2585 Set the server type we will announce as via nmbd.
2586 ********************************************************************/
2588 static void set_default_server_announce_type(void)
2590 default_server_announce = 0;
2591 default_server_announce |= SV_TYPE_WORKSTATION;
2592 default_server_announce |= SV_TYPE_SERVER;
2593 default_server_announce |= SV_TYPE_SERVER_UNIX;
2595 switch (lp_announce_as()) {
2596 case ANNOUNCE_AS_NT_SERVER:
2597 default_server_announce |= SV_TYPE_SERVER_NT;
2598 /* fall through... */
2599 case ANNOUNCE_AS_NT_WORKSTATION:
2600 default_server_announce |= SV_TYPE_NT;
2602 case ANNOUNCE_AS_WIN95:
2603 default_server_announce |= SV_TYPE_WIN95_PLUS;
2605 case ANNOUNCE_AS_WFW:
2606 default_server_announce |= SV_TYPE_WFW;
2612 switch (lp_server_role()) {
2613 case ROLE_DOMAIN_MEMBER:
2614 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2616 case ROLE_DOMAIN_PDC:
2617 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2619 case ROLE_DOMAIN_BDC:
2620 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2622 case ROLE_STANDALONE:
2626 if (lp_time_server())
2627 default_server_announce |= SV_TYPE_TIME_SOURCE;
2629 if (lp_host_msdfs())
2630 default_server_announce |= SV_TYPE_DFS_SERVER;
2632 /* TODO: only announce us as print server when we are a print server */
2633 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2636 /***********************************************************
2637 If we are PDC then prefer us as DMB
2638 ************************************************************/
2640 BOOL lp_domain_master(void)
2642 return (lp_server_role() == ROLE_DOMAIN_PDC);
2645 /***********************************************************
2646 If we are PDC then prefer us as DMB
2647 ************************************************************/
2649 BOOL lp_domain_logons(void)
2651 return (lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC);
2654 /***********************************************************
2655 If we are DMB then prefer us as LMB
2656 ************************************************************/
2658 BOOL lp_preferred_master(void)
2660 return (lp_local_master() && lp_domain_master());
2663 /*******************************************************************
2665 ********************************************************************/
2667 void lp_remove_service(int snum)
2669 ServicePtrs[snum]->valid = False;
2672 /*******************************************************************
2674 ********************************************************************/
2676 void lp_copy_service(int snum, const char *new_name)
2678 const char *oldname = lp_servicename(snum);
2679 do_section(new_name, NULL);
2681 snum = lp_servicenumber(new_name);
2683 lp_do_parameter(snum, "copy", oldname);
2688 /*******************************************************************
2689 Get the default server type we will announce as via nmbd.
2690 ********************************************************************/
2691 int lp_default_server_announce(void)
2693 return default_server_announce;
2696 const char *lp_printername(int snum)
2698 const char *ret = _lp_printername(snum);
2699 if (ret == NULL || (ret != NULL && *ret == '\0'))
2700 ret = lp_const_servicename(snum);
2706 /*******************************************************************
2707 Return the max print jobs per queue.
2708 ********************************************************************/
2710 int lp_maxprintjobs(int snum)
2712 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2713 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2714 maxjobs = PRINT_MAX_JOBID - 1;