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;
112 char *szWINS_CONFIG_URL;
116 char **szPasswordServers;
117 char *szSocketOptions;
119 char **szWINSservers;
121 char *szSocketAddress;
122 char *szAnnounceVersion; /* This is initialised in init_globals */
125 char **szNetbiosAliases;
126 char *szNetbiosScope;
127 char *szDomainOtherSIDs;
128 char **szNameResolveOrder;
129 char **dcerpc_ep_servers;
130 char **server_services;
131 char *ntptr_providor;
132 char *szWinbindSeparator;
133 char *szWinbinddSocketDirectory;
134 int bWinbindSealedPipes;
135 char *swat_directory;
150 int paranoid_server_security;
153 int announce_as; /* This is initialised in init_globals */
160 char *socket_options;
165 int bPreferredMaster;
166 int bEncryptPasswords;
168 int bObeyPamRestrictions;
173 int bBindInterfacesOnly;
175 int bNTStatusSupport;
181 int bClientPlaintextAuth;
182 int bClientLanManAuth;
183 int bClientNTLMv2Auth;
184 int client_use_spnego_principal;
190 struct param_opt *param_opt;
194 static global Globals;
197 * This structure describes a single service.
212 char **ntvfs_handler;
228 struct param_opt *param_opt;
230 char dummy[3]; /* for alignment */
235 /* This is a default service used to prime a services structure */
236 static service sDefault = {
238 NULL, /* szService */
241 NULL, /* szInclude */
242 NULL, /* szPrintername */
243 NULL, /* szHostsallow */
244 NULL, /* szHostsdeny */
248 NULL, /* ntvfs_handler */
249 1000, /* iMaxPrintJobs */
250 0, /* iMaxConnections */
252 True, /* bAvailable */
253 True, /* bBrowseable */
254 True, /* bRead_only */
255 False, /* bPrint_ok */
256 False, /* bMap_system */
257 False, /* bMap_hidden */
258 True, /* bMap_archive */
259 True, /* bStrictLocking */
261 False, /* bMSDfsRoot */
262 False, /* bStrictSync */
263 False, /* bCIFileSystem */
264 NULL, /* Parametric options */
269 /* local variables */
270 static service **ServicePtrs = NULL;
271 static int iNumServices = 0;
272 static int iServiceIndex = 0;
273 static BOOL bInGlobalSection = True;
274 static int default_server_announce;
276 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
278 /* prototypes for the special type handlers */
279 static BOOL handle_include(const char *pszParmValue, char **ptr);
280 static BOOL handle_copy(const char *pszParmValue, char **ptr);
282 static void set_default_server_announce_type(void);
284 static const struct enum_list enum_protocol[] = {
285 {PROTOCOL_SMB2, "SMB2"},
286 {PROTOCOL_NT1, "NT1"},
287 {PROTOCOL_LANMAN2, "LANMAN2"},
288 {PROTOCOL_LANMAN1, "LANMAN1"},
289 {PROTOCOL_CORE, "CORE"},
290 {PROTOCOL_COREPLUS, "COREPLUS"},
291 {PROTOCOL_COREPLUS, "CORE+"},
295 static const struct enum_list enum_security[] = {
296 {SEC_SHARE, "SHARE"},
301 /* Types of machine we can announce as. */
302 #define ANNOUNCE_AS_NT_SERVER 1
303 #define ANNOUNCE_AS_WIN95 2
304 #define ANNOUNCE_AS_WFW 3
305 #define ANNOUNCE_AS_NT_WORKSTATION 4
307 static const struct enum_list enum_announce_as[] = {
308 {ANNOUNCE_AS_NT_SERVER, "NT"},
309 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
310 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
311 {ANNOUNCE_AS_WIN95, "win95"},
312 {ANNOUNCE_AS_WFW, "WfW"},
316 static const struct enum_list enum_bool_auto[] = {
327 /* Client-side offline caching policy types */
328 #define CSC_POLICY_MANUAL 0
329 #define CSC_POLICY_DOCUMENTS 1
330 #define CSC_POLICY_PROGRAMS 2
331 #define CSC_POLICY_DISABLE 3
333 static const struct enum_list enum_csc_policy[] = {
334 {CSC_POLICY_MANUAL, "manual"},
335 {CSC_POLICY_DOCUMENTS, "documents"},
336 {CSC_POLICY_PROGRAMS, "programs"},
337 {CSC_POLICY_DISABLE, "disable"},
341 /* SMB signing types. */
342 static const struct enum_list enum_smb_signing_vals[] = {
343 {SMB_SIGNING_OFF, "No"},
344 {SMB_SIGNING_OFF, "False"},
345 {SMB_SIGNING_OFF, "0"},
346 {SMB_SIGNING_OFF, "Off"},
347 {SMB_SIGNING_OFF, "disabled"},
348 {SMB_SIGNING_SUPPORTED, "Yes"},
349 {SMB_SIGNING_SUPPORTED, "True"},
350 {SMB_SIGNING_SUPPORTED, "1"},
351 {SMB_SIGNING_SUPPORTED, "On"},
352 {SMB_SIGNING_SUPPORTED, "enabled"},
353 {SMB_SIGNING_REQUIRED, "required"},
354 {SMB_SIGNING_REQUIRED, "mandatory"},
355 {SMB_SIGNING_REQUIRED, "force"},
356 {SMB_SIGNING_REQUIRED, "forced"},
357 {SMB_SIGNING_REQUIRED, "enforced"},
358 {SMB_SIGNING_AUTO, "auto"},
362 static const struct enum_list enum_server_role[] = {
363 {ROLE_STANDALONE, "standalone"},
364 {ROLE_DOMAIN_MEMBER, "member server"},
365 {ROLE_DOMAIN_BDC, "bdc"},
366 {ROLE_DOMAIN_PDC, "pdc"},
371 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
373 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
374 * is implied in current control logic. This may change at some later time. A
375 * flag value of 0 means - show as development option only.
377 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
378 * screen in SWAT. This is used to exclude parameters as well as to squash all
379 * parameters that have been duplicated by pseudonyms.
381 static struct parm_struct parm_table[] = {
382 {"Base Options", P_SEP, P_SEPARATOR},
384 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
386 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
387 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
388 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
389 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
390 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
391 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
392 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
393 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
394 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
396 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
397 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
398 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
399 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
402 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
403 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
404 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
406 {"Security Options", P_SEP, P_SEPARATOR},
408 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
409 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
410 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
411 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
412 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
414 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
426 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
428 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
430 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
431 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
433 {"Logging Options", P_SEP, P_SEPARATOR},
435 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
436 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
437 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
439 {"Protocol Options", P_SEP, P_SEPARATOR},
441 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
455 {"server max protocol", P_ENUM, P_GLOBAL, &Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
456 {"server min protocol", P_ENUM, P_GLOBAL, &Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
457 {"client max protocol", P_ENUM, P_GLOBAL, &Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
458 {"client min protocol", P_ENUM, P_GLOBAL, &Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
459 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
460 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
461 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
462 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
464 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
466 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
467 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
468 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"max xmit", P_BYTES, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
471 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
472 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
473 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
475 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
477 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
478 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
479 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
481 {"Tuning Options", P_SEP, P_SEPARATOR},
483 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
484 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
485 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
487 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
488 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
490 {"Printing Options", P_SEP, P_SEPARATOR},
492 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
493 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
494 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
496 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
497 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
499 {"Filename Handling", P_SEP, P_SEPARATOR},
501 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
502 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
503 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
505 {"Domain Options", P_SEP, P_SEPARATOR},
507 {"Logon Options", P_SEP, P_SEPARATOR},
510 {"Browse Options", P_SEP, P_SEPARATOR},
512 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
513 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
514 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
515 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
516 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
518 {"WINS Options", P_SEP, P_SEPARATOR},
520 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
521 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
522 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
523 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
525 {"Locking Options", P_SEP, P_SEPARATOR},
527 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
529 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
531 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
533 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
534 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
537 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"modules dir", P_STRING, P_GLOBAL, &Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
544 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
546 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
547 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
549 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
550 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
551 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
553 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
556 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
558 {"winbindd socket directory", P_STRING, P_GLOBAL, &Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
559 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
561 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
566 return the parameter table
568 struct parm_struct *lp_parm_table(void)
573 /***************************************************************************
574 Initialise the global parameter structure.
575 ***************************************************************************/
576 static void init_globals(void)
581 DEBUG(3, ("Initialising global parameters\n"));
583 for (i = 0; parm_table[i].label; i++) {
584 if ((parm_table[i].type == P_STRING ||
585 parm_table[i].type == P_USTRING) &&
587 !(parm_table[i].flags & FLAG_CMDLINE)) {
588 string_set(parm_table[i].ptr, "");
592 do_parameter("config file", dyn_CONFIGFILE, NULL);
594 do_parameter("server role", "standalone", NULL);
596 /* options that can be set on the command line must be initialised via
597 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
599 do_parameter("socket options", "TCP_NODELAY", NULL);
601 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
602 myname = get_myname();
603 do_parameter("netbios name", myname, NULL);
605 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
607 do_parameter("fstype", FSTYPE_STRING, NULL);
608 do_parameter("ntvfs handler", "unixuid default", NULL);
609 do_parameter("max connections", "-1", NULL);
611 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup", NULL);
612 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc winbind", NULL);
613 do_parameter("ntptr providor", "simple_ldb", NULL);
614 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
615 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
616 do_parameter("sam database", "sam.ldb", NULL);
617 do_parameter("spoolss database", "spoolss.ldb", NULL);
618 do_parameter("wins config database", "wins_config.ldb", NULL);
619 do_parameter("wins database", "wins.ldb", NULL);
620 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
622 /* This hive should be dynamically generated by Samba using
623 data from the sam, but for the moment leave it in a tdb to
624 keep regedt32 from popping up an annoying dialog. */
625 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
627 /* using UTF8 by default allows us to support all chars */
628 do_parameter("unix charset", "UTF8", NULL);
630 /* Use codepage 850 as a default for the dos character set */
631 do_parameter("dos charset", "CP850", NULL);
634 * Allow the default PASSWD_CHAT to be overridden in local.h.
636 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
638 do_parameter("pid directory", dyn_PIDDIR, NULL);
639 do_parameter("lock dir", dyn_LOCKDIR, NULL);
640 do_parameter("modules dir", dyn_MODULESDIR, NULL);
641 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
643 do_parameter("socket address", "0.0.0.0", NULL);
644 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
646 do_parameter_var("announce version", "%d.%d",
647 DEFAULT_MAJOR_VERSION,
648 DEFAULT_MINOR_VERSION);
650 do_parameter("password server", "*", NULL);
652 do_parameter("max mux", "50", NULL);
653 do_parameter("max xmit", "12288", NULL);
654 do_parameter("password level", "0", NULL);
655 do_parameter("LargeReadwrite", "True", NULL);
656 do_parameter("server min protocol", "CORE", NULL);
657 do_parameter("server max protocol", "NT1", NULL);
658 do_parameter("client min protocol", "CORE", NULL);
659 do_parameter("client max protocol", "NT1", NULL);
660 do_parameter("security", "USER", NULL);
661 do_parameter("paranoid server security", "True", NULL);
662 do_parameter("EncryptPasswords", "True", NULL);
663 do_parameter("ReadRaw", "True", NULL);
664 do_parameter("WriteRaw", "True", NULL);
665 do_parameter("NullPasswords", "False", NULL);
666 do_parameter("ObeyPamRestrictions", "False", NULL);
667 do_parameter("announce as", "NT SERVER", NULL);
669 do_parameter("TimeServer", "False", NULL);
670 do_parameter("BindInterfacesOnly", "False", NULL);
671 do_parameter("Unicode", "True", NULL);
672 do_parameter("ClientLanManAuth", "True", NULL);
673 do_parameter("LanmanAuth", "True", NULL);
674 do_parameter("NTLMAuth", "True", NULL);
675 do_parameter("client use spnego principal", "False", NULL);
677 do_parameter("UnixExtensions", "False", NULL);
679 do_parameter("PreferredMaster", "Auto", NULL);
680 do_parameter("LocalMaster", "True", NULL);
682 do_parameter("wins support", "False", NULL);
683 do_parameter("dns proxy", "True", NULL);
685 do_parameter("winbind separator", "\\", NULL);
686 do_parameter("winbind sealed pipes", "True", NULL);
687 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR, NULL);
689 do_parameter("client signing", "Yes", NULL);
690 do_parameter("server signing", "auto", NULL);
692 do_parameter("use spnego", "True", NULL);
694 do_parameter("smb ports", SMB_PORTS, NULL);
695 do_parameter("nbt port", "137", NULL);
696 do_parameter("dgram port", "138", NULL);
697 do_parameter("cldap port", "389", NULL);
698 do_parameter("krb5 port", "88", NULL);
699 do_parameter("kpasswd port", "464", NULL);
700 do_parameter("web port", "901", NULL);
701 do_parameter("swat directory", dyn_SWATDIR, NULL);
703 do_parameter("nt status support", "True", NULL);
705 do_parameter("max wins ttl", "518400", NULL); /* 6 days */
706 do_parameter("min wins ttl", "10", NULL);
708 do_parameter("tls enabled", "True", NULL);
709 do_parameter("tls keyfile", "tls/key.pem", NULL);
710 do_parameter("tls certfile", "tls/cert.pem", NULL);
711 do_parameter("tls cafile", "tls/ca.pem", NULL);
712 do_parameter_var("js include", "%s", dyn_JSDIR);
713 do_parameter_var("setup directory", "%s", dyn_SETUPDIR);
715 for (i = 0; parm_table[i].label; i++) {
716 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
717 parm_table[i].flags |= FLAG_DEFAULT;
722 static TALLOC_CTX *lp_talloc;
724 /******************************************************************* a
725 Free up temporary memory - called from the main loop.
726 ********************************************************************/
728 void lp_talloc_free(void)
732 talloc_free(lp_talloc);
736 /*******************************************************************
737 Convenience routine to grab string parameters into temporary memory
738 and run standard_sub_basic on them. The buffers can be written to by
739 callers without affecting the source string.
740 ********************************************************************/
742 static const char *lp_string(const char *s)
744 #if 0 /* until REWRITE done to make thread-safe */
745 size_t len = s ? strlen(s) : 0;
749 /* The follow debug is useful for tracking down memory problems
750 especially if you have an inner loop that is calling a lp_*()
751 function that returns a string. Perhaps this debug should be
752 present all the time? */
755 DEBUG(10, ("lp_string(%s)\n", s));
758 #if 0 /* until REWRITE done to make thread-safe */
760 lp_talloc = talloc_init("lp_talloc");
762 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
770 strlcpy(ret, s, len);
772 if (trim_string(ret, "\"", "\"")) {
773 if (strchr(ret,'"') != NULL)
774 strlcpy(ret, s, len);
777 standard_sub_basic(ret,len+100);
784 In this section all the functions that are used to access the
785 parameters from the rest of the program are defined
788 #define FN_GLOBAL_STRING(fn_name,ptr) \
789 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
790 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
791 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
792 #define FN_GLOBAL_LIST(fn_name,ptr) \
793 const char **fn_name(void) {return(*(const char ***)(ptr));}
794 #define FN_GLOBAL_BOOL(fn_name,ptr) \
795 BOOL fn_name(void) {return((BOOL)*(int *)(ptr));}
796 #define FN_GLOBAL_CHAR(fn_name,ptr) \
797 char fn_name(void) {return(*(char *)(ptr));}
798 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
799 int fn_name(void) {return(*(int *)(ptr));}
801 #define FN_LOCAL_STRING(fn_name,val) \
802 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
803 #define FN_LOCAL_CONST_STRING(fn_name,val) \
804 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
805 #define FN_LOCAL_LIST(fn_name,val) \
806 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
807 #define FN_LOCAL_BOOL(fn_name,val) \
808 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
809 #define FN_LOCAL_CHAR(fn_name,val) \
810 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
811 #define FN_LOCAL_INTEGER(fn_name,val) \
812 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
814 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &Globals.server_role)
815 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
816 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
817 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
818 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
819 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
820 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &Globals.kpasswd_port)
821 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
822 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
823 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
824 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
825 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
826 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
827 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
828 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
829 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
830 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
831 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
832 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
833 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
834 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL)
835 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
836 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
837 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &Globals.szWinbinddSocketDirectory)
838 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
839 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
840 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
841 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
842 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &Globals.szModulesDir)
843 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
844 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
845 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
846 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
847 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
848 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
849 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
850 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
851 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
852 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
853 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
854 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
855 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
856 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
857 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
858 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
859 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
860 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
861 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
863 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
864 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
865 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &Globals.bWINSdnsProxy)
866 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
867 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
868 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
869 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
870 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
871 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
872 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
873 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
874 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
875 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
876 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
877 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
878 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
879 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
880 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
881 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
882 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
883 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
884 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
885 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
886 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
887 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
888 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
889 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
890 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
891 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
892 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
893 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &Globals.srv_maxprotocol)
894 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &Globals.srv_minprotocol)
895 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &Globals.cli_maxprotocol)
896 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &Globals.cli_minprotocol)
897 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
898 _PUBLIC_ FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
899 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
900 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
901 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
904 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
905 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
906 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
907 static FN_LOCAL_STRING(_lp_printername, szPrintername)
908 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
909 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
910 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
911 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
912 static FN_LOCAL_STRING(lp_volume, volume)
913 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
914 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
915 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
916 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
917 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
918 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
919 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
920 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
921 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
922 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
923 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
924 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
925 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
926 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
927 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
929 /* local prototypes */
931 static int map_parameter(const char *pszParmName);
932 static int getservicebyname(const char *pszServiceName,
933 service * pserviceDest);
934 static void copy_service(service * pserviceDest,
935 service * pserviceSource, int *pcopymapDest);
936 static BOOL service_ok(int iService);
937 static BOOL do_section(const char *pszSectionName, void *);
938 static void init_copymap(service * pservice);
940 /* This is a helper function for parametrical options support. */
941 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
942 /* Actual parametrical functions are quite simple */
943 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
946 struct param_opt *data;
948 if (lookup_service >= iNumServices) return NULL;
950 data = (lookup_service < 0) ?
951 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
953 asprintf(&vfskey, "%s:%s", type, option);
957 if (strcmp(data->key, vfskey) == 0) {
964 if (lookup_service >= 0) {
965 /* Try to fetch the same option but from globals */
966 /* but only if we are not already working with Globals */
967 data = Globals.param_opt;
969 if (strcmp(data->key, vfskey) == 0) {
983 /*******************************************************************
984 convenience routine to return int parameters.
985 ********************************************************************/
986 static int lp_int(const char *s)
990 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
994 return strtol(s, NULL, 0);
997 /*******************************************************************
998 convenience routine to return unsigned long parameters.
999 ********************************************************************/
1000 static int lp_ulong(const char *s)
1004 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1008 return strtoul(s, NULL, 0);
1011 /*******************************************************************
1012 convenience routine to return boolean parameters.
1013 ********************************************************************/
1014 static BOOL lp_bool(const char *s)
1019 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1023 if (!set_boolean(s, &ret)) {
1024 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1032 /* Return parametric option from a given service. Type is a part of option before ':' */
1033 /* Parametric option has following syntax: 'Type: option = value' */
1034 /* Returned value is allocated in 'lp_talloc' context */
1036 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1038 const char *value = lp_get_parametric(lookup_service, type, option);
1041 return lp_string(value);
1046 /* Return parametric option from a given service. Type is a part of option before ':' */
1047 /* Parametric option has following syntax: 'Type: option = value' */
1048 /* Returned value is allocated in 'lp_talloc' context */
1050 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1051 const char *separator)
1053 const char *value = lp_get_parametric(lookup_service, type, option);
1056 return str_list_make(talloc_autofree_context(), value, separator);
1061 /* Return parametric option from a given service. Type is a part of option before ':' */
1062 /* Parametric option has following syntax: 'Type: option = value' */
1064 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1066 const char *value = lp_get_parametric(lookup_service, type, option);
1069 return lp_int(value);
1074 /* Return parametric option from a given service. Type is a part of
1075 * option before ':'.
1076 * Parametric option has following syntax: 'Type: option = value'.
1079 int lp_parm_bytes(int lookup_service, const char *type, const char *option, int default_v)
1083 const char *value = lp_get_parametric(lookup_service, type, option);
1085 if (value && conv_str_size(value, &bval)) {
1086 if (bval <= INT_MAX) {
1094 /* Return parametric option from a given service. Type is a part of option before ':' */
1095 /* Parametric option has following syntax: 'Type: option = value' */
1097 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1099 const char *value = lp_get_parametric(lookup_service, type, option);
1102 return lp_ulong(value);
1107 /* Return parametric option from a given service. Type is a part of option before ':' */
1108 /* Parametric option has following syntax: 'Type: option = value' */
1110 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1112 const char *value = lp_get_parametric(lookup_service, type, option);
1115 return lp_bool(value);
1121 /***************************************************************************
1122 Initialise a service to the defaults.
1123 ***************************************************************************/
1125 static void init_service(service * pservice)
1127 memset((char *)pservice, '\0', sizeof(service));
1128 copy_service(pservice, &sDefault, NULL);
1131 /***************************************************************************
1132 Free the dynamically allocated parts of a service struct.
1133 ***************************************************************************/
1135 static void free_service(service *pservice)
1138 struct param_opt *data, *pdata;
1142 if (pservice->szService)
1143 DEBUG(5, ("free_service: Freeing service %s\n",
1144 pservice->szService));
1146 string_free(&pservice->szService);
1147 SAFE_FREE(pservice->copymap);
1149 for (i = 0; parm_table[i].label; i++) {
1150 if ((parm_table[i].type == P_STRING ||
1151 parm_table[i].type == P_USTRING) &&
1152 parm_table[i].class == P_LOCAL) {
1153 string_free((char **)
1154 (((char *)pservice) +
1155 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1156 } else if (parm_table[i].type == P_LIST &&
1157 parm_table[i].class == P_LOCAL) {
1158 char ***listp = (char ***)(((char *)pservice) +
1159 PTR_DIFF(parm_table[i].ptr, &sDefault));
1160 talloc_free(*listp);
1165 DEBUG(5,("Freeing parametrics:\n"));
1166 data = pservice->param_opt;
1168 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1169 string_free(&data->key);
1170 string_free(&data->value);
1176 ZERO_STRUCTP(pservice);
1179 /***************************************************************************
1180 Add a new service to the services array initialising it with the given
1182 ***************************************************************************/
1184 static int add_a_service(const service *pservice, const char *name)
1188 int num_to_alloc = iNumServices + 1;
1189 struct param_opt *data, *pdata;
1191 tservice = *pservice;
1193 /* it might already exist */
1195 i = getservicebyname(name, NULL);
1197 /* Clean all parametric options for service */
1198 /* They will be added during parsing again */
1199 data = ServicePtrs[i]->param_opt;
1201 string_free(&data->key);
1202 string_free(&data->value);
1207 ServicePtrs[i]->param_opt = NULL;
1212 /* find an invalid one */
1213 for (i = 0; i < iNumServices; i++)
1214 if (!ServicePtrs[i]->valid)
1217 /* if not, then create one */
1218 if (i == iNumServices) {
1221 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1224 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1229 ServicePtrs[iNumServices] = malloc_p(service);
1231 if (!ServicePtrs[iNumServices]) {
1232 DEBUG(0,("add_a_service: out of memory!\n"));
1238 free_service(ServicePtrs[i]);
1240 ServicePtrs[i]->valid = True;
1242 init_service(ServicePtrs[i]);
1243 copy_service(ServicePtrs[i], &tservice, NULL);
1245 string_set(&ServicePtrs[i]->szService, name);
1249 /***************************************************************************
1250 Add a new home service, with the specified home directory, defaults coming
1252 ***************************************************************************/
1254 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1255 const char *user, const char *pszHomedir)
1260 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1265 if (!(*(ServicePtrs[iDefaultService]->szPath))
1266 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1267 pstrcpy(newHomedir, pszHomedir);
1269 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1270 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1273 string_set(&ServicePtrs[i]->szPath, newHomedir);
1275 if (!(*(ServicePtrs[i]->comment))) {
1277 slprintf(comment, sizeof(comment) - 1,
1278 "Home directory of %s", user);
1279 string_set(&ServicePtrs[i]->comment, comment);
1281 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1282 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1284 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1290 /***************************************************************************
1291 Add a new service, based on an old one.
1292 ***************************************************************************/
1294 int lp_add_service(const char *pszService, int iDefaultService)
1296 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1299 /***************************************************************************
1300 Add the IPC service.
1301 ***************************************************************************/
1303 static BOOL lp_add_hidden(const char *name, const char *fstype)
1306 int i = add_a_service(&sDefault, name);
1311 slprintf(comment, sizeof(comment) - 1,
1312 "%s Service (%s)", fstype, Globals.szServerString);
1314 string_set(&ServicePtrs[i]->szPath, tmpdir());
1315 string_set(&ServicePtrs[i]->comment, comment);
1316 string_set(&ServicePtrs[i]->fstype, fstype);
1317 ServicePtrs[i]->iMaxConnections = -1;
1318 ServicePtrs[i]->bAvailable = True;
1319 ServicePtrs[i]->bRead_only = True;
1320 ServicePtrs[i]->bPrint_ok = False;
1321 ServicePtrs[i]->bBrowseable = False;
1323 if (strcasecmp(fstype, "IPC") == 0) {
1324 lp_do_parameter(i, "ntvfs handler", "default");
1327 DEBUG(3, ("adding hidden service %s\n", name));
1332 /***************************************************************************
1333 Add a new printer service, with defaults coming from service iFrom.
1334 ***************************************************************************/
1336 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1338 const char *comment = "From Printcap";
1339 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1344 /* note that we do NOT default the availability flag to True - */
1345 /* we take it from the default service passed. This allows all */
1346 /* dynamic printers to be disabled by disabling the [printers] */
1347 /* entry (if/when the 'available' keyword is implemented!). */
1349 /* the printer name is set to the service name. */
1350 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1351 string_set(&ServicePtrs[i]->comment, comment);
1352 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1353 /* Printers cannot be read_only. */
1354 ServicePtrs[i]->bRead_only = False;
1355 /* Printer services must be printable. */
1356 ServicePtrs[i]->bPrint_ok = True;
1358 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1360 update_server_announce_as_printserver();
1365 /***************************************************************************
1366 Map a parameter's string representation to something we can use.
1367 Returns False if the parameter string is not recognised, else TRUE.
1368 ***************************************************************************/
1370 static int map_parameter(const char *pszParmName)
1374 if (*pszParmName == '-')
1377 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1378 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1381 /* Warn only if it isn't parametric option */
1382 if (strchr(pszParmName, ':') == NULL)
1383 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1384 /* We do return 'fail' for parametric options as well because they are
1385 stored in different storage
1392 return the parameter structure for a parameter
1394 struct parm_struct *lp_parm_struct(const char *name)
1396 int parmnum = map_parameter(name);
1397 if (parmnum == -1) return NULL;
1398 return &parm_table[parmnum];
1402 return the parameter pointer for a parameter
1404 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1409 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1412 /***************************************************************************
1413 Find a service by name. Otherwise works like get_service.
1414 ***************************************************************************/
1416 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1420 for (iService = iNumServices - 1; iService >= 0; iService--)
1421 if (VALID(iService) &&
1422 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1423 if (pserviceDest != NULL)
1424 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1431 /***************************************************************************
1432 Copy a service structure to another.
1433 If pcopymapDest is NULL then copy all fields
1434 ***************************************************************************/
1436 static void copy_service(service * pserviceDest, service * pserviceSource, int *pcopymapDest)
1439 BOOL bcopyall = (pcopymapDest == NULL);
1440 struct param_opt *data, *pdata, *paramo;
1443 for (i = 0; parm_table[i].label; i++)
1444 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1445 (bcopyall || pcopymapDest[i])) {
1446 void *def_ptr = parm_table[i].ptr;
1448 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1451 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1454 switch (parm_table[i].type) {
1456 *(int *)dest_ptr = *(int *)src_ptr;
1461 *(int *)dest_ptr = *(int *)src_ptr;
1465 string_set(dest_ptr,
1470 string_set(dest_ptr,
1472 strupper(*(char **)dest_ptr);
1475 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1476 *(const char ***)src_ptr);
1484 init_copymap(pserviceDest);
1485 if (pserviceSource->copymap)
1486 memcpy((void *)pserviceDest->copymap,
1487 (void *)pserviceSource->copymap,
1488 sizeof(int) * NUMPARAMETERS);
1491 data = pserviceSource->param_opt;
1494 pdata = pserviceDest->param_opt;
1495 /* Traverse destination */
1497 /* If we already have same option, override it */
1498 if (strcmp(pdata->key, data->key) == 0) {
1499 string_free(&pdata->value);
1500 pdata->value = strdup(data->value);
1504 pdata = pdata->next;
1507 paramo = malloc_p(struct param_opt);
1510 paramo->key = strdup(data->key);
1511 paramo->value = strdup(data->value);
1512 DLIST_ADD(pserviceDest->param_opt, paramo);
1518 /***************************************************************************
1519 Check a service for consistency. Return False if the service is in any way
1520 incomplete or faulty, else True.
1521 ***************************************************************************/
1523 static BOOL service_ok(int iService)
1528 if (ServicePtrs[iService]->szService[0] == '\0') {
1529 DEBUG(0, ("The following message indicates an internal error:\n"));
1530 DEBUG(0, ("No service name in service entry.\n"));
1534 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1535 /* I can't see why you'd want a non-printable printer service... */
1536 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1537 if (!ServicePtrs[iService]->bPrint_ok) {
1538 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1539 ServicePtrs[iService]->szService));
1540 ServicePtrs[iService]->bPrint_ok = True;
1541 update_server_announce_as_printserver();
1543 /* [printers] service must also be non-browsable. */
1544 if (ServicePtrs[iService]->bBrowseable)
1545 ServicePtrs[iService]->bBrowseable = False;
1548 /* If a service is flagged unavailable, log the fact at level 0. */
1549 if (!ServicePtrs[iService]->bAvailable)
1550 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1551 ServicePtrs[iService]->szService));
1556 static struct file_lists {
1557 struct file_lists *next;
1561 } *file_lists = NULL;
1563 /*******************************************************************
1564 Keep a linked list of all config files so we know when one has changed
1565 it's date and needs to be reloaded.
1566 ********************************************************************/
1568 static void add_to_file_list(const char *fname, const char *subfname)
1570 struct file_lists *f = file_lists;
1573 if (f->name && !strcmp(f->name, fname))
1579 f = malloc_p(struct file_lists);
1582 f->next = file_lists;
1583 f->name = strdup(fname);
1588 f->subfname = strdup(subfname);
1594 f->modtime = file_modtime(subfname);
1596 time_t t = file_modtime(subfname);
1602 /*******************************************************************
1603 Check if a config file has changed date.
1604 ********************************************************************/
1606 BOOL lp_file_list_changed(void)
1608 struct file_lists *f = file_lists;
1609 DEBUG(6, ("lp_file_list_changed()\n"));
1615 pstrcpy(n2, f->name);
1616 standard_sub_basic(n2,sizeof(n2));
1618 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1619 f->name, n2, ctime(&f->modtime)));
1621 mod_time = file_modtime(n2);
1623 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1625 ("file %s modified: %s\n", n2,
1627 f->modtime = mod_time;
1628 SAFE_FREE(f->subfname);
1629 f->subfname = strdup(n2);
1637 /***************************************************************************
1638 Handle the include operation.
1639 ***************************************************************************/
1641 static BOOL handle_include(const char *pszParmValue, char **ptr)
1644 pstrcpy(fname, pszParmValue);
1646 standard_sub_basic(fname,sizeof(fname));
1648 add_to_file_list(pszParmValue, fname);
1650 string_set(ptr, fname);
1652 if (file_exist(fname))
1653 return (pm_process(fname, do_section, do_parameter, NULL));
1655 DEBUG(2, ("Can't find include file %s\n", fname));
1660 /***************************************************************************
1661 Handle the interpretation of the copy parameter.
1662 ***************************************************************************/
1664 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1668 service serviceTemp;
1670 string_set(ptr, pszParmValue);
1672 init_service(&serviceTemp);
1676 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1678 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1679 if (iTemp == iServiceIndex) {
1680 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1682 copy_service(ServicePtrs[iServiceIndex],
1684 ServicePtrs[iServiceIndex]->copymap);
1688 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1692 free_service(&serviceTemp);
1696 /***************************************************************************
1697 Initialise a copymap.
1698 ***************************************************************************/
1700 static void init_copymap(service * pservice)
1703 SAFE_FREE(pservice->copymap);
1704 pservice->copymap = malloc_array_p(int, NUMPARAMETERS);
1705 if (!pservice->copymap)
1707 ("Couldn't allocate copymap!! (size %d)\n",
1708 (int)NUMPARAMETERS));
1710 for (i = 0; i < NUMPARAMETERS; i++)
1711 pservice->copymap[i] = True;
1714 /***************************************************************************
1715 Return the local pointer to a parameter given the service number and the
1716 pointer into the default structure.
1717 ***************************************************************************/
1719 void *lp_local_ptr(int snum, void *ptr)
1721 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1725 /***************************************************************************
1726 Process a parametric option
1727 ***************************************************************************/
1728 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1730 struct param_opt *paramo, *data;
1733 while (isspace((unsigned char)*pszParmName)) {
1737 name = strdup(pszParmName);
1738 if (!name) return False;
1743 data = Globals.param_opt;
1745 data = ServicePtrs[snum]->param_opt;
1748 /* Traverse destination */
1749 for (paramo=data; paramo; paramo=paramo->next) {
1750 /* If we already have the option set, override it unless
1751 it was a command line option and the new one isn't */
1752 if (strcmp(paramo->key, name) == 0) {
1753 if ((paramo->flags & FLAG_CMDLINE) &&
1754 !(flags & FLAG_CMDLINE)) {
1758 free(paramo->value);
1759 paramo->value = strdup(pszParmValue);
1760 paramo->flags = flags;
1766 paramo = malloc_p(struct param_opt);
1769 paramo->key = strdup(name);
1770 paramo->value = strdup(pszParmValue);
1771 paramo->flags = flags;
1773 DLIST_ADD(Globals.param_opt, paramo);
1775 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1783 /***************************************************************************
1784 Process a parameter for a particular service number. If snum < 0
1785 then assume we are in the globals.
1786 ***************************************************************************/
1787 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1790 void *parm_ptr = NULL; /* where we are going to store the result */
1791 void *def_ptr = NULL;
1793 parmnum = map_parameter(pszParmName);
1796 if (strchr(pszParmName, ':')) {
1797 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1799 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1803 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1804 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1808 /* if the flag has been set on the command line, then don't allow override,
1809 but don't report an error */
1810 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1814 def_ptr = parm_table[parmnum].ptr;
1816 /* we might point at a service, the default service or a global */
1820 if (parm_table[parmnum].class == P_GLOBAL) {
1822 ("Global parameter %s found in service section!\n",
1827 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1832 if (!ServicePtrs[snum]->copymap)
1833 init_copymap(ServicePtrs[snum]);
1835 /* this handles the aliases - set the copymap for other entries with
1836 the same data pointer */
1837 for (i = 0; parm_table[i].label; i++)
1838 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1839 ServicePtrs[snum]->copymap[i] = False;
1842 /* if it is a special case then go ahead */
1843 if (parm_table[parmnum].special) {
1844 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1848 /* now switch on the type of variable it is */
1849 switch (parm_table[parmnum].type)
1852 if (!set_boolean(pszParmValue, parm_ptr)) {
1853 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1859 *(int *)parm_ptr = atoi(pszParmValue);
1865 if (conv_str_size(pszParmValue, &val)) {
1866 if (val <= INT_MAX) {
1867 *(int *)parm_ptr = (int)val;
1872 DEBUG(0,("lp_do_parameter(%s): value is not "
1873 "a valid size specifier!\n", pszParmValue));
1878 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1879 pszParmValue, NULL);
1883 string_set(parm_ptr, pszParmValue);
1887 string_set(parm_ptr, pszParmValue);
1888 strupper(*(char **)parm_ptr);
1892 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1895 parm_table[parmnum].enum_list[i].name)) {
1897 parm_table[parmnum].
1902 if (!parm_table[parmnum].enum_list[i].name) {
1903 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1904 pszParmValue, pszParmName));
1912 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1913 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1914 /* we have to also unset FLAG_DEFAULT on aliases */
1915 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1916 parm_table[i].flags &= ~FLAG_DEFAULT;
1918 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1919 parm_table[i].flags &= ~FLAG_DEFAULT;
1926 /***************************************************************************
1927 Process a parameter.
1928 ***************************************************************************/
1930 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1932 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1933 pszParmName, pszParmValue));
1937 variable argument do parameter
1939 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1941 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1948 s = talloc_vasprintf(NULL, fmt, ap);
1950 ret = do_parameter(pszParmName, s, NULL);
1957 set a parameter from the commandline - this is called from command line parameter
1958 parsing code. It sets the parameter then marks the parameter as unable to be modified
1959 by smb.conf processing
1961 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1963 int parmnum = map_parameter(pszParmName);
1966 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1969 if (parmnum < 0 && strchr(pszParmName, ':')) {
1970 /* set a parametric option */
1971 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1975 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1979 /* reset the CMDLINE flag in case this has been called before */
1980 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1982 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1986 parm_table[parmnum].flags |= FLAG_CMDLINE;
1988 /* we have to also set FLAG_CMDLINE on aliases */
1989 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1990 parm_table[i].flags |= FLAG_CMDLINE;
1992 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1993 parm_table[i].flags |= FLAG_CMDLINE;
2000 set a option from the commandline in 'a=b' format. Use to support --option
2002 BOOL lp_set_option(const char *option)
2020 ret = lp_set_cmdline(s, p+1);
2026 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2028 /***************************************************************************
2029 Print a parameter of the specified type.
2030 ***************************************************************************/
2032 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2038 for (i = 0; p->enum_list[i].name; i++) {
2039 if (*(int *)ptr == p->enum_list[i].value) {
2041 p->enum_list[i].name);
2048 fprintf(f, "%s", BOOLSTR((BOOL)*(int *)ptr));
2053 fprintf(f, "%d", *(int *)ptr);
2057 if ((char ***)ptr && *(char ***)ptr) {
2058 char **list = *(char ***)ptr;
2060 for (; *list; list++)
2061 fprintf(f, "%s%s", *list,
2062 ((*(list+1))?", ":""));
2068 if (*(char **)ptr) {
2069 fprintf(f, "%s", *(char **)ptr);
2077 /***************************************************************************
2078 Check if two parameters are equal.
2079 ***************************************************************************/
2081 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2085 return (*((int *)ptr1) == *((int *)ptr2));
2090 return (*((int *)ptr1) == *((int *)ptr2));
2093 return str_list_equal((const char **)(*(char ***)ptr1),
2094 (const char **)(*(char ***)ptr2));
2099 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2104 return (p1 == p2 || strequal(p1, p2));
2112 /***************************************************************************
2113 Process a new section (service). At this stage all sections are services.
2114 Later we'll have special sections that permit server parameters to be set.
2115 Returns True on success, False on failure.
2116 ***************************************************************************/
2118 static BOOL do_section(const char *pszSectionName, void *userdata)
2121 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2122 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2125 /* if we've just struck a global section, note the fact. */
2126 bInGlobalSection = isglobal;
2128 /* check for multiple global sections */
2129 if (bInGlobalSection) {
2130 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2134 /* if we have a current service, tidy it up before moving on */
2137 if (iServiceIndex >= 0)
2138 bRetval = service_ok(iServiceIndex);
2140 /* if all is still well, move to the next record in the services array */
2142 /* We put this here to avoid an odd message order if messages are */
2143 /* issued by the post-processing of a previous section. */
2144 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2146 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2148 DEBUG(0, ("Failed to add a new service\n"));
2157 /***************************************************************************
2158 Determine if a partcular base parameter is currentl set to the default value.
2159 ***************************************************************************/
2161 static BOOL is_default(int i)
2163 if (!defaults_saved)
2165 switch (parm_table[i].type) {
2167 return str_list_equal((const char **)parm_table[i].def.lvalue,
2168 (const char **)(*(char ***)parm_table[i].ptr));
2171 return strequal(parm_table[i].def.svalue,
2172 *(char **)parm_table[i].ptr);
2174 return parm_table[i].def.bvalue ==
2175 *(int *)parm_table[i].ptr;
2179 return parm_table[i].def.ivalue ==
2180 *(int *)parm_table[i].ptr;
2187 /***************************************************************************
2188 Display the contents of the global structure.
2189 ***************************************************************************/
2191 static void dump_globals(FILE *f, BOOL show_defaults)
2194 struct param_opt *data;
2196 fprintf(f, "# Global parameters\n[global]\n");
2198 for (i = 0; parm_table[i].label; i++)
2199 if (parm_table[i].class == P_GLOBAL &&
2200 parm_table[i].ptr &&
2201 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2202 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2204 fprintf(f, "\t%s = ", parm_table[i].label);
2205 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2208 if (Globals.param_opt != NULL) {
2209 data = Globals.param_opt;
2211 fprintf(f, "\t%s = %s\n", data->key, data->value);
2218 /***************************************************************************
2219 Display the contents of a single services record.
2220 ***************************************************************************/
2222 static void dump_a_service(service * pService, FILE * f)
2225 struct param_opt *data;
2227 if (pService != &sDefault)
2228 fprintf(f, "\n[%s]\n", pService->szService);
2230 for (i = 0; parm_table[i].label; i++)
2231 if (parm_table[i].class == P_LOCAL &&
2232 parm_table[i].ptr &&
2233 (*parm_table[i].label != '-') &&
2234 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2235 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2237 if (pService == &sDefault) {
2238 if (defaults_saved && is_default(i))
2241 if (equal_parameter(parm_table[i].type,
2242 ((char *)pService) +
2244 ((char *)&sDefault) +
2249 fprintf(f, "\t%s = ", parm_table[i].label);
2250 print_parameter(&parm_table[i],
2251 ((char *)pService) + pdiff, f);
2254 if (pService->param_opt != NULL) {
2255 data = pService->param_opt;
2257 fprintf(f, "\t%s = %s\n", data->key, data->value);
2263 BOOL lp_dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
2265 service * pService = ServicePtrs[snum];
2266 struct parm_struct *parm;
2269 parm = lp_parm_struct(parm_name);
2277 ptr = ((char *)pService) +
2278 PTR_DIFF(parm->ptr, &sDefault);
2280 print_parameter(parm,
2286 /***************************************************************************
2287 Return info about the next service in a service. snum==-1 gives the globals.
2288 Return NULL when out of parameters.
2289 ***************************************************************************/
2291 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2294 /* do the globals */
2295 for (; parm_table[*i].label; (*i)++) {
2296 if (parm_table[*i].class == P_SEPARATOR)
2297 return &parm_table[(*i)++];
2299 if (!parm_table[*i].ptr
2300 || (*parm_table[*i].label == '-'))
2304 && (parm_table[*i].ptr ==
2305 parm_table[(*i) - 1].ptr))
2308 return &parm_table[(*i)++];
2311 service *pService = ServicePtrs[snum];
2313 for (; parm_table[*i].label; (*i)++) {
2314 if (parm_table[*i].class == P_SEPARATOR)
2315 return &parm_table[(*i)++];
2317 if (parm_table[*i].class == P_LOCAL &&
2318 parm_table[*i].ptr &&
2319 (*parm_table[*i].label != '-') &&
2321 (parm_table[*i].ptr !=
2322 parm_table[(*i) - 1].ptr)))
2325 PTR_DIFF(parm_table[*i].ptr,
2328 if (allparameters ||
2329 !equal_parameter(parm_table[*i].type,
2330 ((char *)pService) +
2332 ((char *)&sDefault) +
2335 return &parm_table[(*i)++];
2345 /***************************************************************************
2346 Return TRUE if the passed service number is within range.
2347 ***************************************************************************/
2349 BOOL lp_snum_ok(int iService)
2351 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2354 /***************************************************************************
2355 Auto-load some home services.
2356 ***************************************************************************/
2358 static void lp_add_auto_services(const char *str)
2363 /***************************************************************************
2364 Announce ourselves as a print server.
2365 ***************************************************************************/
2367 void update_server_announce_as_printserver(void)
2369 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2372 /***************************************************************************
2373 Have we loaded a services file yet?
2374 ***************************************************************************/
2376 BOOL lp_loaded(void)
2381 /***************************************************************************
2382 Unload unused services.
2383 ***************************************************************************/
2385 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2388 for (i = 0; i < iNumServices; i++) {
2392 if (!snumused || !snumused(smb, i)) {
2393 ServicePtrs[i]->valid = False;
2394 free_service(ServicePtrs[i]);
2399 /***************************************************************************
2401 ***************************************************************************/
2403 void lp_killservice(int iServiceIn)
2405 if (VALID(iServiceIn)) {
2406 ServicePtrs[iServiceIn]->valid = False;
2407 free_service(ServicePtrs[iServiceIn]);
2411 /***************************************************************************
2412 Load the services array from the services file. Return True on success,
2414 ***************************************************************************/
2420 struct param_opt *data;
2424 bInGlobalSection = True;
2426 if (Globals.param_opt != NULL) {
2427 struct param_opt *next;
2428 for (data=Globals.param_opt; data; data=next) {
2430 if (data->flags & FLAG_CMDLINE) continue;
2433 DLIST_REMOVE(Globals.param_opt, data);
2440 pstrcpy(n2, lp_configfile());
2441 standard_sub_basic(n2,sizeof(n2));
2442 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2444 add_to_file_list(lp_configfile(), n2);
2446 /* We get sections first, so have to start 'behind' to make up */
2448 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2450 /* finish up the last section */
2451 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2453 if (iServiceIndex >= 0)
2454 bRetval = service_ok(iServiceIndex);
2456 lp_add_auto_services(lp_auto_services());
2458 lp_add_hidden("IPC$", "IPC");
2459 lp_add_hidden("ADMIN$", "DISK");
2461 set_default_server_announce_type();
2465 if (!Globals.szWINSservers && Globals.bWINSsupport) {
2466 lp_do_parameter(-1, "wins server", "127.0.0.1");
2474 /***************************************************************************
2475 Reset the max number of services.
2476 ***************************************************************************/
2478 void lp_resetnumservices(void)
2483 /***************************************************************************
2484 Return the max number of services.
2485 ***************************************************************************/
2487 int lp_numservices(void)
2489 return (iNumServices);
2492 /***************************************************************************
2493 Display the contents of the services array in human-readable form.
2494 ***************************************************************************/
2496 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2501 defaults_saved = False;
2503 dump_globals(f, show_defaults);
2505 dump_a_service(&sDefault, f);
2507 for (iService = 0; iService < maxtoprint; iService++)
2508 lp_dump_one(f, show_defaults, iService);
2511 /***************************************************************************
2512 Display the contents of one service in human-readable form.
2513 ***************************************************************************/
2515 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2518 if (ServicePtrs[snum]->szService[0] == '\0')
2520 dump_a_service(ServicePtrs[snum], f);
2524 /***************************************************************************
2525 Return the number of the service with the given name, or -1 if it doesn't
2526 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2527 getservicebyname()! This works ONLY if all services have been loaded, and
2528 does not copy the found service.
2529 ***************************************************************************/
2531 int lp_servicenumber(const char *pszServiceName)
2534 fstring serviceName;
2537 for (iService = iNumServices - 1; iService >= 0; iService--) {
2538 if (VALID(iService) && ServicePtrs[iService]->szService) {
2540 * The substitution here is used to support %U is
2543 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2544 standard_sub_basic(serviceName,sizeof(serviceName));
2545 if (strequal(serviceName, pszServiceName))
2551 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2556 int lp_find_valid_service(const char *pszServiceName)
2560 iService = lp_servicenumber(pszServiceName);
2562 if (iService >= 0 && !lp_snum_ok(iService)) {
2563 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService, pszServiceName));
2567 if (iService == -1) {
2568 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName));
2574 /*******************************************************************
2575 A useful volume label function.
2576 ********************************************************************/
2577 const char *volume_label(int snum)
2579 const char *ret = lp_volume(snum);
2581 return lp_servicename(snum);
2586 /*******************************************************************
2587 Set the server type we will announce as via nmbd.
2588 ********************************************************************/
2590 static void set_default_server_announce_type(void)
2592 default_server_announce = 0;
2593 default_server_announce |= SV_TYPE_WORKSTATION;
2594 default_server_announce |= SV_TYPE_SERVER;
2595 default_server_announce |= SV_TYPE_SERVER_UNIX;
2597 switch (lp_announce_as()) {
2598 case ANNOUNCE_AS_NT_SERVER:
2599 default_server_announce |= SV_TYPE_SERVER_NT;
2600 /* fall through... */
2601 case ANNOUNCE_AS_NT_WORKSTATION:
2602 default_server_announce |= SV_TYPE_NT;
2604 case ANNOUNCE_AS_WIN95:
2605 default_server_announce |= SV_TYPE_WIN95_PLUS;
2607 case ANNOUNCE_AS_WFW:
2608 default_server_announce |= SV_TYPE_WFW;
2614 switch (lp_server_role()) {
2615 case ROLE_DOMAIN_MEMBER:
2616 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
2618 case ROLE_DOMAIN_PDC:
2619 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
2621 case ROLE_DOMAIN_BDC:
2622 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
2624 case ROLE_STANDALONE:
2628 if (lp_time_server())
2629 default_server_announce |= SV_TYPE_TIME_SOURCE;
2631 if (lp_host_msdfs())
2632 default_server_announce |= SV_TYPE_DFS_SERVER;
2634 /* TODO: only announce us as print server when we are a print server */
2635 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2638 /***********************************************************
2639 If we are PDC then prefer us as DMB
2640 ************************************************************/
2642 BOOL lp_domain_master(void)
2644 return (lp_server_role() == ROLE_DOMAIN_PDC);
2647 /***********************************************************
2648 If we are PDC then prefer us as DMB
2649 ************************************************************/
2651 BOOL lp_domain_logons(void)
2653 return (lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC);
2656 /***********************************************************
2657 If we are DMB then prefer us as LMB
2658 ************************************************************/
2660 BOOL lp_preferred_master(void)
2662 return (lp_local_master() && lp_domain_master());
2665 /*******************************************************************
2667 ********************************************************************/
2669 void lp_remove_service(int snum)
2671 ServicePtrs[snum]->valid = False;
2674 /*******************************************************************
2676 ********************************************************************/
2678 void lp_copy_service(int snum, const char *new_name)
2680 const char *oldname = lp_servicename(snum);
2681 do_section(new_name, NULL);
2683 snum = lp_servicenumber(new_name);
2685 lp_do_parameter(snum, "copy", oldname);
2690 /*******************************************************************
2691 Get the default server type we will announce as via nmbd.
2692 ********************************************************************/
2693 int lp_default_server_announce(void)
2695 return default_server_announce;
2698 const char *lp_printername(int snum)
2700 const char *ret = _lp_printername(snum);
2701 if (ret == NULL || (ret != NULL && *ret == '\0'))
2702 ret = lp_const_servicename(snum);
2708 /*******************************************************************
2709 Return the max print jobs per queue.
2710 ********************************************************************/
2712 int lp_maxprintjobs(int snum)
2714 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2715 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2716 maxjobs = PRINT_MAX_JOBID - 1;