2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/iconv.h"
60 #include "system/network.h"
61 #include "system/printing.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "librpc/gen_ndr/ndr_nbt.h"
65 #include "dlinklist.h"
66 #include "param/loadparm.h"
68 static BOOL bLoaded = False;
71 #define GLOBAL_NAME "global"
75 #define PRINTERS_NAME "printers"
79 #define HOMES_NAME "homes"
82 /* some helpful bits */
83 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
84 #define VALID(i) ServicePtrs[i]->valid
86 static BOOL do_parameter(const char *, const char *, void *);
87 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
89 static BOOL defaults_saved = False;
93 struct param_opt *prev, *next;
100 * This structure describes global (ie., server-wide) parameters.
108 char *display_charset;
112 char *szServerString;
113 char *szAutoServices;
117 char *szSMBPasswdFile;
123 char **szPasswordServers;
124 char *szSocketOptions;
126 char **szWINSservers;
128 char *szSocketAddress;
129 char *szAnnounceVersion; /* This is initialised in init_globals */
132 char **szNetbiosAliases;
133 char *szNetbiosScope;
134 char *szDomainOtherSIDs;
135 char **szNameResolveOrder;
137 char **dcerpc_ep_servers;
138 char **server_services;
139 char *ntptr_providor;
142 char *szNonUnixAccountRange;
143 char *szWinbindSeparator;
144 char *swat_directory;
157 BOOL paranoid_server_security;
160 int announce_as; /* This is initialised in init_globals */
166 char *socket_options;
169 BOOL bPreferredMaster;
172 BOOL bEncryptPasswords;
174 BOOL bObeyPamRestrictions;
175 BOOL bLargeReadwrite;
179 BOOL bBindInterfacesOnly;
181 BOOL bNTStatusSupport;
187 BOOL bClientPlaintextAuth;
188 BOOL bClientLanManAuth;
189 BOOL bClientNTLMv2Auth;
192 BOOL bUnixExtensions;
193 BOOL bDisableNetbios;
195 struct param_opt *param_opt;
199 static global Globals;
202 * This structure describes a single service.
217 char **ntvfs_handler;
233 struct param_opt *param_opt;
235 char dummy[3]; /* for alignment */
240 /* This is a default service used to prime a services structure */
241 static service sDefault = {
243 NULL, /* szService */
246 NULL, /* szInclude */
247 NULL, /* szPrintername */
248 NULL, /* szHostsallow */
249 NULL, /* szHostsdeny */
253 NULL, /* ntvfs_handler */
254 1000, /* iMaxPrintJobs */
255 0, /* iMaxConnections */
257 True, /* bAvailable */
258 True, /* bBrowseable */
259 True, /* bRead_only */
260 False, /* bPrint_ok */
261 False, /* bMap_system */
262 False, /* bMap_hidden */
263 True, /* bMap_archive */
264 True, /* bStrictLocking */
266 False, /* bMSDfsRoot */
267 False, /* bStrictSync */
268 False, /* bCIFileSystem */
269 NULL, /* Parametric options */
274 /* local variables */
275 static service **ServicePtrs = NULL;
276 static int iNumServices = 0;
277 static int iServiceIndex = 0;
278 static BOOL bInGlobalSection = True;
279 static int server_role;
280 static int default_server_announce;
282 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
284 /* prototypes for the special type handlers */
285 static BOOL handle_include(const char *pszParmValue, char **ptr);
286 static BOOL handle_copy(const char *pszParmValue, char **ptr);
287 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
288 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
289 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
291 static void set_server_role(void);
292 static void set_default_server_announce_type(void);
294 static const struct enum_list enum_protocol[] = {
295 {PROTOCOL_NT1, "NT1"},
296 {PROTOCOL_LANMAN2, "LANMAN2"},
297 {PROTOCOL_LANMAN1, "LANMAN1"},
298 {PROTOCOL_CORE, "CORE"},
299 {PROTOCOL_COREPLUS, "COREPLUS"},
300 {PROTOCOL_COREPLUS, "CORE+"},
304 static const struct enum_list enum_security[] = {
305 {SEC_SHARE, "SHARE"},
307 {SEC_SERVER, "SERVER"},
308 {SEC_DOMAIN, "DOMAIN"},
315 /* Types of machine we can announce as. */
316 #define ANNOUNCE_AS_NT_SERVER 1
317 #define ANNOUNCE_AS_WIN95 2
318 #define ANNOUNCE_AS_WFW 3
319 #define ANNOUNCE_AS_NT_WORKSTATION 4
321 static const struct enum_list enum_announce_as[] = {
322 {ANNOUNCE_AS_NT_SERVER, "NT"},
323 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
324 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
325 {ANNOUNCE_AS_WIN95, "win95"},
326 {ANNOUNCE_AS_WFW, "WfW"},
330 static const struct enum_list enum_bool_auto[] = {
341 /* Client-side offline caching policy types */
342 #define CSC_POLICY_MANUAL 0
343 #define CSC_POLICY_DOCUMENTS 1
344 #define CSC_POLICY_PROGRAMS 2
345 #define CSC_POLICY_DISABLE 3
347 static const struct enum_list enum_csc_policy[] = {
348 {CSC_POLICY_MANUAL, "manual"},
349 {CSC_POLICY_DOCUMENTS, "documents"},
350 {CSC_POLICY_PROGRAMS, "programs"},
351 {CSC_POLICY_DISABLE, "disable"},
355 /* SMB signing types. */
356 static const struct enum_list enum_smb_signing_vals[] = {
357 {SMB_SIGNING_OFF, "No"},
358 {SMB_SIGNING_OFF, "False"},
359 {SMB_SIGNING_OFF, "0"},
360 {SMB_SIGNING_OFF, "Off"},
361 {SMB_SIGNING_OFF, "disabled"},
362 {SMB_SIGNING_SUPPORTED, "Yes"},
363 {SMB_SIGNING_SUPPORTED, "True"},
364 {SMB_SIGNING_SUPPORTED, "1"},
365 {SMB_SIGNING_SUPPORTED, "On"},
366 {SMB_SIGNING_SUPPORTED, "enabled"},
367 {SMB_SIGNING_REQUIRED, "required"},
368 {SMB_SIGNING_REQUIRED, "mandatory"},
369 {SMB_SIGNING_REQUIRED, "force"},
370 {SMB_SIGNING_REQUIRED, "forced"},
371 {SMB_SIGNING_REQUIRED, "enforced"},
372 {SMB_SIGNING_AUTO, "auto"},
377 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
379 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
380 * is implied in current control logic. This may change at some later time. A
381 * flag value of 0 means - show as development option only.
383 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
384 * screen in SWAT. This is used to exclude parameters as well as to squash all
385 * parameters that have been duplicated by pseudonyms.
387 static struct parm_struct parm_table[] = {
388 {"Base Options", P_SEP, P_SEPARATOR},
390 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
391 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
392 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
393 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
394 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
395 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
396 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
397 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
398 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
402 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
403 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
404 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
406 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
407 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
408 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
410 {"Security Options", P_SEP, P_SEPARATOR},
412 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
413 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
414 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
415 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
418 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
430 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
431 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
433 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
435 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
436 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
438 {"Logging Options", P_SEP, P_SEPARATOR},
440 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
442 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"Protocol Options", P_SEP, P_SEPARATOR},
446 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
459 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
460 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
461 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
462 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
463 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
464 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
466 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
468 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
469 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
470 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
471 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
473 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
474 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
475 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
477 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
478 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
479 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
480 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
481 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
483 {"Tuning Options", P_SEP, P_SEPARATOR},
485 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
486 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
487 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
489 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
490 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
492 {"Printing Options", P_SEP, P_SEPARATOR},
494 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
495 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
496 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
498 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
499 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
501 {"Filename Handling", P_SEP, P_SEPARATOR},
503 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
504 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
505 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
507 {"Domain Options", P_SEP, P_SEPARATOR},
509 {"Logon Options", P_SEP, P_SEPARATOR},
511 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
513 {"Browse Options", P_SEP, P_SEPARATOR},
515 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
516 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
517 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
518 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
519 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
520 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
522 {"WINS Options", P_SEP, P_SEPARATOR},
524 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
525 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
527 {"Locking Options", P_SEP, P_SEPARATOR},
529 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
531 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
533 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
535 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
536 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
539 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
545 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
547 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
548 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
550 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
551 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
552 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
554 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
557 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"Winbind options", P_SEP, P_SEPARATOR},
561 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
570 return the parameter table
572 struct parm_struct *lp_parm_table(void)
577 /***************************************************************************
578 Initialise the global parameter structure.
579 ***************************************************************************/
580 static void init_globals(void)
585 DEBUG(3, ("Initialising global parameters\n"));
587 for (i = 0; parm_table[i].label; i++) {
588 if ((parm_table[i].type == P_STRING ||
589 parm_table[i].type == P_USTRING) &&
591 !(parm_table[i].flags & FLAG_CMDLINE)) {
592 string_set(parm_table[i].ptr, "");
596 do_parameter("config file", dyn_CONFIGFILE, NULL);
598 /* options that can be set on the command line must be initialised via
599 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
601 do_parameter("socket options", "TCP_NODELAY", NULL);
603 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
604 myname = get_myname();
605 do_parameter("netbios name", myname, NULL);
607 do_parameter("max protocol", "NT1", NULL);
608 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
610 do_parameter("fstype", FSTYPE_STRING, NULL);
611 do_parameter("ntvfs handler", "unixuid default", NULL);
612 do_parameter("max connections", "-1", NULL);
614 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
615 do_parameter("server services", "smb rpc nbt ldap cldap web kdc", NULL);
616 do_parameter("ntptr providor", "simple_ldb", NULL);
617 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
618 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE, NULL);
619 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
620 do_parameter("sam database", "sam.ldb", NULL);
621 do_parameter("spoolss database", "spoolss.ldb", NULL);
622 do_parameter("wins database", "wins.ldb", NULL);
623 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
625 /* This hive should be dynamically generated by Samba using
626 data from the sam, but for the moment leave it in a tdb to
627 keep regedt32 from popping up an annoying dialog. */
628 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
630 /* using UTF8 by default allows us to support all chars */
631 do_parameter("unix charset", "UTF8", NULL);
633 /* Use codepage 850 as a default for the dos character set */
634 do_parameter("dos charset", "CP850", NULL);
637 * Allow the default PASSWD_CHAT to be overridden in local.h.
639 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
641 do_parameter("pid directory", dyn_PIDDIR, NULL);
642 do_parameter("lock dir", dyn_LOCKDIR, NULL);
643 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
645 do_parameter("socket address", "0.0.0.0", NULL);
646 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
648 do_parameter_var("announce version", "%d.%d",
649 DEFAULT_MAJOR_VERSION,
650 DEFAULT_MINOR_VERSION);
652 do_parameter("password server", "*", NULL);
654 do_parameter("max mux", "50", NULL);
655 do_parameter("max xmit", "12288", NULL);
656 do_parameter("password level", "0", NULL);
657 do_parameter("LargeReadwrite", "True", NULL);
658 do_parameter("minprotocol", "CORE", NULL);
659 do_parameter("security", "USER", NULL);
660 do_parameter("paranoid server security", "True", NULL);
661 do_parameter("EncryptPasswords", "True", NULL);
662 do_parameter("ReadRaw", "True", NULL);
663 do_parameter("WriteRaw", "True", NULL);
664 do_parameter("NullPasswords", "False", NULL);
665 do_parameter("ObeyPamRestrictions", "False", NULL);
666 do_parameter("announce as", "NT SERVER", NULL);
668 do_parameter("TimeServer", "False", NULL);
669 do_parameter("BindInterfacesOnly", "False", NULL);
670 do_parameter("Unicode", "True", NULL);
671 do_parameter("ClientLanManAuth", "True", NULL);
672 do_parameter("LanmanAuth", "True", NULL);
673 do_parameter("NTLMAuth", "True", NULL);
675 do_parameter("UnixExtensions", "False", NULL);
677 do_parameter("PreferredMaster", "Auto", NULL);
678 do_parameter("LocalMaster", "True", NULL);
679 do_parameter("DomainMaster", "Auto", NULL); /* depending on bDomainLogons */
680 do_parameter("DomainLogons", "False", NULL);
681 do_parameter("WINSsupport", "False", NULL);
683 do_parameter("WinbindSeparator", "\\", NULL);
685 do_parameter("client signing", "Yes", NULL);
686 do_parameter("server signing", "auto", NULL);
688 do_parameter("use spnego", "True", NULL);
690 do_parameter("smb ports", SMB_PORTS, NULL);
691 do_parameter("nbt port", "137", NULL);
692 do_parameter("dgram port", "138", NULL);
693 do_parameter("cldap port", "389", NULL);
694 do_parameter("krb5 port", "88", NULL);
695 do_parameter("web port", "901", NULL);
696 do_parameter("swat directory", dyn_SWATDIR, NULL);
698 do_parameter("nt status support", "True", NULL);
700 do_parameter("max wins ttl", "432000", NULL);
701 do_parameter("min wins ttl", "10", NULL);
703 do_parameter("tls enabled", "True", NULL);
704 do_parameter("tls keyfile", "tls/key.pem", NULL);
705 do_parameter("tls certfile", "tls/cert.pem", NULL);
706 do_parameter("tls cafile", "tls/ca.pem", NULL);
707 do_parameter_var("js include", "%s/js", dyn_LIBDIR);
708 do_parameter_var("setup directory", "%s/setup", dyn_LIBDIR);
711 static TALLOC_CTX *lp_talloc;
713 /******************************************************************* a
714 Free up temporary memory - called from the main loop.
715 ********************************************************************/
717 void lp_talloc_free(void)
721 talloc_free(lp_talloc);
725 /*******************************************************************
726 Convenience routine to grab string parameters into temporary memory
727 and run standard_sub_basic on them. The buffers can be written to by
728 callers without affecting the source string.
729 ********************************************************************/
731 static const char *lp_string(const char *s)
733 #if 0 /* until REWRITE done to make thread-safe */
734 size_t len = s ? strlen(s) : 0;
738 /* The follow debug is useful for tracking down memory problems
739 especially if you have an inner loop that is calling a lp_*()
740 function that returns a string. Perhaps this debug should be
741 present all the time? */
744 DEBUG(10, ("lp_string(%s)\n", s));
747 #if 0 /* until REWRITE done to make thread-safe */
749 lp_talloc = talloc_init("lp_talloc");
751 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
759 StrnCpy(ret, s, len);
761 if (trim_string(ret, "\"", "\"")) {
762 if (strchr(ret,'"') != NULL)
763 StrnCpy(ret, s, len);
766 standard_sub_basic(ret,len+100);
773 In this section all the functions that are used to access the
774 parameters from the rest of the program are defined
777 #define FN_GLOBAL_STRING(fn_name,ptr) \
778 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
779 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
780 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
781 #define FN_GLOBAL_LIST(fn_name,ptr) \
782 const char **fn_name(void) {return(*(const char ***)(ptr));}
783 #define FN_GLOBAL_BOOL(fn_name,ptr) \
784 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
785 #define FN_GLOBAL_CHAR(fn_name,ptr) \
786 char fn_name(void) {return(*(char *)(ptr));}
787 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
788 int fn_name(void) {return(*(int *)(ptr));}
790 #define FN_LOCAL_STRING(fn_name,val) \
791 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
792 #define FN_LOCAL_CONST_STRING(fn_name,val) \
793 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
794 #define FN_LOCAL_LIST(fn_name,val) \
795 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
796 #define FN_LOCAL_BOOL(fn_name,val) \
797 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
798 #define FN_LOCAL_CHAR(fn_name,val) \
799 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
800 #define FN_LOCAL_INTEGER(fn_name,val) \
801 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
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_web_port, &Globals.web_port)
809 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
810 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
811 FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
812 FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
813 FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
814 FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
815 FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
816 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
817 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
818 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
819 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
820 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
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_url, &Globals.szWINS_URL)
824 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
825 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
826 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
827 FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
828 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
829 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
830 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
831 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
832 FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
833 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
834 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
835 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
836 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
837 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
838 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
839 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
840 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
841 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
842 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
843 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
844 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
845 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
846 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
849 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
851 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
852 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
853 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
854 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
855 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
856 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
857 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
858 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
859 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
860 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
861 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
862 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
863 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
864 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
865 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
866 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
867 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
868 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
869 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
870 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
871 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
872 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
873 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
874 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
875 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
876 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
877 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
878 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
879 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
880 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
881 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
882 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
883 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
884 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
885 FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
888 FN_LOCAL_STRING(lp_servicename, szService)
889 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
890 FN_LOCAL_STRING(lp_pathname, szPath)
891 static FN_LOCAL_STRING(_lp_printername, szPrintername)
892 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
893 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
894 FN_LOCAL_STRING(lp_comment, comment)
895 FN_LOCAL_STRING(lp_fstype, fstype)
896 static FN_LOCAL_STRING(lp_volume, volume)
897 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
898 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
899 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
900 FN_LOCAL_BOOL(lp_readonly, bRead_only)
901 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
902 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
903 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
904 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
905 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
906 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
907 FN_LOCAL_BOOL(lp_map_system, bMap_system)
908 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
909 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
910 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
911 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
913 /* local prototypes */
915 static int map_parameter(const char *pszParmName);
916 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
917 static int getservicebyname(const char *pszServiceName,
918 service * pserviceDest);
919 static void copy_service(service * pserviceDest,
920 service * pserviceSource, BOOL *pcopymapDest);
921 static BOOL service_ok(int iService);
922 static BOOL do_section(const char *pszSectionName, void *);
923 static void init_copymap(service * pservice);
925 /* This is a helper function for parametrical options support. */
926 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
927 /* Actual parametrical functions are quite simple */
928 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
931 struct param_opt *data;
933 if (lookup_service >= iNumServices) return NULL;
935 data = (lookup_service < 0) ?
936 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
938 asprintf(&vfskey, "%s:%s", type, option);
942 if (strcmp(data->key, vfskey) == 0) {
949 if (lookup_service >= 0) {
950 /* Try to fetch the same option but from globals */
951 /* but only if we are not already working with Globals */
952 data = Globals.param_opt;
954 if (strcmp(data->key, vfskey) == 0) {
968 /*******************************************************************
969 convenience routine to return int parameters.
970 ********************************************************************/
971 static int lp_int(const char *s)
975 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
979 return strtol(s, NULL, 0);
982 /*******************************************************************
983 convenience routine to return unsigned long parameters.
984 ********************************************************************/
985 static int lp_ulong(const char *s)
989 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
993 return strtoul(s, NULL, 0);
996 /*******************************************************************
997 convenience routine to return boolean parameters.
998 ********************************************************************/
999 static BOOL lp_bool(const char *s)
1004 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1008 if (!set_boolean(&ret,s)) {
1009 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1017 /* Return parametric option from a given service. Type is a part of option before ':' */
1018 /* Parametric option has following syntax: 'Type: option = value' */
1019 /* Returned value is allocated in 'lp_talloc' context */
1021 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1023 const char *value = lp_get_parametric(lookup_service, type, option);
1026 return lp_string(value);
1031 /* Return parametric option from a given service. Type is a part of option before ':' */
1032 /* Parametric option has following syntax: 'Type: option = value' */
1033 /* Returned value is allocated in 'lp_talloc' context */
1035 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1036 const char *separator)
1038 const char *value = lp_get_parametric(lookup_service, type, option);
1041 return str_list_make(talloc_autofree_context(), value, separator);
1046 /* Return parametric option from a given service. Type is a part of option before ':' */
1047 /* Parametric option has following syntax: 'Type: option = value' */
1049 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1051 const char *value = lp_get_parametric(lookup_service, type, option);
1054 return lp_int(value);
1059 /* Return parametric option from a given service. Type is a part of option before ':' */
1060 /* Parametric option has following syntax: 'Type: option = value' */
1062 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1064 const char *value = lp_get_parametric(lookup_service, type, option);
1067 return lp_ulong(value);
1072 /* Return parametric option from a given service. Type is a part of option before ':' */
1073 /* Parametric option has following syntax: 'Type: option = value' */
1075 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1077 const char *value = lp_get_parametric(lookup_service, type, option);
1080 return lp_bool(value);
1086 /***************************************************************************
1087 Initialise a service to the defaults.
1088 ***************************************************************************/
1090 static void init_service(service * pservice)
1092 memset((char *)pservice, '\0', sizeof(service));
1093 copy_service(pservice, &sDefault, NULL);
1096 /***************************************************************************
1097 Free the dynamically allocated parts of a service struct.
1098 ***************************************************************************/
1100 static void free_service(service *pservice)
1103 struct param_opt *data, *pdata;
1107 if (pservice->szService)
1108 DEBUG(5, ("free_service: Freeing service %s\n",
1109 pservice->szService));
1111 string_free(&pservice->szService);
1112 SAFE_FREE(pservice->copymap);
1114 for (i = 0; parm_table[i].label; i++) {
1115 if ((parm_table[i].type == P_STRING ||
1116 parm_table[i].type == P_USTRING) &&
1117 parm_table[i].class == P_LOCAL) {
1118 string_free((char **)
1119 (((char *)pservice) +
1120 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1121 } else if (parm_table[i].type == P_LIST &&
1122 parm_table[i].class == P_LOCAL) {
1123 char ***listp = (char ***)(((char *)pservice) +
1124 PTR_DIFF(parm_table[i].ptr, &sDefault));
1125 talloc_free(*listp);
1130 DEBUG(5,("Freeing parametrics:\n"));
1131 data = pservice->param_opt;
1133 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1134 string_free(&data->key);
1135 string_free(&data->value);
1141 ZERO_STRUCTP(pservice);
1144 /***************************************************************************
1145 Add a new service to the services array initialising it with the given
1147 ***************************************************************************/
1149 static int add_a_service(const service *pservice, const char *name)
1153 int num_to_alloc = iNumServices + 1;
1154 struct param_opt *data, *pdata;
1156 tservice = *pservice;
1158 /* it might already exist */
1160 i = getservicebyname(name, NULL);
1162 /* Clean all parametric options for service */
1163 /* They will be added during parsing again */
1164 data = ServicePtrs[i]->param_opt;
1166 string_free(&data->key);
1167 string_free(&data->value);
1172 ServicePtrs[i]->param_opt = NULL;
1177 /* find an invalid one */
1178 for (i = 0; i < iNumServices; i++)
1179 if (!ServicePtrs[i]->valid)
1182 /* if not, then create one */
1183 if (i == iNumServices) {
1186 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1189 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1194 ServicePtrs[iNumServices] = malloc_p(service);
1196 if (!ServicePtrs[iNumServices]) {
1197 DEBUG(0,("add_a_service: out of memory!\n"));
1203 free_service(ServicePtrs[i]);
1205 ServicePtrs[i]->valid = True;
1207 init_service(ServicePtrs[i]);
1208 copy_service(ServicePtrs[i], &tservice, NULL);
1210 string_set(&ServicePtrs[i]->szService, name);
1214 /***************************************************************************
1215 Add a new home service, with the specified home directory, defaults coming
1217 ***************************************************************************/
1219 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1220 const char *user, const char *pszHomedir)
1225 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1230 if (!(*(ServicePtrs[iDefaultService]->szPath))
1231 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1232 pstrcpy(newHomedir, pszHomedir);
1234 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1235 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1238 string_set(&ServicePtrs[i]->szPath, newHomedir);
1240 if (!(*(ServicePtrs[i]->comment))) {
1242 slprintf(comment, sizeof(comment) - 1,
1243 "Home directory of %s", user);
1244 string_set(&ServicePtrs[i]->comment, comment);
1246 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1247 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1249 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1255 /***************************************************************************
1256 Add a new service, based on an old one.
1257 ***************************************************************************/
1259 int lp_add_service(const char *pszService, int iDefaultService)
1261 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1264 /***************************************************************************
1265 Add the IPC service.
1266 ***************************************************************************/
1268 static BOOL lp_add_hidden(const char *name, const char *fstype)
1271 int i = add_a_service(&sDefault, name);
1276 slprintf(comment, sizeof(comment) - 1,
1277 "%s Service (%s)", fstype, Globals.szServerString);
1279 string_set(&ServicePtrs[i]->szPath, tmpdir());
1280 string_set(&ServicePtrs[i]->comment, comment);
1281 string_set(&ServicePtrs[i]->fstype, fstype);
1282 ServicePtrs[i]->iMaxConnections = -1;
1283 ServicePtrs[i]->bAvailable = True;
1284 ServicePtrs[i]->bRead_only = True;
1285 ServicePtrs[i]->bPrint_ok = False;
1286 ServicePtrs[i]->bBrowseable = False;
1288 if (strcasecmp(fstype, "IPC") == 0) {
1289 lp_do_parameter(i, "ntvfs handler", "default");
1292 DEBUG(3, ("adding hidden service %s\n", name));
1297 /***************************************************************************
1298 Add a new printer service, with defaults coming from service iFrom.
1299 ***************************************************************************/
1301 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1303 const char *comment = "From Printcap";
1304 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1309 /* note that we do NOT default the availability flag to True - */
1310 /* we take it from the default service passed. This allows all */
1311 /* dynamic printers to be disabled by disabling the [printers] */
1312 /* entry (if/when the 'available' keyword is implemented!). */
1314 /* the printer name is set to the service name. */
1315 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1316 string_set(&ServicePtrs[i]->comment, comment);
1317 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1318 /* Printers cannot be read_only. */
1319 ServicePtrs[i]->bRead_only = False;
1320 /* Printer services must be printable. */
1321 ServicePtrs[i]->bPrint_ok = True;
1323 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1325 update_server_announce_as_printserver();
1330 /***************************************************************************
1331 Map a parameter's string representation to something we can use.
1332 Returns False if the parameter string is not recognised, else TRUE.
1333 ***************************************************************************/
1335 static int map_parameter(const char *pszParmName)
1339 if (*pszParmName == '-')
1342 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1343 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1346 /* Warn only if it isn't parametric option */
1347 if (strchr(pszParmName, ':') == NULL)
1348 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1349 /* We do return 'fail' for parametric options as well because they are
1350 stored in different storage
1357 return the parameter structure for a parameter
1359 struct parm_struct *lp_parm_struct(const char *name)
1361 int parmnum = map_parameter(name);
1362 if (parmnum == -1) return NULL;
1363 return &parm_table[parmnum];
1367 return the parameter pointer for a parameter
1369 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1374 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1377 /***************************************************************************
1378 Set a boolean variable from the text value stored in the passed string.
1379 Returns True in success, False if the passed string does not correctly
1380 represent a boolean.
1381 ***************************************************************************/
1383 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1388 if (strwicmp(pszParmValue, "yes") == 0 ||
1389 strwicmp(pszParmValue, "true") == 0 ||
1390 strwicmp(pszParmValue, "1") == 0)
1392 else if (strwicmp(pszParmValue, "no") == 0 ||
1393 strwicmp(pszParmValue, "False") == 0 ||
1394 strwicmp(pszParmValue, "0") == 0)
1398 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1405 /***************************************************************************
1406 Find a service by name. Otherwise works like get_service.
1407 ***************************************************************************/
1409 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1413 for (iService = iNumServices - 1; iService >= 0; iService--)
1414 if (VALID(iService) &&
1415 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1416 if (pserviceDest != NULL)
1417 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1424 /***************************************************************************
1425 Copy a service structure to another.
1426 If pcopymapDest is NULL then copy all fields
1427 ***************************************************************************/
1429 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1432 BOOL bcopyall = (pcopymapDest == NULL);
1433 struct param_opt *data, *pdata, *paramo;
1436 for (i = 0; parm_table[i].label; i++)
1437 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1438 (bcopyall || pcopymapDest[i])) {
1439 void *def_ptr = parm_table[i].ptr;
1441 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1444 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1447 switch (parm_table[i].type) {
1449 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1454 *(int *)dest_ptr = *(int *)src_ptr;
1458 string_set(dest_ptr,
1463 string_set(dest_ptr,
1465 strupper(*(char **)dest_ptr);
1468 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1469 *(const char ***)src_ptr);
1477 init_copymap(pserviceDest);
1478 if (pserviceSource->copymap)
1479 memcpy((void *)pserviceDest->copymap,
1480 (void *)pserviceSource->copymap,
1481 sizeof(BOOL) * NUMPARAMETERS);
1484 data = pserviceSource->param_opt;
1487 pdata = pserviceDest->param_opt;
1488 /* Traverse destination */
1490 /* If we already have same option, override it */
1491 if (strcmp(pdata->key, data->key) == 0) {
1492 string_free(&pdata->value);
1493 pdata->value = strdup(data->value);
1497 pdata = pdata->next;
1500 paramo = smb_xmalloc_p(struct param_opt);
1501 paramo->key = strdup(data->key);
1502 paramo->value = strdup(data->value);
1503 DLIST_ADD(pserviceDest->param_opt, paramo);
1509 /***************************************************************************
1510 Check a service for consistency. Return False if the service is in any way
1511 incomplete or faulty, else True.
1512 ***************************************************************************/
1514 static BOOL service_ok(int iService)
1519 if (ServicePtrs[iService]->szService[0] == '\0') {
1520 DEBUG(0, ("The following message indicates an internal error:\n"));
1521 DEBUG(0, ("No service name in service entry.\n"));
1525 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1526 /* I can't see why you'd want a non-printable printer service... */
1527 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1528 if (!ServicePtrs[iService]->bPrint_ok) {
1529 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1530 ServicePtrs[iService]->szService));
1531 ServicePtrs[iService]->bPrint_ok = True;
1532 update_server_announce_as_printserver();
1534 /* [printers] service must also be non-browsable. */
1535 if (ServicePtrs[iService]->bBrowseable)
1536 ServicePtrs[iService]->bBrowseable = False;
1539 /* If a service is flagged unavailable, log the fact at level 0. */
1540 if (!ServicePtrs[iService]->bAvailable)
1541 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1542 ServicePtrs[iService]->szService));
1547 static struct file_lists {
1548 struct file_lists *next;
1552 } *file_lists = NULL;
1554 /*******************************************************************
1555 Keep a linked list of all config files so we know when one has changed
1556 it's date and needs to be reloaded.
1557 ********************************************************************/
1559 static void add_to_file_list(const char *fname, const char *subfname)
1561 struct file_lists *f = file_lists;
1564 if (f->name && !strcmp(f->name, fname))
1570 f = malloc_p(struct file_lists);
1573 f->next = file_lists;
1574 f->name = strdup(fname);
1579 f->subfname = strdup(subfname);
1585 f->modtime = file_modtime(subfname);
1587 time_t t = file_modtime(subfname);
1593 /*******************************************************************
1594 Check if a config file has changed date.
1595 ********************************************************************/
1597 BOOL lp_file_list_changed(void)
1599 struct file_lists *f = file_lists;
1600 DEBUG(6, ("lp_file_list_changed()\n"));
1606 pstrcpy(n2, f->name);
1607 standard_sub_basic(n2,sizeof(n2));
1609 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1610 f->name, n2, ctime(&f->modtime)));
1612 mod_time = file_modtime(n2);
1614 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1616 ("file %s modified: %s\n", n2,
1618 f->modtime = mod_time;
1619 SAFE_FREE(f->subfname);
1620 f->subfname = strdup(n2);
1628 /***************************************************************************
1629 Handle the include operation.
1630 ***************************************************************************/
1632 static BOOL handle_include(const char *pszParmValue, char **ptr)
1635 pstrcpy(fname, pszParmValue);
1637 standard_sub_basic(fname,sizeof(fname));
1639 add_to_file_list(pszParmValue, fname);
1641 string_set(ptr, fname);
1643 if (file_exist(fname))
1644 return (pm_process(fname, do_section, do_parameter, NULL));
1646 DEBUG(2, ("Can't find include file %s\n", fname));
1651 /***************************************************************************
1652 Handle the interpretation of the copy parameter.
1653 ***************************************************************************/
1655 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1659 service serviceTemp;
1661 string_set(ptr, pszParmValue);
1663 init_service(&serviceTemp);
1667 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1669 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1670 if (iTemp == iServiceIndex) {
1671 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1673 copy_service(ServicePtrs[iServiceIndex],
1675 ServicePtrs[iServiceIndex]->copymap);
1679 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1683 free_service(&serviceTemp);
1687 /***************************************************************************
1688 Handle winbind/non unix account uid and gid allocation parameters. The format of these
1693 winbind uid = 1000-1999
1694 winbind gid = 700-899
1696 We only do simple parsing checks here. The strings are parsed into useful
1697 structures in the winbind daemon code.
1699 ***************************************************************************/
1701 /* Some lp_ routines to return winbind [ug]id information */
1703 static uid_t winbind_uid_low, winbind_uid_high;
1704 static gid_t winbind_gid_low, winbind_gid_high;
1705 static uint32_t non_unix_account_low, non_unix_account_high;
1707 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
1709 if (winbind_uid_low == 0 || winbind_uid_high == 0)
1713 *low = winbind_uid_low;
1716 *high = winbind_uid_high;
1721 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
1723 if (winbind_gid_low == 0 || winbind_gid_high == 0)
1727 *low = winbind_gid_low;
1730 *high = winbind_gid_high;
1735 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
1737 if (non_unix_account_low == 0 || non_unix_account_high == 0)
1741 *low = non_unix_account_low;
1744 *high = non_unix_account_high;
1749 /* Do some simple checks on "winbind [ug]id" parameter values */
1751 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
1755 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
1760 string_set(ptr, pszParmValue);
1762 winbind_uid_low = low;
1763 winbind_uid_high = high;
1768 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
1772 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
1777 string_set(ptr, pszParmValue);
1779 winbind_gid_low = low;
1780 winbind_gid_high = high;
1785 /***************************************************************************
1786 Do some simple checks on "non unix account range" parameter values.
1787 ***************************************************************************/
1789 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
1793 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
1798 string_set(ptr, pszParmValue);
1800 non_unix_account_low = low;
1801 non_unix_account_high = high;
1807 /***************************************************************************
1808 Initialise a copymap.
1809 ***************************************************************************/
1811 static void init_copymap(service * pservice)
1814 SAFE_FREE(pservice->copymap);
1815 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
1816 if (!pservice->copymap)
1818 ("Couldn't allocate copymap!! (size %d)\n",
1819 (int)NUMPARAMETERS));
1821 for (i = 0; i < NUMPARAMETERS; i++)
1822 pservice->copymap[i] = True;
1825 /***************************************************************************
1826 Return the local pointer to a parameter given the service number and the
1827 pointer into the default structure.
1828 ***************************************************************************/
1830 void *lp_local_ptr(int snum, void *ptr)
1832 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1836 /***************************************************************************
1837 Process a parametric option
1838 ***************************************************************************/
1839 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1841 struct param_opt *paramo, *data;
1844 while (isspace((unsigned char)*pszParmName)) {
1848 name = strdup(pszParmName);
1849 if (!name) return False;
1854 data = Globals.param_opt;
1856 data = ServicePtrs[snum]->param_opt;
1859 /* Traverse destination */
1860 for (paramo=data; paramo; paramo=paramo->next) {
1861 /* If we already have the option set, override it unless
1862 it was a command line option and the new one isn't */
1863 if (strcmp(paramo->key, name) == 0) {
1864 if ((paramo->flags & FLAG_CMDLINE) &&
1865 !(flags & FLAG_CMDLINE)) {
1869 free(paramo->value);
1870 paramo->value = strdup(pszParmValue);
1871 paramo->flags = flags;
1877 paramo = smb_xmalloc_p(struct param_opt);
1878 paramo->key = strdup(name);
1879 paramo->value = strdup(pszParmValue);
1880 paramo->flags = flags;
1882 DLIST_ADD(Globals.param_opt, paramo);
1884 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1892 /***************************************************************************
1893 Process a parameter for a particular service number. If snum < 0
1894 then assume we are in the globals.
1895 ***************************************************************************/
1896 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1899 void *parm_ptr = NULL; /* where we are going to store the result */
1900 void *def_ptr = NULL;
1902 parmnum = map_parameter(pszParmName);
1905 if (strchr(pszParmName, ':')) {
1906 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1908 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1912 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1913 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1917 /* if the flag has been set on the command line, then don't allow override,
1918 but don't report an error */
1919 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1923 def_ptr = parm_table[parmnum].ptr;
1925 /* we might point at a service, the default service or a global */
1929 if (parm_table[parmnum].class == P_GLOBAL) {
1931 ("Global parameter %s found in service section!\n",
1936 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1941 if (!ServicePtrs[snum]->copymap)
1942 init_copymap(ServicePtrs[snum]);
1944 /* this handles the aliases - set the copymap for other entries with
1945 the same data pointer */
1946 for (i = 0; parm_table[i].label; i++)
1947 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1948 ServicePtrs[snum]->copymap[i] = False;
1951 /* if it is a special case then go ahead */
1952 if (parm_table[parmnum].special) {
1953 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1957 /* now switch on the type of variable it is */
1958 switch (parm_table[parmnum].type)
1961 set_boolean(parm_ptr, pszParmValue);
1965 *(int *)parm_ptr = atoi(pszParmValue);
1969 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1970 pszParmValue, NULL);
1974 string_set(parm_ptr, pszParmValue);
1978 string_set(parm_ptr, pszParmValue);
1979 strupper(*(char **)parm_ptr);
1983 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1986 parm_table[parmnum].enum_list[i].name)) {
1988 parm_table[parmnum].
1993 if (!parm_table[parmnum].enum_list[i].name) {
1994 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1995 pszParmValue, pszParmName));
2006 /***************************************************************************
2007 Process a parameter.
2008 ***************************************************************************/
2010 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
2012 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2013 pszParmName, pszParmValue));
2017 variable argument do parameter
2019 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2021 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2028 s = talloc_vasprintf(NULL, fmt, ap);
2030 ret = do_parameter(pszParmName, s, NULL);
2037 set a parameter from the commandline - this is called from command line parameter
2038 parsing code. It sets the parameter then marks the parameter as unable to be modified
2039 by smb.conf processing
2041 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2043 int parmnum = map_parameter(pszParmName);
2046 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
2049 if (parmnum < 0 && strchr(pszParmName, ':')) {
2050 /* set a parametric option */
2051 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2055 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2059 /* reset the CMDLINE flag in case this has been called before */
2060 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2062 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2066 parm_table[parmnum].flags |= FLAG_CMDLINE;
2068 /* we have to also set FLAG_CMDLINE on aliases */
2069 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2070 parm_table[i].flags |= FLAG_CMDLINE;
2072 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2073 parm_table[i].flags |= FLAG_CMDLINE;
2080 set a option from the commandline in 'a=b' format. Use to support --option
2082 BOOL lp_set_option(const char *option)
2100 ret = lp_set_cmdline(s, p+1);
2106 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2108 /***************************************************************************
2109 Print a parameter of the specified type.
2110 ***************************************************************************/
2112 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2118 for (i = 0; p->enum_list[i].name; i++) {
2119 if (*(int *)ptr == p->enum_list[i].value) {
2121 p->enum_list[i].name);
2128 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2132 fprintf(f, "%d", *(int *)ptr);
2136 if ((char ***)ptr && *(char ***)ptr) {
2137 char **list = *(char ***)ptr;
2139 for (; *list; list++)
2140 fprintf(f, "%s%s", *list,
2141 ((*(list+1))?", ":""));
2147 if (*(char **)ptr) {
2148 fprintf(f, "%s", *(char **)ptr);
2156 /***************************************************************************
2157 Check if two parameters are equal.
2158 ***************************************************************************/
2160 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2164 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2168 return (*((int *)ptr1) == *((int *)ptr2));
2171 return str_list_equal((const char **)(*(char ***)ptr1),
2172 (const char **)(*(char ***)ptr2));
2177 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2182 return (p1 == p2 || strequal(p1, p2));
2190 /***************************************************************************
2191 Process a new section (service). At this stage all sections are services.
2192 Later we'll have special sections that permit server parameters to be set.
2193 Returns True on success, False on failure.
2194 ***************************************************************************/
2196 static BOOL do_section(const char *pszSectionName, void *userdata)
2199 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2200 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2203 /* if we've just struck a global section, note the fact. */
2204 bInGlobalSection = isglobal;
2206 /* check for multiple global sections */
2207 if (bInGlobalSection) {
2208 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2212 /* if we have a current service, tidy it up before moving on */
2215 if (iServiceIndex >= 0)
2216 bRetval = service_ok(iServiceIndex);
2218 /* if all is still well, move to the next record in the services array */
2220 /* We put this here to avoid an odd message order if messages are */
2221 /* issued by the post-processing of a previous section. */
2222 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2224 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2226 DEBUG(0, ("Failed to add a new service\n"));
2235 /***************************************************************************
2236 Determine if a partcular base parameter is currentl set to the default value.
2237 ***************************************************************************/
2239 static BOOL is_default(int i)
2241 if (!defaults_saved)
2243 switch (parm_table[i].type) {
2245 return str_list_equal((const char **)parm_table[i].def.lvalue,
2246 (const char **)(*(char ***)parm_table[i].ptr));
2249 return strequal(parm_table[i].def.svalue,
2250 *(char **)parm_table[i].ptr);
2252 return parm_table[i].def.bvalue ==
2253 *(BOOL *)parm_table[i].ptr;
2256 return parm_table[i].def.ivalue ==
2257 *(int *)parm_table[i].ptr;
2264 /***************************************************************************
2265 Display the contents of the global structure.
2266 ***************************************************************************/
2268 static void dump_globals(FILE *f)
2271 struct param_opt *data;
2273 fprintf(f, "# Global parameters\n[global]\n");
2275 for (i = 0; parm_table[i].label; i++)
2276 if (parm_table[i].class == P_GLOBAL &&
2277 parm_table[i].ptr &&
2278 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2279 if (defaults_saved && is_default(i))
2281 fprintf(f, "\t%s = ", parm_table[i].label);
2282 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2285 if (Globals.param_opt != NULL) {
2286 data = Globals.param_opt;
2288 fprintf(f, "\t%s = %s\n", data->key, data->value);
2295 /***************************************************************************
2296 Display the contents of a single services record.
2297 ***************************************************************************/
2299 static void dump_a_service(service * pService, FILE * f)
2302 struct param_opt *data;
2304 if (pService != &sDefault)
2305 fprintf(f, "\n[%s]\n", pService->szService);
2307 for (i = 0; parm_table[i].label; i++)
2308 if (parm_table[i].class == P_LOCAL &&
2309 parm_table[i].ptr &&
2310 (*parm_table[i].label != '-') &&
2311 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2312 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2314 if (pService == &sDefault) {
2315 if (defaults_saved && is_default(i))
2318 if (equal_parameter(parm_table[i].type,
2319 ((char *)pService) +
2321 ((char *)&sDefault) +
2326 fprintf(f, "\t%s = ", parm_table[i].label);
2327 print_parameter(&parm_table[i],
2328 ((char *)pService) + pdiff, f);
2331 if (pService->param_opt != NULL) {
2332 data = pService->param_opt;
2334 fprintf(f, "\t%s = %s\n", data->key, data->value);
2341 /***************************************************************************
2342 Return info about the next service in a service. snum==-1 gives the globals.
2343 Return NULL when out of parameters.
2344 ***************************************************************************/
2346 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2349 /* do the globals */
2350 for (; parm_table[*i].label; (*i)++) {
2351 if (parm_table[*i].class == P_SEPARATOR)
2352 return &parm_table[(*i)++];
2354 if (!parm_table[*i].ptr
2355 || (*parm_table[*i].label == '-'))
2359 && (parm_table[*i].ptr ==
2360 parm_table[(*i) - 1].ptr))
2363 return &parm_table[(*i)++];
2366 service *pService = ServicePtrs[snum];
2368 for (; parm_table[*i].label; (*i)++) {
2369 if (parm_table[*i].class == P_SEPARATOR)
2370 return &parm_table[(*i)++];
2372 if (parm_table[*i].class == P_LOCAL &&
2373 parm_table[*i].ptr &&
2374 (*parm_table[*i].label != '-') &&
2376 (parm_table[*i].ptr !=
2377 parm_table[(*i) - 1].ptr)))
2380 PTR_DIFF(parm_table[*i].ptr,
2383 if (allparameters ||
2384 !equal_parameter(parm_table[*i].type,
2385 ((char *)pService) +
2387 ((char *)&sDefault) +
2390 return &parm_table[(*i)++];
2400 /***************************************************************************
2401 Return TRUE if the passed service number is within range.
2402 ***************************************************************************/
2404 BOOL lp_snum_ok(int iService)
2406 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2409 /***************************************************************************
2410 Auto-load some home services.
2411 ***************************************************************************/
2413 static void lp_add_auto_services(const char *str)
2418 /***************************************************************************
2419 Announce ourselves as a print server.
2420 ***************************************************************************/
2422 void update_server_announce_as_printserver(void)
2424 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2427 /***************************************************************************
2428 Have we loaded a services file yet?
2429 ***************************************************************************/
2431 BOOL lp_loaded(void)
2436 /***************************************************************************
2437 Unload unused services.
2438 ***************************************************************************/
2440 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2443 for (i = 0; i < iNumServices; i++) {
2447 if (!snumused || !snumused(smb, i)) {
2448 ServicePtrs[i]->valid = False;
2449 free_service(ServicePtrs[i]);
2454 /***************************************************************************
2456 ***************************************************************************/
2458 void lp_killservice(int iServiceIn)
2460 if (VALID(iServiceIn)) {
2461 ServicePtrs[iServiceIn]->valid = False;
2462 free_service(ServicePtrs[iServiceIn]);
2466 /*******************************************************************
2467 Set the server type we will announce as via nmbd.
2468 ********************************************************************/
2470 static void set_server_role(void)
2472 server_role = ROLE_STANDALONE;
2474 switch (lp_security()) {
2476 if (lp_domain_logons())
2477 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2482 if (lp_domain_logons()) {
2483 if (Globals.bDomainMaster) /* auto or yes */
2484 server_role = ROLE_DOMAIN_PDC;
2486 server_role = ROLE_DOMAIN_BDC;
2489 server_role = ROLE_DOMAIN_MEMBER;
2492 if (lp_domain_logons()) {
2494 if (Globals.bDomainMaster) /* auto or yes */
2495 server_role = ROLE_DOMAIN_PDC;
2497 server_role = ROLE_DOMAIN_BDC;
2501 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2505 DEBUG(10, ("set_server_role: role = "));
2507 switch(server_role) {
2508 case ROLE_STANDALONE:
2509 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2511 case ROLE_DOMAIN_MEMBER:
2512 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2514 case ROLE_DOMAIN_BDC:
2515 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2517 case ROLE_DOMAIN_PDC:
2518 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
2523 /***************************************************************************
2524 Load the services array from the services file. Return True on success,
2526 ***************************************************************************/
2532 struct param_opt *data;
2536 bInGlobalSection = True;
2538 if (Globals.param_opt != NULL) {
2539 struct param_opt *next;
2540 for (data=Globals.param_opt; data; data=next) {
2542 if (data->flags & FLAG_CMDLINE) continue;
2545 DLIST_REMOVE(Globals.param_opt, data);
2552 pstrcpy(n2, lp_configfile());
2553 standard_sub_basic(n2,sizeof(n2));
2554 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2556 add_to_file_list(lp_configfile(), n2);
2558 /* We get sections first, so have to start 'behind' to make up */
2560 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2562 /* finish up the last section */
2563 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2565 if (iServiceIndex >= 0)
2566 bRetval = service_ok(iServiceIndex);
2568 lp_add_auto_services(lp_auto_services());
2570 lp_add_hidden("IPC$", "IPC");
2571 lp_add_hidden("ADMIN$", "DISK");
2574 set_default_server_announce_type();
2578 if (Globals.bWINSsupport) {
2579 lp_do_parameter(-1, "wins server", "127.0.0.1");
2587 /***************************************************************************
2588 Reset the max number of services.
2589 ***************************************************************************/
2591 void lp_resetnumservices(void)
2596 /***************************************************************************
2597 Return the max number of services.
2598 ***************************************************************************/
2600 int lp_numservices(void)
2602 return (iNumServices);
2605 /***************************************************************************
2606 Display the contents of the services array in human-readable form.
2607 ***************************************************************************/
2609 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2614 defaults_saved = False;
2618 dump_a_service(&sDefault, f);
2620 for (iService = 0; iService < maxtoprint; iService++)
2621 lp_dump_one(f, show_defaults, iService);
2624 /***************************************************************************
2625 Display the contents of one service in human-readable form.
2626 ***************************************************************************/
2628 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2631 if (ServicePtrs[snum]->szService[0] == '\0')
2633 dump_a_service(ServicePtrs[snum], f);
2637 /***************************************************************************
2638 Return the number of the service with the given name, or -1 if it doesn't
2639 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2640 getservicebyname()! This works ONLY if all services have been loaded, and
2641 does not copy the found service.
2642 ***************************************************************************/
2644 int lp_servicenumber(const char *pszServiceName)
2647 fstring serviceName;
2650 for (iService = iNumServices - 1; iService >= 0; iService--) {
2651 if (VALID(iService) && ServicePtrs[iService]->szService) {
2653 * The substitution here is used to support %U is
2656 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2657 standard_sub_basic(serviceName,sizeof(serviceName));
2658 if (strequal(serviceName, pszServiceName))
2664 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2669 /*******************************************************************
2670 A useful volume label function.
2671 ********************************************************************/
2672 const char *volume_label(int snum)
2674 const char *ret = lp_volume(snum);
2676 return lp_servicename(snum);
2681 /*******************************************************************
2682 Set the server type we will announce as via nmbd.
2683 ********************************************************************/
2685 static void set_default_server_announce_type(void)
2687 default_server_announce = 0;
2688 default_server_announce |= SV_TYPE_WORKSTATION;
2689 default_server_announce |= SV_TYPE_SERVER;
2690 default_server_announce |= SV_TYPE_SERVER_UNIX;
2692 switch (lp_announce_as()) {
2693 case ANNOUNCE_AS_NT_SERVER:
2694 default_server_announce |= SV_TYPE_SERVER_NT;
2695 /* fall through... */
2696 case ANNOUNCE_AS_NT_WORKSTATION:
2697 default_server_announce |= SV_TYPE_NT;
2699 case ANNOUNCE_AS_WIN95:
2700 default_server_announce |= SV_TYPE_WIN95_PLUS;
2702 case ANNOUNCE_AS_WFW:
2703 default_server_announce |= SV_TYPE_WFW;
2709 switch (lp_server_role()) {
2710 case ROLE_DOMAIN_MEMBER:
2711 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2713 case ROLE_DOMAIN_PDC:
2714 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2716 case ROLE_DOMAIN_BDC:
2717 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2719 case ROLE_STANDALONE:
2723 if (lp_time_server())
2724 default_server_announce |= SV_TYPE_TIME_SOURCE;
2726 if (lp_host_msdfs())
2727 default_server_announce |= SV_TYPE_DFS_SERVER;
2729 /* TODO: only announce us as print server when we are a print server */
2730 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2733 /***********************************************************
2734 returns role of Samba server
2735 ************************************************************/
2737 int lp_server_role(void)
2742 /***********************************************************
2743 If we are PDC then prefer us as DMB
2744 ************************************************************/
2746 BOOL lp_domain_master(void)
2748 if (Globals.bDomainMaster == Auto)
2749 return (lp_server_role() == ROLE_DOMAIN_PDC);
2751 return Globals.bDomainMaster;
2754 /***********************************************************
2755 If we are DMB then prefer us as LMB
2756 ************************************************************/
2758 BOOL lp_preferred_master(void)
2760 if (Globals.bPreferredMaster == Auto)
2761 return (lp_local_master() && lp_domain_master());
2763 return Globals.bPreferredMaster;
2766 /*******************************************************************
2768 ********************************************************************/
2770 void lp_remove_service(int snum)
2772 ServicePtrs[snum]->valid = False;
2775 /*******************************************************************
2777 ********************************************************************/
2779 void lp_copy_service(int snum, const char *new_name)
2781 const char *oldname = lp_servicename(snum);
2782 do_section(new_name, NULL);
2784 snum = lp_servicenumber(new_name);
2786 lp_do_parameter(snum, "copy", oldname);
2791 /*******************************************************************
2792 Get the default server type we will announce as via nmbd.
2793 ********************************************************************/
2794 int lp_default_server_announce(void)
2796 return default_server_announce;
2799 const char *lp_printername(int snum)
2801 const char *ret = _lp_printername(snum);
2802 if (ret == NULL || (ret != NULL && *ret == '\0'))
2803 ret = lp_const_servicename(snum);
2809 /*******************************************************************
2810 Return the max print jobs per queue.
2811 ********************************************************************/
2813 int lp_maxprintjobs(int snum)
2815 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2816 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2817 maxjobs = PRINT_MAX_JOBID - 1;