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 3 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, see <http://www.gnu.org/licenses/>.
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
56 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/locale.h"
60 #include "system/network.h" /* needed for TCP_NODELAY */
61 #include "smb_server/smb_server.h"
62 #include "libcli/raw/signing.h"
63 #include "lib/util/dlinklist.h"
64 #include "param/loadparm.h"
66 static BOOL bLoaded = False;
68 #define standard_sub_basic(str,len)
70 /* some helpful bits */
71 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
72 #define VALID(i) ServicePtrs[i]->valid
74 static BOOL do_parameter(const char *, const char *, void *);
75 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
77 static BOOL defaults_saved = False;
81 struct param_opt *prev, *next;
88 * This structure describes global (ie., server-wide) parameters.
98 char *display_charset;
103 char *szServerString;
104 char *szAutoServices;
107 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 *webapps_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;
226 int iCreate_force_mode;
233 struct param_opt *param_opt;
235 char dummy[3]; /* for alignment */
240 /* This is a default service used to prime a services structure */
241 static service sDefault = {
243 NULL, /* szService */
246 NULL, /* szInclude */
247 NULL, /* szPrintername */
248 NULL, /* szHostsallow */
249 NULL, /* szHostsdeny */
253 NULL, /* ntvfs_handler */
254 1000, /* iMaxPrintJobs */
255 0, /* iMaxConnections */
257 True, /* bAvailable */
258 True, /* bBrowseable */
259 True, /* bRead_only */
260 False, /* bPrint_ok */
261 False, /* bMap_system */
262 False, /* bMap_hidden */
263 True, /* bMap_archive */
264 True, /* bStrictLocking */
265 0744, /* iCreate_mask */
266 0000, /* iCreate_force_mode */
267 0755, /* iDir_mask */
268 0000, /* iDir_force_mode */
270 False, /* bMSDfsRoot */
271 False, /* bStrictSync */
272 False, /* bCIFileSystem */
273 NULL, /* Parametric options */
278 /* local variables */
279 static service **ServicePtrs = NULL;
280 static int iNumServices = 0;
281 static int iServiceIndex = 0;
282 static BOOL bInGlobalSection = True;
284 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
286 /* prototypes for the special type handlers */
287 static BOOL handle_include(const char *pszParmValue, char **ptr);
288 static BOOL handle_copy(const char *pszParmValue, char **ptr);
290 static const struct enum_list enum_protocol[] = {
291 {PROTOCOL_SMB2, "SMB2"},
292 {PROTOCOL_NT1, "NT1"},
293 {PROTOCOL_LANMAN2, "LANMAN2"},
294 {PROTOCOL_LANMAN1, "LANMAN1"},
295 {PROTOCOL_CORE, "CORE"},
296 {PROTOCOL_COREPLUS, "COREPLUS"},
297 {PROTOCOL_COREPLUS, "CORE+"},
301 static const struct enum_list enum_security[] = {
302 {SEC_SHARE, "SHARE"},
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_CONTROLLER, "domain controller"},
370 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
372 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
373 * is implied in current control logic. This may change at some later time. A
374 * flag value of 0 means - show as development option only.
376 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
377 * screen in SWAT. This is used to exclude parameters as well as to squash all
378 * parameters that have been duplicated by pseudonyms.
380 static struct parm_struct parm_table[] = {
381 {"Base Options", P_SEP, P_SEPARATOR},
383 {"server role", P_ENUM, P_GLOBAL, &Globals.server_role, NULL, enum_server_role, FLAG_BASIC},
385 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
386 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
387 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
388 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
389 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
390 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
391 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
392 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
393 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
394 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
395 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
396 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
397 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
398 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
399 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
400 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
401 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
402 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
403 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
405 {"Security Options", P_SEP, P_SEPARATOR},
407 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
408 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
409 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
410 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
411 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
412 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
413 {"secrets database", P_STRING, P_GLOBAL, &Globals.szSECRETS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
414 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
415 {"wins config database", P_STRING, P_GLOBAL, &Globals.szWINS_CONFIG_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
416 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
417 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
418 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
419 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
420 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
421 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
422 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
423 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
424 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
425 {"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
427 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
429 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
430 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
431 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
432 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
434 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
435 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
437 {"Logging Options", P_SEP, P_SEPARATOR},
439 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
440 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
441 {"log file", P_STRING, P_GLOBAL, &logfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
443 {"Protocol Options", P_SEP, P_SEPARATOR},
445 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
446 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
447 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
448 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
449 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
450 {"kpasswd port", P_INTEGER, P_GLOBAL, &Globals.kpasswd_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
451 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
452 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
453 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
454 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
455 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
456 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
457 {"tls dh params file", P_STRING, P_GLOBAL, &Globals.tls_dhpfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
458 {"web application directory", P_STRING, P_GLOBAL, &Globals.webapps_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
459 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
460 {"server max protocol", P_ENUM, P_GLOBAL, &Globals.srv_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
461 {"server min protocol", P_ENUM, P_GLOBAL, &Globals.srv_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
462 {"client max protocol", P_ENUM, P_GLOBAL, &Globals.cli_maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
463 {"client min protocol", P_ENUM, P_GLOBAL, &Globals.cli_minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
464 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
465 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
466 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
467 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
469 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
471 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
472 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
473 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
474 {"max xmit", P_BYTES, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
476 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
477 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
478 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
479 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
480 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
481 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
482 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
483 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
484 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
486 {"Tuning Options", P_SEP, P_SEPARATOR},
488 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
489 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
490 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
492 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
493 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
495 {"Printing Options", P_SEP, P_SEPARATOR},
497 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
498 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
499 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
501 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
502 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
504 {"Filename Handling", P_SEP, P_SEPARATOR},
506 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
507 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
508 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
510 {"Domain Options", P_SEP, P_SEPARATOR},
512 {"Logon Options", P_SEP, P_SEPARATOR},
515 {"Browse Options", P_SEP, P_SEPARATOR},
517 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
518 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
519 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
520 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
521 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
523 {"WINS Options", P_SEP, P_SEPARATOR},
525 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
526 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
527 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bWINSdnsProxy, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
528 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
530 {"Locking Options", P_SEP, P_SEPARATOR},
532 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
534 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
536 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
538 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
539 {"share backend", P_STRING, P_GLOBAL, &Globals.szShareBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
543 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"modules dir", P_STRING, P_GLOBAL, &Globals.szModulesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"js include", P_LIST, P_GLOBAL, &Globals.jsInclude, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"jsonrpc services directory", P_STRING, P_GLOBAL, &Globals.jsonrpcServicesDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"setup directory", P_STRING, P_GLOBAL, &Globals.szSetupDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
551 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
553 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
554 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
556 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
557 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
558 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
560 {"panic action", P_STRING, P_GLOBAL, &panic_action, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
563 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
565 {"winbindd socket directory", P_STRING, P_GLOBAL, &Globals.szWinbinddSocketDirectory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
566 {"winbind sealed pipes", P_BOOL, P_GLOBAL, &Globals.bWinbindSealedPipes, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
568 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
573 return the parameter table
575 struct parm_struct *lp_parm_table(void)
580 /***************************************************************************
581 Initialise the global parameter structure.
582 ***************************************************************************/
583 static void init_globals(void)
588 DEBUG(3, ("Initialising global parameters\n"));
590 for (i = 0; parm_table[i].label; i++) {
591 if ((parm_table[i].type == P_STRING ||
592 parm_table[i].type == P_USTRING) &&
594 !(parm_table[i].flags & FLAG_CMDLINE)) {
595 string_set(parm_table[i].ptr, "");
599 do_parameter("config file", dyn_CONFIGFILE, NULL);
601 do_parameter("share backend", "classic", NULL);
603 do_parameter("server role", "standalone", NULL);
605 /* options that can be set on the command line must be initialised via
606 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
608 do_parameter("socket options", "TCP_NODELAY", NULL);
610 do_parameter("workgroup", DEFAULT_WORKGROUP, NULL);
611 myname = get_myname();
612 do_parameter("netbios name", myname, NULL);
614 do_parameter("name resolve order", "lmhosts wins host bcast", NULL);
616 do_parameter("fstype", FSTYPE_STRING, NULL);
617 do_parameter("ntvfs handler", "unixuid default", NULL);
618 do_parameter("max connections", "-1", NULL);
620 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo", NULL);
621 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc drepl winbind", NULL);
622 do_parameter("ntptr providor", "simple_ldb", NULL);
623 do_parameter("auth methods:domain controller", "anonymous sam_ignoredomain", NULL);
624 do_parameter("auth methods:member server", "anonymous sam winbind", NULL);
625 do_parameter("auth methods:standalone", "anonymous sam_ignoredomain", NULL);
626 do_parameter("private dir", dyn_PRIVATE_DIR, NULL);
627 do_parameter("sam database", "sam.ldb", NULL);
628 do_parameter("secrets database", "secrets.ldb", NULL);
629 do_parameter("spoolss database", "spoolss.ldb", NULL);
630 do_parameter("wins config database", "wins_config.ldb", NULL);
631 do_parameter("wins database", "wins.ldb", NULL);
632 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL);
634 /* This hive should be dynamically generated by Samba using
635 data from the sam, but for the moment leave it in a tdb to
636 keep regedt32 from popping up an annoying dialog. */
637 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL);
639 /* using UTF8 by default allows us to support all chars */
640 do_parameter("unix charset", "UTF8", NULL);
642 /* Use codepage 850 as a default for the dos character set */
643 do_parameter("dos charset", "CP850", NULL);
646 * Allow the default PASSWD_CHAT to be overridden in local.h.
648 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT, NULL);
650 do_parameter("pid directory", dyn_PIDDIR, NULL);
651 do_parameter("lock dir", dyn_LOCKDIR, NULL);
652 do_parameter("modules dir", dyn_MODULESDIR, NULL);
653 do_parameter("ncalrpc dir", dyn_NCALRPCDIR, NULL);
655 do_parameter("socket address", "0.0.0.0", NULL);
656 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
658 do_parameter_var("announce version", "%d.%d",
659 DEFAULT_MAJOR_VERSION,
660 DEFAULT_MINOR_VERSION);
662 do_parameter("password server", "*", NULL);
664 do_parameter("max mux", "50", NULL);
665 do_parameter("max xmit", "12288", NULL);
666 do_parameter("password level", "0", NULL);
667 do_parameter("LargeReadwrite", "True", NULL);
668 do_parameter("server min protocol", "CORE", NULL);
669 do_parameter("server max protocol", "NT1", NULL);
670 do_parameter("client min protocol", "CORE", NULL);
671 do_parameter("client max protocol", "NT1", NULL);
672 do_parameter("security", "USER", NULL);
673 do_parameter("paranoid server security", "True", NULL);
674 do_parameter("EncryptPasswords", "True", NULL);
675 do_parameter("ReadRaw", "True", NULL);
676 do_parameter("WriteRaw", "True", NULL);
677 do_parameter("NullPasswords", "False", NULL);
678 do_parameter("ObeyPamRestrictions", "False", NULL);
679 do_parameter("announce as", "NT SERVER", NULL);
681 do_parameter("TimeServer", "False", NULL);
682 do_parameter("BindInterfacesOnly", "False", NULL);
683 do_parameter("Unicode", "True", NULL);
684 do_parameter("ClientLanManAuth", "True", NULL);
685 do_parameter("LanmanAuth", "True", NULL);
686 do_parameter("NTLMAuth", "True", NULL);
687 do_parameter("client use spnego principal", "False", NULL);
689 do_parameter("UnixExtensions", "False", NULL);
691 do_parameter("PreferredMaster", "Auto", NULL);
692 do_parameter("LocalMaster", "True", NULL);
694 do_parameter("wins support", "False", NULL);
695 do_parameter("dns proxy", "True", NULL);
697 do_parameter("winbind separator", "\\", NULL);
698 do_parameter("winbind sealed pipes", "True", NULL);
699 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR, NULL);
701 do_parameter("client signing", "Yes", NULL);
702 do_parameter("server signing", "auto", NULL);
704 do_parameter("use spnego", "True", NULL);
706 do_parameter("smb ports", "445 139", NULL);
707 do_parameter("nbt port", "137", NULL);
708 do_parameter("dgram port", "138", NULL);
709 do_parameter("cldap port", "389", NULL);
710 do_parameter("krb5 port", "88", NULL);
711 do_parameter("kpasswd port", "464", NULL);
712 do_parameter("web port", "901", NULL);
713 do_parameter("web application directory", dyn_WEBAPPSDIR, NULL);
714 do_parameter("jsonrpc services directory", dyn_SERVICESDIR, NULL);
716 do_parameter("nt status support", "True", NULL);
718 do_parameter("max wins ttl", "518400", NULL); /* 6 days */
719 do_parameter("min wins ttl", "10", NULL);
721 do_parameter("tls enabled", "True", NULL);
722 do_parameter("tls keyfile", "tls/key.pem", NULL);
723 do_parameter("tls certfile", "tls/cert.pem", NULL);
724 do_parameter("tls cafile", "tls/ca.pem", NULL);
725 do_parameter_var("js include", "%s", dyn_JSDIR);
726 do_parameter_var("setup directory", "%s", dyn_SETUPDIR);
728 for (i = 0; parm_table[i].label; i++) {
729 if (!(parm_table[i].flags & FLAG_CMDLINE)) {
730 parm_table[i].flags |= FLAG_DEFAULT;
735 static TALLOC_CTX *lp_talloc;
737 /******************************************************************* a
738 Free up temporary memory - called from the main loop.
739 ********************************************************************/
741 void lp_talloc_free(void)
745 talloc_free(lp_talloc);
749 /*******************************************************************
750 Convenience routine to grab string parameters into temporary memory
751 and run standard_sub_basic on them. The buffers can be written to by
752 callers without affecting the source string.
753 ********************************************************************/
755 static const char *lp_string(const char *s)
757 #if 0 /* until REWRITE done to make thread-safe */
758 size_t len = s ? strlen(s) : 0;
762 /* The follow debug is useful for tracking down memory problems
763 especially if you have an inner loop that is calling a lp_*()
764 function that returns a string. Perhaps this debug should be
765 present all the time? */
768 DEBUG(10, ("lp_string(%s)\n", s));
771 #if 0 /* until REWRITE done to make thread-safe */
773 lp_talloc = talloc_init("lp_talloc");
775 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
783 strlcpy(ret, s, len);
785 if (trim_string(ret, "\"", "\"")) {
786 if (strchr(ret,'"') != NULL)
787 strlcpy(ret, s, len);
790 standard_sub_basic(ret,len+100);
797 In this section all the functions that are used to access the
798 parameters from the rest of the program are defined
801 #define FN_GLOBAL_STRING(fn_name,ptr) \
802 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
803 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
804 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
805 #define FN_GLOBAL_LIST(fn_name,ptr) \
806 const char **fn_name(void) {return(*(const char ***)(ptr));}
807 #define FN_GLOBAL_BOOL(fn_name,ptr) \
808 BOOL fn_name(void) {return((BOOL)*(int *)(ptr));}
810 #define FN_GLOBAL_CHAR(fn_name,ptr) \
811 char fn_name(void) {return(*(char *)(ptr));}
813 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
814 int fn_name(void) {return(*(int *)(ptr));}
816 #define FN_LOCAL_STRING(fn_name,val) \
817 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
818 #define FN_LOCAL_CONST_STRING(fn_name,val) \
819 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
820 #define FN_LOCAL_LIST(fn_name,val) \
821 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
822 #define FN_LOCAL_BOOL(fn_name,val) \
823 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
825 #define FN_LOCAL_CHAR(fn_name,val) \
826 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
828 #define FN_LOCAL_INTEGER(fn_name,val) \
829 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
831 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, &Globals.server_role)
832 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
833 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
834 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
835 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
836 _PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
837 _PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, &Globals.kpasswd_port)
838 _PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
839 _PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
840 _PUBLIC_ FN_GLOBAL_STRING(lp_webapps_directory, &Globals.webapps_directory)
841 _PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
842 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
843 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
844 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
845 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
846 _PUBLIC_ FN_GLOBAL_STRING(lp_tls_dhpfile, &Globals.tls_dhpfile)
847 _PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
848 _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
849 _PUBLIC_ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
850 _PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, &Globals.szShareBackend)
851 _PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
852 _PUBLIC_ FN_GLOBAL_STRING(lp_secrets_url, &Globals.szSECRETS_URL)
853 _PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
854 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, &Globals.szWINS_CONFIG_URL)
855 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
856 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
857 _PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, &Globals.szWinbinddSocketDirectory)
858 _PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
859 _PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
860 _PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
861 _PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
862 _PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, &Globals.szModulesDir)
863 _PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, &Globals.szSetupDir)
864 _PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
865 _PUBLIC_ FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
866 _PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
867 _PUBLIC_ FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
868 _PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
869 _PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
870 _PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
871 _PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
872 _PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
873 _PUBLIC_ FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
874 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
875 _PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
876 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
877 _PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
878 _PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
879 _PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
880 _PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
881 _PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
883 _PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
884 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
885 _PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, &Globals.bWINSdnsProxy)
886 _PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
887 _PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
888 _PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
889 _PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
890 _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
891 _PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
892 _PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
893 _PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
894 _PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
895 _PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
896 _PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
897 _PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
898 _PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
899 _PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
900 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
901 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
902 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
903 _PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
904 _PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
905 _PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
906 _PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
907 _PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
908 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
909 _PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
910 _PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
911 _PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
912 _PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
913 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, &Globals.srv_maxprotocol)
914 _PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, &Globals.srv_minprotocol)
915 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, &Globals.cli_maxprotocol)
916 _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &Globals.cli_minprotocol)
917 _PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
918 _PUBLIC_ FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
919 _PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
920 _PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
921 _PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
922 _PUBLIC_ FN_GLOBAL_STRING(lp_jsonrpc_services_dir, &Globals.jsonrpcServicesDir)
925 _PUBLIC_ FN_LOCAL_STRING(lp_servicename, szService)
926 _PUBLIC_ FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
927 _PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath)
928 static FN_LOCAL_STRING(_lp_printername, szPrintername)
929 _PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
930 _PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
931 _PUBLIC_ FN_LOCAL_STRING(lp_comment, comment)
932 _PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype)
933 static FN_LOCAL_STRING(lp_volume, volume)
934 _PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
935 _PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
936 _PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable)
937 _PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only)
938 _PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
939 _PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
940 _PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
941 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
942 _PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
943 _PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
944 _PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system)
945 _PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
946 _PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
947 _PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
948 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
949 _PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
950 _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
951 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
952 _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
954 /* local prototypes */
956 static int map_parameter(const char *pszParmName);
957 static int getservicebyname(const char *pszServiceName,
958 service * pserviceDest);
959 static void copy_service(service * pserviceDest,
960 service * pserviceSource, int *pcopymapDest);
961 static BOOL service_ok(int iService);
962 static BOOL do_section(const char *pszSectionName, void *);
963 static void init_copymap(service * pservice);
965 /* This is a helper function for parametrical options support. */
966 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
967 /* Actual parametrical functions are quite simple */
968 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
971 struct param_opt *data;
973 if (lookup_service >= iNumServices) return NULL;
975 data = (lookup_service < 0) ?
976 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
978 asprintf(&vfskey, "%s:%s", type, option);
982 if (strcmp(data->key, vfskey) == 0) {
989 if (lookup_service >= 0) {
990 /* Try to fetch the same option but from globals */
991 /* but only if we are not already working with Globals */
992 data = Globals.param_opt;
994 if (strcmp(data->key, vfskey) == 0) {
1008 /*******************************************************************
1009 convenience routine to return int parameters.
1010 ********************************************************************/
1011 static int lp_int(const char *s)
1015 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1019 return strtol(s, NULL, 0);
1022 /*******************************************************************
1023 convenience routine to return unsigned long parameters.
1024 ********************************************************************/
1025 static int lp_ulong(const char *s)
1029 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1033 return strtoul(s, NULL, 0);
1036 /*******************************************************************
1037 convenience routine to return unsigned long parameters.
1038 ********************************************************************/
1039 static double lp_double(const char *s)
1043 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
1047 return strtod(s, NULL);
1050 /*******************************************************************
1051 convenience routine to return boolean parameters.
1052 ********************************************************************/
1053 static BOOL lp_bool(const char *s)
1058 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1062 if (!set_boolean(s, &ret)) {
1063 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1071 /* Return parametric option from a given service. Type is a part of option before ':' */
1072 /* Parametric option has following syntax: 'Type: option = value' */
1073 /* Returned value is allocated in 'lp_talloc' context */
1075 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1077 const char *value = lp_get_parametric(lookup_service, type, option);
1080 return lp_string(value);
1085 /* Return parametric option from a given service. Type is a part of option before ':' */
1086 /* Parametric option has following syntax: 'Type: option = value' */
1087 /* Returned value is allocated in 'lp_talloc' context */
1089 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1090 const char *separator)
1092 const char *value = lp_get_parametric(lookup_service, type, option);
1095 return str_list_make(talloc_autofree_context(), value, separator);
1100 /* Return parametric option from a given service. Type is a part of option before ':' */
1101 /* Parametric option has following syntax: 'Type: option = value' */
1103 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1105 const char *value = lp_get_parametric(lookup_service, type, option);
1108 return lp_int(value);
1113 /* Return parametric option from a given service. Type is a part of
1114 * option before ':'.
1115 * Parametric option has following syntax: 'Type: option = value'.
1118 int lp_parm_bytes(int lookup_service, const char *type, const char *option, int default_v)
1122 const char *value = lp_get_parametric(lookup_service, type, option);
1124 if (value && conv_str_size(value, &bval)) {
1125 if (bval <= INT_MAX) {
1133 /* Return parametric option from a given service. Type is a part of option before ':' */
1134 /* Parametric option has following syntax: 'Type: option = value' */
1136 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1138 const char *value = lp_get_parametric(lookup_service, type, option);
1141 return lp_ulong(value);
1147 double lp_parm_double(int lookup_service, const char *type, const char *option, double default_v)
1149 const char *value = lp_get_parametric(lookup_service, type, option);
1152 return lp_double(value);
1157 /* Return parametric option from a given service. Type is a part of option before ':' */
1158 /* Parametric option has following syntax: 'Type: option = value' */
1160 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1162 const char *value = lp_get_parametric(lookup_service, type, option);
1165 return lp_bool(value);
1171 /***************************************************************************
1172 Initialise a service to the defaults.
1173 ***************************************************************************/
1175 static void init_service(service * pservice)
1177 memset((char *)pservice, '\0', sizeof(service));
1178 copy_service(pservice, &sDefault, NULL);
1181 /***************************************************************************
1182 Free the dynamically allocated parts of a service struct.
1183 ***************************************************************************/
1185 static void free_service(service *pservice)
1188 struct param_opt *data, *pdata;
1192 if (pservice->szService)
1193 DEBUG(5, ("free_service: Freeing service %s\n",
1194 pservice->szService));
1196 string_free(&pservice->szService);
1197 SAFE_FREE(pservice->copymap);
1199 for (i = 0; parm_table[i].label; i++) {
1200 if ((parm_table[i].type == P_STRING ||
1201 parm_table[i].type == P_USTRING) &&
1202 parm_table[i].class == P_LOCAL) {
1203 string_free((char **)
1204 (((char *)pservice) +
1205 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1206 } else if (parm_table[i].type == P_LIST &&
1207 parm_table[i].class == P_LOCAL) {
1208 char ***listp = (char ***)(((char *)pservice) +
1209 PTR_DIFF(parm_table[i].ptr, &sDefault));
1210 talloc_free(*listp);
1215 DEBUG(5,("Freeing parametrics:\n"));
1216 data = pservice->param_opt;
1218 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1219 string_free(&data->key);
1220 string_free(&data->value);
1226 ZERO_STRUCTP(pservice);
1229 /***************************************************************************
1230 Add a new service to the services array initialising it with the given
1232 ***************************************************************************/
1234 static int add_a_service(const service *pservice, const char *name)
1238 int num_to_alloc = iNumServices + 1;
1239 struct param_opt *data, *pdata;
1241 tservice = *pservice;
1243 /* it might already exist */
1245 i = getservicebyname(name, NULL);
1247 /* Clean all parametric options for service */
1248 /* They will be added during parsing again */
1249 data = ServicePtrs[i]->param_opt;
1251 string_free(&data->key);
1252 string_free(&data->value);
1257 ServicePtrs[i]->param_opt = NULL;
1262 /* find an invalid one */
1263 for (i = 0; i < iNumServices; i++)
1264 if (!ServicePtrs[i]->valid)
1267 /* if not, then create one */
1268 if (i == iNumServices) {
1271 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1274 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1279 ServicePtrs[iNumServices] = malloc_p(service);
1281 if (!ServicePtrs[iNumServices]) {
1282 DEBUG(0,("add_a_service: out of memory!\n"));
1288 free_service(ServicePtrs[i]);
1290 ServicePtrs[i]->valid = True;
1292 init_service(ServicePtrs[i]);
1293 copy_service(ServicePtrs[i], &tservice, NULL);
1295 string_set(&ServicePtrs[i]->szService, name);
1299 /***************************************************************************
1300 Add a new home service, with the specified home directory, defaults coming
1302 ***************************************************************************/
1304 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1305 const char *user, const char *pszHomedir)
1310 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1315 if (!(*(ServicePtrs[iDefaultService]->szPath))
1316 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1317 pstrcpy(newHomedir, pszHomedir);
1319 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1320 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1323 string_set(&ServicePtrs[i]->szPath, newHomedir);
1325 if (!(*(ServicePtrs[i]->comment))) {
1327 slprintf(comment, sizeof(comment) - 1,
1328 "Home directory of %s", user);
1329 string_set(&ServicePtrs[i]->comment, comment);
1331 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1332 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1334 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1340 /***************************************************************************
1341 Add a new service, based on an old one.
1342 ***************************************************************************/
1344 int lp_add_service(const char *pszService, int iDefaultService)
1346 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1349 /***************************************************************************
1350 Add the IPC service.
1351 ***************************************************************************/
1353 static BOOL lp_add_hidden(const char *name, const char *fstype)
1356 int i = add_a_service(&sDefault, name);
1361 slprintf(comment, sizeof(comment) - 1,
1362 "%s Service (%s)", fstype, Globals.szServerString);
1364 string_set(&ServicePtrs[i]->szPath, tmpdir());
1365 string_set(&ServicePtrs[i]->comment, comment);
1366 string_set(&ServicePtrs[i]->fstype, fstype);
1367 ServicePtrs[i]->iMaxConnections = -1;
1368 ServicePtrs[i]->bAvailable = True;
1369 ServicePtrs[i]->bRead_only = True;
1370 ServicePtrs[i]->bPrint_ok = False;
1371 ServicePtrs[i]->bBrowseable = False;
1373 if (strcasecmp(fstype, "IPC") == 0) {
1374 lp_do_parameter(i, "ntvfs handler", "default");
1377 DEBUG(3, ("adding hidden service %s\n", name));
1382 /***************************************************************************
1383 Add a new printer service, with defaults coming from service iFrom.
1384 ***************************************************************************/
1386 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1388 const char *comment = "From Printcap";
1389 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1394 /* note that we do NOT default the availability flag to True - */
1395 /* we take it from the default service passed. This allows all */
1396 /* dynamic printers to be disabled by disabling the [printers] */
1397 /* entry (if/when the 'available' keyword is implemented!). */
1399 /* the printer name is set to the service name. */
1400 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1401 string_set(&ServicePtrs[i]->comment, comment);
1402 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1403 /* Printers cannot be read_only. */
1404 ServicePtrs[i]->bRead_only = False;
1405 /* Printer services must be printable. */
1406 ServicePtrs[i]->bPrint_ok = True;
1408 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1413 /***************************************************************************
1414 Map a parameter's string representation to something we can use.
1415 Returns False if the parameter string is not recognised, else TRUE.
1416 ***************************************************************************/
1418 static int map_parameter(const char *pszParmName)
1422 if (*pszParmName == '-')
1425 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1426 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1429 /* Warn only if it isn't parametric option */
1430 if (strchr(pszParmName, ':') == NULL)
1431 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1432 /* We do return 'fail' for parametric options as well because they are
1433 stored in different storage
1440 return the parameter structure for a parameter
1442 struct parm_struct *lp_parm_struct(const char *name)
1444 int parmnum = map_parameter(name);
1445 if (parmnum == -1) return NULL;
1446 return &parm_table[parmnum];
1450 return the parameter pointer for a parameter
1452 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1457 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1460 /***************************************************************************
1461 Find a service by name. Otherwise works like get_service.
1462 ***************************************************************************/
1464 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1468 for (iService = iNumServices - 1; iService >= 0; iService--)
1469 if (VALID(iService) &&
1470 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1471 if (pserviceDest != NULL)
1472 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1479 /***************************************************************************
1480 Copy a service structure to another.
1481 If pcopymapDest is NULL then copy all fields
1482 ***************************************************************************/
1484 static void copy_service(service * pserviceDest, service * pserviceSource, int *pcopymapDest)
1487 BOOL bcopyall = (pcopymapDest == NULL);
1488 struct param_opt *data, *pdata, *paramo;
1491 for (i = 0; parm_table[i].label; i++)
1492 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1493 (bcopyall || pcopymapDest[i])) {
1494 void *def_ptr = parm_table[i].ptr;
1496 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1499 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1502 switch (parm_table[i].type) {
1504 *(int *)dest_ptr = *(int *)src_ptr;
1510 *(int *)dest_ptr = *(int *)src_ptr;
1514 string_set(dest_ptr,
1519 string_set(dest_ptr,
1521 strupper(*(char **)dest_ptr);
1524 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1525 *(const char ***)src_ptr);
1533 init_copymap(pserviceDest);
1534 if (pserviceSource->copymap)
1535 memcpy((void *)pserviceDest->copymap,
1536 (void *)pserviceSource->copymap,
1537 sizeof(int) * NUMPARAMETERS);
1540 data = pserviceSource->param_opt;
1543 pdata = pserviceDest->param_opt;
1544 /* Traverse destination */
1546 /* If we already have same option, override it */
1547 if (strcmp(pdata->key, data->key) == 0) {
1548 string_free(&pdata->value);
1549 pdata->value = strdup(data->value);
1553 pdata = pdata->next;
1556 paramo = malloc_p(struct param_opt);
1559 paramo->key = strdup(data->key);
1560 paramo->value = strdup(data->value);
1561 DLIST_ADD(pserviceDest->param_opt, paramo);
1567 /***************************************************************************
1568 Check a service for consistency. Return False if the service is in any way
1569 incomplete or faulty, else True.
1570 ***************************************************************************/
1572 static BOOL service_ok(int iService)
1577 if (ServicePtrs[iService]->szService[0] == '\0') {
1578 DEBUG(0, ("The following message indicates an internal error:\n"));
1579 DEBUG(0, ("No service name in service entry.\n"));
1583 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1584 /* I can't see why you'd want a non-printable printer service... */
1585 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1586 if (!ServicePtrs[iService]->bPrint_ok) {
1587 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1588 ServicePtrs[iService]->szService));
1589 ServicePtrs[iService]->bPrint_ok = True;
1591 /* [printers] service must also be non-browsable. */
1592 if (ServicePtrs[iService]->bBrowseable)
1593 ServicePtrs[iService]->bBrowseable = False;
1596 /* If a service is flagged unavailable, log the fact at level 0. */
1597 if (!ServicePtrs[iService]->bAvailable)
1598 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1599 ServicePtrs[iService]->szService));
1604 static struct file_lists {
1605 struct file_lists *next;
1609 } *file_lists = NULL;
1611 /*******************************************************************
1612 Keep a linked list of all config files so we know when one has changed
1613 it's date and needs to be reloaded.
1614 ********************************************************************/
1616 static void add_to_file_list(const char *fname, const char *subfname)
1618 struct file_lists *f = file_lists;
1621 if (f->name && !strcmp(f->name, fname))
1627 f = malloc_p(struct file_lists);
1630 f->next = file_lists;
1631 f->name = strdup(fname);
1636 f->subfname = strdup(subfname);
1642 f->modtime = file_modtime(subfname);
1644 time_t t = file_modtime(subfname);
1650 /*******************************************************************
1651 Check if a config file has changed date.
1652 ********************************************************************/
1654 BOOL lp_file_list_changed(void)
1656 struct file_lists *f = file_lists;
1657 DEBUG(6, ("lp_file_list_changed()\n"));
1663 pstrcpy(n2, f->name);
1664 standard_sub_basic(n2,sizeof(n2));
1666 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1667 f->name, n2, ctime(&f->modtime)));
1669 mod_time = file_modtime(n2);
1671 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1673 ("file %s modified: %s\n", n2,
1675 f->modtime = mod_time;
1676 SAFE_FREE(f->subfname);
1677 f->subfname = strdup(n2);
1685 /***************************************************************************
1686 Handle the include operation.
1687 ***************************************************************************/
1689 static BOOL handle_include(const char *pszParmValue, char **ptr)
1692 pstrcpy(fname, pszParmValue);
1694 standard_sub_basic(fname,sizeof(fname));
1696 add_to_file_list(pszParmValue, fname);
1698 string_set(ptr, fname);
1700 if (file_exist(fname))
1701 return (pm_process(fname, do_section, do_parameter, NULL));
1703 DEBUG(2, ("Can't find include file %s\n", fname));
1708 /***************************************************************************
1709 Handle the interpretation of the copy parameter.
1710 ***************************************************************************/
1712 static BOOL handle_copy(const char *pszParmValue, char **ptr)
1716 service serviceTemp;
1718 string_set(ptr, pszParmValue);
1720 init_service(&serviceTemp);
1724 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1726 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
1727 if (iTemp == iServiceIndex) {
1728 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1730 copy_service(ServicePtrs[iServiceIndex],
1732 ServicePtrs[iServiceIndex]->copymap);
1736 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1740 free_service(&serviceTemp);
1744 /***************************************************************************
1745 Initialise a copymap.
1746 ***************************************************************************/
1748 static void init_copymap(service * pservice)
1751 SAFE_FREE(pservice->copymap);
1752 pservice->copymap = malloc_array_p(int, NUMPARAMETERS);
1753 if (!pservice->copymap)
1755 ("Couldn't allocate copymap!! (size %d)\n",
1756 (int)NUMPARAMETERS));
1758 for (i = 0; i < NUMPARAMETERS; i++)
1759 pservice->copymap[i] = True;
1762 #if 0 /* not used anywhere */
1763 /***************************************************************************
1764 Return the local pointer to a parameter given the service number and the
1765 pointer into the default structure.
1766 ***************************************************************************/
1768 void *lp_local_ptr(int snum, void *ptr)
1770 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
1774 /***************************************************************************
1775 Process a parametric option
1776 ***************************************************************************/
1777 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
1779 struct param_opt *paramo, *data;
1782 while (isspace((unsigned char)*pszParmName)) {
1786 name = strdup(pszParmName);
1787 if (!name) return False;
1792 data = Globals.param_opt;
1794 data = ServicePtrs[snum]->param_opt;
1797 /* Traverse destination */
1798 for (paramo=data; paramo; paramo=paramo->next) {
1799 /* If we already have the option set, override it unless
1800 it was a command line option and the new one isn't */
1801 if (strcmp(paramo->key, name) == 0) {
1802 if ((paramo->flags & FLAG_CMDLINE) &&
1803 !(flags & FLAG_CMDLINE)) {
1807 free(paramo->value);
1808 paramo->value = strdup(pszParmValue);
1809 paramo->flags = flags;
1815 paramo = malloc_p(struct param_opt);
1818 paramo->key = strdup(name);
1819 paramo->value = strdup(pszParmValue);
1820 paramo->flags = flags;
1822 DLIST_ADD(Globals.param_opt, paramo);
1824 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
1832 /***************************************************************************
1833 Process a parameter for a particular service number. If snum < 0
1834 then assume we are in the globals.
1835 ***************************************************************************/
1836 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
1839 void *parm_ptr = NULL; /* where we are going to store the result */
1840 void *def_ptr = NULL;
1842 parmnum = map_parameter(pszParmName);
1845 if (strchr(pszParmName, ':')) {
1846 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
1848 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1852 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
1853 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1857 /* if the flag has been set on the command line, then don't allow override,
1858 but don't report an error */
1859 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
1863 def_ptr = parm_table[parmnum].ptr;
1865 /* we might point at a service, the default service or a global */
1869 if (parm_table[parmnum].class == P_GLOBAL) {
1871 ("Global parameter %s found in service section!\n",
1876 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
1881 if (!ServicePtrs[snum]->copymap)
1882 init_copymap(ServicePtrs[snum]);
1884 /* this handles the aliases - set the copymap for other entries with
1885 the same data pointer */
1886 for (i = 0; parm_table[i].label; i++)
1887 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1888 ServicePtrs[snum]->copymap[i] = False;
1891 /* if it is a special case then go ahead */
1892 if (parm_table[parmnum].special) {
1893 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
1897 /* now switch on the type of variable it is */
1898 switch (parm_table[parmnum].type)
1902 if (!set_boolean(pszParmValue, &b)) {
1903 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
1906 *(int *)parm_ptr = b;
1911 *(int *)parm_ptr = atoi(pszParmValue);
1915 *(int *)parm_ptr = strtol(pszParmValue, NULL, 8);
1921 if (conv_str_size(pszParmValue, &val)) {
1922 if (val <= INT_MAX) {
1923 *(int *)parm_ptr = (int)val;
1928 DEBUG(0,("lp_do_parameter(%s): value is not "
1929 "a valid size specifier!\n", pszParmValue));
1934 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
1935 pszParmValue, NULL);
1939 string_set(parm_ptr, pszParmValue);
1943 string_set(parm_ptr, pszParmValue);
1944 strupper(*(char **)parm_ptr);
1948 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
1951 parm_table[parmnum].enum_list[i].name)) {
1953 parm_table[parmnum].
1958 if (!parm_table[parmnum].enum_list[i].name) {
1959 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1960 pszParmValue, pszParmName));
1968 if (parm_table[parmnum].flags & FLAG_DEFAULT) {
1969 parm_table[parmnum].flags &= ~FLAG_DEFAULT;
1970 /* we have to also unset FLAG_DEFAULT on aliases */
1971 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
1972 parm_table[i].flags &= ~FLAG_DEFAULT;
1974 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
1975 parm_table[i].flags &= ~FLAG_DEFAULT;
1982 /***************************************************************************
1983 Process a parameter.
1984 ***************************************************************************/
1986 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata)
1988 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1989 pszParmName, pszParmValue));
1993 variable argument do parameter
1995 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
1997 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2004 s = talloc_vasprintf(NULL, fmt, ap);
2006 ret = do_parameter(pszParmName, s, NULL);
2013 set a parameter from the commandline - this is called from command line parameter
2014 parsing code. It sets the parameter then marks the parameter as unable to be modified
2015 by smb.conf processing
2017 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2019 int parmnum = map_parameter(pszParmName);
2022 while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
2025 if (parmnum < 0 && strchr(pszParmName, ':')) {
2026 /* set a parametric option */
2027 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2031 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2035 /* reset the CMDLINE flag in case this has been called before */
2036 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2038 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2042 parm_table[parmnum].flags |= FLAG_CMDLINE;
2044 /* we have to also set FLAG_CMDLINE on aliases */
2045 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2046 parm_table[i].flags |= FLAG_CMDLINE;
2048 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2049 parm_table[i].flags |= FLAG_CMDLINE;
2056 set a option from the commandline in 'a=b' format. Use to support --option
2058 BOOL lp_set_option(const char *option)
2076 ret = lp_set_cmdline(s, p+1);
2082 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2084 /***************************************************************************
2085 Print a parameter of the specified type.
2086 ***************************************************************************/
2088 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2094 for (i = 0; p->enum_list[i].name; i++) {
2095 if (*(int *)ptr == p->enum_list[i].value) {
2097 p->enum_list[i].name);
2104 fprintf(f, "%s", BOOLSTR((BOOL)*(int *)ptr));
2109 fprintf(f, "%d", *(int *)ptr);
2113 fprintf(f, "0%o", *(int *)ptr);
2117 if ((char ***)ptr && *(char ***)ptr) {
2118 char **list = *(char ***)ptr;
2120 for (; *list; list++)
2121 fprintf(f, "%s%s", *list,
2122 ((*(list+1))?", ":""));
2128 if (*(char **)ptr) {
2129 fprintf(f, "%s", *(char **)ptr);
2137 /***************************************************************************
2138 Check if two parameters are equal.
2139 ***************************************************************************/
2141 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2145 return (*((int *)ptr1) == *((int *)ptr2));
2151 return (*((int *)ptr1) == *((int *)ptr2));
2154 return str_list_equal((const char **)(*(char ***)ptr1),
2155 (const char **)(*(char ***)ptr2));
2160 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2165 return (p1 == p2 || strequal(p1, p2));
2173 /***************************************************************************
2174 Process a new section (service). At this stage all sections are services.
2175 Later we'll have special sections that permit server parameters to be set.
2176 Returns True on success, False on failure.
2177 ***************************************************************************/
2179 static BOOL do_section(const char *pszSectionName, void *userdata)
2182 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2183 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2186 /* if we've just struck a global section, note the fact. */
2187 bInGlobalSection = isglobal;
2189 /* check for multiple global sections */
2190 if (bInGlobalSection) {
2191 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2195 /* if we have a current service, tidy it up before moving on */
2198 if (iServiceIndex >= 0)
2199 bRetval = service_ok(iServiceIndex);
2201 /* if all is still well, move to the next record in the services array */
2203 /* We put this here to avoid an odd message order if messages are */
2204 /* issued by the post-processing of a previous section. */
2205 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2207 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2209 DEBUG(0, ("Failed to add a new service\n"));
2218 /***************************************************************************
2219 Determine if a partcular base parameter is currentl set to the default value.
2220 ***************************************************************************/
2222 static BOOL is_default(int i)
2224 if (!defaults_saved)
2226 switch (parm_table[i].type) {
2228 return str_list_equal((const char **)parm_table[i].def.lvalue,
2229 (const char **)(*(char ***)parm_table[i].ptr));
2232 return strequal(parm_table[i].def.svalue,
2233 *(char **)parm_table[i].ptr);
2235 return parm_table[i].def.bvalue ==
2236 *(int *)parm_table[i].ptr;
2241 return parm_table[i].def.ivalue ==
2242 *(int *)parm_table[i].ptr;
2249 /***************************************************************************
2250 Display the contents of the global structure.
2251 ***************************************************************************/
2253 static void dump_globals(FILE *f, BOOL show_defaults)
2256 struct param_opt *data;
2258 fprintf(f, "# Global parameters\n[global]\n");
2260 for (i = 0; parm_table[i].label; i++)
2261 if (parm_table[i].class == P_GLOBAL &&
2262 parm_table[i].ptr &&
2263 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2264 if (!show_defaults && (parm_table[i].flags & FLAG_DEFAULT))
2266 fprintf(f, "\t%s = ", parm_table[i].label);
2267 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2270 if (Globals.param_opt != NULL) {
2271 data = Globals.param_opt;
2273 fprintf(f, "\t%s = %s\n", data->key, data->value);
2280 /***************************************************************************
2281 Display the contents of a single services record.
2282 ***************************************************************************/
2284 static void dump_a_service(service * pService, FILE * f)
2287 struct param_opt *data;
2289 if (pService != &sDefault)
2290 fprintf(f, "\n[%s]\n", pService->szService);
2292 for (i = 0; parm_table[i].label; i++)
2293 if (parm_table[i].class == P_LOCAL &&
2294 parm_table[i].ptr &&
2295 (*parm_table[i].label != '-') &&
2296 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2297 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2299 if (pService == &sDefault) {
2300 if (defaults_saved && is_default(i))
2303 if (equal_parameter(parm_table[i].type,
2304 ((char *)pService) +
2306 ((char *)&sDefault) +
2311 fprintf(f, "\t%s = ", parm_table[i].label);
2312 print_parameter(&parm_table[i],
2313 ((char *)pService) + pdiff, f);
2316 if (pService->param_opt != NULL) {
2317 data = pService->param_opt;
2319 fprintf(f, "\t%s = %s\n", data->key, data->value);
2325 BOOL lp_dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
2327 service * pService = ServicePtrs[snum];
2328 struct parm_struct *parm;
2331 parm = lp_parm_struct(parm_name);
2339 ptr = ((char *)pService) +
2340 PTR_DIFF(parm->ptr, &sDefault);
2342 print_parameter(parm,
2348 /***************************************************************************
2349 Return info about the next service in a service. snum==-1 gives the globals.
2350 Return NULL when out of parameters.
2351 ***************************************************************************/
2353 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2356 /* do the globals */
2357 for (; parm_table[*i].label; (*i)++) {
2358 if (parm_table[*i].class == P_SEPARATOR)
2359 return &parm_table[(*i)++];
2361 if (!parm_table[*i].ptr
2362 || (*parm_table[*i].label == '-'))
2366 && (parm_table[*i].ptr ==
2367 parm_table[(*i) - 1].ptr))
2370 return &parm_table[(*i)++];
2373 service *pService = ServicePtrs[snum];
2375 for (; parm_table[*i].label; (*i)++) {
2376 if (parm_table[*i].class == P_SEPARATOR)
2377 return &parm_table[(*i)++];
2379 if (parm_table[*i].class == P_LOCAL &&
2380 parm_table[*i].ptr &&
2381 (*parm_table[*i].label != '-') &&
2383 (parm_table[*i].ptr !=
2384 parm_table[(*i) - 1].ptr)))
2387 PTR_DIFF(parm_table[*i].ptr,
2390 if (allparameters ||
2391 !equal_parameter(parm_table[*i].type,
2392 ((char *)pService) +
2394 ((char *)&sDefault) +
2397 return &parm_table[(*i)++];
2407 /***************************************************************************
2408 Return TRUE if the passed service number is within range.
2409 ***************************************************************************/
2411 BOOL lp_snum_ok(int iService)
2413 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2416 /***************************************************************************
2417 Auto-load some home services.
2418 ***************************************************************************/
2420 static void lp_add_auto_services(const char *str)
2425 /***************************************************************************
2426 Have we loaded a services file yet?
2427 ***************************************************************************/
2429 BOOL lp_loaded(void)
2434 /***************************************************************************
2435 Unload unused services.
2436 ***************************************************************************/
2438 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2441 for (i = 0; i < iNumServices; i++) {
2445 if (!snumused || !snumused(smb, i)) {
2446 ServicePtrs[i]->valid = False;
2447 free_service(ServicePtrs[i]);
2452 /***************************************************************************
2454 ***************************************************************************/
2456 void lp_killservice(int iServiceIn)
2458 if (VALID(iServiceIn)) {
2459 ServicePtrs[iServiceIn]->valid = False;
2460 free_service(ServicePtrs[iServiceIn]);
2464 /***************************************************************************
2465 Load the services array from the services file. Return True on success,
2467 ***************************************************************************/
2473 struct param_opt *data;
2477 bInGlobalSection = True;
2479 if (Globals.param_opt != NULL) {
2480 struct param_opt *next;
2481 for (data=Globals.param_opt; data; data=next) {
2483 if (data->flags & FLAG_CMDLINE) continue;
2486 DLIST_REMOVE(Globals.param_opt, data);
2493 pstrcpy(n2, lp_configfile());
2494 standard_sub_basic(n2,sizeof(n2));
2495 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2));
2497 add_to_file_list(lp_configfile(), n2);
2499 /* We get sections first, so have to start 'behind' to make up */
2501 bRetval = pm_process(n2, do_section, do_parameter, NULL);
2503 /* finish up the last section */
2504 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2506 if (iServiceIndex >= 0)
2507 bRetval = service_ok(iServiceIndex);
2509 lp_add_auto_services(lp_auto_services());
2511 lp_add_hidden("IPC$", "IPC");
2512 lp_add_hidden("ADMIN$", "DISK");
2516 if (!Globals.szWINSservers && Globals.bWINSsupport) {
2517 lp_do_parameter(-1, "wins server", "127.0.0.1");
2525 /***************************************************************************
2526 Reset the max number of services.
2527 ***************************************************************************/
2529 void lp_resetnumservices(void)
2534 /***************************************************************************
2535 Return the max number of services.
2536 ***************************************************************************/
2538 int lp_numservices(void)
2540 return (iNumServices);
2543 /***************************************************************************
2544 Display the contents of the services array in human-readable form.
2545 ***************************************************************************/
2547 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
2552 defaults_saved = False;
2554 dump_globals(f, show_defaults);
2556 dump_a_service(&sDefault, f);
2558 for (iService = 0; iService < maxtoprint; iService++)
2559 lp_dump_one(f, show_defaults, iService);
2562 /***************************************************************************
2563 Display the contents of one service in human-readable form.
2564 ***************************************************************************/
2566 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
2569 if (ServicePtrs[snum]->szService[0] == '\0')
2571 dump_a_service(ServicePtrs[snum], f);
2575 /***************************************************************************
2576 Return the number of the service with the given name, or -1 if it doesn't
2577 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2578 getservicebyname()! This works ONLY if all services have been loaded, and
2579 does not copy the found service.
2580 ***************************************************************************/
2582 int lp_servicenumber(const char *pszServiceName)
2585 fstring serviceName;
2588 for (iService = iNumServices - 1; iService >= 0; iService--) {
2589 if (VALID(iService) && ServicePtrs[iService]->szService) {
2591 * The substitution here is used to support %U is
2594 fstrcpy(serviceName, ServicePtrs[iService]->szService);
2595 standard_sub_basic(serviceName,sizeof(serviceName));
2596 if (strequal(serviceName, pszServiceName))
2602 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
2607 int lp_find_valid_service(const char *pszServiceName)
2611 iService = lp_servicenumber(pszServiceName);
2613 if (iService >= 0 && !lp_snum_ok(iService)) {
2614 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService, pszServiceName));
2618 if (iService == -1) {
2619 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName));
2625 /*******************************************************************
2626 A useful volume label function.
2627 ********************************************************************/
2628 const char *volume_label(int snum)
2630 const char *ret = lp_volume(snum);
2632 return lp_servicename(snum);
2637 /***********************************************************
2638 If we are PDC then prefer us as DMB
2639 ************************************************************/
2641 BOOL lp_domain_logons(void)
2643 return (lp_server_role() == ROLE_DOMAIN_CONTROLLER);
2646 /*******************************************************************
2648 ********************************************************************/
2650 void lp_remove_service(int snum)
2652 ServicePtrs[snum]->valid = False;
2655 /*******************************************************************
2657 ********************************************************************/
2659 void lp_copy_service(int snum, const char *new_name)
2661 const char *oldname = lp_servicename(snum);
2662 do_section(new_name, NULL);
2664 snum = lp_servicenumber(new_name);
2666 lp_do_parameter(snum, "copy", oldname);
2670 const char *lp_printername(int snum)
2672 const char *ret = _lp_printername(snum);
2673 if (ret == NULL || (ret != NULL && *ret == '\0'))
2674 ret = lp_const_servicename(snum);
2680 /*******************************************************************
2681 Return the max print jobs per queue.
2682 ********************************************************************/
2684 int lp_maxprintjobs(int snum)
2686 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
2687 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2688 maxjobs = PRINT_MAX_JOBID - 1;