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 #define standard_sub_basic(str,len)
73 /* some helpful bits */
74 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
75 #define VALID(i) ServicePtrs[i]->valid
77 static BOOL do_parameter(const char *, const char *, void *);
78 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
80 static BOOL defaults_saved = False;
84 struct param_opt *prev, *next;
91 * This structure describes global (ie., server-wide) parameters.
101 char *display_charset;
106 char *szServerString;
107 char *szAutoServices;
110 char *szShareBackend;
113 char *szWINS_CONFIG_URL;
117 char **szPasswordServers;
118 char *szSocketOptions;
120 char **szWINSservers;
122 char *szSocketAddress;
123 char *szAnnounceVersion; /* This is initialised in init_globals */
126 char **szNetbiosAliases;
127 char *szNetbiosScope;
128 char *szDomainOtherSIDs;
129 char **szNameResolveOrder;
130 char **dcerpc_ep_servers;
131 char **server_services;
132 char *ntptr_providor;
133 char *szWinbindSeparator;
134 char *szWinbinddSocketDirectory;
135 int bWinbindSealedPipes;
136 char *swat_directory;
151 int paranoid_server_security;
154 int announce_as; /* This is initialised in init_globals */
161 char *socket_options;
166 int bPreferredMaster;
167 int bEncryptPasswords;
169 int bObeyPamRestrictions;
174 int bBindInterfacesOnly;
176 int bNTStatusSupport;
182 int bClientPlaintextAuth;
183 int bClientLanManAuth;
184 int bClientNTLMv2Auth;
185 int client_use_spnego_principal;
191 struct param_opt *param_opt;
195 static global Globals;
198 * This structure describes a single service.
213 char **ntvfs_handler;
229 struct param_opt *param_opt;
231 char dummy[3]; /* for alignment */
236 /* This is a default service used to prime a services structure */
237 static service sDefault = {
239 NULL, /* szService */
242 NULL, /* szInclude */
243 NULL, /* szPrintername */
244 NULL, /* szHostsallow */
245 NULL, /* szHostsdeny */
249 NULL, /* ntvfs_handler */
250 1000, /* iMaxPrintJobs */
251 0, /* iMaxConnections */
253 True, /* bAvailable */
254 True, /* bBrowseable */
255 True, /* bRead_only */
256 False, /* bPrint_ok */
257 False, /* bMap_system */
258 False, /* bMap_hidden */
259 True, /* bMap_archive */
260 True, /* bStrictLocking */
262 False, /* bMSDfsRoot */
263 False, /* bStrictSync */
264 False, /* bCIFileSystem */
265 NULL, /* Parametric options */
270 /* local variables */
271 static service **ServicePtrs = NULL;
272 static int iNumServices = 0;
273 static int iServiceIndex = 0;
274 static BOOL bInGlobalSection = True;
275 static int default_server_announce;
277 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
279 /* prototypes for the special type handlers */
280 static BOOL handle_include(const char *pszParmValue, char **ptr);
281 static BOOL handle_copy(const char *pszParmValue, char **ptr);
283 static void set_default_server_announce_type(void);
285 static const struct enum_list enum_protocol[] = {
286 {PROTOCOL_SMB2, "SMB2"},
287 {PROTOCOL_NT1, "NT1"},
288 {PROTOCOL_LANMAN2, "LANMAN2"},
289 {PROTOCOL_LANMAN1, "LANMAN1"},
290 {PROTOCOL_CORE, "CORE"},
291 {PROTOCOL_COREPLUS, "COREPLUS"},
292 {PROTOCOL_COREPLUS, "CORE+"},
296 static const struct enum_list enum_security[] = {
297 {SEC_SHARE, "SHARE"},
302 /* Types of machine we can announce as. */
303 #define ANNOUNCE_AS_NT_SERVER 1
304 #define ANNOUNCE_AS_WIN95 2
305 #define ANNOUNCE_AS_WFW 3
306 #define ANNOUNCE_AS_NT_WORKSTATION 4
308 static const struct enum_list enum_announce_as[] = {
309 {ANNOUNCE_AS_NT_SERVER, "NT"},
310 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
311 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
312 {ANNOUNCE_AS_WIN95, "win95"},
313 {ANNOUNCE_AS_WFW, "WfW"},
317 static const struct enum_list enum_bool_auto[] = {
328 /* Client-side offline caching policy types */
329 #define CSC_POLICY_MANUAL 0
330 #define CSC_POLICY_DOCUMENTS 1
331 #define CSC_POLICY_PROGRAMS 2
332 #define CSC_POLICY_DISABLE 3
334 static const struct enum_list enum_csc_policy[] = {
335 {CSC_POLICY_MANUAL, "manual"},
336 {CSC_POLICY_DOCUMENTS, "documents"},
337 {CSC_POLICY_PROGRAMS, "programs"},
338 {CSC_POLICY_DISABLE, "disable"},
342 /* SMB signing types. */
343 static const struct enum_list enum_smb_signing_vals[] = {
344 {SMB_SIGNING_OFF, "No"},
345 {SMB_SIGNING_OFF, "False"},
346 {SMB_SIGNING_OFF, "0"},
347 {SMB_SIGNING_OFF, "Off"},
348 {SMB_SIGNING_OFF, "disabled"},
349 {SMB_SIGNING_SUPPORTED, "Yes"},
350 {SMB_SIGNING_SUPPORTED, "True"},
351 {SMB_SIGNING_SUPPORTED, "1"},
352 {SMB_SIGNING_SUPPORTED, "On"},
353 {SMB_SIGNING_SUPPORTED, "enabled"},
354 {SMB_SIGNING_REQUIRED, "required"},
355 {SMB_SIGNING_REQUIRED, "mandatory"},
356 {SMB_SIGNING_REQUIRED, "force"},
357 {SMB_SIGNING_REQUIRED, "forced"},
358 {SMB_SIGNING_REQUIRED, "enforced"},
359 {SMB_SIGNING_AUTO, "auto"},
363 static const struct enum_list enum_server_role[] = {
364 {ROLE_STANDALONE, "standalone"},
365 {ROLE_DOMAIN_MEMBER, "member server"},
366 {ROLE_DOMAIN_BDC, "bdc"},
367 {ROLE_DOMAIN_PDC, "pdc"},
372 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
374 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
375 * is implied in current control logic. This may change at some later time. A
376 * flag value of 0 means - show as development option only.
378 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
379 * screen in SWAT. This is used to exclude parameters as well as to squash all
380 * parameters that have been duplicated by pseudonyms.
382 static struct parm_struct parm_table[] = {
383 {"Base Options", P_SEP, P_SEPARATOR},
385 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
387 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
388 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
389 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
390 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
391 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
392 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
393 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
394 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
396 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
397 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
398 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
399 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
400 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
402 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
403 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
404 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
405 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
407 {"Security Options", P_SEP, P_SEPARATOR},
409 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
410 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
411 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
412 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
415 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
429 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
431 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
432 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
434 {"Logging Options", P_SEP, P_SEPARATOR},
436 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
437 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
438 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"Protocol Options", P_SEP, P_SEPARATOR},
442 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
456 {"server max protocol", P_ENUM, P_GLOBAL, &Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
457 {"server min protocol", P_ENUM, P_GLOBAL, &Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
458 {"client max protocol", P_ENUM, P_GLOBAL, &Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
459 {"client min protocol", P_ENUM, P_GLOBAL, &Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
460 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
461 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
462 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
463 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
465 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
467 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
468 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
469 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
470 {"max xmit", P_BYTES, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
472 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
473 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
475 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
477 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
478 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
479 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
480 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
482 {"Tuning Options", P_SEP, P_SEPARATOR},
484 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
485 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
486 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
488 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
489 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
491 {"Printing Options", P_SEP, P_SEPARATOR},
493 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
494 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
495 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
497 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
498 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
500 {"Filename Handling", P_SEP, P_SEPARATOR},
502 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
503 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
504 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
506 {"Domain Options", P_SEP, P_SEPARATOR},
508 {"Logon Options", P_SEP, P_SEPARATOR},
511 {"Browse Options", P_SEP, P_SEPARATOR},
513 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
514 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
515 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
516 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
517 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
519 {"WINS Options", P_SEP, P_SEPARATOR},
521 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
522 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
523 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
524 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
526 {"Locking Options", P_SEP, P_SEPARATOR},
528 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
530 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
532 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
534 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
535 {"share backend", P_STRING, P_GLOBAL, &Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
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 {"modules dir", P_STRING, P_GLOBAL, &Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
546 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
548 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
549 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
551 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
552 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
553 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
555 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
558 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
560 {"winbindd socket directory", P_STRING, P_GLOBAL, &Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
561 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
563 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
568 return the parameter table
570 struct parm_struct *lp_parm_table(void)
575 /***************************************************************************
576 Initialise the global parameter structure.
577 ***************************************************************************/
578 static void init_globals(void)
583 DEBUG(3, ("Initialising global parameters\n"));
585 for (i = 0; parm_table[i].label; i++) {
586 if ((parm_table[i].type == P_STRING ||
587 parm_table[i].type == P_USTRING) &&
589 !(parm_table[i].flags & FLAG_CMDLINE)) {
590 string_set(parm_table[i].ptr, "");
594 do_parameter("config file", dyn_CONFIGFILE, NULL);
596 do_parameter("share backend", "classic", NULL);
598 do_parameter("server role", "standalone", NULL);
600 /* options that can be set on the command line must be initialised via
601 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
603 do_parameter("socket options", "TCP_NODELAY", NULL);
605 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
606 myname = get_myname();
607 do_parameter("netbios name", myname, NULL);
609 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
611 do_parameter("fstype", FSTYPE_STRING, NULL);
612 do_parameter("ntvfs handler", "unixuid default", NULL);
613 do_parameter("max connections", "-1", NULL);
615 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
616 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc winbind", NULL);
617 do_parameter("ntptr providor", "simple_ldb", NULL);
618 do_parameter("auth methods", "anonymous sam_ignoredomain", 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 config database", "wins_config.ldb", NULL);
623 do_parameter("wins database", "wins.ldb", NULL);
624 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
626 /* This hive should be dynamically generated by Samba using
627 data from the sam, but for the moment leave it in a tdb to
628 keep regedt32 from popping up an annoying dialog. */
629 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
631 /* using UTF8 by default allows us to support all chars */
632 do_parameter("unix charset", "UTF8", NULL);
634 /* Use codepage 850 as a default for the dos character set */
635 do_parameter("dos charset", "CP850", NULL);
638 * Allow the default PASSWD_CHAT to be overridden in local.h.
640 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
642 do_parameter("pid directory", dyn_PIDDIR, NULL);
643 do_parameter("lock dir", dyn_LOCKDIR, NULL);
644 do_parameter("modules dir", dyn_MODULESDIR, NULL);
645 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
647 do_parameter("socket address", "0.0.0.0", NULL);
648 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
650 do_parameter_var("announce version", "%d.%d",
651 DEFAULT_MAJOR_VERSION,
652 DEFAULT_MINOR_VERSION);
654 do_parameter("password server", "*", NULL);
656 do_parameter("max mux", "50", NULL);
657 do_parameter("max xmit", "12288", NULL);
658 do_parameter("password level", "0", NULL);
659 do_parameter("LargeReadwrite", "True", NULL);
660 do_parameter("server min protocol", "CORE", NULL);
661 do_parameter("server max protocol", "NT1", NULL);
662 do_parameter("client min protocol", "CORE", NULL);
663 do_parameter("client max protocol", "NT1", NULL);
664 do_parameter("security", "USER", NULL);
665 do_parameter("paranoid server security", "True", NULL);
666 do_parameter("EncryptPasswords", "True", NULL);
667 do_parameter("ReadRaw", "True", NULL);
668 do_parameter("WriteRaw", "True", NULL);
669 do_parameter("NullPasswords", "False", NULL);
670 do_parameter("ObeyPamRestrictions", "False", NULL);
671 do_parameter("announce as", "NT SERVER", NULL);
673 do_parameter("TimeServer", "False", NULL);
674 do_parameter("BindInterfacesOnly", "False", NULL);
675 do_parameter("Unicode", "True", NULL);
676 do_parameter("ClientLanManAuth", "True", NULL);
677 do_parameter("LanmanAuth", "True", NULL);
678 do_parameter("NTLMAuth", "True", NULL);
679 do_parameter("client use spnego principal", "False", NULL);
681 do_parameter("UnixExtensions", "False", NULL);
683 do_parameter("PreferredMaster", "Auto", NULL);
684 do_parameter("LocalMaster", "True", NULL);
686 do_parameter("wins support", "False", NULL);
687 do_parameter("dns proxy", "True", NULL);
689 do_parameter("winbind separator", "\\", NULL);
690 do_parameter("winbind sealed pipes", "True", NULL);
691 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR, NULL);
693 do_parameter("client signing", "Yes", NULL);
694 do_parameter("server signing", "auto", NULL);
696 do_parameter("use spnego", "True", NULL);
698 do_parameter("smb ports", SMB_PORTS, NULL);
699 do_parameter("nbt port", "137", NULL);
700 do_parameter("dgram port", "138", NULL);
701 do_parameter("cldap port", "389", NULL);
702 do_parameter("krb5 port", "88", NULL);
703 do_parameter("kpasswd port", "464", NULL);
704 do_parameter("web port", "901", NULL);
705 do_parameter("swat directory", dyn_SWATDIR, NULL);
707 do_parameter("nt status support", "True", NULL);
709 do_parameter("max wins ttl", "518400", NULL); /* 6 days */
710 do_parameter("min wins ttl", "10", NULL);
712 do_parameter("tls enabled", "True", NULL);
713 do_parameter("tls keyfile", "tls/key.pem", NULL);
714 do_parameter("tls certfile", "tls/cert.pem", NULL);
715 do_parameter("tls cafile", "tls/ca.pem", NULL);
716 do_parameter_var("js include", "%s", dyn_JSDIR);
717 do_parameter_var("setup directory", "%s", dyn_SETUPDIR);
719 for (i = 0; parm_table[i].label; i++) {
720 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
721 parm_table[i].flags |= FLAG_DEFAULT;
726 static TALLOC_CTX *lp_talloc;
728 /******************************************************************* a
729 Free up temporary memory - called from the main loop.
730 ********************************************************************/
732 void lp_talloc_free(void)
736 talloc_free(lp_talloc);
740 /*******************************************************************
741 Convenience routine to grab string parameters into temporary memory
742 and run standard_sub_basic on them. The buffers can be written to by
743 callers without affecting the source string.
744 ********************************************************************/
746 static const char *lp_string(const char *s)
748 #if 0 /* until REWRITE done to make thread-safe */
749 size_t len = s ? strlen(s) : 0;
753 /* The follow debug is useful for tracking down memory problems
754 especially if you have an inner loop that is calling a lp_*()
755 function that returns a string. Perhaps this debug should be
756 present all the time? */
759 DEBUG(10, ("lp_string(%s)\n", s));
762 #if 0 /* until REWRITE done to make thread-safe */
764 lp_talloc = talloc_init("lp_talloc");
766 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
774 strlcpy(ret, s, len);
776 if (trim_string(ret, "\"", "\"")) {
777 if (strchr(ret,'"') != NULL)
778 strlcpy(ret, s, len);
781 standard_sub_basic(ret,len+100);
788 In this section all the functions that are used to access the
789 parameters from the rest of the program are defined
792 #define FN_GLOBAL_STRING(fn_name,ptr) \
793 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
794 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
795 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
796 #define FN_GLOBAL_LIST(fn_name,ptr) \
797 const char **fn_name(void) {return(*(const char ***)(ptr));}
798 #define FN_GLOBAL_BOOL(fn_name,ptr) \
799 BOOL fn_name(void) {return((BOOL)*(int *)(ptr));}
800 #define FN_GLOBAL_CHAR(fn_name,ptr) \
801 char fn_name(void) {return(*(char *)(ptr));}
802 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
803 int fn_name(void) {return(*(int *)(ptr));}
805 #define FN_LOCAL_STRING(fn_name,val) \
806 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
807 #define FN_LOCAL_CONST_STRING(fn_name,val) \
808 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
809 #define FN_LOCAL_LIST(fn_name,val) \
810 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
811 #define FN_LOCAL_BOOL(fn_name,val) \
812 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
813 #define FN_LOCAL_CHAR(fn_name,val) \
814 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
815 #define FN_LOCAL_INTEGER(fn_name,val) \
816 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
818 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &Globals.server_role)
819 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
820 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
821 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
822 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
823 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
824 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &Globals.kpasswd_port)
825 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
826 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
827 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
828 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
829 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
830 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
831 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
832 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
833 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
834 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
835 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
836 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, &Globals.szShareBackend)
837 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
838 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
839 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL)
840 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
841 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
842 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &Globals.szWinbinddSocketDirectory)
843 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
844 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
845 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
846 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
847 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &Globals.szModulesDir)
848 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
849 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
850 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
851 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
852 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
853 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
854 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
855 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
856 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
857 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
858 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
859 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
860 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
861 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
862 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
863 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
864 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
865 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
866 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
868 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
869 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
870 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &Globals.bWINSdnsProxy)
871 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
872 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
873 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
874 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
875 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
876 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
877 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
878 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
879 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
880 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
881 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
882 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
883 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
884 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
885 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
886 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
887 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
888 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
889 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
890 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
891 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
892 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
893 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
894 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
895 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
896 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
897 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
898 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &Globals.srv_maxprotocol)
899 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &Globals.srv_minprotocol)
900 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &Globals.cli_maxprotocol)
901 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &Globals.cli_minprotocol)
902 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
903 _PUBLIC_ FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
904 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
905 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
906 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
909 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
910 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
911 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
912 static FN_LOCAL_STRING(_lp_printername, szPrintername)
913 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
914 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
915 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
916 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
917 static FN_LOCAL_STRING(lp_volume, volume)
918 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
919 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
920 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
921 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
922 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
923 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
924 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
925 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
926 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
927 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
928 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
929 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
930 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
931 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
932 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
934 /* local prototypes */
936 static int map_parameter(const char *pszParmName);
937 static int getservicebyname(const char *pszServiceName,
938 service * pserviceDest);
939 static void copy_service(service * pserviceDest,
940 service * pserviceSource, int *pcopymapDest);
941 static BOOL service_ok(int iService);
942 static BOOL do_section(const char *pszSectionName, void *);
943 static void init_copymap(service * pservice);
945 /* This is a helper function for parametrical options support. */
946 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
947 /* Actual parametrical functions are quite simple */
948 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
951 struct param_opt *data;
953 if (lookup_service >= iNumServices) return NULL;
955 data = (lookup_service < 0) ?
956 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
958 asprintf(&vfskey, "%s:%s", type, option);
962 if (strcmp(data->key, vfskey) == 0) {
969 if (lookup_service >= 0) {
970 /* Try to fetch the same option but from globals */
971 /* but only if we are not already working with Globals */
972 data = Globals.param_opt;
974 if (strcmp(data->key, vfskey) == 0) {
988 /*******************************************************************
989 convenience routine to return int parameters.
990 ********************************************************************/
991 static int lp_int(const char *s)
995 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
999 return strtol(s, NULL, 0);
1002 /*******************************************************************
1003 convenience routine to return unsigned long parameters.
1004 ********************************************************************/
1005 static int lp_ulong(const char *s)
1009 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1013 return strtoul(s, NULL, 0);
1016 /*******************************************************************
1017 convenience routine to return boolean parameters.
1018 ********************************************************************/
1019 static BOOL lp_bool(const char *s)
1024 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1028 if (!set_boolean(s, &ret)) {
1029 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1037 /* Return parametric option from a given service. Type is a part of option before ':' */
1038 /* Parametric option has following syntax: 'Type: option = value' */
1039 /* Returned value is allocated in 'lp_talloc' context */
1041 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1043 const char *value = lp_get_parametric(lookup_service, type, option);
1046 return lp_string(value);
1051 /* Return parametric option from a given service. Type is a part of option before ':' */
1052 /* Parametric option has following syntax: 'Type: option = value' */
1053 /* Returned value is allocated in 'lp_talloc' context */
1055 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1056 const char *separator)
1058 const char *value = lp_get_parametric(lookup_service, type, option);
1061 return str_list_make(talloc_autofree_context(), value, separator);
1066 /* Return parametric option from a given service. Type is a part of option before ':' */
1067 /* Parametric option has following syntax: 'Type: option = value' */
1069 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1071 const char *value = lp_get_parametric(lookup_service, type, option);
1074 return lp_int(value);
1079 /* Return parametric option from a given service. Type is a part of
1080 * option before ':'.
1081 * Parametric option has following syntax: 'Type: option = value'.
1084 int lp_parm_bytes(int lookup_service, const char *type, const char *option, int default_v)
1088 const char *value = lp_get_parametric(lookup_service, type, option);
1090 if (value && conv_str_size(value, &bval)) {
1091 if (bval <= INT_MAX) {
1099 /* Return parametric option from a given service. Type is a part of option before ':' */
1100 /* Parametric option has following syntax: 'Type: option = value' */
1102 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1104 const char *value = lp_get_parametric(lookup_service, type, option);
1107 return lp_ulong(value);
1112 /* Return parametric option from a given service. Type is a part of option before ':' */
1113 /* Parametric option has following syntax: 'Type: option = value' */
1115 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1117 const char *value = lp_get_parametric(lookup_service, type, option);
1120 return lp_bool(value);
1126 /***************************************************************************
1127 Initialise a service to the defaults.
1128 ***************************************************************************/
1130 static void init_service(service * pservice)
1132 memset((char *)pservice, '\0', sizeof(service));
1133 copy_service(pservice, &sDefault, NULL);
1136 /***************************************************************************
1137 Free the dynamically allocated parts of a service struct.
1138 ***************************************************************************/
1140 static void free_service(service *pservice)
1143 struct param_opt *data, *pdata;
1147 if (pservice->szService)
1148 DEBUG(5, ("free_service: Freeing service %s\n",
1149 pservice->szService));
1151 string_free(&pservice->szService);
1152 SAFE_FREE(pservice->copymap);
1154 for (i = 0; parm_table[i].label; i++) {
1155 if ((parm_table[i].type == P_STRING ||
1156 parm_table[i].type == P_USTRING) &&
1157 parm_table[i].class == P_LOCAL) {
1158 string_free((char **)
1159 (((char *)pservice) +
1160 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1161 } else if (parm_table[i].type == P_LIST &&
1162 parm_table[i].class == P_LOCAL) {
1163 char ***listp = (char ***)(((char *)pservice) +
1164 PTR_DIFF(parm_table[i].ptr, &sDefault));
1165 talloc_free(*listp);
1170 DEBUG(5,("Freeing parametrics:\n"));
1171 data = pservice->param_opt;
1173 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1174 string_free(&data->key);
1175 string_free(&data->value);
1181 ZERO_STRUCTP(pservice);
1184 /***************************************************************************
1185 Add a new service to the services array initialising it with the given
1187 ***************************************************************************/
1189 static int add_a_service(const service *pservice, const char *name)
1193 int num_to_alloc = iNumServices + 1;
1194 struct param_opt *data, *pdata;
1196 tservice = *pservice;
1198 /* it might already exist */
1200 i = getservicebyname(name, NULL);
1202 /* Clean all parametric options for service */
1203 /* They will be added during parsing again */
1204 data = ServicePtrs[i]->param_opt;
1206 string_free(&data->key);
1207 string_free(&data->value);
1212 ServicePtrs[i]->param_opt = NULL;
1217 /* find an invalid one */
1218 for (i = 0; i < iNumServices; i++)
1219 if (!ServicePtrs[i]->valid)
1222 /* if not, then create one */
1223 if (i == iNumServices) {
1226 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1229 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1234 ServicePtrs[iNumServices] = malloc_p(service);
1236 if (!ServicePtrs[iNumServices]) {
1237 DEBUG(0,("add_a_service: out of memory!\n"));
1243 free_service(ServicePtrs[i]);
1245 ServicePtrs[i]->valid = True;
1247 init_service(ServicePtrs[i]);
1248 copy_service(ServicePtrs[i], &tservice, NULL);
1250 string_set(&ServicePtrs[i]->szService, name);
1254 /***************************************************************************
1255 Add a new home service, with the specified home directory, defaults coming
1257 ***************************************************************************/
1259 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1260 const char *user, const char *pszHomedir)
1265 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1270 if (!(*(ServicePtrs[iDefaultService]->szPath))
1271 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1272 pstrcpy(newHomedir, pszHomedir);
1274 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1275 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1278 string_set(&ServicePtrs[i]->szPath, newHomedir);
1280 if (!(*(ServicePtrs[i]->comment))) {
1282 slprintf(comment, sizeof(comment) - 1,
1283 "Home directory of %s", user);
1284 string_set(&ServicePtrs[i]->comment, comment);
1286 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1287 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1289 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1295 /***************************************************************************
1296 Add a new service, based on an old one.
1297 ***************************************************************************/
1299 int lp_add_service(const char *pszService, int iDefaultService)
1301 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1304 /***************************************************************************
1305 Add the IPC service.
1306 ***************************************************************************/
1308 static BOOL lp_add_hidden(const char *name, const char *fstype)
1311 int i = add_a_service(&sDefault, name);
1316 slprintf(comment, sizeof(comment) - 1,
1317 "%s Service (%s)", fstype, Globals.szServerString);
1319 string_set(&ServicePtrs[i]->szPath, tmpdir());
1320 string_set(&ServicePtrs[i]->comment, comment);
1321 string_set(&ServicePtrs[i]->fstype, fstype);
1322 ServicePtrs[i]->iMaxConnections = -1;
1323 ServicePtrs[i]->bAvailable = True;
1324 ServicePtrs[i]->bRead_only = True;
1325 ServicePtrs[i]->bPrint_ok = False;
1326 ServicePtrs[i]->bBrowseable = False;
1328 if (strcasecmp(fstype, "IPC") == 0) {
1329 lp_do_parameter(i, "ntvfs handler", "default");
1332 DEBUG(3, ("adding hidden service %s\n", name));
1337 /***************************************************************************
1338 Add a new printer service, with defaults coming from service iFrom.
1339 ***************************************************************************/
1341 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1343 const char *comment = "From Printcap";
1344 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1349 /* note that we do NOT default the availability flag to True - */
1350 /* we take it from the default service passed. This allows all */
1351 /* dynamic printers to be disabled by disabling the [printers] */
1352 /* entry (if/when the 'available' keyword is implemented!). */
1354 /* the printer name is set to the service name. */
1355 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1356 string_set(&ServicePtrs[i]->comment, comment);
1357 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1358 /* Printers cannot be read_only. */
1359 ServicePtrs[i]->bRead_only = False;
1360 /* Printer services must be printable. */
1361 ServicePtrs[i]->bPrint_ok = True;
1363 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1365 update_server_announce_as_printserver();
1370 /***************************************************************************
1371 Map a parameter's string representation to something we can use.
1372 Returns False if the parameter string is not recognised, else TRUE.
1373 ***************************************************************************/
1375 static int map_parameter(const char *pszParmName)
1379 if (*pszParmName == '-')
1382 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1383 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1386 /* Warn only if it isn't parametric option */
1387 if (strchr(pszParmName, ':') == NULL)
1388 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1389 /* We do return 'fail' for parametric options as well because they are
1390 stored in different storage
1397 return the parameter structure for a parameter
1399 struct parm_struct *lp_parm_struct(const char *name)
1401 int parmnum = map_parameter(name);
1402 if (parmnum == -1) return NULL;
1403 return &parm_table[parmnum];
1407 return the parameter pointer for a parameter
1409 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1414 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1417 /***************************************************************************
1418 Find a service by name. Otherwise works like get_service.
1419 ***************************************************************************/
1421 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1425 for (iService = iNumServices - 1; iService >= 0; iService--)
1426 if (VALID(iService) &&
1427 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1428 if (pserviceDest != NULL)
1429 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1436 /***************************************************************************
1437 Copy a service structure to another.
1438 If pcopymapDest is NULL then copy all fields
1439 ***************************************************************************/
1441 static void copy_service(service * pserviceDest, service * pserviceSource, int *pcopymapDest)
1444 BOOL bcopyall = (pcopymapDest == NULL);
1445 struct param_opt *data, *pdata, *paramo;
1448 for (i = 0; parm_table[i].label; i++)
1449 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1450 (bcopyall || pcopymapDest[i])) {
1451 void *def_ptr = parm_table[i].ptr;
1453 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1456 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1459 switch (parm_table[i].type) {
1461 *(int *)dest_ptr = *(int *)src_ptr;
1466 *(int *)dest_ptr = *(int *)src_ptr;
1470 string_set(dest_ptr,
1475 string_set(dest_ptr,
1477 strupper(*(char **)dest_ptr);
1480 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1481 *(const char ***)src_ptr);
1489 init_copymap(pserviceDest);
1490 if (pserviceSource->copymap)
1491 memcpy((void *)pserviceDest->copymap,
1492 (void *)pserviceSource->copymap,
1493 sizeof(int) * NUMPARAMETERS);
1496 data = pserviceSource->param_opt;
1499 pdata = pserviceDest->param_opt;
1500 /* Traverse destination */
1502 /* If we already have same option, override it */
1503 if (strcmp(pdata->key, data->key) == 0) {
1504 string_free(&pdata->value);
1505 pdata->value = strdup(data->value);
1509 pdata = pdata->next;
1512 paramo = malloc_p(struct param_opt);
1515 paramo->key = strdup(data->key);
1516 paramo->value = strdup(data->value);
1517 DLIST_ADD(pserviceDest->param_opt, paramo);
1523 /***************************************************************************
1524 Check a service for consistency. Return False if the service is in any way
1525 incomplete or faulty, else True.
1526 ***************************************************************************/
1528 static BOOL service_ok(int iService)
1533 if (ServicePtrs[iService]->szService[0] == '\0') {
1534 DEBUG(0, ("The following message indicates an internal error:\n"));
1535 DEBUG(0, ("No service name in service entry.\n"));
1539 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1540 /* I can't see why you'd want a non-printable printer service... */
1541 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1542 if (!ServicePtrs[iService]->bPrint_ok) {
1543 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1544 ServicePtrs[iService]->szService));
1545 ServicePtrs[iService]->bPrint_ok = True;
1546 update_server_announce_as_printserver();
1548 /* [printers] service must also be non-browsable. */
1549 if (ServicePtrs[iService]->bBrowseable)
1550 ServicePtrs[iService]->bBrowseable = False;
1553 /* If a service is flagged unavailable, log the fact at level 0. */
1554 if (!ServicePtrs[iService]->bAvailable)
1555 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1556 ServicePtrs[iService]->szService));
1561 static struct file_lists {
1562 struct file_lists *next;
1566 } *file_lists = NULL;
1568 /*******************************************************************
1569 Keep a linked list of all config files so we know when one has changed
1570 it's date and needs to be reloaded.
1571 ********************************************************************/
1573 static void add_to_file_list(const char *fname, const char *subfname)
1575 struct file_lists *f = file_lists;
1578 if (f->name && !strcmp(f->name, fname))
1584 f = malloc_p(struct file_lists);
1587 f->next = file_lists;
1588 f->name = strdup(fname);
1593 f->subfname = strdup(subfname);
1599 f->modtime = file_modtime(subfname);
1601 time_t t = file_modtime(subfname);
1607 /*******************************************************************
1608 Check if a config file has changed date.
1609 ********************************************************************/
1611 BOOL lp_file_list_changed(void)
1613 struct file_lists *f = file_lists;
1614 DEBUG(6, ("lp_file_list_changed()\n"));
1620 pstrcpy(n2, f->name);
1621 standard_sub_basic(n2,sizeof(n2));
1623 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1624 f->name, n2, ctime(&f->modtime)));
1626 mod_time = file_modtime(n2);
1628 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1630 ("file %s modified: %s\n", n2,
1632 f->modtime = mod_time;
1633 SAFE_FREE(f->subfname);
1634 f->subfname = strdup(n2);
1642 /***************************************************************************
1643 Handle the include operation.
1644 ***************************************************************************/
1646 static BOOL handle_include(const char *pszParmValue, char **ptr)
1649 pstrcpy(fname, pszParmValue);
1651 standard_sub_basic(fname,sizeof(fname));
1653 add_to_file_list(pszParmValue, fname);
1655 string_set(ptr, fname);
1657 if (file_exist(fname))
1658 return (pm_process(fname, do_section, do_parameter, NULL));
1660 DEBUG(2, ("Can't find include file %s\n", fname));
1665 /***************************************************************************
1666 Handle the interpretation of the copy parameter.
1667 ***************************************************************************/
1669 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1673 service serviceTemp;
1675 string_set(ptr, pszParmValue);
1677 init_service(&serviceTemp);
1681 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1683 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1684 if (iTemp == iServiceIndex) {
1685 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1687 copy_service(ServicePtrs[iServiceIndex],
1689 ServicePtrs[iServiceIndex]->copymap);
1693 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1697 free_service(&serviceTemp);
1701 /***************************************************************************
1702 Initialise a copymap.
1703 ***************************************************************************/
1705 static void init_copymap(service * pservice)
1708 SAFE_FREE(pservice->copymap);
1709 pservice->copymap = malloc_array_p(int, NUMPARAMETERS);
1710 if (!pservice->copymap)
1712 ("Couldn't allocate copymap!! (size %d)\n",
1713 (int)NUMPARAMETERS));
1715 for (i = 0; i < NUMPARAMETERS; i++)
1716 pservice->copymap[i] = True;
1719 #if 0 /* not used anywhere */
1720 /***************************************************************************
1721 Return the local pointer to a parameter given the service number and the
1722 pointer into the default structure.
1723 ***************************************************************************/
1725 void *lp_local_ptr(int snum, void *ptr)
1727 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1731 /***************************************************************************
1732 Process a parametric option
1733 ***************************************************************************/
1734 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1736 struct param_opt *paramo, *data;
1739 while (isspace((unsigned char)*pszParmName)) {
1743 name = strdup(pszParmName);
1744 if (!name) return False;
1749 data = Globals.param_opt;
1751 data = ServicePtrs[snum]->param_opt;
1754 /* Traverse destination */
1755 for (paramo=data; paramo; paramo=paramo->next) {
1756 /* If we already have the option set, override it unless
1757 it was a command line option and the new one isn't */
1758 if (strcmp(paramo->key, name) == 0) {
1759 if ((paramo->flags & FLAG_CMDLINE) &&
1760 !(flags & FLAG_CMDLINE)) {
1764 free(paramo->value);
1765 paramo->value = strdup(pszParmValue);
1766 paramo->flags = flags;
1772 paramo = malloc_p(struct param_opt);
1775 paramo->key = strdup(name);
1776 paramo->value = strdup(pszParmValue);
1777 paramo->flags = flags;
1779 DLIST_ADD(Globals.param_opt, paramo);
1781 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1789 /***************************************************************************
1790 Process a parameter for a particular service number. If snum < 0
1791 then assume we are in the globals.
1792 ***************************************************************************/
1793 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1796 void *parm_ptr = NULL; /* where we are going to store the result */
1797 void *def_ptr = NULL;
1799 parmnum = map_parameter(pszParmName);
1802 if (strchr(pszParmName, ':')) {
1803 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1805 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1809 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1810 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1814 /* if the flag has been set on the command line, then don't allow override,
1815 but don't report an error */
1816 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1820 def_ptr = parm_table[parmnum].ptr;
1822 /* we might point at a service, the default service or a global */
1826 if (parm_table[parmnum].class == P_GLOBAL) {
1828 ("Global parameter %s found in service section!\n",
1833 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1838 if (!ServicePtrs[snum]->copymap)
1839 init_copymap(ServicePtrs[snum]);
1841 /* this handles the aliases - set the copymap for other entries with
1842 the same data pointer */
1843 for (i = 0; parm_table[i].label; i++)
1844 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1845 ServicePtrs[snum]->copymap[i] = False;
1848 /* if it is a special case then go ahead */
1849 if (parm_table[parmnum].special) {
1850 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1854 /* now switch on the type of variable it is */
1855 switch (parm_table[parmnum].type)
1858 if (!set_boolean(pszParmValue, parm_ptr)) {
1859 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1865 *(int *)parm_ptr = atoi(pszParmValue);
1871 if (conv_str_size(pszParmValue, &val)) {
1872 if (val <= INT_MAX) {
1873 *(int *)parm_ptr = (int)val;
1878 DEBUG(0,("lp_do_parameter(%s): value is not "
1879 "a valid size specifier!\n", pszParmValue));
1884 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1885 pszParmValue, NULL);
1889 string_set(parm_ptr, pszParmValue);
1893 string_set(parm_ptr, pszParmValue);
1894 strupper(*(char **)parm_ptr);
1898 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1901 parm_table[parmnum].enum_list[i].name)) {
1903 parm_table[parmnum].
1908 if (!parm_table[parmnum].enum_list[i].name) {
1909 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1910 pszParmValue, pszParmName));
1918 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1919 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1920 /* we have to also unset FLAG_DEFAULT on aliases */
1921 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1922 parm_table[i].flags &= ~FLAG_DEFAULT;
1924 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1925 parm_table[i].flags &= ~FLAG_DEFAULT;
1932 /***************************************************************************
1933 Process a parameter.
1934 ***************************************************************************/
1936 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1938 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1939 pszParmName, pszParmValue));
1943 variable argument do parameter
1945 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1947 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1954 s = talloc_vasprintf(NULL, fmt, ap);
1956 ret = do_parameter(pszParmName, s, NULL);
1963 set a parameter from the commandline - this is called from command line parameter
1964 parsing code. It sets the parameter then marks the parameter as unable to be modified
1965 by smb.conf processing
1967 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1969 int parmnum = map_parameter(pszParmName);
1972 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1975 if (parmnum < 0 && strchr(pszParmName, ':')) {
1976 /* set a parametric option */
1977 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1981 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1985 /* reset the CMDLINE flag in case this has been called before */
1986 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1988 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1992 parm_table[parmnum].flags |= FLAG_CMDLINE;
1994 /* we have to also set FLAG_CMDLINE on aliases */
1995 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1996 parm_table[i].flags |= FLAG_CMDLINE;
1998 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1999 parm_table[i].flags |= FLAG_CMDLINE;
2006 set a option from the commandline in 'a=b' format. Use to support --option
2008 BOOL lp_set_option(const char *option)
2026 ret = lp_set_cmdline(s, p+1);
2032 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2034 /***************************************************************************
2035 Print a parameter of the specified type.
2036 ***************************************************************************/
2038 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2044 for (i = 0; p->enum_list[i].name; i++) {
2045 if (*(int *)ptr == p->enum_list[i].value) {
2047 p->enum_list[i].name);
2054 fprintf(f, "%s", BOOLSTR((BOOL)*(int *)ptr));
2059 fprintf(f, "%d", *(int *)ptr);
2063 if ((char ***)ptr && *(char ***)ptr) {
2064 char **list = *(char ***)ptr;
2066 for (; *list; list++)
2067 fprintf(f, "%s%s", *list,
2068 ((*(list+1))?", ":""));
2074 if (*(char **)ptr) {
2075 fprintf(f, "%s", *(char **)ptr);
2083 /***************************************************************************
2084 Check if two parameters are equal.
2085 ***************************************************************************/
2087 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2091 return (*((int *)ptr1) == *((int *)ptr2));
2096 return (*((int *)ptr1) == *((int *)ptr2));
2099 return str_list_equal((const char **)(*(char ***)ptr1),
2100 (const char **)(*(char ***)ptr2));
2105 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2110 return (p1 == p2 || strequal(p1, p2));
2118 /***************************************************************************
2119 Process a new section (service). At this stage all sections are services.
2120 Later we'll have special sections that permit server parameters to be set.
2121 Returns True on success, False on failure.
2122 ***************************************************************************/
2124 static BOOL do_section(const char *pszSectionName, void *userdata)
2127 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2128 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2131 /* if we've just struck a global section, note the fact. */
2132 bInGlobalSection = isglobal;
2134 /* check for multiple global sections */
2135 if (bInGlobalSection) {
2136 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2140 /* if we have a current service, tidy it up before moving on */
2143 if (iServiceIndex >= 0)
2144 bRetval = service_ok(iServiceIndex);
2146 /* if all is still well, move to the next record in the services array */
2148 /* We put this here to avoid an odd message order if messages are */
2149 /* issued by the post-processing of a previous section. */
2150 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2152 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2154 DEBUG(0, ("Failed to add a new service\n"));
2163 /***************************************************************************
2164 Determine if a partcular base parameter is currentl set to the default value.
2165 ***************************************************************************/
2167 static BOOL is_default(int i)
2169 if (!defaults_saved)
2171 switch (parm_table[i].type) {
2173 return str_list_equal((const char **)parm_table[i].def.lvalue,
2174 (const char **)(*(char ***)parm_table[i].ptr));
2177 return strequal(parm_table[i].def.svalue,
2178 *(char **)parm_table[i].ptr);
2180 return parm_table[i].def.bvalue ==
2181 *(int *)parm_table[i].ptr;
2185 return parm_table[i].def.ivalue ==
2186 *(int *)parm_table[i].ptr;
2193 /***************************************************************************
2194 Display the contents of the global structure.
2195 ***************************************************************************/
2197 static void dump_globals(FILE *f, BOOL show_defaults)
2200 struct param_opt *data;
2202 fprintf(f, "# Global parameters\n[global]\n");
2204 for (i = 0; parm_table[i].label; i++)
2205 if (parm_table[i].class == P_GLOBAL &&
2206 parm_table[i].ptr &&
2207 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2208 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2210 fprintf(f, "\t%s = ", parm_table[i].label);
2211 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2214 if (Globals.param_opt != NULL) {
2215 data = Globals.param_opt;
2217 fprintf(f, "\t%s = %s\n", data->key, data->value);
2224 /***************************************************************************
2225 Display the contents of a single services record.
2226 ***************************************************************************/
2228 static void dump_a_service(service * pService, FILE * f)
2231 struct param_opt *data;
2233 if (pService != &sDefault)
2234 fprintf(f, "\n[%s]\n", pService->szService);
2236 for (i = 0; parm_table[i].label; i++)
2237 if (parm_table[i].class == P_LOCAL &&
2238 parm_table[i].ptr &&
2239 (*parm_table[i].label != '-') &&
2240 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2241 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2243 if (pService == &sDefault) {
2244 if (defaults_saved && is_default(i))
2247 if (equal_parameter(parm_table[i].type,
2248 ((char *)pService) +
2250 ((char *)&sDefault) +
2255 fprintf(f, "\t%s = ", parm_table[i].label);
2256 print_parameter(&parm_table[i],
2257 ((char *)pService) + pdiff, f);
2260 if (pService->param_opt != NULL) {
2261 data = pService->param_opt;
2263 fprintf(f, "\t%s = %s\n", data->key, data->value);
2269 BOOL lp_dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
2271 service * pService = ServicePtrs[snum];
2272 struct parm_struct *parm;
2275 parm = lp_parm_struct(parm_name);
2283 ptr = ((char *)pService) +
2284 PTR_DIFF(parm->ptr, &sDefault);
2286 print_parameter(parm,
2292 /***************************************************************************
2293 Return info about the next service in a service. snum==-1 gives the globals.
2294 Return NULL when out of parameters.
2295 ***************************************************************************/
2297 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2300 /* do the globals */
2301 for (; parm_table[*i].label; (*i)++) {
2302 if (parm_table[*i].class == P_SEPARATOR)
2303 return &parm_table[(*i)++];
2305 if (!parm_table[*i].ptr
2306 || (*parm_table[*i].label == '-'))
2310 && (parm_table[*i].ptr ==
2311 parm_table[(*i) - 1].ptr))
2314 return &parm_table[(*i)++];
2317 service *pService = ServicePtrs[snum];
2319 for (; parm_table[*i].label; (*i)++) {
2320 if (parm_table[*i].class == P_SEPARATOR)
2321 return &parm_table[(*i)++];
2323 if (parm_table[*i].class == P_LOCAL &&
2324 parm_table[*i].ptr &&
2325 (*parm_table[*i].label != '-') &&
2327 (parm_table[*i].ptr !=
2328 parm_table[(*i) - 1].ptr)))
2331 PTR_DIFF(parm_table[*i].ptr,
2334 if (allparameters ||
2335 !equal_parameter(parm_table[*i].type,
2336 ((char *)pService) +
2338 ((char *)&sDefault) +
2341 return &parm_table[(*i)++];
2351 /***************************************************************************
2352 Return TRUE if the passed service number is within range.
2353 ***************************************************************************/
2355 BOOL lp_snum_ok(int iService)
2357 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2360 /***************************************************************************
2361 Auto-load some home services.
2362 ***************************************************************************/
2364 static void lp_add_auto_services(const char *str)
2369 /***************************************************************************
2370 Announce ourselves as a print server.
2371 ***************************************************************************/
2373 void update_server_announce_as_printserver(void)
2375 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2378 /***************************************************************************
2379 Have we loaded a services file yet?
2380 ***************************************************************************/
2382 BOOL lp_loaded(void)
2387 /***************************************************************************
2388 Unload unused services.
2389 ***************************************************************************/
2391 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2394 for (i = 0; i < iNumServices; i++) {
2398 if (!snumused || !snumused(smb, i)) {
2399 ServicePtrs[i]->valid = False;
2400 free_service(ServicePtrs[i]);
2405 /***************************************************************************
2407 ***************************************************************************/
2409 void lp_killservice(int iServiceIn)
2411 if (VALID(iServiceIn)) {
2412 ServicePtrs[iServiceIn]->valid = False;
2413 free_service(ServicePtrs[iServiceIn]);
2417 /***************************************************************************
2418 Load the services array from the services file. Return True on success,
2420 ***************************************************************************/
2426 struct param_opt *data;
2430 bInGlobalSection = True;
2432 if (Globals.param_opt != NULL) {
2433 struct param_opt *next;
2434 for (data=Globals.param_opt; data; data=next) {
2436 if (data->flags & FLAG_CMDLINE) continue;
2439 DLIST_REMOVE(Globals.param_opt, data);
2446 pstrcpy(n2, lp_configfile());
2447 standard_sub_basic(n2,sizeof(n2));
2448 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2450 add_to_file_list(lp_configfile(), n2);
2452 /* We get sections first, so have to start 'behind' to make up */
2454 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2456 /* finish up the last section */
2457 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2459 if (iServiceIndex >= 0)
2460 bRetval = service_ok(iServiceIndex);
2462 lp_add_auto_services(lp_auto_services());
2464 lp_add_hidden("IPC$", "IPC");
2465 lp_add_hidden("ADMIN$", "DISK");
2467 set_default_server_announce_type();
2471 if (!Globals.szWINSservers && Globals.bWINSsupport) {
2472 lp_do_parameter(-1, "wins server", "127.0.0.1");
2480 /***************************************************************************
2481 Reset the max number of services.
2482 ***************************************************************************/
2484 void lp_resetnumservices(void)
2489 /***************************************************************************
2490 Return the max number of services.
2491 ***************************************************************************/
2493 int lp_numservices(void)
2495 return (iNumServices);
2498 /***************************************************************************
2499 Display the contents of the services array in human-readable form.
2500 ***************************************************************************/
2502 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2507 defaults_saved = False;
2509 dump_globals(f, show_defaults);
2511 dump_a_service(&sDefault, f);
2513 for (iService = 0; iService < maxtoprint; iService++)
2514 lp_dump_one(f, show_defaults, iService);
2517 /***************************************************************************
2518 Display the contents of one service in human-readable form.
2519 ***************************************************************************/
2521 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2524 if (ServicePtrs[snum]->szService[0] == '\0')
2526 dump_a_service(ServicePtrs[snum], f);
2530 /***************************************************************************
2531 Return the number of the service with the given name, or -1 if it doesn't
2532 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2533 getservicebyname()! This works ONLY if all services have been loaded, and
2534 does not copy the found service.
2535 ***************************************************************************/
2537 int lp_servicenumber(const char *pszServiceName)
2540 fstring serviceName;
2543 for (iService = iNumServices - 1; iService >= 0; iService--) {
2544 if (VALID(iService) && ServicePtrs[iService]->szService) {
2546 * The substitution here is used to support %U is
2549 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2550 standard_sub_basic(serviceName,sizeof(serviceName));
2551 if (strequal(serviceName, pszServiceName))
2557 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2562 int lp_find_valid_service(const char *pszServiceName)
2566 iService = lp_servicenumber(pszServiceName);
2568 if (iService >= 0 && !lp_snum_ok(iService)) {
2569 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService, pszServiceName));
2573 if (iService == -1) {
2574 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName));
2580 /*******************************************************************
2581 A useful volume label function.
2582 ********************************************************************/
2583 const char *volume_label(int snum)
2585 const char *ret = lp_volume(snum);
2587 return lp_servicename(snum);
2592 /*******************************************************************
2593 Set the server type we will announce as via nmbd.
2594 ********************************************************************/
2596 static void set_default_server_announce_type(void)
2598 default_server_announce = 0;
2599 default_server_announce |= SV_TYPE_WORKSTATION;
2600 default_server_announce |= SV_TYPE_SERVER;
2601 default_server_announce |= SV_TYPE_SERVER_UNIX;
2603 switch (lp_announce_as()) {
2604 case ANNOUNCE_AS_NT_SERVER:
2605 default_server_announce |= SV_TYPE_SERVER_NT;
2606 /* fall through... */
2607 case ANNOUNCE_AS_NT_WORKSTATION:
2608 default_server_announce |= SV_TYPE_NT;
2610 case ANNOUNCE_AS_WIN95:
2611 default_server_announce |= SV_TYPE_WIN95_PLUS;
2613 case ANNOUNCE_AS_WFW:
2614 default_server_announce |= SV_TYPE_WFW;
2620 switch (lp_server_role()) {
2621 case ROLE_DOMAIN_MEMBER:
2622 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2624 case ROLE_DOMAIN_PDC:
2625 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2627 case ROLE_DOMAIN_BDC:
2628 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2630 case ROLE_STANDALONE:
2634 if (lp_time_server())
2635 default_server_announce |= SV_TYPE_TIME_SOURCE;
2637 if (lp_host_msdfs())
2638 default_server_announce |= SV_TYPE_DFS_SERVER;
2640 /* TODO: only announce us as print server when we are a print server */
2641 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2644 /***********************************************************
2645 If we are PDC then prefer us as DMB
2646 ************************************************************/
2648 BOOL lp_domain_master(void)
2650 return (lp_server_role() == ROLE_DOMAIN_PDC);
2653 /***********************************************************
2654 If we are PDC then prefer us as DMB
2655 ************************************************************/
2657 BOOL lp_domain_logons(void)
2659 return (lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC);
2662 /***********************************************************
2663 If we are DMB then prefer us as LMB
2664 ************************************************************/
2666 BOOL lp_preferred_master(void)
2668 return (lp_local_master() && lp_domain_master());
2671 /*******************************************************************
2673 ********************************************************************/
2675 void lp_remove_service(int snum)
2677 ServicePtrs[snum]->valid = False;
2680 /*******************************************************************
2682 ********************************************************************/
2684 void lp_copy_service(int snum, const char *new_name)
2686 const char *oldname = lp_servicename(snum);
2687 do_section(new_name, NULL);
2689 snum = lp_servicenumber(new_name);
2691 lp_do_parameter(snum, "copy", oldname);
2696 /*******************************************************************
2697 Get the default server type we will announce as via nmbd.
2698 ********************************************************************/
2699 int lp_default_server_announce(void)
2701 return default_server_announce;
2704 const char *lp_printername(int snum)
2706 const char *ret = _lp_printername(snum);
2707 if (ret == NULL || (ret != NULL && *ret == '\0'))
2708 ret = lp_const_servicename(snum);
2714 /*******************************************************************
2715 Return the max print jobs per queue.
2716 ********************************************************************/
2718 int lp_maxprintjobs(int snum)
2720 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2721 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2722 maxjobs = PRINT_MAX_JOBID - 1;