2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
59 #include "system/time.h"
60 #include "system/locale.h"
61 #include "system/network.h" /* needed for TCP_NODELAY */
62 #include "smb_server/smb_server.h"
63 #include "libcli/raw/signing.h"
64 #include "lib/util/dlinklist.h"
65 #include "param/loadparm.h"
67 static BOOL bLoaded = False;
69 #define standard_sub_basic(str,len)
71 /* some helpful bits */
72 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
73 #define VALID(i) ServicePtrs[i]->valid
75 static BOOL do_parameter(const char *, const char *, void *);
76 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
78 static BOOL defaults_saved = False;
82 struct param_opt *prev, *next;
89 * This structure describes global (ie., server-wide) parameters.
99 char *display_charset;
104 char *szServerString;
105 char *szAutoServices;
108 char *szShareBackend;
111 char *szWINS_CONFIG_URL;
115 char *jsonrpcServicesDir;
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;
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;
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 const struct enum_list enum_protocol[] = {
283 {PROTOCOL_SMB2, "SMB2"},
284 {PROTOCOL_NT1, "NT1"},
285 {PROTOCOL_LANMAN2, "LANMAN2"},
286 {PROTOCOL_LANMAN1, "LANMAN1"},
287 {PROTOCOL_CORE, "CORE"},
288 {PROTOCOL_COREPLUS, "COREPLUS"},
289 {PROTOCOL_COREPLUS, "CORE+"},
293 static const struct enum_list enum_security[] = {
294 {SEC_SHARE, "SHARE"},
299 static const struct enum_list enum_announce_as[] = {
300 {ANNOUNCE_AS_NT_SERVER, "NT"},
301 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
302 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
303 {ANNOUNCE_AS_WIN95, "win95"},
304 {ANNOUNCE_AS_WFW, "WfW"},
308 static const struct enum_list enum_bool_auto[] = {
319 /* Client-side offline caching policy types */
320 #define CSC_POLICY_MANUAL 0
321 #define CSC_POLICY_DOCUMENTS 1
322 #define CSC_POLICY_PROGRAMS 2
323 #define CSC_POLICY_DISABLE 3
325 static const struct enum_list enum_csc_policy[] = {
326 {CSC_POLICY_MANUAL, "manual"},
327 {CSC_POLICY_DOCUMENTS, "documents"},
328 {CSC_POLICY_PROGRAMS, "programs"},
329 {CSC_POLICY_DISABLE, "disable"},
333 /* SMB signing types. */
334 static const struct enum_list enum_smb_signing_vals[] = {
335 {SMB_SIGNING_OFF, "No"},
336 {SMB_SIGNING_OFF, "False"},
337 {SMB_SIGNING_OFF, "0"},
338 {SMB_SIGNING_OFF, "Off"},
339 {SMB_SIGNING_OFF, "disabled"},
340 {SMB_SIGNING_SUPPORTED, "Yes"},
341 {SMB_SIGNING_SUPPORTED, "True"},
342 {SMB_SIGNING_SUPPORTED, "1"},
343 {SMB_SIGNING_SUPPORTED, "On"},
344 {SMB_SIGNING_SUPPORTED, "enabled"},
345 {SMB_SIGNING_REQUIRED, "required"},
346 {SMB_SIGNING_REQUIRED, "mandatory"},
347 {SMB_SIGNING_REQUIRED, "force"},
348 {SMB_SIGNING_REQUIRED, "forced"},
349 {SMB_SIGNING_REQUIRED, "enforced"},
350 {SMB_SIGNING_AUTO, "auto"},
354 static const struct enum_list enum_server_role[] = {
355 {ROLE_STANDALONE, "standalone"},
356 {ROLE_DOMAIN_MEMBER, "member server"},
357 {ROLE_DOMAIN_CONTROLLER, "domain controller"},
362 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
364 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
365 * is implied in current control logic. This may change at some later time. A
366 * flag value of 0 means - show as development option only.
368 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
369 * screen in SWAT. This is used to exclude parameters as well as to squash all
370 * parameters that have been duplicated by pseudonyms.
372 static struct parm_struct parm_table[] = {
373 {"Base Options", P_SEP, P_SEPARATOR},
375 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
377 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
378 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
379 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
380 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
381 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
382 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
383 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
384 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
385 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
386 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
387 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
388 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
389 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
390 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
391 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
392 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
393 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
394 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
395 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
397 {"Security Options", P_SEP, P_SEPARATOR},
399 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
401 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
402 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
403 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
404 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
405 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
406 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
407 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
408 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
409 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
410 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
412 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
421 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
422 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
424 {"Logging Options", P_SEP, P_SEPARATOR},
426 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
428 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
430 {"Protocol Options", P_SEP, P_SEPARATOR},
432 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
433 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
434 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
435 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
436 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
437 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
438 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
439 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
441 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
442 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
444 {"tls dh params file", P_STRING, P_GLOBAL, &Globals.tls_dhpfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
445 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
447 {"server max protocol", P_ENUM, P_GLOBAL, &Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
448 {"server min protocol", P_ENUM, P_GLOBAL, &Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
449 {"client max protocol", P_ENUM, P_GLOBAL, &Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
450 {"client min protocol", P_ENUM, P_GLOBAL, &Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
451 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
452 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
453 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
454 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
459 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
460 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
461 {"max xmit", P_BYTES, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
463 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
464 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
465 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
466 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
467 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
468 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
469 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
470 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
471 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
473 {"Tuning Options", P_SEP, P_SEPARATOR},
475 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
476 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
477 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
479 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
480 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
482 {"Printing Options", P_SEP, P_SEPARATOR},
484 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
485 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
486 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
488 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
489 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
491 {"Filename Handling", P_SEP, P_SEPARATOR},
493 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
494 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
495 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
497 {"Domain Options", P_SEP, P_SEPARATOR},
499 {"Logon Options", P_SEP, P_SEPARATOR},
502 {"Browse Options", P_SEP, P_SEPARATOR},
504 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
505 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
506 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
507 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
508 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
510 {"WINS Options", P_SEP, P_SEPARATOR},
512 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
513 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
514 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
515 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
517 {"Locking Options", P_SEP, P_SEPARATOR},
519 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
521 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
523 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
525 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
526 {"share backend", P_STRING, P_GLOBAL, &Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
527 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
528 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
529 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
530 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
531 {"modules dir", P_STRING, P_GLOBAL, &Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
532 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
533 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"jsonrpc services directory", P_STRING, P_GLOBAL, &Globals.jsonrpcServicesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
538 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
540 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
541 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
543 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
544 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
545 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
547 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
550 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
552 {"winbindd socket directory", P_STRING, P_GLOBAL, &Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
553 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
555 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
560 return the parameter table
562 struct parm_struct *lp_parm_table(void)
567 /***************************************************************************
568 Initialise the global parameter structure.
569 ***************************************************************************/
570 static void init_globals(void)
575 DEBUG(3, ("Initialising global parameters\n"));
577 for (i = 0; parm_table[i].label; i++) {
578 if ((parm_table[i].type == P_STRING ||
579 parm_table[i].type == P_USTRING) &&
581 !(parm_table[i].flags & FLAG_CMDLINE)) {
582 string_set(parm_table[i].ptr, "");
586 do_parameter("config file", dyn_CONFIGFILE, NULL);
588 do_parameter("share backend", "classic", NULL);
590 do_parameter("server role", "standalone", NULL);
592 /* options that can be set on the command line must be initialised via
593 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
595 do_parameter("socket options", "TCP_NODELAY", NULL);
597 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
598 myname = get_myname();
599 do_parameter("netbios name", myname, NULL);
601 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
603 do_parameter("fstype", FSTYPE_STRING, NULL);
604 do_parameter("ntvfs handler", "unixuid default", NULL);
605 do_parameter("max connections", "-1", NULL);
607 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo", NULL);
608 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc winbind", NULL);
609 do_parameter("ntptr providor", "simple_ldb", NULL);
610 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL);
611 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
612 do_parameter("sam database", "sam.ldb", NULL);
613 do_parameter("spoolss database", "spoolss.ldb", NULL);
614 do_parameter("wins config database", "wins_config.ldb", NULL);
615 do_parameter("wins database", "wins.ldb", NULL);
616 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
618 /* This hive should be dynamically generated by Samba using
619 data from the sam, but for the moment leave it in a tdb to
620 keep regedt32 from popping up an annoying dialog. */
621 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
623 /* using UTF8 by default allows us to support all chars */
624 do_parameter("unix charset", "UTF8", NULL);
626 /* Use codepage 850 as a default for the dos character set */
627 do_parameter("dos charset", "CP850", NULL);
630 * Allow the default PASSWD_CHAT to be overridden in local.h.
632 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
634 do_parameter("pid directory", dyn_PIDDIR, NULL);
635 do_parameter("lock dir", dyn_LOCKDIR, NULL);
636 do_parameter("modules dir", dyn_MODULESDIR, NULL);
637 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
639 do_parameter("socket address", "0.0.0.0", NULL);
640 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
642 do_parameter_var("announce version", "%d.%d",
643 DEFAULT_MAJOR_VERSION,
644 DEFAULT_MINOR_VERSION);
646 do_parameter("password server", "*", NULL);
648 do_parameter("max mux", "50", NULL);
649 do_parameter("max xmit", "12288", NULL);
650 do_parameter("password level", "0", NULL);
651 do_parameter("LargeReadwrite", "True", NULL);
652 do_parameter("server min protocol", "CORE", NULL);
653 do_parameter("server max protocol", "NT1", NULL);
654 do_parameter("client min protocol", "CORE", NULL);
655 do_parameter("client max protocol", "NT1", NULL);
656 do_parameter("security", "USER", NULL);
657 do_parameter("paranoid server security", "True", NULL);
658 do_parameter("EncryptPasswords", "True", NULL);
659 do_parameter("ReadRaw", "True", NULL);
660 do_parameter("WriteRaw", "True", NULL);
661 do_parameter("NullPasswords", "False", NULL);
662 do_parameter("ObeyPamRestrictions", "False", NULL);
663 do_parameter("announce as", "NT SERVER", NULL);
665 do_parameter("TimeServer", "False", NULL);
666 do_parameter("BindInterfacesOnly", "False", NULL);
667 do_parameter("Unicode", "True", NULL);
668 do_parameter("ClientLanManAuth", "True", NULL);
669 do_parameter("LanmanAuth", "True", NULL);
670 do_parameter("NTLMAuth", "True", NULL);
671 do_parameter("client use spnego principal", "False", NULL);
673 do_parameter("UnixExtensions", "False", NULL);
675 do_parameter("PreferredMaster", "Auto", NULL);
676 do_parameter("LocalMaster", "True", NULL);
678 do_parameter("wins support", "False", NULL);
679 do_parameter("dns proxy", "True", NULL);
681 do_parameter("winbind separator", "\\", NULL);
682 do_parameter("winbind sealed pipes", "True", NULL);
683 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR, NULL);
685 do_parameter("client signing", "Yes", NULL);
686 do_parameter("server signing", "auto", NULL);
688 do_parameter("use spnego", "True", NULL);
690 do_parameter("smb ports", "445 139", NULL);
691 do_parameter("nbt port", "137", NULL);
692 do_parameter("dgram port", "138", NULL);
693 do_parameter("cldap port", "389", NULL);
694 do_parameter("krb5 port", "88", NULL);
695 do_parameter("kpasswd port", "464", NULL);
696 do_parameter("web port", "901", NULL);
697 do_parameter("swat directory", dyn_SWATDIR, NULL);
698 do_parameter("jsonrpc services directory", dyn_SERVICESDIR, NULL);
700 do_parameter("nt status support", "True", NULL);
702 do_parameter("max wins ttl", "518400", NULL); /* 6 days */
703 do_parameter("min wins ttl", "10", NULL);
705 do_parameter("tls enabled", "True", NULL);
706 do_parameter("tls keyfile", "tls/key.pem", NULL);
707 do_parameter("tls certfile", "tls/cert.pem", NULL);
708 do_parameter("tls cafile", "tls/ca.pem", NULL);
709 do_parameter_var("js include", "%s", dyn_JSDIR);
710 do_parameter_var("setup directory", "%s", dyn_SETUPDIR);
712 for (i = 0; parm_table[i].label; i++) {
713 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
714 parm_table[i].flags |= FLAG_DEFAULT;
719 static TALLOC_CTX *lp_talloc;
721 /******************************************************************* a
722 Free up temporary memory - called from the main loop.
723 ********************************************************************/
725 void lp_talloc_free(void)
729 talloc_free(lp_talloc);
733 /*******************************************************************
734 Convenience routine to grab string parameters into temporary memory
735 and run standard_sub_basic on them. The buffers can be written to by
736 callers without affecting the source string.
737 ********************************************************************/
739 static const char *lp_string(const char *s)
741 #if 0 /* until REWRITE done to make thread-safe */
742 size_t len = s ? strlen(s) : 0;
746 /* The follow debug is useful for tracking down memory problems
747 especially if you have an inner loop that is calling a lp_*()
748 function that returns a string. Perhaps this debug should be
749 present all the time? */
752 DEBUG(10, ("lp_string(%s)\n", s));
755 #if 0 /* until REWRITE done to make thread-safe */
757 lp_talloc = talloc_init("lp_talloc");
759 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
767 strlcpy(ret, s, len);
769 if (trim_string(ret, "\"", "\"")) {
770 if (strchr(ret,'"') != NULL)
771 strlcpy(ret, s, len);
774 standard_sub_basic(ret,len+100);
781 In this section all the functions that are used to access the
782 parameters from the rest of the program are defined
785 #define FN_GLOBAL_STRING(fn_name,ptr) \
786 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
787 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
788 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
789 #define FN_GLOBAL_LIST(fn_name,ptr) \
790 const char **fn_name(void) {return(*(const char ***)(ptr));}
791 #define FN_GLOBAL_BOOL(fn_name,ptr) \
792 BOOL fn_name(void) {return((BOOL)*(int *)(ptr));}
794 #define FN_GLOBAL_CHAR(fn_name,ptr) \
795 char fn_name(void) {return(*(char *)(ptr));}
797 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
798 int fn_name(void) {return(*(int *)(ptr));}
800 #define FN_LOCAL_STRING(fn_name,val) \
801 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
802 #define FN_LOCAL_CONST_STRING(fn_name,val) \
803 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
804 #define FN_LOCAL_LIST(fn_name,val) \
805 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
806 #define FN_LOCAL_BOOL(fn_name,val) \
807 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);}
812 #define FN_LOCAL_INTEGER(fn_name,val) \
813 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
815 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &Globals.server_role)
816 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
817 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
818 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
819 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
820 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
821 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &Globals.kpasswd_port)
822 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
823 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
824 _PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
825 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
826 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
827 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
828 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
829 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
830 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_dhpfile, &Globals.tls_dhpfile)
831 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
832 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
833 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
834 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, &Globals.szShareBackend)
835 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
836 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
837 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL)
838 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
839 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
840 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &Globals.szWinbinddSocketDirectory)
841 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
842 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
843 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
844 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
845 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &Globals.szModulesDir)
846 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
847 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
848 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
849 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
850 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
851 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
852 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
853 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
854 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
855 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
856 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
857 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
858 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
859 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
860 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
861 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
862 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
863 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
864 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
866 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
867 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
868 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &Globals.bWINSdnsProxy)
869 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
870 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
871 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
872 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
873 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
874 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
875 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
876 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
877 _PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
878 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
879 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
880 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
881 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
882 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
883 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
884 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
885 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
886 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
887 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
888 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
889 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
890 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
891 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
892 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
893 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
894 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
895 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
896 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &Globals.srv_maxprotocol)
897 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &Globals.srv_minprotocol)
898 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &Globals.cli_maxprotocol)
899 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &Globals.cli_minprotocol)
900 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
901 _PUBLIC_ FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
902 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
903 _PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
904 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
905 _PUBLIC_ FN_GLOBAL_STRING(lp_jsonrpc_services_dir, &Globals.jsonrpcServicesDir)
908 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
909 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
910 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
911 static FN_LOCAL_STRING(_lp_printername, szPrintername)
912 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
913 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
914 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
915 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
916 static FN_LOCAL_STRING(lp_volume, volume)
917 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
918 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
919 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
920 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
921 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
922 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
923 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
924 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
925 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
926 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
927 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
928 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
929 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
930 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
931 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
933 /* local prototypes */
935 static int map_parameter(const char *pszParmName);
936 static int getservicebyname(const char *pszServiceName,
937 service * pserviceDest);
938 static void copy_service(service * pserviceDest,
939 service * pserviceSource, int *pcopymapDest);
940 static BOOL service_ok(int iService);
941 static BOOL do_section(const char *pszSectionName, void *);
942 static void init_copymap(service * pservice);
944 /* This is a helper function for parametrical options support. */
945 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
946 /* Actual parametrical functions are quite simple */
947 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
950 struct param_opt *data;
952 if (lookup_service >= iNumServices) return NULL;
954 data = (lookup_service < 0) ?
955 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
957 asprintf(&vfskey, "%s:%s", type, option);
961 if (strcmp(data->key, vfskey) == 0) {
968 if (lookup_service >= 0) {
969 /* Try to fetch the same option but from globals */
970 /* but only if we are not already working with Globals */
971 data = Globals.param_opt;
973 if (strcmp(data->key, vfskey) == 0) {
987 /*******************************************************************
988 convenience routine to return int parameters.
989 ********************************************************************/
990 static int lp_int(const char *s)
994 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
998 return strtol(s, NULL, 0);
1001 /*******************************************************************
1002 convenience routine to return unsigned long parameters.
1003 ********************************************************************/
1004 static int lp_ulong(const char *s)
1008 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1012 return strtoul(s, NULL, 0);
1015 /*******************************************************************
1016 convenience routine to return boolean parameters.
1017 ********************************************************************/
1018 static BOOL lp_bool(const char *s)
1023 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1027 if (!set_boolean(s, &ret)) {
1028 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1036 /* Return parametric option from a given service. Type is a part of option before ':' */
1037 /* Parametric option has following syntax: 'Type: option = value' */
1038 /* Returned value is allocated in 'lp_talloc' context */
1040 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1042 const char *value = lp_get_parametric(lookup_service, type, option);
1045 return lp_string(value);
1050 /* Return parametric option from a given service. Type is a part of option before ':' */
1051 /* Parametric option has following syntax: 'Type: option = value' */
1052 /* Returned value is allocated in 'lp_talloc' context */
1054 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1055 const char *separator)
1057 const char *value = lp_get_parametric(lookup_service, type, option);
1060 return str_list_make(talloc_autofree_context(), value, separator);
1065 /* Return parametric option from a given service. Type is a part of option before ':' */
1066 /* Parametric option has following syntax: 'Type: option = value' */
1068 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1070 const char *value = lp_get_parametric(lookup_service, type, option);
1073 return lp_int(value);
1078 /* Return parametric option from a given service. Type is a part of
1079 * option before ':'.
1080 * Parametric option has following syntax: 'Type: option = value'.
1083 int lp_parm_bytes(int lookup_service, const char *type, const char *option, int default_v)
1087 const char *value = lp_get_parametric(lookup_service, type, option);
1089 if (value && conv_str_size(value, &bval)) {
1090 if (bval <= INT_MAX) {
1098 /* Return parametric option from a given service. Type is a part of option before ':' */
1099 /* Parametric option has following syntax: 'Type: option = value' */
1101 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1103 const char *value = lp_get_parametric(lookup_service, type, option);
1106 return lp_ulong(value);
1111 /* Return parametric option from a given service. Type is a part of option before ':' */
1112 /* Parametric option has following syntax: 'Type: option = value' */
1114 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1116 const char *value = lp_get_parametric(lookup_service, type, option);
1119 return lp_bool(value);
1125 /***************************************************************************
1126 Initialise a service to the defaults.
1127 ***************************************************************************/
1129 static void init_service(service * pservice)
1131 memset((char *)pservice, '\0', sizeof(service));
1132 copy_service(pservice, &sDefault, NULL);
1135 /***************************************************************************
1136 Free the dynamically allocated parts of a service struct.
1137 ***************************************************************************/
1139 static void free_service(service *pservice)
1142 struct param_opt *data, *pdata;
1146 if (pservice->szService)
1147 DEBUG(5, ("free_service: Freeing service %s\n",
1148 pservice->szService));
1150 string_free(&pservice->szService);
1151 SAFE_FREE(pservice->copymap);
1153 for (i = 0; parm_table[i].label; i++) {
1154 if ((parm_table[i].type == P_STRING ||
1155 parm_table[i].type == P_USTRING) &&
1156 parm_table[i].class == P_LOCAL) {
1157 string_free((char **)
1158 (((char *)pservice) +
1159 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1160 } else if (parm_table[i].type == P_LIST &&
1161 parm_table[i].class == P_LOCAL) {
1162 char ***listp = (char ***)(((char *)pservice) +
1163 PTR_DIFF(parm_table[i].ptr, &sDefault));
1164 talloc_free(*listp);
1169 DEBUG(5,("Freeing parametrics:\n"));
1170 data = pservice->param_opt;
1172 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1173 string_free(&data->key);
1174 string_free(&data->value);
1180 ZERO_STRUCTP(pservice);
1183 /***************************************************************************
1184 Add a new service to the services array initialising it with the given
1186 ***************************************************************************/
1188 static int add_a_service(const service *pservice, const char *name)
1192 int num_to_alloc = iNumServices + 1;
1193 struct param_opt *data, *pdata;
1195 tservice = *pservice;
1197 /* it might already exist */
1199 i = getservicebyname(name, NULL);
1201 /* Clean all parametric options for service */
1202 /* They will be added during parsing again */
1203 data = ServicePtrs[i]->param_opt;
1205 string_free(&data->key);
1206 string_free(&data->value);
1211 ServicePtrs[i]->param_opt = NULL;
1216 /* find an invalid one */
1217 for (i = 0; i < iNumServices; i++)
1218 if (!ServicePtrs[i]->valid)
1221 /* if not, then create one */
1222 if (i == iNumServices) {
1225 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1228 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1233 ServicePtrs[iNumServices] = malloc_p(service);
1235 if (!ServicePtrs[iNumServices]) {
1236 DEBUG(0,("add_a_service: out of memory!\n"));
1242 free_service(ServicePtrs[i]);
1244 ServicePtrs[i]->valid = True;
1246 init_service(ServicePtrs[i]);
1247 copy_service(ServicePtrs[i], &tservice, NULL);
1249 string_set(&ServicePtrs[i]->szService, name);
1253 /***************************************************************************
1254 Add a new home service, with the specified home directory, defaults coming
1256 ***************************************************************************/
1258 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1259 const char *user, const char *pszHomedir)
1264 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1269 if (!(*(ServicePtrs[iDefaultService]->szPath))
1270 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1271 pstrcpy(newHomedir, pszHomedir);
1273 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1274 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1277 string_set(&ServicePtrs[i]->szPath, newHomedir);
1279 if (!(*(ServicePtrs[i]->comment))) {
1281 slprintf(comment, sizeof(comment) - 1,
1282 "Home directory of %s", user);
1283 string_set(&ServicePtrs[i]->comment, comment);
1285 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1286 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1288 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1294 /***************************************************************************
1295 Add a new service, based on an old one.
1296 ***************************************************************************/
1298 int lp_add_service(const char *pszService, int iDefaultService)
1300 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1303 /***************************************************************************
1304 Add the IPC service.
1305 ***************************************************************************/
1307 static BOOL lp_add_hidden(const char *name, const char *fstype)
1310 int i = add_a_service(&sDefault, name);
1315 slprintf(comment, sizeof(comment) - 1,
1316 "%s Service (%s)", fstype, Globals.szServerString);
1318 string_set(&ServicePtrs[i]->szPath, tmpdir());
1319 string_set(&ServicePtrs[i]->comment, comment);
1320 string_set(&ServicePtrs[i]->fstype, fstype);
1321 ServicePtrs[i]->iMaxConnections = -1;
1322 ServicePtrs[i]->bAvailable = True;
1323 ServicePtrs[i]->bRead_only = True;
1324 ServicePtrs[i]->bPrint_ok = False;
1325 ServicePtrs[i]->bBrowseable = False;
1327 if (strcasecmp(fstype, "IPC") == 0) {
1328 lp_do_parameter(i, "ntvfs handler", "default");
1331 DEBUG(3, ("adding hidden service %s\n", name));
1336 /***************************************************************************
1337 Add a new printer service, with defaults coming from service iFrom.
1338 ***************************************************************************/
1340 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1342 const char *comment = "From Printcap";
1343 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1348 /* note that we do NOT default the availability flag to True - */
1349 /* we take it from the default service passed. This allows all */
1350 /* dynamic printers to be disabled by disabling the [printers] */
1351 /* entry (if/when the 'available' keyword is implemented!). */
1353 /* the printer name is set to the service name. */
1354 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1355 string_set(&ServicePtrs[i]->comment, comment);
1356 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1357 /* Printers cannot be read_only. */
1358 ServicePtrs[i]->bRead_only = False;
1359 /* Printer services must be printable. */
1360 ServicePtrs[i]->bPrint_ok = True;
1362 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1367 /***************************************************************************
1368 Map a parameter's string representation to something we can use.
1369 Returns False if the parameter string is not recognised, else TRUE.
1370 ***************************************************************************/
1372 static int map_parameter(const char *pszParmName)
1376 if (*pszParmName == '-')
1379 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1380 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1383 /* Warn only if it isn't parametric option */
1384 if (strchr(pszParmName, ':') == NULL)
1385 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1386 /* We do return 'fail' for parametric options as well because they are
1387 stored in different storage
1394 return the parameter structure for a parameter
1396 struct parm_struct *lp_parm_struct(const char *name)
1398 int parmnum = map_parameter(name);
1399 if (parmnum == -1) return NULL;
1400 return &parm_table[parmnum];
1404 return the parameter pointer for a parameter
1406 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1411 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1414 /***************************************************************************
1415 Find a service by name. Otherwise works like get_service.
1416 ***************************************************************************/
1418 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1422 for (iService = iNumServices - 1; iService >= 0; iService--)
1423 if (VALID(iService) &&
1424 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1425 if (pserviceDest != NULL)
1426 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1433 /***************************************************************************
1434 Copy a service structure to another.
1435 If pcopymapDest is NULL then copy all fields
1436 ***************************************************************************/
1438 static void copy_service(service * pserviceDest, service * pserviceSource, int *pcopymapDest)
1441 BOOL bcopyall = (pcopymapDest == NULL);
1442 struct param_opt *data, *pdata, *paramo;
1445 for (i = 0; parm_table[i].label; i++)
1446 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1447 (bcopyall || pcopymapDest[i])) {
1448 void *def_ptr = parm_table[i].ptr;
1450 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1453 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1456 switch (parm_table[i].type) {
1458 *(int *)dest_ptr = *(int *)src_ptr;
1463 *(int *)dest_ptr = *(int *)src_ptr;
1467 string_set(dest_ptr,
1472 string_set(dest_ptr,
1474 strupper(*(char **)dest_ptr);
1477 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1478 *(const char ***)src_ptr);
1486 init_copymap(pserviceDest);
1487 if (pserviceSource->copymap)
1488 memcpy((void *)pserviceDest->copymap,
1489 (void *)pserviceSource->copymap,
1490 sizeof(int) * NUMPARAMETERS);
1493 data = pserviceSource->param_opt;
1496 pdata = pserviceDest->param_opt;
1497 /* Traverse destination */
1499 /* If we already have same option, override it */
1500 if (strcmp(pdata->key, data->key) == 0) {
1501 string_free(&pdata->value);
1502 pdata->value = strdup(data->value);
1506 pdata = pdata->next;
1509 paramo = malloc_p(struct param_opt);
1512 paramo->key = strdup(data->key);
1513 paramo->value = strdup(data->value);
1514 DLIST_ADD(pserviceDest->param_opt, paramo);
1520 /***************************************************************************
1521 Check a service for consistency. Return False if the service is in any way
1522 incomplete or faulty, else True.
1523 ***************************************************************************/
1525 static BOOL service_ok(int iService)
1530 if (ServicePtrs[iService]->szService[0] == '\0') {
1531 DEBUG(0, ("The following message indicates an internal error:\n"));
1532 DEBUG(0, ("No service name in service entry.\n"));
1536 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1537 /* I can't see why you'd want a non-printable printer service... */
1538 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1539 if (!ServicePtrs[iService]->bPrint_ok) {
1540 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1541 ServicePtrs[iService]->szService));
1542 ServicePtrs[iService]->bPrint_ok = True;
1544 /* [printers] service must also be non-browsable. */
1545 if (ServicePtrs[iService]->bBrowseable)
1546 ServicePtrs[iService]->bBrowseable = False;
1549 /* If a service is flagged unavailable, log the fact at level 0. */
1550 if (!ServicePtrs[iService]->bAvailable)
1551 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1552 ServicePtrs[iService]->szService));
1557 static struct file_lists {
1558 struct file_lists *next;
1562 } *file_lists = NULL;
1564 /*******************************************************************
1565 Keep a linked list of all config files so we know when one has changed
1566 it's date and needs to be reloaded.
1567 ********************************************************************/
1569 static void add_to_file_list(const char *fname, const char *subfname)
1571 struct file_lists *f = file_lists;
1574 if (f->name && !strcmp(f->name, fname))
1580 f = malloc_p(struct file_lists);
1583 f->next = file_lists;
1584 f->name = strdup(fname);
1589 f->subfname = strdup(subfname);
1595 f->modtime = file_modtime(subfname);
1597 time_t t = file_modtime(subfname);
1603 /*******************************************************************
1604 Check if a config file has changed date.
1605 ********************************************************************/
1607 BOOL lp_file_list_changed(void)
1609 struct file_lists *f = file_lists;
1610 DEBUG(6, ("lp_file_list_changed()\n"));
1616 pstrcpy(n2, f->name);
1617 standard_sub_basic(n2,sizeof(n2));
1619 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1620 f->name, n2, ctime(&f->modtime)));
1622 mod_time = file_modtime(n2);
1624 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1626 ("file %s modified: %s\n", n2,
1628 f->modtime = mod_time;
1629 SAFE_FREE(f->subfname);
1630 f->subfname = strdup(n2);
1638 /***************************************************************************
1639 Handle the include operation.
1640 ***************************************************************************/
1642 static BOOL handle_include(const char *pszParmValue, char **ptr)
1645 pstrcpy(fname, pszParmValue);
1647 standard_sub_basic(fname,sizeof(fname));
1649 add_to_file_list(pszParmValue, fname);
1651 string_set(ptr, fname);
1653 if (file_exist(fname))
1654 return (pm_process(fname, do_section, do_parameter, NULL));
1656 DEBUG(2, ("Can't find include file %s\n", fname));
1661 /***************************************************************************
1662 Handle the interpretation of the copy parameter.
1663 ***************************************************************************/
1665 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1669 service serviceTemp;
1671 string_set(ptr, pszParmValue);
1673 init_service(&serviceTemp);
1677 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1679 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1680 if (iTemp == iServiceIndex) {
1681 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1683 copy_service(ServicePtrs[iServiceIndex],
1685 ServicePtrs[iServiceIndex]->copymap);
1689 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1693 free_service(&serviceTemp);
1697 /***************************************************************************
1698 Initialise a copymap.
1699 ***************************************************************************/
1701 static void init_copymap(service * pservice)
1704 SAFE_FREE(pservice->copymap);
1705 pservice->copymap = malloc_array_p(int, NUMPARAMETERS);
1706 if (!pservice->copymap)
1708 ("Couldn't allocate copymap!! (size %d)\n",
1709 (int)NUMPARAMETERS));
1711 for (i = 0; i < NUMPARAMETERS; i++)
1712 pservice->copymap[i] = True;
1715 #if 0 /* not used anywhere */
1716 /***************************************************************************
1717 Return the local pointer to a parameter given the service number and the
1718 pointer into the default structure.
1719 ***************************************************************************/
1721 void *lp_local_ptr(int snum, void *ptr)
1723 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1727 /***************************************************************************
1728 Process a parametric option
1729 ***************************************************************************/
1730 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1732 struct param_opt *paramo, *data;
1735 while (isspace((unsigned char)*pszParmName)) {
1739 name = strdup(pszParmName);
1740 if (!name) return False;
1745 data = Globals.param_opt;
1747 data = ServicePtrs[snum]->param_opt;
1750 /* Traverse destination */
1751 for (paramo=data; paramo; paramo=paramo->next) {
1752 /* If we already have the option set, override it unless
1753 it was a command line option and the new one isn't */
1754 if (strcmp(paramo->key, name) == 0) {
1755 if ((paramo->flags & FLAG_CMDLINE) &&
1756 !(flags & FLAG_CMDLINE)) {
1760 free(paramo->value);
1761 paramo->value = strdup(pszParmValue);
1762 paramo->flags = flags;
1768 paramo = malloc_p(struct param_opt);
1771 paramo->key = strdup(name);
1772 paramo->value = strdup(pszParmValue);
1773 paramo->flags = flags;
1775 DLIST_ADD(Globals.param_opt, paramo);
1777 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1785 /***************************************************************************
1786 Process a parameter for a particular service number. If snum < 0
1787 then assume we are in the globals.
1788 ***************************************************************************/
1789 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1792 void *parm_ptr = NULL; /* where we are going to store the result */
1793 void *def_ptr = NULL;
1795 parmnum = map_parameter(pszParmName);
1798 if (strchr(pszParmName, ':')) {
1799 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1801 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1805 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1806 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1810 /* if the flag has been set on the command line, then don't allow override,
1811 but don't report an error */
1812 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1816 def_ptr = parm_table[parmnum].ptr;
1818 /* we might point at a service, the default service or a global */
1822 if (parm_table[parmnum].class == P_GLOBAL) {
1824 ("Global parameter %s found in service section!\n",
1829 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1834 if (!ServicePtrs[snum]->copymap)
1835 init_copymap(ServicePtrs[snum]);
1837 /* this handles the aliases - set the copymap for other entries with
1838 the same data pointer */
1839 for (i = 0; parm_table[i].label; i++)
1840 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1841 ServicePtrs[snum]->copymap[i] = False;
1844 /* if it is a special case then go ahead */
1845 if (parm_table[parmnum].special) {
1846 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1850 /* now switch on the type of variable it is */
1851 switch (parm_table[parmnum].type)
1855 if (!set_boolean(pszParmValue, &b)) {
1856 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1859 *(int *)parm_ptr = b;
1864 *(int *)parm_ptr = atoi(pszParmValue);
1870 if (conv_str_size(pszParmValue, &val)) {
1871 if (val <= INT_MAX) {
1872 *(int *)parm_ptr = (int)val;
1877 DEBUG(0,("lp_do_parameter(%s): value is not "
1878 "a valid size specifier!\n", pszParmValue));
1883 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1884 pszParmValue, NULL);
1888 string_set(parm_ptr, pszParmValue);
1892 string_set(parm_ptr, pszParmValue);
1893 strupper(*(char **)parm_ptr);
1897 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1900 parm_table[parmnum].enum_list[i].name)) {
1902 parm_table[parmnum].
1907 if (!parm_table[parmnum].enum_list[i].name) {
1908 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1909 pszParmValue, pszParmName));
1917 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1918 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1919 /* we have to also unset FLAG_DEFAULT on aliases */
1920 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1921 parm_table[i].flags &= ~FLAG_DEFAULT;
1923 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1924 parm_table[i].flags &= ~FLAG_DEFAULT;
1931 /***************************************************************************
1932 Process a parameter.
1933 ***************************************************************************/
1935 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1937 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1938 pszParmName, pszParmValue));
1942 variable argument do parameter
1944 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1946 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
1953 s = talloc_vasprintf(NULL, fmt, ap);
1955 ret = do_parameter(pszParmName, s, NULL);
1962 set a parameter from the commandline - this is called from command line parameter
1963 parsing code. It sets the parameter then marks the parameter as unable to be modified
1964 by smb.conf processing
1966 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
1968 int parmnum = map_parameter(pszParmName);
1971 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1974 if (parmnum < 0 && strchr(pszParmName, ':')) {
1975 /* set a parametric option */
1976 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
1980 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1984 /* reset the CMDLINE flag in case this has been called before */
1985 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
1987 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
1991 parm_table[parmnum].flags |= FLAG_CMDLINE;
1993 /* we have to also set FLAG_CMDLINE on aliases */
1994 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1995 parm_table[i].flags |= FLAG_CMDLINE;
1997 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1998 parm_table[i].flags |= FLAG_CMDLINE;
2005 set a option from the commandline in 'a=b' format. Use to support --option
2007 BOOL lp_set_option(const char *option)
2025 ret = lp_set_cmdline(s, p+1);
2031 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2033 /***************************************************************************
2034 Print a parameter of the specified type.
2035 ***************************************************************************/
2037 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2043 for (i = 0; p->enum_list[i].name; i++) {
2044 if (*(int *)ptr == p->enum_list[i].value) {
2046 p->enum_list[i].name);
2053 fprintf(f, "%s", BOOLSTR((BOOL)*(int *)ptr));
2058 fprintf(f, "%d", *(int *)ptr);
2062 if ((char ***)ptr && *(char ***)ptr) {
2063 char **list = *(char ***)ptr;
2065 for (; *list; list++)
2066 fprintf(f, "%s%s", *list,
2067 ((*(list+1))?", ":""));
2073 if (*(char **)ptr) {
2074 fprintf(f, "%s", *(char **)ptr);
2082 /***************************************************************************
2083 Check if two parameters are equal.
2084 ***************************************************************************/
2086 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2090 return (*((int *)ptr1) == *((int *)ptr2));
2095 return (*((int *)ptr1) == *((int *)ptr2));
2098 return str_list_equal((const char **)(*(char ***)ptr1),
2099 (const char **)(*(char ***)ptr2));
2104 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2109 return (p1 == p2 || strequal(p1, p2));
2117 /***************************************************************************
2118 Process a new section (service). At this stage all sections are services.
2119 Later we'll have special sections that permit server parameters to be set.
2120 Returns True on success, False on failure.
2121 ***************************************************************************/
2123 static BOOL do_section(const char *pszSectionName, void *userdata)
2126 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2127 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2130 /* if we've just struck a global section, note the fact. */
2131 bInGlobalSection = isglobal;
2133 /* check for multiple global sections */
2134 if (bInGlobalSection) {
2135 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2139 /* if we have a current service, tidy it up before moving on */
2142 if (iServiceIndex >= 0)
2143 bRetval = service_ok(iServiceIndex);
2145 /* if all is still well, move to the next record in the services array */
2147 /* We put this here to avoid an odd message order if messages are */
2148 /* issued by the post-processing of a previous section. */
2149 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2151 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2153 DEBUG(0, ("Failed to add a new service\n"));
2162 /***************************************************************************
2163 Determine if a partcular base parameter is currentl set to the default value.
2164 ***************************************************************************/
2166 static BOOL is_default(int i)
2168 if (!defaults_saved)
2170 switch (parm_table[i].type) {
2172 return str_list_equal((const char **)parm_table[i].def.lvalue,
2173 (const char **)(*(char ***)parm_table[i].ptr));
2176 return strequal(parm_table[i].def.svalue,
2177 *(char **)parm_table[i].ptr);
2179 return parm_table[i].def.bvalue ==
2180 *(int *)parm_table[i].ptr;
2184 return parm_table[i].def.ivalue ==
2185 *(int *)parm_table[i].ptr;
2192 /***************************************************************************
2193 Display the contents of the global structure.
2194 ***************************************************************************/
2196 static void dump_globals(FILE *f, BOOL show_defaults)
2199 struct param_opt *data;
2201 fprintf(f, "# Global parameters\n[global]\n");
2203 for (i = 0; parm_table[i].label; i++)
2204 if (parm_table[i].class == P_GLOBAL &&
2205 parm_table[i].ptr &&
2206 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2207 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2209 fprintf(f, "\t%s = ", parm_table[i].label);
2210 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2213 if (Globals.param_opt != NULL) {
2214 data = Globals.param_opt;
2216 fprintf(f, "\t%s = %s\n", data->key, data->value);
2223 /***************************************************************************
2224 Display the contents of a single services record.
2225 ***************************************************************************/
2227 static void dump_a_service(service * pService, FILE * f)
2230 struct param_opt *data;
2232 if (pService != &sDefault)
2233 fprintf(f, "\n[%s]\n", pService->szService);
2235 for (i = 0; parm_table[i].label; i++)
2236 if (parm_table[i].class == P_LOCAL &&
2237 parm_table[i].ptr &&
2238 (*parm_table[i].label != '-') &&
2239 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2240 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2242 if (pService == &sDefault) {
2243 if (defaults_saved && is_default(i))
2246 if (equal_parameter(parm_table[i].type,
2247 ((char *)pService) +
2249 ((char *)&sDefault) +
2254 fprintf(f, "\t%s = ", parm_table[i].label);
2255 print_parameter(&parm_table[i],
2256 ((char *)pService) + pdiff, f);
2259 if (pService->param_opt != NULL) {
2260 data = pService->param_opt;
2262 fprintf(f, "\t%s = %s\n", data->key, data->value);
2268 BOOL lp_dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
2270 service * pService = ServicePtrs[snum];
2271 struct parm_struct *parm;
2274 parm = lp_parm_struct(parm_name);
2282 ptr = ((char *)pService) +
2283 PTR_DIFF(parm->ptr, &sDefault);
2285 print_parameter(parm,
2291 /***************************************************************************
2292 Return info about the next service in a service. snum==-1 gives the globals.
2293 Return NULL when out of parameters.
2294 ***************************************************************************/
2296 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2299 /* do the globals */
2300 for (; parm_table[*i].label; (*i)++) {
2301 if (parm_table[*i].class == P_SEPARATOR)
2302 return &parm_table[(*i)++];
2304 if (!parm_table[*i].ptr
2305 || (*parm_table[*i].label == '-'))
2309 && (parm_table[*i].ptr ==
2310 parm_table[(*i) - 1].ptr))
2313 return &parm_table[(*i)++];
2316 service *pService = ServicePtrs[snum];
2318 for (; parm_table[*i].label; (*i)++) {
2319 if (parm_table[*i].class == P_SEPARATOR)
2320 return &parm_table[(*i)++];
2322 if (parm_table[*i].class == P_LOCAL &&
2323 parm_table[*i].ptr &&
2324 (*parm_table[*i].label != '-') &&
2326 (parm_table[*i].ptr !=
2327 parm_table[(*i) - 1].ptr)))
2330 PTR_DIFF(parm_table[*i].ptr,
2333 if (allparameters ||
2334 !equal_parameter(parm_table[*i].type,
2335 ((char *)pService) +
2337 ((char *)&sDefault) +
2340 return &parm_table[(*i)++];
2350 /***************************************************************************
2351 Return TRUE if the passed service number is within range.
2352 ***************************************************************************/
2354 BOOL lp_snum_ok(int iService)
2356 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2359 /***************************************************************************
2360 Auto-load some home services.
2361 ***************************************************************************/
2363 static void lp_add_auto_services(const char *str)
2368 /***************************************************************************
2369 Have we loaded a services file yet?
2370 ***************************************************************************/
2372 BOOL lp_loaded(void)
2377 /***************************************************************************
2378 Unload unused services.
2379 ***************************************************************************/
2381 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2384 for (i = 0; i < iNumServices; i++) {
2388 if (!snumused || !snumused(smb, i)) {
2389 ServicePtrs[i]->valid = False;
2390 free_service(ServicePtrs[i]);
2395 /***************************************************************************
2397 ***************************************************************************/
2399 void lp_killservice(int iServiceIn)
2401 if (VALID(iServiceIn)) {
2402 ServicePtrs[iServiceIn]->valid = False;
2403 free_service(ServicePtrs[iServiceIn]);
2407 /***************************************************************************
2408 Load the services array from the services file. Return True on success,
2410 ***************************************************************************/
2416 struct param_opt *data;
2420 bInGlobalSection = True;
2422 if (Globals.param_opt != NULL) {
2423 struct param_opt *next;
2424 for (data=Globals.param_opt; data; data=next) {
2426 if (data->flags & FLAG_CMDLINE) continue;
2429 DLIST_REMOVE(Globals.param_opt, data);
2436 pstrcpy(n2, lp_configfile());
2437 standard_sub_basic(n2,sizeof(n2));
2438 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2440 add_to_file_list(lp_configfile(), n2);
2442 /* We get sections first, so have to start 'behind' to make up */
2444 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2446 /* finish up the last section */
2447 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2449 if (iServiceIndex >= 0)
2450 bRetval = service_ok(iServiceIndex);
2452 lp_add_auto_services(lp_auto_services());
2454 lp_add_hidden("IPC$", "IPC");
2455 lp_add_hidden("ADMIN$", "DISK");
2459 if (!Globals.szWINSservers && Globals.bWINSsupport) {
2460 lp_do_parameter(-1, "wins server", "127.0.0.1");
2468 /***************************************************************************
2469 Reset the max number of services.
2470 ***************************************************************************/
2472 void lp_resetnumservices(void)
2477 /***************************************************************************
2478 Return the max number of services.
2479 ***************************************************************************/
2481 int lp_numservices(void)
2483 return (iNumServices);
2486 /***************************************************************************
2487 Display the contents of the services array in human-readable form.
2488 ***************************************************************************/
2490 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2495 defaults_saved = False;
2497 dump_globals(f, show_defaults);
2499 dump_a_service(&sDefault, f);
2501 for (iService = 0; iService < maxtoprint; iService++)
2502 lp_dump_one(f, show_defaults, iService);
2505 /***************************************************************************
2506 Display the contents of one service in human-readable form.
2507 ***************************************************************************/
2509 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2512 if (ServicePtrs[snum]->szService[0] == '\0')
2514 dump_a_service(ServicePtrs[snum], f);
2518 /***************************************************************************
2519 Return the number of the service with the given name, or -1 if it doesn't
2520 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2521 getservicebyname()! This works ONLY if all services have been loaded, and
2522 does not copy the found service.
2523 ***************************************************************************/
2525 int lp_servicenumber(const char *pszServiceName)
2528 fstring serviceName;
2531 for (iService = iNumServices - 1; iService >= 0; iService--) {
2532 if (VALID(iService) && ServicePtrs[iService]->szService) {
2534 * The substitution here is used to support %U is
2537 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2538 standard_sub_basic(serviceName,sizeof(serviceName));
2539 if (strequal(serviceName, pszServiceName))
2545 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2550 int lp_find_valid_service(const char *pszServiceName)
2554 iService = lp_servicenumber(pszServiceName);
2556 if (iService >= 0 && !lp_snum_ok(iService)) {
2557 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService, pszServiceName));
2561 if (iService == -1) {
2562 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName));
2568 /*******************************************************************
2569 A useful volume label function.
2570 ********************************************************************/
2571 const char *volume_label(int snum)
2573 const char *ret = lp_volume(snum);
2575 return lp_servicename(snum);
2580 /***********************************************************
2581 If we are PDC then prefer us as DMB
2582 ************************************************************/
2584 BOOL lp_domain_logons(void)
2586 return (lp_server_role() == ROLE_DOMAIN_CONTROLLER);
2589 /*******************************************************************
2591 ********************************************************************/
2593 void lp_remove_service(int snum)
2595 ServicePtrs[snum]->valid = False;
2598 /*******************************************************************
2600 ********************************************************************/
2602 void lp_copy_service(int snum, const char *new_name)
2604 const char *oldname = lp_servicename(snum);
2605 do_section(new_name, NULL);
2607 snum = lp_servicenumber(new_name);
2609 lp_do_parameter(snum, "copy", oldname);
2613 const char *lp_printername(int snum)
2615 const char *ret = _lp_printername(snum);
2616 if (ret == NULL || (ret != NULL && *ret == '\0'))
2617 ret = lp_const_servicename(snum);
2623 /*******************************************************************
2624 Return the max print jobs per queue.
2625 ********************************************************************/
2627 int lp_maxprintjobs(int snum)
2629 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2630 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2631 maxjobs = PRINT_MAX_JOBID - 1;