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
;
112 char *szWINS_CONFIG_URL
;
116 char *jsonrpcServicesDir
;
117 char **szPasswordServers
;
118 char *szSocketOptions
;
120 char **szWINSservers
;
122 char *szSocketAddress
;
123 char *szAnnounceVersion
; /* This is initialised in init_globals */
126 char **szNetbiosAliases
;
127 char *szNetbiosScope
;
128 char *szDomainOtherSIDs
;
129 char **szNameResolveOrder
;
130 char **dcerpc_ep_servers
;
131 char **server_services
;
132 char *ntptr_providor
;
133 char *szWinbindSeparator
;
134 char *szWinbinddSocketDirectory
;
135 int bWinbindSealedPipes
;
136 char *webapps_directory
;
152 int paranoid_server_security
;
155 int announce_as
; /* This is initialised in init_globals */
162 char *socket_options
;
167 int bPreferredMaster
;
168 int bEncryptPasswords
;
170 int bObeyPamRestrictions
;
175 int bBindInterfacesOnly
;
177 int bNTStatusSupport
;
183 int bClientPlaintextAuth
;
184 int bClientLanManAuth
;
185 int bClientNTLMv2Auth
;
186 int client_use_spnego_principal
;
192 struct param_opt
*param_opt
;
196 static global Globals
;
199 * This structure describes a single service.
214 char **ntvfs_handler
;
230 struct param_opt
*param_opt
;
232 char dummy
[3]; /* for alignment */
237 /* This is a default service used to prime a services structure */
238 static service sDefault
= {
240 NULL
, /* szService */
243 NULL
, /* szInclude */
244 NULL
, /* szPrintername */
245 NULL
, /* szHostsallow */
246 NULL
, /* szHostsdeny */
250 NULL
, /* ntvfs_handler */
251 1000, /* iMaxPrintJobs */
252 0, /* iMaxConnections */
254 True
, /* bAvailable */
255 True
, /* bBrowseable */
256 True
, /* bRead_only */
257 False
, /* bPrint_ok */
258 False
, /* bMap_system */
259 False
, /* bMap_hidden */
260 True
, /* bMap_archive */
261 True
, /* bStrictLocking */
263 False
, /* bMSDfsRoot */
264 False
, /* bStrictSync */
265 False
, /* bCIFileSystem */
266 NULL
, /* Parametric options */
271 /* local variables */
272 static service
**ServicePtrs
= NULL
;
273 static int iNumServices
= 0;
274 static int iServiceIndex
= 0;
275 static BOOL bInGlobalSection
= True
;
277 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
279 /* prototypes for the special type handlers */
280 static BOOL
handle_include(const char *pszParmValue
, char **ptr
);
281 static BOOL
handle_copy(const char *pszParmValue
, char **ptr
);
283 static const struct enum_list enum_protocol
[] = {
284 {PROTOCOL_SMB2
, "SMB2"},
285 {PROTOCOL_NT1
, "NT1"},
286 {PROTOCOL_LANMAN2
, "LANMAN2"},
287 {PROTOCOL_LANMAN1
, "LANMAN1"},
288 {PROTOCOL_CORE
, "CORE"},
289 {PROTOCOL_COREPLUS
, "COREPLUS"},
290 {PROTOCOL_COREPLUS
, "CORE+"},
294 static const struct enum_list enum_security
[] = {
295 {SEC_SHARE
, "SHARE"},
300 static const struct enum_list enum_announce_as
[] = {
301 {ANNOUNCE_AS_NT_SERVER
, "NT"},
302 {ANNOUNCE_AS_NT_SERVER
, "NT Server"},
303 {ANNOUNCE_AS_NT_WORKSTATION
, "NT Workstation"},
304 {ANNOUNCE_AS_WIN95
, "win95"},
305 {ANNOUNCE_AS_WFW
, "WfW"},
309 static const struct enum_list enum_bool_auto
[] = {
320 /* Client-side offline caching policy types */
321 #define CSC_POLICY_MANUAL 0
322 #define CSC_POLICY_DOCUMENTS 1
323 #define CSC_POLICY_PROGRAMS 2
324 #define CSC_POLICY_DISABLE 3
326 static const struct enum_list enum_csc_policy
[] = {
327 {CSC_POLICY_MANUAL
, "manual"},
328 {CSC_POLICY_DOCUMENTS
, "documents"},
329 {CSC_POLICY_PROGRAMS
, "programs"},
330 {CSC_POLICY_DISABLE
, "disable"},
334 /* SMB signing types. */
335 static const struct enum_list enum_smb_signing_vals
[] = {
336 {SMB_SIGNING_OFF
, "No"},
337 {SMB_SIGNING_OFF
, "False"},
338 {SMB_SIGNING_OFF
, "0"},
339 {SMB_SIGNING_OFF
, "Off"},
340 {SMB_SIGNING_OFF
, "disabled"},
341 {SMB_SIGNING_SUPPORTED
, "Yes"},
342 {SMB_SIGNING_SUPPORTED
, "True"},
343 {SMB_SIGNING_SUPPORTED
, "1"},
344 {SMB_SIGNING_SUPPORTED
, "On"},
345 {SMB_SIGNING_SUPPORTED
, "enabled"},
346 {SMB_SIGNING_REQUIRED
, "required"},
347 {SMB_SIGNING_REQUIRED
, "mandatory"},
348 {SMB_SIGNING_REQUIRED
, "force"},
349 {SMB_SIGNING_REQUIRED
, "forced"},
350 {SMB_SIGNING_REQUIRED
, "enforced"},
351 {SMB_SIGNING_AUTO
, "auto"},
355 static const struct enum_list enum_server_role
[] = {
356 {ROLE_STANDALONE
, "standalone"},
357 {ROLE_DOMAIN_MEMBER
, "member server"},
358 {ROLE_DOMAIN_CONTROLLER
, "domain controller"},
363 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
365 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
366 * is implied in current control logic. This may change at some later time. A
367 * flag value of 0 means - show as development option only.
369 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
370 * screen in SWAT. This is used to exclude parameters as well as to squash all
371 * parameters that have been duplicated by pseudonyms.
373 static struct parm_struct parm_table
[] = {
374 {"Base Options", P_SEP
, P_SEPARATOR
},
376 {"server role", P_ENUM
, P_GLOBAL
, &Globals
.server_role
, NULL
, enum_server_role
, FLAG_BASIC
},
378 {"dos charset", P_STRING
, P_GLOBAL
, &Globals
.dos_charset
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
379 {"unix charset", P_STRING
, P_GLOBAL
, &Globals
.unix_charset
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
380 {"ncalrpc dir", P_STRING
, P_GLOBAL
, &Globals
.ncalrpc_dir
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
381 {"display charset", P_STRING
, P_GLOBAL
, &Globals
.display_charset
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
382 {"comment", P_STRING
, P_LOCAL
, &sDefault
.comment
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
| FLAG_DEVELOPER
},
383 {"path", P_STRING
, P_LOCAL
, &sDefault
.szPath
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
| FLAG_DEVELOPER
},
384 {"directory", P_STRING
, P_LOCAL
, &sDefault
.szPath
, NULL
, NULL
, FLAG_HIDE
},
385 {"workgroup", P_USTRING
, P_GLOBAL
, &Globals
.szWorkgroup
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
386 {"realm", P_STRING
, P_GLOBAL
, &Globals
.szRealm
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
387 {"netbios name", P_USTRING
, P_GLOBAL
, &Globals
.szNetbiosName
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
388 {"netbios aliases", P_LIST
, P_GLOBAL
, &Globals
.szNetbiosAliases
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
389 {"netbios scope", P_USTRING
, P_GLOBAL
, &Globals
.szNetbiosScope
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
390 {"server string", P_STRING
, P_GLOBAL
, &Globals
.szServerString
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_DEVELOPER
},
391 {"interfaces", P_LIST
, P_GLOBAL
, &Globals
.szInterfaces
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
392 {"bind interfaces only", P_BOOL
, P_GLOBAL
, &Globals
.bBindInterfacesOnly
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
393 {"ntvfs handler", P_LIST
, P_LOCAL
, &sDefault
.ntvfs_handler
, NULL
, NULL
, FLAG_ADVANCED
},
394 {"ntptr providor", P_STRING
, P_GLOBAL
, &Globals
.ntptr_providor
, NULL
, NULL
, FLAG_ADVANCED
},
395 {"dcerpc endpoint servers", P_LIST
, P_GLOBAL
, &Globals
.dcerpc_ep_servers
, NULL
, NULL
, FLAG_ADVANCED
},
396 {"server services", P_LIST
, P_GLOBAL
, &Globals
.server_services
, NULL
, NULL
, FLAG_ADVANCED
},
398 {"Security Options", P_SEP
, P_SEPARATOR
},
400 {"security", P_ENUM
, P_GLOBAL
, &Globals
.security
, NULL
, enum_security
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
401 {"auth methods", P_LIST
, P_GLOBAL
, &Globals
.AuthMethods
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
402 {"encrypt passwords", P_BOOL
, P_GLOBAL
, &Globals
.bEncryptPasswords
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
403 {"null passwords", P_BOOL
, P_GLOBAL
, &Globals
.bNullPasswords
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
404 {"obey pam restrictions", P_BOOL
, P_GLOBAL
, &Globals
.bObeyPamRestrictions
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
405 {"password server", P_LIST
, P_GLOBAL
, &Globals
.szPasswordServers
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
406 {"sam database", P_STRING
, P_GLOBAL
, &Globals
.szSAM_URL
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
407 {"secrets database", P_STRING
, P_GLOBAL
, &Globals
.szSECRETS_URL
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
408 {"spoolss database", P_STRING
, P_GLOBAL
, &Globals
.szSPOOLSS_URL
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
409 {"wins config database", P_STRING
, P_GLOBAL
, &Globals
.szWINS_CONFIG_URL
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
410 {"wins database", P_STRING
, P_GLOBAL
, &Globals
.szWINS_URL
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
411 {"private dir", P_STRING
, P_GLOBAL
, &Globals
.szPrivateDir
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
412 {"passwd chat", P_STRING
, P_GLOBAL
, &Globals
.szPasswdChat
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
413 {"password level", P_INTEGER
, P_GLOBAL
, &Globals
.pwordlevel
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
414 {"lanman auth", P_BOOL
, P_GLOBAL
, &Globals
.bLanmanAuth
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
415 {"ntlm auth", P_BOOL
, P_GLOBAL
, &Globals
.bNTLMAuth
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
416 {"client NTLMv2 auth", P_BOOL
, P_GLOBAL
, &Globals
.bClientNTLMv2Auth
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
417 {"client lanman auth", P_BOOL
, P_GLOBAL
, &Globals
.bClientLanManAuth
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
418 {"client plaintext auth", P_BOOL
, P_GLOBAL
, &Globals
.bClientPlaintextAuth
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
419 {"client use spnego principal", P_BOOL
, P_GLOBAL
, &Globals
.client_use_spnego_principal
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
421 {"read only", P_BOOL
, P_LOCAL
, &sDefault
.bRead_only
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
},
423 {"hosts allow", P_LIST
, P_LOCAL
, &sDefault
.szHostsallow
, NULL
, NULL
, FLAG_GLOBAL
| FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
| FLAG_DEVELOPER
},
424 {"hosts deny", P_LIST
, P_LOCAL
, &sDefault
.szHostsdeny
, NULL
, NULL
, FLAG_GLOBAL
| FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
| FLAG_DEVELOPER
},
426 {"Logging Options", P_SEP
, P_SEPARATOR
},
428 {"log level", P_INTEGER
, P_GLOBAL
, &DEBUGLEVEL
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
429 {"debuglevel", P_INTEGER
, P_GLOBAL
, &DEBUGLEVEL
, NULL
, NULL
, FLAG_HIDE
},
430 {"log file", P_STRING
, P_GLOBAL
, &logfile
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
432 {"Protocol Options", P_SEP
, P_SEPARATOR
},
434 {"smb ports", P_LIST
, P_GLOBAL
, &Globals
.smb_ports
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
435 {"nbt port", P_INTEGER
, P_GLOBAL
, &Globals
.nbt_port
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
436 {"dgram port", P_INTEGER
, P_GLOBAL
, &Globals
.dgram_port
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
437 {"cldap port", P_INTEGER
, P_GLOBAL
, &Globals
.cldap_port
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
438 {"krb5 port", P_INTEGER
, P_GLOBAL
, &Globals
.krb5_port
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
439 {"kpasswd port", P_INTEGER
, P_GLOBAL
, &Globals
.kpasswd_port
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
440 {"web port", P_INTEGER
, P_GLOBAL
, &Globals
.web_port
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
441 {"tls enabled", P_BOOL
, P_GLOBAL
, &Globals
.tls_enabled
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
442 {"tls keyfile", P_STRING
, P_GLOBAL
, &Globals
.tls_keyfile
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
443 {"tls certfile", P_STRING
, P_GLOBAL
, &Globals
.tls_certfile
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
444 {"tls cafile", P_STRING
, P_GLOBAL
, &Globals
.tls_cafile
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
445 {"tls crlfile", P_STRING
, P_GLOBAL
, &Globals
.tls_crlfile
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
446 {"tls dh params file", P_STRING
, P_GLOBAL
, &Globals
.tls_dhpfile
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
447 {"web application directory", P_STRING
, P_GLOBAL
, &Globals
.webapps_directory
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
448 {"large readwrite", P_BOOL
, P_GLOBAL
, &Globals
.bLargeReadwrite
, NULL
, NULL
, FLAG_DEVELOPER
},
449 {"server max protocol", P_ENUM
, P_GLOBAL
, &Globals
.srv_maxprotocol
, NULL
, enum_protocol
, FLAG_DEVELOPER
},
450 {"server min protocol", P_ENUM
, P_GLOBAL
, &Globals
.srv_minprotocol
, NULL
, enum_protocol
, FLAG_DEVELOPER
},
451 {"client max protocol", P_ENUM
, P_GLOBAL
, &Globals
.cli_maxprotocol
, NULL
, enum_protocol
, FLAG_DEVELOPER
},
452 {"client min protocol", P_ENUM
, P_GLOBAL
, &Globals
.cli_minprotocol
, NULL
, enum_protocol
, FLAG_DEVELOPER
},
453 {"unicode", P_BOOL
, P_GLOBAL
, &Globals
.bUnicode
, NULL
, NULL
, FLAG_DEVELOPER
},
454 {"read raw", P_BOOL
, P_GLOBAL
, &Globals
.bReadRaw
, NULL
, NULL
, FLAG_DEVELOPER
},
455 {"write raw", P_BOOL
, P_GLOBAL
, &Globals
.bWriteRaw
, NULL
, NULL
, FLAG_DEVELOPER
},
456 {"disable netbios", P_BOOL
, P_GLOBAL
, &Globals
.bDisableNetbios
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
458 {"nt status support", P_BOOL
, P_GLOBAL
, &Globals
.bNTStatusSupport
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
460 {"announce version", P_STRING
, P_GLOBAL
, &Globals
.szAnnounceVersion
, NULL
, NULL
, FLAG_DEVELOPER
},
461 {"announce as", P_ENUM
, P_GLOBAL
, &Globals
.announce_as
, NULL
, enum_announce_as
, FLAG_DEVELOPER
},
462 {"max mux", P_INTEGER
, P_GLOBAL
, &Globals
.max_mux
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
463 {"max xmit", P_BYTES
, P_GLOBAL
, &Globals
.max_xmit
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
465 {"name resolve order", P_LIST
, P_GLOBAL
, &Globals
.szNameResolveOrder
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
466 {"max wins ttl", P_INTEGER
, P_GLOBAL
, &Globals
.max_wins_ttl
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
467 {"min wins ttl", P_INTEGER
, P_GLOBAL
, &Globals
.min_wins_ttl
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
468 {"time server", P_BOOL
, P_GLOBAL
, &Globals
.bTimeServer
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
469 {"unix extensions", P_BOOL
, P_GLOBAL
, &Globals
.bUnixExtensions
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
470 {"use spnego", P_BOOL
, P_GLOBAL
, &Globals
.bUseSpnego
, NULL
, NULL
, FLAG_DEVELOPER
},
471 {"server signing", P_ENUM
, P_GLOBAL
, &Globals
.server_signing
, NULL
, enum_smb_signing_vals
, FLAG_ADVANCED
},
472 {"client signing", P_ENUM
, P_GLOBAL
, &Globals
.client_signing
, NULL
, enum_smb_signing_vals
, FLAG_ADVANCED
},
473 {"rpc big endian", P_BOOL
, P_GLOBAL
, &Globals
.bRpcBigEndian
, NULL
, NULL
, FLAG_DEVELOPER
},
475 {"Tuning Options", P_SEP
, P_SEPARATOR
},
477 {"max connections", P_INTEGER
, P_LOCAL
, &sDefault
.iMaxConnections
, NULL
, NULL
, FLAG_SHARE
},
478 {"paranoid server security", P_BOOL
, P_GLOBAL
, &Globals
.paranoid_server_security
, NULL
, NULL
, FLAG_DEVELOPER
},
479 {"socket options", P_STRING
, P_GLOBAL
, &Globals
.socket_options
, NULL
, NULL
, FLAG_DEVELOPER
},
481 {"strict sync", P_BOOL
, P_LOCAL
, &sDefault
.bStrictSync
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_SHARE
},
482 {"case insensitive filesystem", P_BOOL
, P_LOCAL
, &sDefault
.bCIFileSystem
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_SHARE
},
484 {"Printing Options", P_SEP
, P_SEPARATOR
},
486 {"max print jobs", P_INTEGER
, P_LOCAL
, &sDefault
.iMaxPrintJobs
, NULL
, NULL
, FLAG_PRINT
},
487 {"printable", P_BOOL
, P_LOCAL
, &sDefault
.bPrint_ok
, NULL
, NULL
, FLAG_PRINT
},
488 {"print ok", P_BOOL
, P_LOCAL
, &sDefault
.bPrint_ok
, NULL
, NULL
, FLAG_HIDE
},
490 {"printer name", P_STRING
, P_LOCAL
, &sDefault
.szPrintername
, NULL
, NULL
, FLAG_PRINT
},
491 {"printer", P_STRING
, P_LOCAL
, &sDefault
.szPrintername
, NULL
, NULL
, FLAG_HIDE
},
493 {"Filename Handling", P_SEP
, P_SEPARATOR
},
495 {"map system", P_BOOL
, P_LOCAL
, &sDefault
.bMap_system
, NULL
, NULL
, FLAG_SHARE
| FLAG_GLOBAL
},
496 {"map hidden", P_BOOL
, P_LOCAL
, &sDefault
.bMap_hidden
, NULL
, NULL
, FLAG_SHARE
| FLAG_GLOBAL
},
497 {"map archive", P_BOOL
, P_LOCAL
, &sDefault
.bMap_archive
, NULL
, NULL
, FLAG_SHARE
| FLAG_GLOBAL
},
499 {"Domain Options", P_SEP
, P_SEPARATOR
},
501 {"Logon Options", P_SEP
, P_SEPARATOR
},
504 {"Browse Options", P_SEP
, P_SEPARATOR
},
506 {"preferred master", P_ENUM
, P_GLOBAL
, &Globals
.bPreferredMaster
, NULL
, enum_bool_auto
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_DEVELOPER
},
507 {"prefered master", P_ENUM
, P_GLOBAL
, &Globals
.bPreferredMaster
, NULL
, enum_bool_auto
, FLAG_HIDE
},
508 {"local master", P_BOOL
, P_GLOBAL
, &Globals
.bLocalMaster
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_DEVELOPER
},
509 {"browseable", P_BOOL
, P_LOCAL
, &sDefault
.bBrowseable
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
| FLAG_DEVELOPER
},
510 {"browsable", P_BOOL
, P_LOCAL
, &sDefault
.bBrowseable
, NULL
, NULL
, FLAG_HIDE
},
512 {"WINS Options", P_SEP
, P_SEPARATOR
},
514 {"wins server", P_LIST
, P_GLOBAL
, &Globals
.szWINSservers
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
515 {"wins support", P_BOOL
, P_GLOBAL
, &Globals
.bWINSsupport
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
516 {"dns proxy", P_BOOL
, P_GLOBAL
, &Globals
.bWINSdnsProxy
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_WIZARD
| FLAG_DEVELOPER
},
517 {"wins hook", P_STRING
, P_GLOBAL
, &Globals
.szWINSHook
, NULL
, NULL
, FLAG_ADVANCED
},
519 {"Locking Options", P_SEP
, P_SEPARATOR
},
521 {"csc policy", P_ENUM
, P_LOCAL
, &sDefault
.iCSCPolicy
, NULL
, enum_csc_policy
, FLAG_SHARE
| FLAG_GLOBAL
},
523 {"strict locking", P_BOOL
, P_LOCAL
, &sDefault
.bStrictLocking
, NULL
, NULL
, FLAG_SHARE
| FLAG_GLOBAL
},
525 {"Miscellaneous Options", P_SEP
, P_SEPARATOR
},
527 {"config file", P_STRING
, P_GLOBAL
, &Globals
.szConfigFile
, NULL
, NULL
, FLAG_HIDE
},
528 {"share backend", P_STRING
, P_GLOBAL
, &Globals
.szShareBackend
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
529 {"preload", P_STRING
, P_GLOBAL
, &Globals
.szAutoServices
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
530 {"auto services", P_STRING
, P_GLOBAL
, &Globals
.szAutoServices
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
531 {"lock dir", P_STRING
, P_GLOBAL
, &Globals
.szLockDir
, NULL
, NULL
, FLAG_HIDE
},
532 {"lock directory", P_STRING
, P_GLOBAL
, &Globals
.szLockDir
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
533 {"modules dir", P_STRING
, P_GLOBAL
, &Globals
.szModulesDir
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
534 {"pid directory", P_STRING
, P_GLOBAL
, &Globals
.szPidDir
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
535 {"js include", P_LIST
, P_GLOBAL
, &Globals
.jsInclude
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
536 {"jsonrpc services directory", P_STRING
, P_GLOBAL
, &Globals
.jsonrpcServicesDir
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
537 {"setup directory", P_STRING
, P_GLOBAL
, &Globals
.szSetupDir
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
539 {"socket address", P_STRING
, P_GLOBAL
, &Globals
.szSocketAddress
, NULL
, NULL
, FLAG_DEVELOPER
},
540 {"-valid", P_BOOL
, P_LOCAL
, &sDefault
.valid
, NULL
, NULL
, FLAG_HIDE
},
542 {"copy", P_STRING
, P_LOCAL
, &sDefault
.szCopy
, handle_copy
, NULL
, FLAG_HIDE
},
543 {"include", P_STRING
, P_LOCAL
, &sDefault
.szInclude
, handle_include
, NULL
, FLAG_HIDE
},
545 {"available", P_BOOL
, P_LOCAL
, &sDefault
.bAvailable
, NULL
, NULL
, FLAG_BASIC
| FLAG_ADVANCED
| FLAG_SHARE
| FLAG_PRINT
},
546 {"volume", P_STRING
, P_LOCAL
, &sDefault
.volume
, NULL
, NULL
, FLAG_SHARE
},
547 {"fstype", P_STRING
, P_LOCAL
, &sDefault
.fstype
, NULL
, NULL
, FLAG_SHARE
},
549 {"panic action", P_STRING
, P_GLOBAL
, &panic_action
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
551 {"msdfs root", P_BOOL
, P_LOCAL
, &sDefault
.bMSDfsRoot
, NULL
, NULL
, FLAG_SHARE
},
552 {"host msdfs", P_BOOL
, P_GLOBAL
, &Globals
.bHostMSDfs
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
553 {"winbind separator", P_STRING
, P_GLOBAL
, &Globals
.szWinbindSeparator
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
554 {"winbindd socket directory", P_STRING
, P_GLOBAL
, &Globals
.szWinbinddSocketDirectory
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
555 {"winbind sealed pipes", P_BOOL
, P_GLOBAL
, &Globals
.bWinbindSealedPipes
, NULL
, NULL
, FLAG_ADVANCED
| FLAG_DEVELOPER
},
557 {NULL
, P_BOOL
, P_NONE
, NULL
, NULL
, NULL
, 0}
562 return the parameter table
564 struct parm_struct
*lp_parm_table(void)
569 /***************************************************************************
570 Initialise the global parameter structure.
571 ***************************************************************************/
572 static void init_globals(void)
577 DEBUG(3, ("Initialising global parameters\n"));
579 for (i
= 0; parm_table
[i
].label
; i
++) {
580 if ((parm_table
[i
].type
== P_STRING
||
581 parm_table
[i
].type
== P_USTRING
) &&
583 !(parm_table
[i
].flags
& FLAG_CMDLINE
)) {
584 string_set(parm_table
[i
].ptr
, "");
588 do_parameter("config file", dyn_CONFIGFILE
, NULL
);
590 do_parameter("share backend", "classic", NULL
);
592 do_parameter("server role", "standalone", NULL
);
594 /* options that can be set on the command line must be initialised via
595 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
597 do_parameter("socket options", "TCP_NODELAY", NULL
);
599 do_parameter("workgroup", DEFAULT_WORKGROUP
, NULL
);
600 myname
= get_myname();
601 do_parameter("netbios name", myname
, NULL
);
603 do_parameter("name resolve order", "lmhosts wins host bcast", NULL
);
605 do_parameter("fstype", FSTYPE_STRING
, NULL
);
606 do_parameter("ntvfs handler", "unixuid default", NULL
);
607 do_parameter("max connections", "-1", NULL
);
609 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo", NULL
);
610 do_parameter("server services", "smb rpc nbt wrepl ldap cldap web kdc winbind", NULL
);
611 do_parameter("ntptr providor", "simple_ldb", NULL
);
612 do_parameter("auth methods", "anonymous sam_ignoredomain", NULL
);
613 do_parameter("private dir", dyn_PRIVATE_DIR
, NULL
);
614 do_parameter("sam database", "sam.ldb", NULL
);
615 do_parameter("secrets database", "secrets.ldb", NULL
);
616 do_parameter("spoolss database", "spoolss.ldb", NULL
);
617 do_parameter("wins config database", "wins_config.ldb", NULL
);
618 do_parameter("wins database", "wins.ldb", NULL
);
619 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb", NULL
);
621 /* This hive should be dynamically generated by Samba using
622 data from the sam, but for the moment leave it in a tdb to
623 keep regedt32 from popping up an annoying dialog. */
624 do_parameter("registry:HKEY_USERS", "hku.ldb", NULL
);
626 /* using UTF8 by default allows us to support all chars */
627 do_parameter("unix charset", "UTF8", NULL
);
629 /* Use codepage 850 as a default for the dos character set */
630 do_parameter("dos charset", "CP850", NULL
);
633 * Allow the default PASSWD_CHAT to be overridden in local.h.
635 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT
, NULL
);
637 do_parameter("pid directory", dyn_PIDDIR
, NULL
);
638 do_parameter("lock dir", dyn_LOCKDIR
, NULL
);
639 do_parameter("modules dir", dyn_MODULESDIR
, NULL
);
640 do_parameter("ncalrpc dir", dyn_NCALRPCDIR
, NULL
);
642 do_parameter("socket address", "0.0.0.0", NULL
);
643 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING
);
645 do_parameter_var("announce version", "%d.%d",
646 DEFAULT_MAJOR_VERSION
,
647 DEFAULT_MINOR_VERSION
);
649 do_parameter("password server", "*", NULL
);
651 do_parameter("max mux", "50", NULL
);
652 do_parameter("max xmit", "12288", NULL
);
653 do_parameter("password level", "0", NULL
);
654 do_parameter("LargeReadwrite", "True", NULL
);
655 do_parameter("server min protocol", "CORE", NULL
);
656 do_parameter("server max protocol", "NT1", NULL
);
657 do_parameter("client min protocol", "CORE", NULL
);
658 do_parameter("client max protocol", "NT1", NULL
);
659 do_parameter("security", "USER", NULL
);
660 do_parameter("paranoid server security", "True", NULL
);
661 do_parameter("EncryptPasswords", "True", NULL
);
662 do_parameter("ReadRaw", "True", NULL
);
663 do_parameter("WriteRaw", "True", NULL
);
664 do_parameter("NullPasswords", "False", NULL
);
665 do_parameter("ObeyPamRestrictions", "False", NULL
);
666 do_parameter("announce as", "NT SERVER", NULL
);
668 do_parameter("TimeServer", "False", NULL
);
669 do_parameter("BindInterfacesOnly", "False", NULL
);
670 do_parameter("Unicode", "True", NULL
);
671 do_parameter("ClientLanManAuth", "True", NULL
);
672 do_parameter("LanmanAuth", "True", NULL
);
673 do_parameter("NTLMAuth", "True", NULL
);
674 do_parameter("client use spnego principal", "False", NULL
);
676 do_parameter("UnixExtensions", "False", NULL
);
678 do_parameter("PreferredMaster", "Auto", NULL
);
679 do_parameter("LocalMaster", "True", NULL
);
681 do_parameter("wins support", "False", NULL
);
682 do_parameter("dns proxy", "True", NULL
);
684 do_parameter("winbind separator", "\\", NULL
);
685 do_parameter("winbind sealed pipes", "True", NULL
);
686 do_parameter("winbindd socket directory", dyn_WINBINDD_SOCKET_DIR
, NULL
);
688 do_parameter("client signing", "Yes", NULL
);
689 do_parameter("server signing", "auto", NULL
);
691 do_parameter("use spnego", "True", NULL
);
693 do_parameter("smb ports", "445 139", NULL
);
694 do_parameter("nbt port", "137", NULL
);
695 do_parameter("dgram port", "138", NULL
);
696 do_parameter("cldap port", "389", NULL
);
697 do_parameter("krb5 port", "88", NULL
);
698 do_parameter("kpasswd port", "464", NULL
);
699 do_parameter("web port", "901", NULL
);
700 do_parameter("web application directory", dyn_WEBAPPSDIR
, NULL
);
701 do_parameter("jsonrpc services directory", dyn_SERVICESDIR
, NULL
);
703 do_parameter("nt status support", "True", NULL
);
705 do_parameter("max wins ttl", "518400", NULL
); /* 6 days */
706 do_parameter("min wins ttl", "10", NULL
);
708 do_parameter("tls enabled", "True", NULL
);
709 do_parameter("tls keyfile", "tls/key.pem", NULL
);
710 do_parameter("tls certfile", "tls/cert.pem", NULL
);
711 do_parameter("tls cafile", "tls/ca.pem", NULL
);
712 do_parameter_var("js include", "%s", dyn_JSDIR
);
713 do_parameter_var("setup directory", "%s", dyn_SETUPDIR
);
715 for (i
= 0; parm_table
[i
].label
; i
++) {
716 if (!(parm_table
[i
].flags
& FLAG_CMDLINE
)) {
717 parm_table
[i
].flags
|= FLAG_DEFAULT
;
722 static TALLOC_CTX
*lp_talloc
;
724 /******************************************************************* a
725 Free up temporary memory - called from the main loop.
726 ********************************************************************/
728 void lp_talloc_free(void)
732 talloc_free(lp_talloc
);
736 /*******************************************************************
737 Convenience routine to grab string parameters into temporary memory
738 and run standard_sub_basic on them. The buffers can be written to by
739 callers without affecting the source string.
740 ********************************************************************/
742 static const char *lp_string(const char *s
)
744 #if 0 /* until REWRITE done to make thread-safe */
745 size_t len
= s
? strlen(s
) : 0;
749 /* The follow debug is useful for tracking down memory problems
750 especially if you have an inner loop that is calling a lp_*()
751 function that returns a string. Perhaps this debug should be
752 present all the time? */
755 DEBUG(10, ("lp_string(%s)\n", s
));
758 #if 0 /* until REWRITE done to make thread-safe */
760 lp_talloc
= talloc_init("lp_talloc");
762 ret
= talloc_array(lp_talloc
, char, len
+ 100); /* leave room for substitution */
770 strlcpy(ret
, s
, len
);
772 if (trim_string(ret
, "\"", "\"")) {
773 if (strchr(ret
,'"') != NULL
)
774 strlcpy(ret
, s
, len
);
777 standard_sub_basic(ret
,len
+100);
784 In this section all the functions that are used to access the
785 parameters from the rest of the program are defined
788 #define FN_GLOBAL_STRING(fn_name,ptr) \
789 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
790 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
791 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
792 #define FN_GLOBAL_LIST(fn_name,ptr) \
793 const char **fn_name(void) {return(*(const char ***)(ptr));}
794 #define FN_GLOBAL_BOOL(fn_name,ptr) \
795 BOOL fn_name(void) {return((BOOL)*(int *)(ptr));}
797 #define FN_GLOBAL_CHAR(fn_name,ptr) \
798 char fn_name(void) {return(*(char *)(ptr));}
800 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
801 int fn_name(void) {return(*(int *)(ptr));}
803 #define FN_LOCAL_STRING(fn_name,val) \
804 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
805 #define FN_LOCAL_CONST_STRING(fn_name,val) \
806 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
807 #define FN_LOCAL_LIST(fn_name,val) \
808 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
809 #define FN_LOCAL_BOOL(fn_name,val) \
810 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
812 #define FN_LOCAL_CHAR(fn_name,val) \
813 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
815 #define FN_LOCAL_INTEGER(fn_name,val) \
816 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
818 _PUBLIC_
FN_GLOBAL_INTEGER(lp_server_role
, &Globals
.server_role
)
819 _PUBLIC_
FN_GLOBAL_LIST(lp_smb_ports
, &Globals
.smb_ports
)
820 _PUBLIC_
FN_GLOBAL_INTEGER(lp_nbt_port
, &Globals
.nbt_port
)
821 _PUBLIC_
FN_GLOBAL_INTEGER(lp_dgram_port
, &Globals
.dgram_port
)
822 _PUBLIC_
FN_GLOBAL_INTEGER(lp_cldap_port
, &Globals
.cldap_port
)
823 _PUBLIC_
FN_GLOBAL_INTEGER(lp_krb5_port
, &Globals
.krb5_port
)
824 _PUBLIC_
FN_GLOBAL_INTEGER(lp_kpasswd_port
, &Globals
.kpasswd_port
)
825 _PUBLIC_
FN_GLOBAL_INTEGER(lp_web_port
, &Globals
.web_port
)
826 _PUBLIC_
FN_GLOBAL_STRING(lp_dos_charset
, &Globals
.dos_charset
)
827 _PUBLIC_
FN_GLOBAL_STRING(lp_webapps_directory
, &Globals
.webapps_directory
)
828 _PUBLIC_
FN_GLOBAL_BOOL(lp_tls_enabled
, &Globals
.tls_enabled
)
829 _PUBLIC_
FN_GLOBAL_STRING(lp_tls_keyfile
, &Globals
.tls_keyfile
)
830 _PUBLIC_
FN_GLOBAL_STRING(lp_tls_certfile
, &Globals
.tls_certfile
)
831 _PUBLIC_
FN_GLOBAL_STRING(lp_tls_cafile
, &Globals
.tls_cafile
)
832 _PUBLIC_
FN_GLOBAL_STRING(lp_tls_crlfile
, &Globals
.tls_crlfile
)
833 _PUBLIC_
FN_GLOBAL_STRING(lp_tls_dhpfile
, &Globals
.tls_dhpfile
)
834 _PUBLIC_
FN_GLOBAL_STRING(lp_unix_charset
, &Globals
.unix_charset
)
835 _PUBLIC_
FN_GLOBAL_STRING(lp_display_charset
, &Globals
.display_charset
)
836 _PUBLIC_
FN_GLOBAL_STRING(lp_configfile
, &Globals
.szConfigFile
)
837 _PUBLIC_
FN_GLOBAL_STRING(lp_share_backend
, &Globals
.szShareBackend
)
838 _PUBLIC_
FN_GLOBAL_STRING(lp_sam_url
, &Globals
.szSAM_URL
)
839 _PUBLIC_
FN_GLOBAL_STRING(lp_secrets_url
, &Globals
.szSECRETS_URL
)
840 _PUBLIC_
FN_GLOBAL_STRING(lp_spoolss_url
, &Globals
.szSPOOLSS_URL
)
841 _PUBLIC_
FN_GLOBAL_STRING(lp_wins_config_url
, &Globals
.szWINS_CONFIG_URL
)
842 _PUBLIC_
FN_GLOBAL_STRING(lp_wins_url
, &Globals
.szWINS_URL
)
843 _PUBLIC_
FN_GLOBAL_CONST_STRING(lp_winbind_separator
, &Globals
.szWinbindSeparator
)
844 _PUBLIC_
FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory
, &Globals
.szWinbinddSocketDirectory
)
845 _PUBLIC_
FN_GLOBAL_BOOL(lp_winbind_sealed_pipes
, &Globals
.bWinbindSealedPipes
)
846 _PUBLIC_
FN_GLOBAL_STRING(lp_private_dir
, &Globals
.szPrivateDir
)
847 _PUBLIC_
FN_GLOBAL_STRING(lp_serverstring
, &Globals
.szServerString
)
848 _PUBLIC_
FN_GLOBAL_STRING(lp_lockdir
, &Globals
.szLockDir
)
849 _PUBLIC_
FN_GLOBAL_STRING(lp_modulesdir
, &Globals
.szModulesDir
)
850 _PUBLIC_
FN_GLOBAL_STRING(lp_setupdir
, &Globals
.szSetupDir
)
851 _PUBLIC_
FN_GLOBAL_STRING(lp_ncalrpc_dir
, &Globals
.ncalrpc_dir
)
852 _PUBLIC_
FN_GLOBAL_STRING(lp_piddir
, &Globals
.szPidDir
)
853 _PUBLIC_
FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers
, &Globals
.dcerpc_ep_servers
)
854 _PUBLIC_
FN_GLOBAL_LIST(lp_server_services
, &Globals
.server_services
)
855 _PUBLIC_
FN_GLOBAL_STRING(lp_ntptr_providor
, &Globals
.ntptr_providor
)
856 _PUBLIC_
FN_GLOBAL_STRING(lp_auto_services
, &Globals
.szAutoServices
)
857 _PUBLIC_
FN_GLOBAL_STRING(lp_passwd_chat
, &Globals
.szPasswdChat
)
858 _PUBLIC_
FN_GLOBAL_LIST(lp_passwordserver
, &Globals
.szPasswordServers
)
859 _PUBLIC_
FN_GLOBAL_LIST(lp_name_resolve_order
, &Globals
.szNameResolveOrder
)
860 _PUBLIC_
FN_GLOBAL_STRING(lp_realm
, &Globals
.szRealm
)
861 _PUBLIC_
FN_GLOBAL_STRING(lp_socket_options
, &Globals
.socket_options
)
862 _PUBLIC_
FN_GLOBAL_STRING(lp_workgroup
, &Globals
.szWorkgroup
)
863 _PUBLIC_
FN_GLOBAL_STRING(lp_netbios_name
, &Globals
.szNetbiosName
)
864 _PUBLIC_
FN_GLOBAL_STRING(lp_netbios_scope
, &Globals
.szNetbiosScope
)
865 _PUBLIC_
FN_GLOBAL_LIST(lp_wins_server_list
, &Globals
.szWINSservers
)
866 _PUBLIC_
FN_GLOBAL_LIST(lp_interfaces
, &Globals
.szInterfaces
)
867 _PUBLIC_
FN_GLOBAL_STRING(lp_socket_address
, &Globals
.szSocketAddress
)
868 _PUBLIC_
FN_GLOBAL_LIST(lp_netbios_aliases
, &Globals
.szNetbiosAliases
)
870 _PUBLIC_
FN_GLOBAL_BOOL(lp_disable_netbios
, &Globals
.bDisableNetbios
)
871 _PUBLIC_
FN_GLOBAL_BOOL(lp_wins_support
, &Globals
.bWINSsupport
)
872 _PUBLIC_
FN_GLOBAL_BOOL(lp_wins_dns_proxy
, &Globals
.bWINSdnsProxy
)
873 _PUBLIC_
FN_GLOBAL_STRING(lp_wins_hook
, &Globals
.szWINSHook
)
874 _PUBLIC_
FN_GLOBAL_BOOL(lp_local_master
, &Globals
.bLocalMaster
)
875 _PUBLIC_
FN_GLOBAL_BOOL(lp_readraw
, &Globals
.bReadRaw
)
876 _PUBLIC_
FN_GLOBAL_BOOL(lp_large_readwrite
, &Globals
.bLargeReadwrite
)
877 _PUBLIC_
FN_GLOBAL_BOOL(lp_writeraw
, &Globals
.bWriteRaw
)
878 _PUBLIC_
FN_GLOBAL_BOOL(lp_null_passwords
, &Globals
.bNullPasswords
)
879 _PUBLIC_
FN_GLOBAL_BOOL(lp_obey_pam_restrictions
, &Globals
.bObeyPamRestrictions
)
880 _PUBLIC_
FN_GLOBAL_BOOL(lp_encrypted_passwords
, &Globals
.bEncryptPasswords
)
881 _PUBLIC_
FN_GLOBAL_BOOL(lp_time_server
, &Globals
.bTimeServer
)
882 _PUBLIC_
FN_GLOBAL_BOOL(lp_bind_interfaces_only
, &Globals
.bBindInterfacesOnly
)
883 _PUBLIC_
FN_GLOBAL_BOOL(lp_unicode
, &Globals
.bUnicode
)
884 _PUBLIC_
FN_GLOBAL_BOOL(lp_nt_status_support
, &Globals
.bNTStatusSupport
)
885 _PUBLIC_
FN_GLOBAL_BOOL(lp_lanman_auth
, &Globals
.bLanmanAuth
)
886 _PUBLIC_
FN_GLOBAL_BOOL(lp_ntlm_auth
, &Globals
.bNTLMAuth
)
887 _PUBLIC_
FN_GLOBAL_BOOL(lp_client_plaintext_auth
, &Globals
.bClientPlaintextAuth
)
888 _PUBLIC_
FN_GLOBAL_BOOL(lp_client_lanman_auth
, &Globals
.bClientLanManAuth
)
889 _PUBLIC_
FN_GLOBAL_BOOL(lp_client_ntlmv2_auth
, &Globals
.bClientNTLMv2Auth
)
890 _PUBLIC_
FN_GLOBAL_BOOL(lp_client_use_spnego_principal
, &Globals
.client_use_spnego_principal
)
891 _PUBLIC_
FN_GLOBAL_BOOL(lp_host_msdfs
, &Globals
.bHostMSDfs
)
892 _PUBLIC_
FN_GLOBAL_BOOL(lp_unix_extensions
, &Globals
.bUnixExtensions
)
893 _PUBLIC_
FN_GLOBAL_BOOL(lp_use_spnego
, &Globals
.bUseSpnego
)
894 _PUBLIC_
FN_GLOBAL_BOOL(lp_rpc_big_endian
, &Globals
.bRpcBigEndian
)
895 _PUBLIC_
FN_GLOBAL_INTEGER(lp_max_wins_ttl
, &Globals
.max_wins_ttl
)
896 _PUBLIC_
FN_GLOBAL_INTEGER(lp_min_wins_ttl
, &Globals
.min_wins_ttl
)
897 _PUBLIC_
FN_GLOBAL_INTEGER(lp_maxmux
, &Globals
.max_mux
)
898 _PUBLIC_
FN_GLOBAL_INTEGER(lp_max_xmit
, &Globals
.max_xmit
)
899 _PUBLIC_
FN_GLOBAL_INTEGER(lp_passwordlevel
, &Globals
.pwordlevel
)
900 _PUBLIC_
FN_GLOBAL_INTEGER(lp_srv_maxprotocol
, &Globals
.srv_maxprotocol
)
901 _PUBLIC_
FN_GLOBAL_INTEGER(lp_srv_minprotocol
, &Globals
.srv_minprotocol
)
902 _PUBLIC_
FN_GLOBAL_INTEGER(lp_cli_maxprotocol
, &Globals
.cli_maxprotocol
)
903 _PUBLIC_
FN_GLOBAL_INTEGER(lp_cli_minprotocol
, &Globals
.cli_minprotocol
)
904 _PUBLIC_
FN_GLOBAL_INTEGER(lp_security
, &Globals
.security
)
905 _PUBLIC_
FN_GLOBAL_LIST(lp_auth_methods
, &Globals
.AuthMethods
)
906 _PUBLIC_
FN_GLOBAL_BOOL(lp_paranoid_server_security
, &Globals
.paranoid_server_security
)
907 _PUBLIC_
FN_GLOBAL_INTEGER(lp_announce_as
, &Globals
.announce_as
)
908 _PUBLIC_
FN_GLOBAL_LIST(lp_js_include
, &Globals
.jsInclude
)
909 _PUBLIC_
FN_GLOBAL_STRING(lp_jsonrpc_services_dir
, &Globals
.jsonrpcServicesDir
)
912 _PUBLIC_
FN_LOCAL_STRING(lp_servicename
, szService
)
913 _PUBLIC_
FN_LOCAL_CONST_STRING(lp_const_servicename
, szService
)
914 _PUBLIC_
FN_LOCAL_STRING(lp_pathname
, szPath
)
915 static FN_LOCAL_STRING(_lp_printername
, szPrintername
)
916 _PUBLIC_
FN_LOCAL_LIST(lp_hostsallow
, szHostsallow
)
917 _PUBLIC_
FN_LOCAL_LIST(lp_hostsdeny
, szHostsdeny
)
918 _PUBLIC_
FN_LOCAL_STRING(lp_comment
, comment
)
919 _PUBLIC_
FN_LOCAL_STRING(lp_fstype
, fstype
)
920 static FN_LOCAL_STRING(lp_volume
, volume
)
921 _PUBLIC_
FN_LOCAL_LIST(lp_ntvfs_handler
, ntvfs_handler
)
922 _PUBLIC_
FN_LOCAL_BOOL(lp_msdfs_root
, bMSDfsRoot
)
923 _PUBLIC_
FN_LOCAL_BOOL(lp_browseable
, bBrowseable
)
924 _PUBLIC_
FN_LOCAL_BOOL(lp_readonly
, bRead_only
)
925 _PUBLIC_
FN_LOCAL_BOOL(lp_print_ok
, bPrint_ok
)
926 _PUBLIC_
FN_LOCAL_BOOL(lp_map_hidden
, bMap_hidden
)
927 _PUBLIC_
FN_LOCAL_BOOL(lp_map_archive
, bMap_archive
)
928 _PUBLIC_
FN_LOCAL_BOOL(lp_strict_locking
, bStrictLocking
)
929 _PUBLIC_
FN_LOCAL_BOOL(lp_strict_sync
, bStrictSync
)
930 _PUBLIC_
FN_LOCAL_BOOL(lp_ci_filesystem
, bCIFileSystem
)
931 _PUBLIC_
FN_LOCAL_BOOL(lp_map_system
, bMap_system
)
932 _PUBLIC_
FN_LOCAL_INTEGER(lp_max_connections
, iMaxConnections
)
933 _PUBLIC_
FN_LOCAL_INTEGER(lp_csc_policy
, iCSCPolicy
)
934 _PUBLIC_
FN_GLOBAL_INTEGER(lp_server_signing
, &Globals
.server_signing
)
935 _PUBLIC_
FN_GLOBAL_INTEGER(lp_client_signing
, &Globals
.client_signing
)
937 /* local prototypes */
939 static int map_parameter(const char *pszParmName
);
940 static int getservicebyname(const char *pszServiceName
,
941 service
* pserviceDest
);
942 static void copy_service(service
* pserviceDest
,
943 service
* pserviceSource
, int *pcopymapDest
);
944 static BOOL
service_ok(int iService
);
945 static BOOL
do_section(const char *pszSectionName
, void *);
946 static void init_copymap(service
* pservice
);
948 /* This is a helper function for parametrical options support. */
949 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
950 /* Actual parametrical functions are quite simple */
951 const char *lp_get_parametric(int lookup_service
, const char *type
, const char *option
)
954 struct param_opt
*data
;
956 if (lookup_service
>= iNumServices
) return NULL
;
958 data
= (lookup_service
< 0) ?
959 Globals
.param_opt
: ServicePtrs
[lookup_service
]->param_opt
;
961 asprintf(&vfskey
, "%s:%s", type
, option
);
965 if (strcmp(data
->key
, vfskey
) == 0) {
972 if (lookup_service
>= 0) {
973 /* Try to fetch the same option but from globals */
974 /* but only if we are not already working with Globals */
975 data
= Globals
.param_opt
;
977 if (strcmp(data
->key
, vfskey
) == 0) {
991 /*******************************************************************
992 convenience routine to return int parameters.
993 ********************************************************************/
994 static int lp_int(const char *s
)
998 DEBUG(0,("lp_int(%s): is called with NULL!\n",s
));
1002 return strtol(s
, NULL
, 0);
1005 /*******************************************************************
1006 convenience routine to return unsigned long parameters.
1007 ********************************************************************/
1008 static int lp_ulong(const char *s
)
1012 DEBUG(0,("lp_int(%s): is called with NULL!\n",s
));
1016 return strtoul(s
, NULL
, 0);
1019 /*******************************************************************
1020 convenience routine to return boolean parameters.
1021 ********************************************************************/
1022 static BOOL
lp_bool(const char *s
)
1027 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s
));
1031 if (!set_boolean(s
, &ret
)) {
1032 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
1040 /* Return parametric option from a given service. Type is a part of option before ':' */
1041 /* Parametric option has following syntax: 'Type: option = value' */
1042 /* Returned value is allocated in 'lp_talloc' context */
1044 const char *lp_parm_string(int lookup_service
, const char *type
, const char *option
)
1046 const char *value
= lp_get_parametric(lookup_service
, type
, option
);
1049 return lp_string(value
);
1054 /* Return parametric option from a given service. Type is a part of option before ':' */
1055 /* Parametric option has following syntax: 'Type: option = value' */
1056 /* Returned value is allocated in 'lp_talloc' context */
1058 const char **lp_parm_string_list(int lookup_service
, const char *type
, const char *option
,
1059 const char *separator
)
1061 const char *value
= lp_get_parametric(lookup_service
, type
, option
);
1064 return str_list_make(talloc_autofree_context(), value
, separator
);
1069 /* Return parametric option from a given service. Type is a part of option before ':' */
1070 /* Parametric option has following syntax: 'Type: option = value' */
1072 int lp_parm_int(int lookup_service
, const char *type
, const char *option
, int default_v
)
1074 const char *value
= lp_get_parametric(lookup_service
, type
, option
);
1077 return lp_int(value
);
1082 /* Return parametric option from a given service. Type is a part of
1083 * option before ':'.
1084 * Parametric option has following syntax: 'Type: option = value'.
1087 int lp_parm_bytes(int lookup_service
, const char *type
, const char *option
, int default_v
)
1091 const char *value
= lp_get_parametric(lookup_service
, type
, option
);
1093 if (value
&& conv_str_size(value
, &bval
)) {
1094 if (bval
<= INT_MAX
) {
1102 /* Return parametric option from a given service. Type is a part of option before ':' */
1103 /* Parametric option has following syntax: 'Type: option = value' */
1105 unsigned long lp_parm_ulong(int lookup_service
, const char *type
, const char *option
, unsigned long default_v
)
1107 const char *value
= lp_get_parametric(lookup_service
, type
, option
);
1110 return lp_ulong(value
);
1115 /* Return parametric option from a given service. Type is a part of option before ':' */
1116 /* Parametric option has following syntax: 'Type: option = value' */
1118 BOOL
lp_parm_bool(int lookup_service
, const char *type
, const char *option
, BOOL default_v
)
1120 const char *value
= lp_get_parametric(lookup_service
, type
, option
);
1123 return lp_bool(value
);
1129 /***************************************************************************
1130 Initialise a service to the defaults.
1131 ***************************************************************************/
1133 static void init_service(service
* pservice
)
1135 memset((char *)pservice
, '\0', sizeof(service
));
1136 copy_service(pservice
, &sDefault
, NULL
);
1139 /***************************************************************************
1140 Free the dynamically allocated parts of a service struct.
1141 ***************************************************************************/
1143 static void free_service(service
*pservice
)
1146 struct param_opt
*data
, *pdata
;
1150 if (pservice
->szService
)
1151 DEBUG(5, ("free_service: Freeing service %s\n",
1152 pservice
->szService
));
1154 string_free(&pservice
->szService
);
1155 SAFE_FREE(pservice
->copymap
);
1157 for (i
= 0; parm_table
[i
].label
; i
++) {
1158 if ((parm_table
[i
].type
== P_STRING
||
1159 parm_table
[i
].type
== P_USTRING
) &&
1160 parm_table
[i
].class == P_LOCAL
) {
1161 string_free((char **)
1162 (((char *)pservice
) +
1163 PTR_DIFF(parm_table
[i
].ptr
, &sDefault
)));
1164 } else if (parm_table
[i
].type
== P_LIST
&&
1165 parm_table
[i
].class == P_LOCAL
) {
1166 char ***listp
= (char ***)(((char *)pservice
) +
1167 PTR_DIFF(parm_table
[i
].ptr
, &sDefault
));
1168 talloc_free(*listp
);
1173 DEBUG(5,("Freeing parametrics:\n"));
1174 data
= pservice
->param_opt
;
1176 DEBUG(5,("[%s = %s]\n", data
->key
, data
->value
));
1177 string_free(&data
->key
);
1178 string_free(&data
->value
);
1184 ZERO_STRUCTP(pservice
);
1187 /***************************************************************************
1188 Add a new service to the services array initialising it with the given
1190 ***************************************************************************/
1192 static int add_a_service(const service
*pservice
, const char *name
)
1196 int num_to_alloc
= iNumServices
+ 1;
1197 struct param_opt
*data
, *pdata
;
1199 tservice
= *pservice
;
1201 /* it might already exist */
1203 i
= getservicebyname(name
, NULL
);
1205 /* Clean all parametric options for service */
1206 /* They will be added during parsing again */
1207 data
= ServicePtrs
[i
]->param_opt
;
1209 string_free(&data
->key
);
1210 string_free(&data
->value
);
1215 ServicePtrs
[i
]->param_opt
= NULL
;
1220 /* find an invalid one */
1221 for (i
= 0; i
< iNumServices
; i
++)
1222 if (!ServicePtrs
[i
]->valid
)
1225 /* if not, then create one */
1226 if (i
== iNumServices
) {
1229 tsp
= realloc_p(ServicePtrs
, service
*, num_to_alloc
);
1232 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1237 ServicePtrs
[iNumServices
] = malloc_p(service
);
1239 if (!ServicePtrs
[iNumServices
]) {
1240 DEBUG(0,("add_a_service: out of memory!\n"));
1246 free_service(ServicePtrs
[i
]);
1248 ServicePtrs
[i
]->valid
= True
;
1250 init_service(ServicePtrs
[i
]);
1251 copy_service(ServicePtrs
[i
], &tservice
, NULL
);
1253 string_set(&ServicePtrs
[i
]->szService
, name
);
1257 /***************************************************************************
1258 Add a new home service, with the specified home directory, defaults coming
1260 ***************************************************************************/
1262 BOOL
lp_add_home(const char *pszHomename
, int iDefaultService
,
1263 const char *user
, const char *pszHomedir
)
1268 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
1273 if (!(*(ServicePtrs
[iDefaultService
]->szPath
))
1274 || strequal(ServicePtrs
[iDefaultService
]->szPath
, lp_pathname(-1))) {
1275 pstrcpy(newHomedir
, pszHomedir
);
1277 pstrcpy(newHomedir
, lp_pathname(iDefaultService
));
1278 string_sub(newHomedir
,"%H", pszHomedir
, sizeof(newHomedir
));
1281 string_set(&ServicePtrs
[i
]->szPath
, newHomedir
);
1283 if (!(*(ServicePtrs
[i
]->comment
))) {
1285 slprintf(comment
, sizeof(comment
) - 1,
1286 "Home directory of %s", user
);
1287 string_set(&ServicePtrs
[i
]->comment
, comment
);
1289 ServicePtrs
[i
]->bAvailable
= sDefault
.bAvailable
;
1290 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
1292 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
1298 /***************************************************************************
1299 Add a new service, based on an old one.
1300 ***************************************************************************/
1302 int lp_add_service(const char *pszService
, int iDefaultService
)
1304 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
1307 /***************************************************************************
1308 Add the IPC service.
1309 ***************************************************************************/
1311 static BOOL
lp_add_hidden(const char *name
, const char *fstype
)
1314 int i
= add_a_service(&sDefault
, name
);
1319 slprintf(comment
, sizeof(comment
) - 1,
1320 "%s Service (%s)", fstype
, Globals
.szServerString
);
1322 string_set(&ServicePtrs
[i
]->szPath
, tmpdir());
1323 string_set(&ServicePtrs
[i
]->comment
, comment
);
1324 string_set(&ServicePtrs
[i
]->fstype
, fstype
);
1325 ServicePtrs
[i
]->iMaxConnections
= -1;
1326 ServicePtrs
[i
]->bAvailable
= True
;
1327 ServicePtrs
[i
]->bRead_only
= True
;
1328 ServicePtrs
[i
]->bPrint_ok
= False
;
1329 ServicePtrs
[i
]->bBrowseable
= False
;
1331 if (strcasecmp(fstype
, "IPC") == 0) {
1332 lp_do_parameter(i
, "ntvfs handler", "default");
1335 DEBUG(3, ("adding hidden service %s\n", name
));
1340 /***************************************************************************
1341 Add a new printer service, with defaults coming from service iFrom.
1342 ***************************************************************************/
1344 BOOL
lp_add_printer(const char *pszPrintername
, int iDefaultService
)
1346 const char *comment
= "From Printcap";
1347 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
1352 /* note that we do NOT default the availability flag to True - */
1353 /* we take it from the default service passed. This allows all */
1354 /* dynamic printers to be disabled by disabling the [printers] */
1355 /* entry (if/when the 'available' keyword is implemented!). */
1357 /* the printer name is set to the service name. */
1358 string_set(&ServicePtrs
[i
]->szPrintername
, pszPrintername
);
1359 string_set(&ServicePtrs
[i
]->comment
, comment
);
1360 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
1361 /* Printers cannot be read_only. */
1362 ServicePtrs
[i
]->bRead_only
= False
;
1363 /* Printer services must be printable. */
1364 ServicePtrs
[i
]->bPrint_ok
= True
;
1366 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
1371 /***************************************************************************
1372 Map a parameter's string representation to something we can use.
1373 Returns False if the parameter string is not recognised, else TRUE.
1374 ***************************************************************************/
1376 static int map_parameter(const char *pszParmName
)
1380 if (*pszParmName
== '-')
1383 for (iIndex
= 0; parm_table
[iIndex
].label
; iIndex
++)
1384 if (strwicmp(parm_table
[iIndex
].label
, pszParmName
) == 0)
1387 /* Warn only if it isn't parametric option */
1388 if (strchr(pszParmName
, ':') == NULL
)
1389 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName
));
1390 /* We do return 'fail' for parametric options as well because they are
1391 stored in different storage
1398 return the parameter structure for a parameter
1400 struct parm_struct
*lp_parm_struct(const char *name
)
1402 int parmnum
= map_parameter(name
);
1403 if (parmnum
== -1) return NULL
;
1404 return &parm_table
[parmnum
];
1408 return the parameter pointer for a parameter
1410 void *lp_parm_ptr(int snum
, struct parm_struct
*parm
)
1415 return ((char *)ServicePtrs
[snum
]) + PTR_DIFF(parm
->ptr
, &sDefault
);
1418 /***************************************************************************
1419 Find a service by name. Otherwise works like get_service.
1420 ***************************************************************************/
1422 static int getservicebyname(const char *pszServiceName
, service
* pserviceDest
)
1426 for (iService
= iNumServices
- 1; iService
>= 0; iService
--)
1427 if (VALID(iService
) &&
1428 strwicmp(ServicePtrs
[iService
]->szService
, pszServiceName
) == 0) {
1429 if (pserviceDest
!= NULL
)
1430 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
1437 /***************************************************************************
1438 Copy a service structure to another.
1439 If pcopymapDest is NULL then copy all fields
1440 ***************************************************************************/
1442 static void copy_service(service
* pserviceDest
, service
* pserviceSource
, int *pcopymapDest
)
1445 BOOL bcopyall
= (pcopymapDest
== NULL
);
1446 struct param_opt
*data
, *pdata
, *paramo
;
1449 for (i
= 0; parm_table
[i
].label
; i
++)
1450 if (parm_table
[i
].ptr
&& parm_table
[i
].class == P_LOCAL
&&
1451 (bcopyall
|| pcopymapDest
[i
])) {
1452 void *def_ptr
= parm_table
[i
].ptr
;
1454 ((char *)pserviceSource
) + PTR_DIFF(def_ptr
,
1457 ((char *)pserviceDest
) + PTR_DIFF(def_ptr
,
1460 switch (parm_table
[i
].type
) {
1462 *(int *)dest_ptr
= *(int *)src_ptr
;
1467 *(int *)dest_ptr
= *(int *)src_ptr
;
1471 string_set(dest_ptr
,
1476 string_set(dest_ptr
,
1478 strupper(*(char **)dest_ptr
);
1481 *(const char ***)dest_ptr
= str_list_copy(talloc_autofree_context(),
1482 *(const char ***)src_ptr
);
1490 init_copymap(pserviceDest
);
1491 if (pserviceSource
->copymap
)
1492 memcpy((void *)pserviceDest
->copymap
,
1493 (void *)pserviceSource
->copymap
,
1494 sizeof(int) * NUMPARAMETERS
);
1497 data
= pserviceSource
->param_opt
;
1500 pdata
= pserviceDest
->param_opt
;
1501 /* Traverse destination */
1503 /* If we already have same option, override it */
1504 if (strcmp(pdata
->key
, data
->key
) == 0) {
1505 string_free(&pdata
->value
);
1506 pdata
->value
= strdup(data
->value
);
1510 pdata
= pdata
->next
;
1513 paramo
= malloc_p(struct param_opt
);
1516 paramo
->key
= strdup(data
->key
);
1517 paramo
->value
= strdup(data
->value
);
1518 DLIST_ADD(pserviceDest
->param_opt
, paramo
);
1524 /***************************************************************************
1525 Check a service for consistency. Return False if the service is in any way
1526 incomplete or faulty, else True.
1527 ***************************************************************************/
1529 static BOOL
service_ok(int iService
)
1534 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
1535 DEBUG(0, ("The following message indicates an internal error:\n"));
1536 DEBUG(0, ("No service name in service entry.\n"));
1540 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1541 /* I can't see why you'd want a non-printable printer service... */
1542 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
1543 if (!ServicePtrs
[iService
]->bPrint_ok
) {
1544 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1545 ServicePtrs
[iService
]->szService
));
1546 ServicePtrs
[iService
]->bPrint_ok
= True
;
1548 /* [printers] service must also be non-browsable. */
1549 if (ServicePtrs
[iService
]->bBrowseable
)
1550 ServicePtrs
[iService
]->bBrowseable
= False
;
1553 /* If a service is flagged unavailable, log the fact at level 0. */
1554 if (!ServicePtrs
[iService
]->bAvailable
)
1555 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1556 ServicePtrs
[iService
]->szService
));
1561 static struct file_lists
{
1562 struct file_lists
*next
;
1566 } *file_lists
= NULL
;
1568 /*******************************************************************
1569 Keep a linked list of all config files so we know when one has changed
1570 it's date and needs to be reloaded.
1571 ********************************************************************/
1573 static void add_to_file_list(const char *fname
, const char *subfname
)
1575 struct file_lists
*f
= file_lists
;
1578 if (f
->name
&& !strcmp(f
->name
, fname
))
1584 f
= malloc_p(struct file_lists
);
1587 f
->next
= file_lists
;
1588 f
->name
= strdup(fname
);
1593 f
->subfname
= strdup(subfname
);
1599 f
->modtime
= file_modtime(subfname
);
1601 time_t t
= file_modtime(subfname
);
1607 /*******************************************************************
1608 Check if a config file has changed date.
1609 ********************************************************************/
1611 BOOL
lp_file_list_changed(void)
1613 struct file_lists
*f
= file_lists
;
1614 DEBUG(6, ("lp_file_list_changed()\n"));
1620 pstrcpy(n2
, f
->name
);
1621 standard_sub_basic(n2
,sizeof(n2
));
1623 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1624 f
->name
, n2
, ctime(&f
->modtime
)));
1626 mod_time
= file_modtime(n2
);
1628 if (mod_time
&& ((f
->modtime
!= mod_time
) || (f
->subfname
== NULL
) || (strcmp(n2
, f
->subfname
) != 0))) {
1630 ("file %s modified: %s\n", n2
,
1632 f
->modtime
= mod_time
;
1633 SAFE_FREE(f
->subfname
);
1634 f
->subfname
= strdup(n2
);
1642 /***************************************************************************
1643 Handle the include operation.
1644 ***************************************************************************/
1646 static BOOL
handle_include(const char *pszParmValue
, char **ptr
)
1649 pstrcpy(fname
, pszParmValue
);
1651 standard_sub_basic(fname
,sizeof(fname
));
1653 add_to_file_list(pszParmValue
, fname
);
1655 string_set(ptr
, fname
);
1657 if (file_exist(fname
))
1658 return (pm_process(fname
, do_section
, do_parameter
, NULL
));
1660 DEBUG(2, ("Can't find include file %s\n", fname
));
1665 /***************************************************************************
1666 Handle the interpretation of the copy parameter.
1667 ***************************************************************************/
1669 static BOOL
handle_copy(const char *pszParmValue
, char **ptr
)
1673 service serviceTemp
;
1675 string_set(ptr
, pszParmValue
);
1677 init_service(&serviceTemp
);
1681 DEBUG(3, ("Copying service from service %s\n", pszParmValue
));
1683 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0) {
1684 if (iTemp
== iServiceIndex
) {
1685 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue
));
1687 copy_service(ServicePtrs
[iServiceIndex
],
1689 ServicePtrs
[iServiceIndex
]->copymap
);
1693 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue
));
1697 free_service(&serviceTemp
);
1701 /***************************************************************************
1702 Initialise a copymap.
1703 ***************************************************************************/
1705 static void init_copymap(service
* pservice
)
1708 SAFE_FREE(pservice
->copymap
);
1709 pservice
->copymap
= malloc_array_p(int, NUMPARAMETERS
);
1710 if (!pservice
->copymap
)
1712 ("Couldn't allocate copymap!! (size %d)\n",
1713 (int)NUMPARAMETERS
));
1715 for (i
= 0; i
< NUMPARAMETERS
; i
++)
1716 pservice
->copymap
[i
] = True
;
1719 #if 0 /* not used anywhere */
1720 /***************************************************************************
1721 Return the local pointer to a parameter given the service number and the
1722 pointer into the default structure.
1723 ***************************************************************************/
1725 void *lp_local_ptr(int snum
, void *ptr
)
1727 return (void *)(((char *)ServicePtrs
[snum
]) + PTR_DIFF(ptr
, &sDefault
));
1731 /***************************************************************************
1732 Process a parametric option
1733 ***************************************************************************/
1734 static BOOL
lp_do_parameter_parametric(int snum
, const char *pszParmName
, const char *pszParmValue
, int flags
)
1736 struct param_opt
*paramo
, *data
;
1739 while (isspace((unsigned char)*pszParmName
)) {
1743 name
= strdup(pszParmName
);
1744 if (!name
) return False
;
1749 data
= Globals
.param_opt
;
1751 data
= ServicePtrs
[snum
]->param_opt
;
1754 /* Traverse destination */
1755 for (paramo
=data
; paramo
; paramo
=paramo
->next
) {
1756 /* If we already have the option set, override it unless
1757 it was a command line option and the new one isn't */
1758 if (strcmp(paramo
->key
, name
) == 0) {
1759 if ((paramo
->flags
& FLAG_CMDLINE
) &&
1760 !(flags
& FLAG_CMDLINE
)) {
1764 free(paramo
->value
);
1765 paramo
->value
= strdup(pszParmValue
);
1766 paramo
->flags
= flags
;
1772 paramo
= malloc_p(struct param_opt
);
1775 paramo
->key
= strdup(name
);
1776 paramo
->value
= strdup(pszParmValue
);
1777 paramo
->flags
= flags
;
1779 DLIST_ADD(Globals
.param_opt
, paramo
);
1781 DLIST_ADD(ServicePtrs
[snum
]->param_opt
, paramo
);
1789 /***************************************************************************
1790 Process a parameter for a particular service number. If snum < 0
1791 then assume we are in the globals.
1792 ***************************************************************************/
1793 BOOL
lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
1796 void *parm_ptr
= NULL
; /* where we are going to store the result */
1797 void *def_ptr
= NULL
;
1799 parmnum
= map_parameter(pszParmName
);
1802 if (strchr(pszParmName
, ':')) {
1803 return lp_do_parameter_parametric(snum
, pszParmName
, pszParmValue
, 0);
1805 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
1809 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
1810 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
1814 /* if the flag has been set on the command line, then don't allow override,
1815 but don't report an error */
1816 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
1820 def_ptr
= parm_table
[parmnum
].ptr
;
1822 /* we might point at a service, the default service or a global */
1826 if (parm_table
[parmnum
].class == P_GLOBAL
) {
1828 ("Global parameter %s found in service section!\n",
1833 ((char *)ServicePtrs
[snum
]) + PTR_DIFF(def_ptr
,
1838 if (!ServicePtrs
[snum
]->copymap
)
1839 init_copymap(ServicePtrs
[snum
]);
1841 /* this handles the aliases - set the copymap for other entries with
1842 the same data pointer */
1843 for (i
= 0; parm_table
[i
].label
; i
++)
1844 if (parm_table
[i
].ptr
== parm_table
[parmnum
].ptr
)
1845 ServicePtrs
[snum
]->copymap
[i
] = False
;
1848 /* if it is a special case then go ahead */
1849 if (parm_table
[parmnum
].special
) {
1850 parm_table
[parmnum
].special(pszParmValue
, (char **)parm_ptr
);
1854 /* now switch on the type of variable it is */
1855 switch (parm_table
[parmnum
].type
)
1859 if (!set_boolean(pszParmValue
, &b
)) {
1860 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue
));
1863 *(int *)parm_ptr
= b
;
1868 *(int *)parm_ptr
= atoi(pszParmValue
);
1874 if (conv_str_size(pszParmValue
, &val
)) {
1875 if (val
<= INT_MAX
) {
1876 *(int *)parm_ptr
= (int)val
;
1881 DEBUG(0,("lp_do_parameter(%s): value is not "
1882 "a valid size specifier!\n", pszParmValue
));
1887 *(const char ***)parm_ptr
= str_list_make(talloc_autofree_context(),
1888 pszParmValue
, NULL
);
1892 string_set(parm_ptr
, pszParmValue
);
1896 string_set(parm_ptr
, pszParmValue
);
1897 strupper(*(char **)parm_ptr
);
1901 for (i
= 0; parm_table
[parmnum
].enum_list
[i
].name
; i
++) {
1904 parm_table
[parmnum
].enum_list
[i
].name
)) {
1906 parm_table
[parmnum
].
1911 if (!parm_table
[parmnum
].enum_list
[i
].name
) {
1912 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
1913 pszParmValue
, pszParmName
));
1921 if (parm_table
[parmnum
].flags
& FLAG_DEFAULT
) {
1922 parm_table
[parmnum
].flags
&= ~FLAG_DEFAULT
;
1923 /* we have to also unset FLAG_DEFAULT on aliases */
1924 for (i
=parmnum
-1;i
>=0 && parm_table
[i
].ptr
== parm_table
[parmnum
].ptr
;i
--) {
1925 parm_table
[i
].flags
&= ~FLAG_DEFAULT
;
1927 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].ptr
== parm_table
[parmnum
].ptr
;i
++) {
1928 parm_table
[i
].flags
&= ~FLAG_DEFAULT
;
1935 /***************************************************************************
1936 Process a parameter.
1937 ***************************************************************************/
1939 static BOOL
do_parameter(const char *pszParmName
, const char *pszParmValue
, void *userdata
)
1941 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
1942 pszParmName
, pszParmValue
));
1946 variable argument do parameter
1948 static BOOL
do_parameter_var(const char *pszParmName
, const char *fmt
, ...) PRINTF_ATTRIBUTE(2, 3);
1950 static BOOL
do_parameter_var(const char *pszParmName
, const char *fmt
, ...)
1957 s
= talloc_vasprintf(NULL
, fmt
, ap
);
1959 ret
= do_parameter(pszParmName
, s
, NULL
);
1966 set a parameter from the commandline - this is called from command line parameter
1967 parsing code. It sets the parameter then marks the parameter as unable to be modified
1968 by smb.conf processing
1970 BOOL
lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
1972 int parmnum
= map_parameter(pszParmName
);
1975 while (isspace((unsigned char)*pszParmValue
)) pszParmValue
++;
1978 if (parmnum
< 0 && strchr(pszParmName
, ':')) {
1979 /* set a parametric option */
1980 return lp_do_parameter_parametric(-1, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
1984 DEBUG(0,("Unknown option '%s'\n", pszParmName
));
1988 /* reset the CMDLINE flag in case this has been called before */
1989 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
1991 if (!lp_do_parameter(-2, pszParmName
, pszParmValue
)) {
1995 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
1997 /* we have to also set FLAG_CMDLINE on aliases */
1998 for (i
=parmnum
-1;i
>=0 && parm_table
[i
].ptr
== parm_table
[parmnum
].ptr
;i
--) {
1999 parm_table
[i
].flags
|= FLAG_CMDLINE
;
2001 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].ptr
== parm_table
[parmnum
].ptr
;i
++) {
2002 parm_table
[i
].flags
|= FLAG_CMDLINE
;
2009 set a option from the commandline in 'a=b' format. Use to support --option
2011 BOOL
lp_set_option(const char *option
)
2029 ret
= lp_set_cmdline(s
, p
+1);
2035 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2037 /***************************************************************************
2038 Print a parameter of the specified type.
2039 ***************************************************************************/
2041 static void print_parameter(struct parm_struct
*p
, void *ptr
, FILE * f
)
2047 for (i
= 0; p
->enum_list
[i
].name
; i
++) {
2048 if (*(int *)ptr
== p
->enum_list
[i
].value
) {
2050 p
->enum_list
[i
].name
);
2057 fprintf(f
, "%s", BOOLSTR((BOOL
)*(int *)ptr
));
2062 fprintf(f
, "%d", *(int *)ptr
);
2066 if ((char ***)ptr
&& *(char ***)ptr
) {
2067 char **list
= *(char ***)ptr
;
2069 for (; *list
; list
++)
2070 fprintf(f
, "%s%s", *list
,
2071 ((*(list
+1))?", ":""));
2077 if (*(char **)ptr
) {
2078 fprintf(f
, "%s", *(char **)ptr
);
2086 /***************************************************************************
2087 Check if two parameters are equal.
2088 ***************************************************************************/
2090 static BOOL
equal_parameter(parm_type type
, void *ptr1
, void *ptr2
)
2094 return (*((int *)ptr1
) == *((int *)ptr2
));
2099 return (*((int *)ptr1
) == *((int *)ptr2
));
2102 return str_list_equal((const char **)(*(char ***)ptr1
),
2103 (const char **)(*(char ***)ptr2
));
2108 char *p1
= *(char **)ptr1
, *p2
= *(char **)ptr2
;
2113 return (p1
== p2
|| strequal(p1
, p2
));
2121 /***************************************************************************
2122 Process a new section (service). At this stage all sections are services.
2123 Later we'll have special sections that permit server parameters to be set.
2124 Returns True on success, False on failure.
2125 ***************************************************************************/
2127 static BOOL
do_section(const char *pszSectionName
, void *userdata
)
2130 BOOL isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
2131 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
2134 /* if we've just struck a global section, note the fact. */
2135 bInGlobalSection
= isglobal
;
2137 /* check for multiple global sections */
2138 if (bInGlobalSection
) {
2139 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
2143 /* if we have a current service, tidy it up before moving on */
2146 if (iServiceIndex
>= 0)
2147 bRetval
= service_ok(iServiceIndex
);
2149 /* if all is still well, move to the next record in the services array */
2151 /* We put this here to avoid an odd message order if messages are */
2152 /* issued by the post-processing of a previous section. */
2153 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
2155 if ((iServiceIndex
= add_a_service(&sDefault
, pszSectionName
))
2157 DEBUG(0, ("Failed to add a new service\n"));
2166 /***************************************************************************
2167 Determine if a partcular base parameter is currentl set to the default value.
2168 ***************************************************************************/
2170 static BOOL
is_default(int i
)
2172 if (!defaults_saved
)
2174 switch (parm_table
[i
].type
) {
2176 return str_list_equal((const char **)parm_table
[i
].def
.lvalue
,
2177 (const char **)(*(char ***)parm_table
[i
].ptr
));
2180 return strequal(parm_table
[i
].def
.svalue
,
2181 *(char **)parm_table
[i
].ptr
);
2183 return parm_table
[i
].def
.bvalue
==
2184 *(int *)parm_table
[i
].ptr
;
2188 return parm_table
[i
].def
.ivalue
==
2189 *(int *)parm_table
[i
].ptr
;
2196 /***************************************************************************
2197 Display the contents of the global structure.
2198 ***************************************************************************/
2200 static void dump_globals(FILE *f
, BOOL show_defaults
)
2203 struct param_opt
*data
;
2205 fprintf(f
, "# Global parameters\n[global]\n");
2207 for (i
= 0; parm_table
[i
].label
; i
++)
2208 if (parm_table
[i
].class == P_GLOBAL
&&
2209 parm_table
[i
].ptr
&&
2210 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
))) {
2211 if (!show_defaults
&& (parm_table
[i
].flags
& FLAG_DEFAULT
))
2213 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
2214 print_parameter(&parm_table
[i
], parm_table
[i
].ptr
, f
);
2217 if (Globals
.param_opt
!= NULL
) {
2218 data
= Globals
.param_opt
;
2220 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
2227 /***************************************************************************
2228 Display the contents of a single services record.
2229 ***************************************************************************/
2231 static void dump_a_service(service
* pService
, FILE * f
)
2234 struct param_opt
*data
;
2236 if (pService
!= &sDefault
)
2237 fprintf(f
, "\n[%s]\n", pService
->szService
);
2239 for (i
= 0; parm_table
[i
].label
; i
++)
2240 if (parm_table
[i
].class == P_LOCAL
&&
2241 parm_table
[i
].ptr
&&
2242 (*parm_table
[i
].label
!= '-') &&
2243 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
))) {
2244 int pdiff
= PTR_DIFF(parm_table
[i
].ptr
, &sDefault
);
2246 if (pService
== &sDefault
) {
2247 if (defaults_saved
&& is_default(i
))
2250 if (equal_parameter(parm_table
[i
].type
,
2251 ((char *)pService
) +
2253 ((char *)&sDefault
) +
2258 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
2259 print_parameter(&parm_table
[i
],
2260 ((char *)pService
) + pdiff
, f
);
2263 if (pService
->param_opt
!= NULL
) {
2264 data
= pService
->param_opt
;
2266 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
2272 BOOL
lp_dump_a_parameter(int snum
, char *parm_name
, FILE * f
, BOOL isGlobal
)
2274 service
* pService
= ServicePtrs
[snum
];
2275 struct parm_struct
*parm
;
2278 parm
= lp_parm_struct(parm_name
);
2286 ptr
= ((char *)pService
) +
2287 PTR_DIFF(parm
->ptr
, &sDefault
);
2289 print_parameter(parm
,
2295 /***************************************************************************
2296 Return info about the next service in a service. snum==-1 gives the globals.
2297 Return NULL when out of parameters.
2298 ***************************************************************************/
2300 struct parm_struct
*lp_next_parameter(int snum
, int *i
, int allparameters
)
2303 /* do the globals */
2304 for (; parm_table
[*i
].label
; (*i
)++) {
2305 if (parm_table
[*i
].class == P_SEPARATOR
)
2306 return &parm_table
[(*i
)++];
2308 if (!parm_table
[*i
].ptr
2309 || (*parm_table
[*i
].label
== '-'))
2313 && (parm_table
[*i
].ptr
==
2314 parm_table
[(*i
) - 1].ptr
))
2317 return &parm_table
[(*i
)++];
2320 service
*pService
= ServicePtrs
[snum
];
2322 for (; parm_table
[*i
].label
; (*i
)++) {
2323 if (parm_table
[*i
].class == P_SEPARATOR
)
2324 return &parm_table
[(*i
)++];
2326 if (parm_table
[*i
].class == P_LOCAL
&&
2327 parm_table
[*i
].ptr
&&
2328 (*parm_table
[*i
].label
!= '-') &&
2330 (parm_table
[*i
].ptr
!=
2331 parm_table
[(*i
) - 1].ptr
)))
2334 PTR_DIFF(parm_table
[*i
].ptr
,
2337 if (allparameters
||
2338 !equal_parameter(parm_table
[*i
].type
,
2339 ((char *)pService
) +
2341 ((char *)&sDefault
) +
2344 return &parm_table
[(*i
)++];
2354 /***************************************************************************
2355 Return TRUE if the passed service number is within range.
2356 ***************************************************************************/
2358 BOOL
lp_snum_ok(int iService
)
2360 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
2363 /***************************************************************************
2364 Auto-load some home services.
2365 ***************************************************************************/
2367 static void lp_add_auto_services(const char *str
)
2372 /***************************************************************************
2373 Have we loaded a services file yet?
2374 ***************************************************************************/
2376 BOOL
lp_loaded(void)
2381 /***************************************************************************
2382 Unload unused services.
2383 ***************************************************************************/
2385 void lp_killunused(struct smbsrv_connection
*smb
, BOOL (*snumused
) (struct smbsrv_connection
*, int))
2388 for (i
= 0; i
< iNumServices
; i
++) {
2392 if (!snumused
|| !snumused(smb
, i
)) {
2393 ServicePtrs
[i
]->valid
= False
;
2394 free_service(ServicePtrs
[i
]);
2399 /***************************************************************************
2401 ***************************************************************************/
2403 void lp_killservice(int iServiceIn
)
2405 if (VALID(iServiceIn
)) {
2406 ServicePtrs
[iServiceIn
]->valid
= False
;
2407 free_service(ServicePtrs
[iServiceIn
]);
2411 /***************************************************************************
2412 Load the services array from the services file. Return True on success,
2414 ***************************************************************************/
2420 struct param_opt
*data
;
2424 bInGlobalSection
= True
;
2426 if (Globals
.param_opt
!= NULL
) {
2427 struct param_opt
*next
;
2428 for (data
=Globals
.param_opt
; data
; data
=next
) {
2430 if (data
->flags
& FLAG_CMDLINE
) continue;
2433 DLIST_REMOVE(Globals
.param_opt
, data
);
2440 pstrcpy(n2
, lp_configfile());
2441 standard_sub_basic(n2
,sizeof(n2
));
2442 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2
));
2444 add_to_file_list(lp_configfile(), n2
);
2446 /* We get sections first, so have to start 'behind' to make up */
2448 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
2450 /* finish up the last section */
2451 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
2453 if (iServiceIndex
>= 0)
2454 bRetval
= service_ok(iServiceIndex
);
2456 lp_add_auto_services(lp_auto_services());
2458 lp_add_hidden("IPC$", "IPC");
2459 lp_add_hidden("ADMIN$", "DISK");
2463 if (!Globals
.szWINSservers
&& Globals
.bWINSsupport
) {
2464 lp_do_parameter(-1, "wins server", "127.0.0.1");
2472 /***************************************************************************
2473 Reset the max number of services.
2474 ***************************************************************************/
2476 void lp_resetnumservices(void)
2481 /***************************************************************************
2482 Return the max number of services.
2483 ***************************************************************************/
2485 int lp_numservices(void)
2487 return (iNumServices
);
2490 /***************************************************************************
2491 Display the contents of the services array in human-readable form.
2492 ***************************************************************************/
2494 void lp_dump(FILE *f
, BOOL show_defaults
, int maxtoprint
)
2499 defaults_saved
= False
;
2501 dump_globals(f
, show_defaults
);
2503 dump_a_service(&sDefault
, f
);
2505 for (iService
= 0; iService
< maxtoprint
; iService
++)
2506 lp_dump_one(f
, show_defaults
, iService
);
2509 /***************************************************************************
2510 Display the contents of one service in human-readable form.
2511 ***************************************************************************/
2513 void lp_dump_one(FILE * f
, BOOL show_defaults
, int snum
)
2516 if (ServicePtrs
[snum
]->szService
[0] == '\0')
2518 dump_a_service(ServicePtrs
[snum
], f
);
2522 /***************************************************************************
2523 Return the number of the service with the given name, or -1 if it doesn't
2524 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2525 getservicebyname()! This works ONLY if all services have been loaded, and
2526 does not copy the found service.
2527 ***************************************************************************/
2529 int lp_servicenumber(const char *pszServiceName
)
2532 fstring serviceName
;
2535 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
2536 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
2538 * The substitution here is used to support %U is
2541 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
2542 standard_sub_basic(serviceName
,sizeof(serviceName
));
2543 if (strequal(serviceName
, pszServiceName
))
2549 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
2554 int lp_find_valid_service(const char *pszServiceName
)
2558 iService
= lp_servicenumber(pszServiceName
);
2560 if (iService
>= 0 && !lp_snum_ok(iService
)) {
2561 DEBUG(0,("lp_find_valid_service: Invalid snum %d for '%s'\n",iService
, pszServiceName
));
2565 if (iService
== -1) {
2566 DEBUG(3,("lp_find_valid_service: failed to find service '%s'\n", pszServiceName
));
2572 /*******************************************************************
2573 A useful volume label function.
2574 ********************************************************************/
2575 const char *volume_label(int snum
)
2577 const char *ret
= lp_volume(snum
);
2579 return lp_servicename(snum
);
2584 /***********************************************************
2585 If we are PDC then prefer us as DMB
2586 ************************************************************/
2588 BOOL
lp_domain_logons(void)
2590 return (lp_server_role() == ROLE_DOMAIN_CONTROLLER
);
2593 /*******************************************************************
2595 ********************************************************************/
2597 void lp_remove_service(int snum
)
2599 ServicePtrs
[snum
]->valid
= False
;
2602 /*******************************************************************
2604 ********************************************************************/
2606 void lp_copy_service(int snum
, const char *new_name
)
2608 const char *oldname
= lp_servicename(snum
);
2609 do_section(new_name
, NULL
);
2611 snum
= lp_servicenumber(new_name
);
2613 lp_do_parameter(snum
, "copy", oldname
);
2617 const char *lp_printername(int snum
)
2619 const char *ret
= _lp_printername(snum
);
2620 if (ret
== NULL
|| (ret
!= NULL
&& *ret
== '\0'))
2621 ret
= lp_const_servicename(snum
);
2627 /*******************************************************************
2628 Return the max print jobs per queue.
2629 ********************************************************************/
2631 int lp_maxprintjobs(int snum
)
2633 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
2634 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
2635 maxjobs
= PRINT_MAX_JOBID
- 1;