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;
146 int paranoid_server_security;
149 int announce_as; /* This is initialised in init_globals */
156 char *socket_options;
161 int bPreferredMaster;
162 int bEncryptPasswords;
164 int bObeyPamRestrictions;
169 int bBindInterfacesOnly;
171 int bNTStatusSupport;
177 int bClientPlaintextAuth;
178 int bClientLanManAuth;
179 int bClientNTLMv2Auth;
180 int client_use_spnego_principal;
186 struct param_opt *param_opt;
190 static global Globals;
193 * This structure describes a single service.
208 char **ntvfs_handler;
224 struct param_opt *param_opt;
226 char dummy[3]; /* for alignment */
231 /* This is a default service used to prime a services structure */
232 static service sDefault = {
234 NULL, /* szService */
237 NULL, /* szInclude */
238 NULL, /* szPrintername */
239 NULL, /* szHostsallow */
240 NULL, /* szHostsdeny */
244 NULL, /* ntvfs_handler */
245 1000, /* iMaxPrintJobs */
246 0, /* iMaxConnections */
248 True, /* bAvailable */
249 True, /* bBrowseable */
250 True, /* bRead_only */
251 False, /* bPrint_ok */
252 False, /* bMap_system */
253 False, /* bMap_hidden */
254 True, /* bMap_archive */
255 True, /* bStrictLocking */
257 False, /* bMSDfsRoot */
258 False, /* bStrictSync */
259 False, /* bCIFileSystem */
260 NULL, /* Parametric options */
265 /* local variables */
266 static service **ServicePtrs = NULL;
267 static int iNumServices = 0;
268 static int iServiceIndex = 0;
269 static BOOL bInGlobalSection = True;
270 static int default_server_announce;
272 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
274 /* prototypes for the special type handlers */
275 static BOOL handle_include(const char *pszParmValue, char **ptr);
276 static BOOL handle_copy(const char *pszParmValue, char **ptr);
278 static void set_default_server_announce_type(void);
280 static const struct enum_list enum_protocol[] = {
281 {PROTOCOL_SMB2, "SMB2"},
282 {PROTOCOL_NT1, "NT1"},
283 {PROTOCOL_LANMAN2, "LANMAN2"},
284 {PROTOCOL_LANMAN1, "LANMAN1"},
285 {PROTOCOL_CORE, "CORE"},
286 {PROTOCOL_COREPLUS, "COREPLUS"},
287 {PROTOCOL_COREPLUS, "CORE+"},
291 static const struct enum_list enum_security[] = {
292 {SEC_SHARE, "SHARE"},
297 /* Types of machine we can announce as. */
298 #define ANNOUNCE_AS_NT_SERVER 1
299 #define ANNOUNCE_AS_WIN95 2
300 #define ANNOUNCE_AS_WFW 3
301 #define ANNOUNCE_AS_NT_WORKSTATION 4
303 static const struct enum_list enum_announce_as[] = {
304 {ANNOUNCE_AS_NT_SERVER, "NT"},
305 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
306 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
307 {ANNOUNCE_AS_WIN95, "win95"},
308 {ANNOUNCE_AS_WFW, "WfW"},
312 static const struct enum_list enum_bool_auto[] = {
323 /* Client-side offline caching policy types */
324 #define CSC_POLICY_MANUAL 0
325 #define CSC_POLICY_DOCUMENTS 1
326 #define CSC_POLICY_PROGRAMS 2
327 #define CSC_POLICY_DISABLE 3
329 static const struct enum_list enum_csc_policy[] = {
330 {CSC_POLICY_MANUAL, "manual"},
331 {CSC_POLICY_DOCUMENTS, "documents"},
332 {CSC_POLICY_PROGRAMS, "programs"},
333 {CSC_POLICY_DISABLE, "disable"},
337 /* SMB signing types. */
338 static const struct enum_list enum_smb_signing_vals[] = {
339 {SMB_SIGNING_OFF, "No"},
340 {SMB_SIGNING_OFF, "False"},
341 {SMB_SIGNING_OFF, "0"},
342 {SMB_SIGNING_OFF, "Off"},
343 {SMB_SIGNING_OFF, "disabled"},
344 {SMB_SIGNING_SUPPORTED, "Yes"},
345 {SMB_SIGNING_SUPPORTED, "True"},
346 {SMB_SIGNING_SUPPORTED, "1"},
347 {SMB_SIGNING_SUPPORTED, "On"},
348 {SMB_SIGNING_SUPPORTED, "enabled"},
349 {SMB_SIGNING_REQUIRED, "required"},
350 {SMB_SIGNING_REQUIRED, "mandatory"},
351 {SMB_SIGNING_REQUIRED, "force"},
352 {SMB_SIGNING_REQUIRED, "forced"},
353 {SMB_SIGNING_REQUIRED, "enforced"},
354 {SMB_SIGNING_AUTO, "auto"},
358 static const struct enum_list enum_server_role[] = {
359 {ROLE_STANDALONE, "standalone"},
360 {ROLE_DOMAIN_MEMBER, "member server"},
361 {ROLE_DOMAIN_BDC, "bdc"},
362 {ROLE_DOMAIN_PDC, "pdc"},
367 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
369 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
370 * is implied in current control logic. This may change at some later time. A
371 * flag value of 0 means - show as development option only.
373 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
374 * screen in SWAT. This is used to exclude parameters as well as to squash all
375 * parameters that have been duplicated by pseudonyms.
377 static struct parm_struct parm_table[] = {
378 {"Base Options", P_SEP, P_SEPARATOR},
380 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
382 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
383 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
384 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
385 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
386 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
387 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
388 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
389 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
390 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
391 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
392 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
393 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
394 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
395 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
396 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
397 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
398 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
399 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
400 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
402 {"Security Options", P_SEP, P_SEPARATOR},
404 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
406 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
407 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
408 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
409 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
410 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
412 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
426 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
427 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
429 {"Logging Options", P_SEP, P_SEPARATOR},
431 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
432 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
433 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
435 {"Protocol Options", P_SEP, P_SEPARATOR},
437 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
438 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
439 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
451 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
452 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
453 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
454 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
455 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
456 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
460 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
461 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
462 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
463 {"max xmit", P_BYTES, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
465 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
466 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
467 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
468 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
470 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
471 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
472 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
473 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
475 {"Tuning Options", P_SEP, P_SEPARATOR},
477 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
478 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
479 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
481 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
482 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
484 {"Printing Options", P_SEP, P_SEPARATOR},
486 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
487 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
488 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
490 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
491 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
493 {"Filename Handling", P_SEP, P_SEPARATOR},
495 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
496 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
497 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
499 {"Domain Options", P_SEP, P_SEPARATOR},
501 {"Logon Options", P_SEP, P_SEPARATOR},
504 {"Browse Options", P_SEP, P_SEPARATOR},
506 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
507 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
508 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
509 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
510 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
512 {"WINS Options", P_SEP, P_SEPARATOR},
514 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
515 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
516 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
517 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
519 {"Locking Options", P_SEP, P_SEPARATOR},
521 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
523 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
525 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
527 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
528 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
529 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
530 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
531 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
532 {"modules dir", P_STRING, P_GLOBAL, &Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
533 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
538 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
540 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
541 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
543 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
544 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
545 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
547 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
550 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
552 {"winbindd socket directory", P_STRING, P_GLOBAL, &Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
553 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
555 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
560 return the parameter table
562 struct parm_struct *lp_parm_table(void)
567 /***************************************************************************
568 Initialise the global parameter structure.
569 ***************************************************************************/
570 static void init_globals(void)
575 DEBUG(3, ("Initialising global parameters\n"));
577 for (i = 0; parm_table[i].label; i++) {
578 if ((parm_table[i].type == P_STRING ||
579 parm_table[i].type == P_USTRING) &&
581 !(parm_table[i].flags & FLAG_CMDLINE)) {
582 string_set(parm_table[i].ptr, "");
586 do_parameter("config file", dyn_CONFIGFILE, NULL);
588 do_parameter("server role", "standalone", NULL);
590 /* options that can be set on the command line must be initialised via
591 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
593 do_parameter("socket options", "TCP_NODELAY", NULL);
595 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
596 myname = get_myname();
597 do_parameter("netbios name", myname, NULL);
599 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
601 do_parameter("fstype", FSTYPE_STRING, NULL);
602 do_parameter("ntvfs handler", "unixuid default", NULL);
603 do_parameter("max connections", "-1", NULL);
605 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
606 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc winbind", NULL);
607 do_parameter("ntptr providor", "simple_ldb", NULL);
608 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
609 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
610 do_parameter("sam database", "sam.ldb", NULL);
611 do_parameter("spoolss database", "spoolss.ldb", NULL);
612 do_parameter("wins config database", "wins_config.ldb", NULL);
613 do_parameter("wins database", "wins.ldb", NULL);
614 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
616 /* This hive should be dynamically generated by Samba using
617 data from the sam, but for the moment leave it in a tdb to
618 keep regedt32 from popping up an annoying dialog. */
619 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
621 /* using UTF8 by default allows us to support all chars */
622 do_parameter("unix charset", "UTF8", NULL);
624 /* Use codepage 850 as a default for the dos character set */
625 do_parameter("dos charset", "CP850", NULL);
628 * Allow the default PASSWD_CHAT to be overridden in local.h.
630 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
632 do_parameter("pid directory", dyn_PIDDIR, NULL);
633 do_parameter("lock dir", dyn_LOCKDIR, NULL);
634 do_parameter("modules dir", dyn_MODULESDIR, NULL);
635 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
637 do_parameter("socket address", "0.0.0.0", NULL);
638 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
640 do_parameter_var("announce version", "%d.%d",
641 DEFAULT_MAJOR_VERSION,
642 DEFAULT_MINOR_VERSION);
644 do_parameter("password server", "*", NULL);
646 do_parameter("max mux", "50", NULL);
647 do_parameter("max xmit", "12288", NULL);
648 do_parameter("password level", "0", NULL);
649 do_parameter("LargeReadwrite", "True", NULL);
650 do_parameter("min protocol", "CORE", NULL);
651 do_parameter("max protocol", "NT1", NULL);
652 do_parameter("security", "USER", NULL);
653 do_parameter("paranoid server security", "True", NULL);
654 do_parameter("EncryptPasswords", "True", NULL);
655 do_parameter("ReadRaw", "True", NULL);
656 do_parameter("WriteRaw", "True", NULL);
657 do_parameter("NullPasswords", "False", NULL);
658 do_parameter("ObeyPamRestrictions", "False", NULL);
659 do_parameter("announce as", "NT SERVER", NULL);
661 do_parameter("TimeServer", "False", NULL);
662 do_parameter("BindInterfacesOnly", "False", NULL);
663 do_parameter("Unicode", "True", NULL);
664 do_parameter("ClientLanManAuth", "True", NULL);
665 do_parameter("LanmanAuth", "True", NULL);
666 do_parameter("NTLMAuth", "True", NULL);
667 do_parameter("client use spnego principal", "False", NULL);
669 do_parameter("UnixExtensions", "False", NULL);
671 do_parameter("PreferredMaster", "Auto", NULL);
672 do_parameter("LocalMaster", "True", NULL);
674 do_parameter("wins support", "False", NULL);
675 do_parameter("dns proxy", "True", NULL);
677 do_parameter("winbind separator", "\\", NULL);
678 do_parameter("winbind sealed pipes", "True", NULL);
679 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR, NULL);
681 do_parameter("client signing", "Yes", NULL);
682 do_parameter("server signing", "auto", NULL);
684 do_parameter("use spnego", "True", NULL);
686 do_parameter("smb ports", SMB_PORTS, NULL);
687 do_parameter("nbt port", "137", NULL);
688 do_parameter("dgram port", "138", NULL);
689 do_parameter("cldap port", "389", NULL);
690 do_parameter("krb5 port", "88", NULL);
691 do_parameter("kpasswd port", "464", NULL);
692 do_parameter("web port", "901", NULL);
693 do_parameter("swat directory", dyn_SWATDIR, NULL);
695 do_parameter("nt status support", "True", NULL);
697 do_parameter("max wins ttl", "518400", NULL); /* 6 days */
698 do_parameter("min wins ttl", "10", NULL);
700 do_parameter("tls enabled", "True", NULL);
701 do_parameter("tls keyfile", "tls/key.pem", NULL);
702 do_parameter("tls certfile", "tls/cert.pem", NULL);
703 do_parameter("tls cafile", "tls/ca.pem", NULL);
704 do_parameter_var("js include", "%s", dyn_JSDIR);
705 do_parameter_var("setup directory", "%s", dyn_SETUPDIR);
707 for (i = 0; parm_table[i].label; i++) {
708 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
709 parm_table[i].flags |= FLAG_DEFAULT;
714 static TALLOC_CTX *lp_talloc;
716 /******************************************************************* a
717 Free up temporary memory - called from the main loop.
718 ********************************************************************/
720 void lp_talloc_free(void)
724 talloc_free(lp_talloc);
728 /*******************************************************************
729 Convenience routine to grab string parameters into temporary memory
730 and run standard_sub_basic on them. The buffers can be written to by
731 callers without affecting the source string.
732 ********************************************************************/
734 static const char *lp_string(const char *s)
736 #if 0 /* until REWRITE done to make thread-safe */
737 size_t len = s ? strlen(s) : 0;
741 /* The follow debug is useful for tracking down memory problems
742 especially if you have an inner loop that is calling a lp_*()
743 function that returns a string. Perhaps this debug should be
744 present all the time? */
747 DEBUG(10, ("lp_string(%s)\n", s));
750 #if 0 /* until REWRITE done to make thread-safe */
752 lp_talloc = talloc_init("lp_talloc");
754 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
762 strlcpy(ret, s, len);
764 if (trim_string(ret, "\"", "\"")) {
765 if (strchr(ret,'"') != NULL)
766 strlcpy(ret, s, len);
769 standard_sub_basic(ret,len+100);
776 In this section all the functions that are used to access the
777 parameters from the rest of the program are defined
780 #define FN_GLOBAL_STRING(fn_name,ptr) \
781 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
782 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
783 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
784 #define FN_GLOBAL_LIST(fn_name,ptr) \
785 const char **fn_name(void) {return(*(const char ***)(ptr));}
786 #define FN_GLOBAL_BOOL(fn_name,ptr) \
787 BOOL fn_name(void) {return((BOOL)*(int *)(ptr));}
788 #define FN_GLOBAL_CHAR(fn_name,ptr) \
789 char fn_name(void) {return(*(char *)(ptr));}
790 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
791 int fn_name(void) {return(*(int *)(ptr));}
793 #define FN_LOCAL_STRING(fn_name,val) \
794 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
795 #define FN_LOCAL_CONST_STRING(fn_name,val) \
796 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
797 #define FN_LOCAL_LIST(fn_name,val) \
798 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
799 #define FN_LOCAL_BOOL(fn_name,val) \
800 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
801 #define FN_LOCAL_CHAR(fn_name,val) \
802 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
803 #define FN_LOCAL_INTEGER(fn_name,val) \
804 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
806 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &Globals.server_role)
807 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
808 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
809 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
810 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
811 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
812 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &Globals.kpasswd_port)
813 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
814 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
815 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
816 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
817 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
818 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
819 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
820 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
821 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
822 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
823 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
824 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
825 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
826 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL)
827 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
828 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
829 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &Globals.szWinbinddSocketDirectory)
830 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
831 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
832 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
833 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
834 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &Globals.szModulesDir)
835 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
836 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
837 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
838 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
839 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
840 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
841 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
842 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
843 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
844 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
845 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
846 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
847 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
848 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
849 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
850 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
851 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
852 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
853 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
855 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
856 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
857 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &Globals.bWINSdnsProxy)
858 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
859 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
860 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
861 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
862 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
863 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
864 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
865 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
866 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
867 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
868 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
869 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
870 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
871 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
872 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
873 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
874 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
875 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
876 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
877 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
878 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
879 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
880 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
881 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
882 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
883 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
884 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
885 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
886 _PUBLIC_ FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
887 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
888 _PUBLIC_ FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
889 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
890 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
891 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
894 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
895 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
896 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
897 static FN_LOCAL_STRING(_lp_printername, szPrintername)
898 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
899 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
900 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
901 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
902 static FN_LOCAL_STRING(lp_volume, volume)
903 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
904 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
905 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
906 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
907 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
908 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
909 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
910 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
911 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
912 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
913 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
914 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
915 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
916 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
917 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
919 /* local prototypes */
921 static int map_parameter(const char *pszParmName);
922 static int getservicebyname(const char *pszServiceName,
923 service * pserviceDest);
924 static void copy_service(service * pserviceDest,
925 service * pserviceSource, int *pcopymapDest);
926 static BOOL service_ok(int iService);
927 static BOOL do_section(const char *pszSectionName, void *);
928 static void init_copymap(service * pservice);
930 /* This is a helper function for parametrical options support. */
931 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
932 /* Actual parametrical functions are quite simple */
933 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
936 struct param_opt *data;
938 if (lookup_service >= iNumServices) return NULL;
940 data = (lookup_service < 0) ?
941 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
943 asprintf(&vfskey, "%s:%s", type, option);
947 if (strcmp(data->key, vfskey) == 0) {
954 if (lookup_service >= 0) {
955 /* Try to fetch the same option but from globals */
956 /* but only if we are not already working with Globals */
957 data = Globals.param_opt;
959 if (strcmp(data->key, vfskey) == 0) {
973 /*******************************************************************
974 convenience routine to return int parameters.
975 ********************************************************************/
976 static int lp_int(const char *s)
980 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
984 return strtol(s, NULL, 0);
987 /*******************************************************************
988 convenience routine to return unsigned long parameters.
989 ********************************************************************/
990 static int lp_ulong(const char *s)
994 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
998 return strtoul(s, NULL, 0);
1001 /*******************************************************************
1002 convenience routine to return boolean parameters.
1003 ********************************************************************/
1004 static BOOL lp_bool(const char *s)
1009 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1013 if (!set_boolean(s, &ret)) {
1014 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1022 /* Return parametric option from a given service. Type is a part of option before ':' */
1023 /* Parametric option has following syntax: 'Type: option = value' */
1024 /* Returned value is allocated in 'lp_talloc' context */
1026 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1028 const char *value = lp_get_parametric(lookup_service, type, option);
1031 return lp_string(value);
1036 /* Return parametric option from a given service. Type is a part of option before ':' */
1037 /* Parametric option has following syntax: 'Type: option = value' */
1038 /* Returned value is allocated in 'lp_talloc' context */
1040 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1041 const char *separator)
1043 const char *value = lp_get_parametric(lookup_service, type, option);
1046 return str_list_make(talloc_autofree_context(), value, separator);
1051 /* Return parametric option from a given service. Type is a part of option before ':' */
1052 /* Parametric option has following syntax: 'Type: option = value' */
1054 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1056 const char *value = lp_get_parametric(lookup_service, type, option);
1059 return lp_int(value);
1064 /* Return parametric option from a given service. Type is a part of
1065 * option before ':'.
1066 * Parametric option has following syntax: 'Type: option = value'.
1069 int lp_parm_bytes(int lookup_service, const char *type, const char *option, int default_v)
1073 const char *value = lp_get_parametric(lookup_service, type, option);
1075 if (value && conv_str_size(value, &bval)) {
1076 if (bval <= INT_MAX) {
1084 /* Return parametric option from a given service. Type is a part of option before ':' */
1085 /* Parametric option has following syntax: 'Type: option = value' */
1087 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1089 const char *value = lp_get_parametric(lookup_service, type, option);
1092 return lp_ulong(value);
1097 /* Return parametric option from a given service. Type is a part of option before ':' */
1098 /* Parametric option has following syntax: 'Type: option = value' */
1100 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1102 const char *value = lp_get_parametric(lookup_service, type, option);
1105 return lp_bool(value);
1111 /***************************************************************************
1112 Initialise a service to the defaults.
1113 ***************************************************************************/
1115 static void init_service(service * pservice)
1117 memset((char *)pservice, '\0', sizeof(service));
1118 copy_service(pservice, &sDefault, NULL);
1121 /***************************************************************************
1122 Free the dynamically allocated parts of a service struct.
1123 ***************************************************************************/
1125 static void free_service(service *pservice)
1128 struct param_opt *data, *pdata;
1132 if (pservice->szService)
1133 DEBUG(5, ("free_service: Freeing service %s\n",
1134 pservice->szService));
1136 string_free(&pservice->szService);
1137 SAFE_FREE(pservice->copymap);
1139 for (i = 0; parm_table[i].label; i++) {
1140 if ((parm_table[i].type == P_STRING ||
1141 parm_table[i].type == P_USTRING) &&
1142 parm_table[i].class == P_LOCAL) {
1143 string_free((char **)
1144 (((char *)pservice) +
1145 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1146 } else if (parm_table[i].type == P_LIST &&
1147 parm_table[i].class == P_LOCAL) {
1148 char ***listp = (char ***)(((char *)pservice) +
1149 PTR_DIFF(parm_table[i].ptr, &sDefault));
1150 talloc_free(*listp);
1155 DEBUG(5,("Freeing parametrics:\n"));
1156 data = pservice->param_opt;
1158 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1159 string_free(&data->key);
1160 string_free(&data->value);
1166 ZERO_STRUCTP(pservice);
1169 /***************************************************************************
1170 Add a new service to the services array initialising it with the given
1172 ***************************************************************************/
1174 static int add_a_service(const service *pservice, const char *name)
1178 int num_to_alloc = iNumServices + 1;
1179 struct param_opt *data, *pdata;
1181 tservice = *pservice;
1183 /* it might already exist */
1185 i = getservicebyname(name, NULL);
1187 /* Clean all parametric options for service */
1188 /* They will be added during parsing again */
1189 data = ServicePtrs[i]->param_opt;
1191 string_free(&data->key);
1192 string_free(&data->value);
1197 ServicePtrs[i]->param_opt = NULL;
1202 /* find an invalid one */
1203 for (i = 0; i < iNumServices; i++)
1204 if (!ServicePtrs[i]->valid)
1207 /* if not, then create one */
1208 if (i == iNumServices) {
1211 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1214 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1219 ServicePtrs[iNumServices] = malloc_p(service);
1221 if (!ServicePtrs[iNumServices]) {
1222 DEBUG(0,("add_a_service: out of memory!\n"));
1228 free_service(ServicePtrs[i]);
1230 ServicePtrs[i]->valid = True;
1232 init_service(ServicePtrs[i]);
1233 copy_service(ServicePtrs[i], &tservice, NULL);
1235 string_set(&ServicePtrs[i]->szService, name);
1239 /***************************************************************************
1240 Add a new home service, with the specified home directory, defaults coming
1242 ***************************************************************************/
1244 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1245 const char *user, const char *pszHomedir)
1250 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1255 if (!(*(ServicePtrs[iDefaultService]->szPath))
1256 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1257 pstrcpy(newHomedir, pszHomedir);
1259 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1260 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1263 string_set(&ServicePtrs[i]->szPath, newHomedir);
1265 if (!(*(ServicePtrs[i]->comment))) {
1267 slprintf(comment, sizeof(comment) - 1,
1268 "Home directory of %s", user);
1269 string_set(&ServicePtrs[i]->comment, comment);
1271 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1272 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1274 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1280 /***************************************************************************
1281 Add a new service, based on an old one.
1282 ***************************************************************************/
1284 int lp_add_service(const char *pszService, int iDefaultService)
1286 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1289 /***************************************************************************
1290 Add the IPC service.
1291 ***************************************************************************/
1293 static BOOL lp_add_hidden(const char *name, const char *fstype)
1296 int i = add_a_service(&sDefault, name);
1301 slprintf(comment, sizeof(comment) - 1,
1302 "%s Service (%s)", fstype, Globals.szServerString);
1304 string_set(&ServicePtrs[i]->szPath, tmpdir());
1305 string_set(&ServicePtrs[i]->comment, comment);
1306 string_set(&ServicePtrs[i]->fstype, fstype);
1307 ServicePtrs[i]->iMaxConnections = -1;
1308 ServicePtrs[i]->bAvailable = True;
1309 ServicePtrs[i]->bRead_only = True;
1310 ServicePtrs[i]->bPrint_ok = False;
1311 ServicePtrs[i]->bBrowseable = False;
1313 if (strcasecmp(fstype, "IPC") == 0) {
1314 lp_do_parameter(i, "ntvfs handler", "default");
1317 DEBUG(3, ("adding hidden service %s\n", name));
1322 /***************************************************************************
1323 Add a new printer service, with defaults coming from service iFrom.
1324 ***************************************************************************/
1326 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1328 const char *comment = "From Printcap";
1329 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1334 /* note that we do NOT default the availability flag to True - */
1335 /* we take it from the default service passed. This allows all */
1336 /* dynamic printers to be disabled by disabling the [printers] */
1337 /* entry (if/when the 'available' keyword is implemented!). */
1339 /* the printer name is set to the service name. */
1340 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1341 string_set(&ServicePtrs[i]->comment, comment);
1342 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1343 /* Printers cannot be read_only. */
1344 ServicePtrs[i]->bRead_only = False;
1345 /* Printer services must be printable. */
1346 ServicePtrs[i]->bPrint_ok = True;
1348 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1350 update_server_announce_as_printserver();
1355 /***************************************************************************
1356 Map a parameter's string representation to something we can use.
1357 Returns False if the parameter string is not recognised, else TRUE.
1358 ***************************************************************************/
1360 static int map_parameter(const char *pszParmName)
1364 if (*pszParmName == '-')
1367 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1368 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1371 /* Warn only if it isn't parametric option */
1372 if (strchr(pszParmName, ':') == NULL)
1373 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1374 /* We do return 'fail' for parametric options as well because they are
1375 stored in different storage
1382 return the parameter structure for a parameter
1384 struct parm_struct *lp_parm_struct(const char *name)
1386 int parmnum = map_parameter(name);
1387 if (parmnum == -1) return NULL;
1388 return &parm_table[parmnum];
1392 return the parameter pointer for a parameter
1394 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1399 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1402 /***************************************************************************
1403 Find a service by name. Otherwise works like get_service.
1404 ***************************************************************************/
1406 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1410 for (iService = iNumServices - 1; iService >= 0; iService--)
1411 if (VALID(iService) &&
1412 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1413 if (pserviceDest != NULL)
1414 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1421 /***************************************************************************
1422 Copy a service structure to another.
1423 If pcopymapDest is NULL then copy all fields
1424 ***************************************************************************/
1426 static void copy_service(service * pserviceDest, service * pserviceSource, int *pcopymapDest)
1429 BOOL bcopyall = (pcopymapDest == NULL);
1430 struct param_opt *data, *pdata, *paramo;
1433 for (i = 0; parm_table[i].label; i++)
1434 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1435 (bcopyall || pcopymapDest[i])) {
1436 void *def_ptr = parm_table[i].ptr;
1438 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1441 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1444 switch (parm_table[i].type) {
1446 *(int *)dest_ptr = *(int *)src_ptr;
1451 *(int *)dest_ptr = *(int *)src_ptr;
1455 string_set(dest_ptr,
1460 string_set(dest_ptr,
1462 strupper(*(char **)dest_ptr);
1465 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1466 *(const char ***)src_ptr);
1474 init_copymap(pserviceDest);
1475 if (pserviceSource->copymap)
1476 memcpy((void *)pserviceDest->copymap,
1477 (void *)pserviceSource->copymap,
1478 sizeof(int) * NUMPARAMETERS);
1481 data = pserviceSource->param_opt;
1484 pdata = pserviceDest->param_opt;
1485 /* Traverse destination */
1487 /* If we already have same option, override it */
1488 if (strcmp(pdata->key, data->key) == 0) {
1489 string_free(&pdata->value);
1490 pdata->value = strdup(data->value);
1494 pdata = pdata->next;
1497 paramo = malloc_p(struct param_opt);
1500 paramo->key = strdup(data->key);
1501 paramo->value = strdup(data->value);
1502 DLIST_ADD(pserviceDest->param_opt, paramo);
1508 /***************************************************************************
1509 Check a service for consistency. Return False if the service is in any way
1510 incomplete or faulty, else True.
1511 ***************************************************************************/
1513 static BOOL service_ok(int iService)
1518 if (ServicePtrs[iService]->szService[0] == '\0') {
1519 DEBUG(0, ("The following message indicates an internal error:\n"));
1520 DEBUG(0, ("No service name in service entry.\n"));
1524 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1525 /* I can't see why you'd want a non-printable printer service... */
1526 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1527 if (!ServicePtrs[iService]->bPrint_ok) {
1528 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1529 ServicePtrs[iService]->szService));
1530 ServicePtrs[iService]->bPrint_ok = True;
1531 update_server_announce_as_printserver();
1533 /* [printers] service must also be non-browsable. */
1534 if (ServicePtrs[iService]->bBrowseable)
1535 ServicePtrs[iService]->bBrowseable = False;
1538 /* If a service is flagged unavailable, log the fact at level 0. */
1539 if (!ServicePtrs[iService]->bAvailable)
1540 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1541 ServicePtrs[iService]->szService));
1546 static struct file_lists {
1547 struct file_lists *next;
1551 } *file_lists = NULL;
1553 /*******************************************************************
1554 Keep a linked list of all config files so we know when one has changed
1555 it's date and needs to be reloaded.
1556 ********************************************************************/
1558 static void add_to_file_list(const char *fname, const char *subfname)
1560 struct file_lists *f = file_lists;
1563 if (f->name && !strcmp(f->name, fname))
1569 f = malloc_p(struct file_lists);
1572 f->next = file_lists;
1573 f->name = strdup(fname);
1578 f->subfname = strdup(subfname);
1584 f->modtime = file_modtime(subfname);
1586 time_t t = file_modtime(subfname);
1592 /*******************************************************************
1593 Check if a config file has changed date.
1594 ********************************************************************/
1596 BOOL lp_file_list_changed(void)
1598 struct file_lists *f = file_lists;
1599 DEBUG(6, ("lp_file_list_changed()\n"));
1605 pstrcpy(n2, f->name);
1606 standard_sub_basic(n2,sizeof(n2));
1608 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1609 f->name, n2, ctime(&f->modtime)));
1611 mod_time = file_modtime(n2);
1613 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1615 ("file %s modified: %s\n", n2,
1617 f->modtime = mod_time;
1618 SAFE_FREE(f->subfname);
1619 f->subfname = strdup(n2);
1627 /***************************************************************************
1628 Handle the include operation.
1629 ***************************************************************************/
1631 static BOOL handle_include(const char *pszParmValue, char **ptr)
1634 pstrcpy(fname, pszParmValue);
1636 standard_sub_basic(fname,sizeof(fname));
1638 add_to_file_list(pszParmValue, fname);
1640 string_set(ptr, fname);
1642 if (file_exist(fname))
1643 return (pm_process(fname, do_section, do_parameter, NULL));
1645 DEBUG(2, ("Can't find include file %s\n", fname));
1650 /***************************************************************************
1651 Handle the interpretation of the copy parameter.
1652 ***************************************************************************/
1654 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1658 service serviceTemp;
1660 string_set(ptr, pszParmValue);
1662 init_service(&serviceTemp);
1666 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1668 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1669 if (iTemp == iServiceIndex) {
1670 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1672 copy_service(ServicePtrs[iServiceIndex],
1674 ServicePtrs[iServiceIndex]->copymap);
1678 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1682 free_service(&serviceTemp);
1686 /***************************************************************************
1687 Initialise a copymap.
1688 ***************************************************************************/
1690 static void init_copymap(service * pservice)
1693 SAFE_FREE(pservice->copymap);
1694 pservice->copymap = malloc_array_p(int, NUMPARAMETERS);
1695 if (!pservice->copymap)
1697 ("Couldn't allocate copymap!! (size %d)\n",
1698 (int)NUMPARAMETERS));
1700 for (i = 0; i < NUMPARAMETERS; i++)
1701 pservice->copymap[i] = True;
1704 /***************************************************************************
1705 Return the local pointer to a parameter given the service number and the
1706 pointer into the default structure.
1707 ***************************************************************************/
1709 void *lp_local_ptr(int snum, void *ptr)
1711 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1715 /***************************************************************************
1716 Process a parametric option
1717 ***************************************************************************/
1718 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1720 struct param_opt *paramo, *data;
1723 while (isspace((unsigned char)*pszParmName)) {
1727 name = strdup(pszParmName);
1728 if (!name) return False;
1733 data = Globals.param_opt;
1735 data = ServicePtrs[snum]->param_opt;
1738 /* Traverse destination */
1739 for (paramo=data; paramo; paramo=paramo->next) {
1740 /* If we already have the option set, override it unless
1741 it was a command line option and the new one isn't */
1742 if (strcmp(paramo->key, name) == 0) {
1743 if ((paramo->flags & FLAG_CMDLINE) &&
1744 !(flags & FLAG_CMDLINE)) {
1748 free(paramo->value);
1749 paramo->value = strdup(pszParmValue);
1750 paramo->flags = flags;
1756 paramo = malloc_p(struct param_opt);
1759 paramo->key = strdup(name);
1760 paramo->value = strdup(pszParmValue);
1761 paramo->flags = flags;
1763 DLIST_ADD(Globals.param_opt, paramo);
1765 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1773 /***************************************************************************
1774 Process a parameter for a particular service number. If snum < 0
1775 then assume we are in the globals.
1776 ***************************************************************************/
1777 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1780 void *parm_ptr = NULL; /* where we are going to store the result */
1781 void *def_ptr = NULL;
1783 parmnum = map_parameter(pszParmName);
1786 if (strchr(pszParmName, ':')) {
1787 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1789 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1793 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1794 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1798 /* if the flag has been set on the command line, then don't allow override,
1799 but don't report an error */
1800 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1804 def_ptr = parm_table[parmnum].ptr;
1806 /* we might point at a service, the default service or a global */
1810 if (parm_table[parmnum].class == P_GLOBAL) {
1812 ("Global parameter %s found in service section!\n",
1817 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1822 if (!ServicePtrs[snum]->copymap)
1823 init_copymap(ServicePtrs[snum]);
1825 /* this handles the aliases - set the copymap for other entries with
1826 the same data pointer */
1827 for (i = 0; parm_table[i].label; i++)
1828 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1829 ServicePtrs[snum]->copymap[i] = False;
1832 /* if it is a special case then go ahead */
1833 if (parm_table[parmnum].special) {
1834 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1838 /* now switch on the type of variable it is */
1839 switch (parm_table[parmnum].type)
1842 if (!set_boolean(pszParmValue, parm_ptr)) {
1843 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1849 *(int *)parm_ptr = atoi(pszParmValue);
1855 if (conv_str_size(pszParmValue, &val)) {
1856 if (val <= INT_MAX) {
1857 *(int *)parm_ptr = (int)val;
1862 DEBUG(0,("lp_do_parameter(%s): value is not "
1863 "a valid size specifier!\n", pszParmValue));
1868 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1869 pszParmValue, NULL);
1873 string_set(parm_ptr, pszParmValue);
1877 string_set(parm_ptr, pszParmValue);
1878 strupper(*(char **)parm_ptr);
1882 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1885 parm_table[parmnum].enum_list[i].name)) {
1887 parm_table[parmnum].
1892 if (!parm_table[parmnum].enum_list[i].name) {
1893 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1894 pszParmValue, pszParmName));
1902 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1903 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1904 /* we have to also unset FLAG_DEFAULT on aliases */
1905 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1906 parm_table[i].flags &= ~FLAG_DEFAULT;
1908 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1909 parm_table[i].flags &= ~FLAG_DEFAULT;
1916 /***************************************************************************
1917 Process a parameter.
1918 ***************************************************************************/
1920 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1922 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1923 pszParmName, pszParmValue));
1927 variable argument do parameter
1929 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1931 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1938 s = talloc_vasprintf(NULL, fmt, ap);
1940 ret = do_parameter(pszParmName, s, NULL);
1947 set a parameter from the commandline - this is called from command line parameter
1948 parsing code. It sets the parameter then marks the parameter as unable to be modified
1949 by smb.conf processing
1951 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1953 int parmnum = map_parameter(pszParmName);
1956 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1959 if (parmnum < 0 && strchr(pszParmName, ':')) {
1960 /* set a parametric option */
1961 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1965 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1969 /* reset the CMDLINE flag in case this has been called before */
1970 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1972 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1976 parm_table[parmnum].flags |= FLAG_CMDLINE;
1978 /* we have to also set FLAG_CMDLINE on aliases */
1979 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1980 parm_table[i].flags |= FLAG_CMDLINE;
1982 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1983 parm_table[i].flags |= FLAG_CMDLINE;
1990 set a option from the commandline in 'a=b' format. Use to support --option
1992 BOOL lp_set_option(const char *option)
2010 ret = lp_set_cmdline(s, p+1);
2016 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2018 /***************************************************************************
2019 Print a parameter of the specified type.
2020 ***************************************************************************/
2022 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2028 for (i = 0; p->enum_list[i].name; i++) {
2029 if (*(int *)ptr == p->enum_list[i].value) {
2031 p->enum_list[i].name);
2038 fprintf(f, "%s", BOOLSTR((BOOL)*(int *)ptr));
2043 fprintf(f, "%d", *(int *)ptr);
2047 if ((char ***)ptr && *(char ***)ptr) {
2048 char **list = *(char ***)ptr;
2050 for (; *list; list++)
2051 fprintf(f, "%s%s", *list,
2052 ((*(list+1))?", ":""));
2058 if (*(char **)ptr) {
2059 fprintf(f, "%s", *(char **)ptr);
2067 /***************************************************************************
2068 Check if two parameters are equal.
2069 ***************************************************************************/
2071 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2075 return (*((int *)ptr1) == *((int *)ptr2));
2080 return (*((int *)ptr1) == *((int *)ptr2));
2083 return str_list_equal((const char **)(*(char ***)ptr1),
2084 (const char **)(*(char ***)ptr2));
2089 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2094 return (p1 == p2 || strequal(p1, p2));
2102 /***************************************************************************
2103 Process a new section (service). At this stage all sections are services.
2104 Later we'll have special sections that permit server parameters to be set.
2105 Returns True on success, False on failure.
2106 ***************************************************************************/
2108 static BOOL do_section(const char *pszSectionName, void *userdata)
2111 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2112 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2115 /* if we've just struck a global section, note the fact. */
2116 bInGlobalSection = isglobal;
2118 /* check for multiple global sections */
2119 if (bInGlobalSection) {
2120 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2124 /* if we have a current service, tidy it up before moving on */
2127 if (iServiceIndex >= 0)
2128 bRetval = service_ok(iServiceIndex);
2130 /* if all is still well, move to the next record in the services array */
2132 /* We put this here to avoid an odd message order if messages are */
2133 /* issued by the post-processing of a previous section. */
2134 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2136 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2138 DEBUG(0, ("Failed to add a new service\n"));
2147 /***************************************************************************
2148 Determine if a partcular base parameter is currentl set to the default value.
2149 ***************************************************************************/
2151 static BOOL is_default(int i)
2153 if (!defaults_saved)
2155 switch (parm_table[i].type) {
2157 return str_list_equal((const char **)parm_table[i].def.lvalue,
2158 (const char **)(*(char ***)parm_table[i].ptr));
2161 return strequal(parm_table[i].def.svalue,
2162 *(char **)parm_table[i].ptr);
2164 return parm_table[i].def.bvalue ==
2165 *(int *)parm_table[i].ptr;
2169 return parm_table[i].def.ivalue ==
2170 *(int *)parm_table[i].ptr;
2177 /***************************************************************************
2178 Display the contents of the global structure.
2179 ***************************************************************************/
2181 static void dump_globals(FILE *f, BOOL show_defaults)
2184 struct param_opt *data;
2186 fprintf(f, "# Global parameters\n[global]\n");
2188 for (i = 0; parm_table[i].label; i++)
2189 if (parm_table[i].class == P_GLOBAL &&
2190 parm_table[i].ptr &&
2191 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2192 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2194 fprintf(f, "\t%s = ", parm_table[i].label);
2195 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2198 if (Globals.param_opt != NULL) {
2199 data = Globals.param_opt;
2201 fprintf(f, "\t%s = %s\n", data->key, data->value);
2208 /***************************************************************************
2209 Display the contents of a single services record.
2210 ***************************************************************************/
2212 static void dump_a_service(service * pService, FILE * f)
2215 struct param_opt *data;
2217 if (pService != &sDefault)
2218 fprintf(f, "\n[%s]\n", pService->szService);
2220 for (i = 0; parm_table[i].label; i++)
2221 if (parm_table[i].class == P_LOCAL &&
2222 parm_table[i].ptr &&
2223 (*parm_table[i].label != '-') &&
2224 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2225 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2227 if (pService == &sDefault) {
2228 if (defaults_saved && is_default(i))
2231 if (equal_parameter(parm_table[i].type,
2232 ((char *)pService) +
2234 ((char *)&sDefault) +
2239 fprintf(f, "\t%s = ", parm_table[i].label);
2240 print_parameter(&parm_table[i],
2241 ((char *)pService) + pdiff, f);
2244 if (pService->param_opt != NULL) {
2245 data = pService->param_opt;
2247 fprintf(f, "\t%s = %s\n", data->key, data->value);
2253 BOOL lp_dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
2255 service * pService = ServicePtrs[snum];
2256 struct parm_struct *parm;
2259 parm = lp_parm_struct(parm_name);
2267 ptr = ((char *)pService) +
2268 PTR_DIFF(parm->ptr, &sDefault);
2270 print_parameter(parm,
2276 /***************************************************************************
2277 Return info about the next service in a service. snum==-1 gives the globals.
2278 Return NULL when out of parameters.
2279 ***************************************************************************/
2281 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2284 /* do the globals */
2285 for (; parm_table[*i].label; (*i)++) {
2286 if (parm_table[*i].class == P_SEPARATOR)
2287 return &parm_table[(*i)++];
2289 if (!parm_table[*i].ptr
2290 || (*parm_table[*i].label == '-'))
2294 && (parm_table[*i].ptr ==
2295 parm_table[(*i) - 1].ptr))
2298 return &parm_table[(*i)++];
2301 service *pService = ServicePtrs[snum];
2303 for (; parm_table[*i].label; (*i)++) {
2304 if (parm_table[*i].class == P_SEPARATOR)
2305 return &parm_table[(*i)++];
2307 if (parm_table[*i].class == P_LOCAL &&
2308 parm_table[*i].ptr &&
2309 (*parm_table[*i].label != '-') &&
2311 (parm_table[*i].ptr !=
2312 parm_table[(*i) - 1].ptr)))
2315 PTR_DIFF(parm_table[*i].ptr,
2318 if (allparameters ||
2319 !equal_parameter(parm_table[*i].type,
2320 ((char *)pService) +
2322 ((char *)&sDefault) +
2325 return &parm_table[(*i)++];
2335 /***************************************************************************
2336 Return TRUE if the passed service number is within range.
2337 ***************************************************************************/
2339 BOOL lp_snum_ok(int iService)
2341 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2344 /***************************************************************************
2345 Auto-load some home services.
2346 ***************************************************************************/
2348 static void lp_add_auto_services(const char *str)
2353 /***************************************************************************
2354 Announce ourselves as a print server.
2355 ***************************************************************************/
2357 void update_server_announce_as_printserver(void)
2359 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2362 /***************************************************************************
2363 Have we loaded a services file yet?
2364 ***************************************************************************/
2366 BOOL lp_loaded(void)
2371 /***************************************************************************
2372 Unload unused services.
2373 ***************************************************************************/
2375 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2378 for (i = 0; i < iNumServices; i++) {
2382 if (!snumused || !snumused(smb, i)) {
2383 ServicePtrs[i]->valid = False;
2384 free_service(ServicePtrs[i]);
2389 /***************************************************************************
2391 ***************************************************************************/
2393 void lp_killservice(int iServiceIn)
2395 if (VALID(iServiceIn)) {
2396 ServicePtrs[iServiceIn]->valid = False;
2397 free_service(ServicePtrs[iServiceIn]);
2401 /***************************************************************************
2402 Load the services array from the services file. Return True on success,
2404 ***************************************************************************/
2410 struct param_opt *data;
2414 bInGlobalSection = True;
2416 if (Globals.param_opt != NULL) {
2417 struct param_opt *next;
2418 for (data=Globals.param_opt; data; data=next) {
2420 if (data->flags & FLAG_CMDLINE) continue;
2423 DLIST_REMOVE(Globals.param_opt, data);
2430 pstrcpy(n2, lp_configfile());
2431 standard_sub_basic(n2,sizeof(n2));
2432 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2434 add_to_file_list(lp_configfile(), n2);
2436 /* We get sections first, so have to start 'behind' to make up */
2438 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2440 /* finish up the last section */
2441 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2443 if (iServiceIndex >= 0)
2444 bRetval = service_ok(iServiceIndex);
2446 lp_add_auto_services(lp_auto_services());
2448 lp_add_hidden("IPC$", "IPC");
2449 lp_add_hidden("ADMIN$", "DISK");
2451 set_default_server_announce_type();
2455 if (!Globals.szWINSservers && Globals.bWINSsupport) {
2456 lp_do_parameter(-1, "wins server", "127.0.0.1");
2464 /***************************************************************************
2465 Reset the max number of services.
2466 ***************************************************************************/
2468 void lp_resetnumservices(void)
2473 /***************************************************************************
2474 Return the max number of services.
2475 ***************************************************************************/
2477 int lp_numservices(void)
2479 return (iNumServices);
2482 /***************************************************************************
2483 Display the contents of the services array in human-readable form.
2484 ***************************************************************************/
2486 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2491 defaults_saved = False;
2493 dump_globals(f, show_defaults);
2495 dump_a_service(&sDefault, f);
2497 for (iService = 0; iService < maxtoprint; iService++)
2498 lp_dump_one(f, show_defaults, iService);
2501 /***************************************************************************
2502 Display the contents of one service in human-readable form.
2503 ***************************************************************************/
2505 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2508 if (ServicePtrs[snum]->szService[0] == '\0')
2510 dump_a_service(ServicePtrs[snum], f);
2514 /***************************************************************************
2515 Return the number of the service with the given name, or -1 if it doesn't
2516 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2517 getservicebyname()! This works ONLY if all services have been loaded, and
2518 does not copy the found service.
2519 ***************************************************************************/
2521 int lp_servicenumber(const char *pszServiceName)
2524 fstring serviceName;
2527 for (iService = iNumServices - 1; iService >= 0; iService--) {
2528 if (VALID(iService) && ServicePtrs[iService]->szService) {
2530 * The substitution here is used to support %U is
2533 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2534 standard_sub_basic(serviceName,sizeof(serviceName));
2535 if (strequal(serviceName, pszServiceName))
2541 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2546 int lp_find_valid_service(const char *pszServiceName)
2550 iService = lp_servicenumber(pszServiceName);
2552 if (iService >= 0 && !lp_snum_ok(iService)) {
2553 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService, pszServiceName));
2557 if (iService == -1) {
2558 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName));
2564 /*******************************************************************
2565 A useful volume label function.
2566 ********************************************************************/
2567 const char *volume_label(int snum)
2569 const char *ret = lp_volume(snum);
2571 return lp_servicename(snum);
2576 /*******************************************************************
2577 Set the server type we will announce as via nmbd.
2578 ********************************************************************/
2580 static void set_default_server_announce_type(void)
2582 default_server_announce = 0;
2583 default_server_announce |= SV_TYPE_WORKSTATION;
2584 default_server_announce |= SV_TYPE_SERVER;
2585 default_server_announce |= SV_TYPE_SERVER_UNIX;
2587 switch (lp_announce_as()) {
2588 case ANNOUNCE_AS_NT_SERVER:
2589 default_server_announce |= SV_TYPE_SERVER_NT;
2590 /* fall through... */
2591 case ANNOUNCE_AS_NT_WORKSTATION:
2592 default_server_announce |= SV_TYPE_NT;
2594 case ANNOUNCE_AS_WIN95:
2595 default_server_announce |= SV_TYPE_WIN95_PLUS;
2597 case ANNOUNCE_AS_WFW:
2598 default_server_announce |= SV_TYPE_WFW;
2604 switch (lp_server_role()) {
2605 case ROLE_DOMAIN_MEMBER:
2606 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2608 case ROLE_DOMAIN_PDC:
2609 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2611 case ROLE_DOMAIN_BDC:
2612 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2614 case ROLE_STANDALONE:
2618 if (lp_time_server())
2619 default_server_announce |= SV_TYPE_TIME_SOURCE;
2621 if (lp_host_msdfs())
2622 default_server_announce |= SV_TYPE_DFS_SERVER;
2624 /* TODO: only announce us as print server when we are a print server */
2625 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2628 /***********************************************************
2629 If we are PDC then prefer us as DMB
2630 ************************************************************/
2632 BOOL lp_domain_master(void)
2634 return (lp_server_role() == ROLE_DOMAIN_PDC);
2637 /***********************************************************
2638 If we are PDC then prefer us as DMB
2639 ************************************************************/
2641 BOOL lp_domain_logons(void)
2643 return (lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC);
2646 /***********************************************************
2647 If we are DMB then prefer us as LMB
2648 ************************************************************/
2650 BOOL lp_preferred_master(void)
2652 return (lp_local_master() && lp_domain_master());
2655 /*******************************************************************
2657 ********************************************************************/
2659 void lp_remove_service(int snum)
2661 ServicePtrs[snum]->valid = False;
2664 /*******************************************************************
2666 ********************************************************************/
2668 void lp_copy_service(int snum, const char *new_name)
2670 const char *oldname = lp_servicename(snum);
2671 do_section(new_name, NULL);
2673 snum = lp_servicenumber(new_name);
2675 lp_do_parameter(snum, "copy", oldname);
2680 /*******************************************************************
2681 Get the default server type we will announce as via nmbd.
2682 ********************************************************************/
2683 int lp_default_server_announce(void)
2685 return default_server_announce;
2688 const char *lp_printername(int snum)
2690 const char *ret = _lp_printername(snum);
2691 if (ret == NULL || (ret != NULL && *ret == '\0'))
2692 ret = lp_const_servicename(snum);
2698 /*******************************************************************
2699 Return the max print jobs per queue.
2700 ********************************************************************/
2702 int lp_maxprintjobs(int snum)
2704 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2705 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2706 maxjobs = PRINT_MAX_JOBID - 1;