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 BOOL in_client = False; /* Not in the client by default */
58 static BOOL bLoaded = False;
61 #define GLOBAL_NAME "global"
65 #define PRINTERS_NAME "printers"
69 #define HOMES_NAME "homes"
72 /* some helpful bits */
73 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
74 #define VALID(i) ServicePtrs[i]->valid
76 static BOOL do_parameter(const char *, const char *);
77 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
79 static BOOL defaults_saved = False;
82 struct param_opt *prev, *next;
89 * This structure describes global (ie., server-wide) parameters.
97 char *display_charset;
102 char *szDefaultService;
104 char *szServerString;
105 char *szAutoServices;
106 char *szPasswdProgram;
110 char *szSMBPasswdFile;
114 char **szPreloadModules;
115 char *szPasswordServer;
116 char *szSocketOptions;
123 char **szWINSservers;
125 char *szRemoteAnnounce;
126 char *szRemoteBrowseSync;
127 char *szSocketAddress;
128 char *szAnnounceVersion; /* This is initialised in init_globals */
131 char **szNetbiosAliases;
132 char *szNetbiosScope;
133 char *szDomainOtherSIDs;
134 char *szNameResolveOrder;
136 char *szAddUserScript;
137 char *szAddMachineScript;
139 char *szWINSPartners;
140 char **dcerpc_ep_servers;
141 char **server_services;
144 char *szNonUnixAccountRange;
145 char *szTemplateHomedir;
146 char *szTemplateShell;
147 char *szWinbindSeparator;
148 BOOL bWinbindEnumUsers;
149 BOOL bWinbindEnumGroups;
150 BOOL bWinbindUseDefaultDomain;
151 char *szIDMapBackend;
152 char *szGuestaccount;
161 BOOL paranoid_server_security;
163 BOOL bDisableSpoolss;
165 int enhanced_browsing;
172 int announce_as; /* This is initialised in init_globals */
173 int machine_password_timeout;
174 int winbind_cache_time;
177 char *socket_options;
182 BOOL bPreferredMaster;
185 BOOL bEncryptPasswords;
187 BOOL bObeyPamRestrictions;
189 BOOL bLargeReadwrite;
193 BOOL bBindInterfacesOnly;
194 BOOL bPamPasswordChange;
196 BOOL bNTStatusSupport;
197 BOOL bAllowTrustedDomains;
203 BOOL bClientLanManAuth;
204 BOOL bClientNTLMv2Auth;
206 BOOL bHideLocalUsers;
209 BOOL bHostnameLookups;
210 BOOL bUnixExtensions;
211 BOOL bDisableNetbios;
213 int restrict_anonymous;
214 int name_cache_timeout;
215 struct param_opt *param_opt;
219 static global Globals;
222 * This structure describes a single service.
231 char **szInvalidUsers;
236 char *szPrintcommand;
239 char *szLppausecommand;
240 char *szLpresumecommand;
241 char *szQueuepausecommand;
242 char *szQueueresumecommand;
250 char **ntvfs_handler;
275 struct param_opt *param_opt;
277 char dummy[3]; /* for alignment */
282 /* This is a default service used to prime a services structure */
283 static service sDefault = {
285 False, /* not autoloaded */
286 NULL, /* szService */
288 NULL, /* szUsername */
289 NULL, /* szInvalidUsers */
290 NULL, /* szValidUsers */
291 NULL, /* szAdminUsers */
293 NULL, /* szInclude */
294 NULL, /* szPrintcommand */
295 NULL, /* szLpqcommand */
296 NULL, /* szLprmcommand */
297 NULL, /* szLppausecommand */
298 NULL, /* szLpresumecommand */
299 NULL, /* szQueuepausecommand */
300 NULL, /* szQueueresumecommand */
301 NULL, /* szPrintername */
302 NULL, /* szHostsallow */
303 NULL, /* szHostsdeny */
307 NULL, /* szMSDfsProxy */
308 NULL, /* ntvfs_handler */
309 0, /* iMinPrintSpace */
310 1000, /* iMaxPrintJobs */
311 0, /* iMaxConnections */
312 DEFAULT_PRINTING, /* iPrinting */
314 True, /* bAvailable */
315 True, /* bBrowseable */
316 True, /* bRead_only */
317 False, /* bPrint_ok */
318 False, /* bMap_system */
319 False, /* bMap_hidden */
320 True, /* bMap_archive */
322 True, /* bStrictLocking */
323 True, /* bPosixLocking */
325 True, /* bLevel2OpLocks */
326 False, /* bOnlyUser */
327 False, /* bGuest_only */
328 False, /* bGuest_ok */
330 False, /* bMSDfsRoot */
331 True, /* bShareModes */
332 False, /* bStrictSync */
333 NULL, /* Parametric options */
338 /* local variables */
339 static service **ServicePtrs = NULL;
340 static int iNumServices = 0;
341 static int iServiceIndex = 0;
342 static BOOL bInGlobalSection = True;
343 static BOOL bGlobalOnly = False;
344 static int server_role;
345 static int default_server_announce;
347 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
349 /* prototypes for the special type handlers */
350 static BOOL handle_include(const char *pszParmValue, char **ptr);
351 static BOOL handle_copy(const char *pszParmValue, char **ptr);
352 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
353 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
354 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
356 static void set_server_role(void);
357 static void set_default_server_announce_type(void);
359 static const struct enum_list enum_protocol[] = {
360 {PROTOCOL_NT1, "NT1"},
361 {PROTOCOL_LANMAN2, "LANMAN2"},
362 {PROTOCOL_LANMAN1, "LANMAN1"},
363 {PROTOCOL_CORE, "CORE"},
364 {PROTOCOL_COREPLUS, "COREPLUS"},
365 {PROTOCOL_COREPLUS, "CORE+"},
369 static const struct enum_list enum_security[] = {
370 {SEC_SHARE, "SHARE"},
372 {SEC_SERVER, "SERVER"},
373 {SEC_DOMAIN, "DOMAIN"},
380 static const struct enum_list enum_printing[] = {
381 {PRINT_SYSV, "sysv"},
383 {PRINT_HPUX, "hpux"},
387 {PRINT_LPRNG, "lprng"},
388 {PRINT_SOFTQ, "softq"},
389 {PRINT_CUPS, "cups"},
391 {PRINT_LPROS2, "os2"},
393 {PRINT_TEST, "test"},
395 #endif /* DEVELOPER */
399 /* Types of machine we can announce as. */
400 #define ANNOUNCE_AS_NT_SERVER 1
401 #define ANNOUNCE_AS_WIN95 2
402 #define ANNOUNCE_AS_WFW 3
403 #define ANNOUNCE_AS_NT_WORKSTATION 4
405 static const struct enum_list enum_announce_as[] = {
406 {ANNOUNCE_AS_NT_SERVER, "NT"},
407 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
408 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
409 {ANNOUNCE_AS_WIN95, "win95"},
410 {ANNOUNCE_AS_WFW, "WfW"},
414 static const struct enum_list enum_case[] = {
415 {CASE_LOWER, "lower"},
416 {CASE_UPPER, "upper"},
420 static const struct enum_list enum_bool_auto[] = {
431 /* Client-side offline caching policy types */
432 #define CSC_POLICY_MANUAL 0
433 #define CSC_POLICY_DOCUMENTS 1
434 #define CSC_POLICY_PROGRAMS 2
435 #define CSC_POLICY_DISABLE 3
437 static const struct enum_list enum_csc_policy[] = {
438 {CSC_POLICY_MANUAL, "manual"},
439 {CSC_POLICY_DOCUMENTS, "documents"},
440 {CSC_POLICY_PROGRAMS, "programs"},
441 {CSC_POLICY_DISABLE, "disable"},
445 /* SMB signing types. */
446 static const struct enum_list enum_smb_signing_vals[] = {
447 {SMB_SIGNING_OFF, "No"},
448 {SMB_SIGNING_OFF, "False"},
449 {SMB_SIGNING_OFF, "0"},
450 {SMB_SIGNING_OFF, "Off"},
451 {SMB_SIGNING_OFF, "disabled"},
452 {SMB_SIGNING_SUPPORTED, "Yes"},
453 {SMB_SIGNING_SUPPORTED, "True"},
454 {SMB_SIGNING_SUPPORTED, "1"},
455 {SMB_SIGNING_SUPPORTED, "On"},
456 {SMB_SIGNING_SUPPORTED, "enabled"},
457 {SMB_SIGNING_SUPPORTED, "auto"},
458 {SMB_SIGNING_REQUIRED, "required"},
459 {SMB_SIGNING_REQUIRED, "mandatory"},
460 {SMB_SIGNING_REQUIRED, "force"},
461 {SMB_SIGNING_REQUIRED, "forced"},
462 {SMB_SIGNING_REQUIRED, "enforced"},
467 Do you want session setups at user level security with a invalid
468 password to be rejected or allowed in as guest? WinNT rejects them
469 but it can be a pain as it means "net view" needs to use a password
471 You have 3 choices in the setting of map_to_guest:
473 "Never" means session setups with an invalid password
474 are rejected. This is the default.
476 "Bad User" means session setups with an invalid password
477 are rejected, unless the username does not exist, in which case it
478 is treated as a guest login
480 "Bad Password" means session setups with an invalid password
481 are treated as a guest login
483 Note that map_to_guest only has an effect in user or server
487 static const struct enum_list enum_map_to_guest[] = {
488 {NEVER_MAP_TO_GUEST, "Never"},
489 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
490 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
494 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
496 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
497 * is implied in current control logic. This may change at some later time. A
498 * flag value of 0 means - show as development option only.
500 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
501 * screen in SWAT. This is used to exclude parameters as well as to squash all
502 * parameters that have been duplicated by pseudonyms.
504 static struct parm_struct parm_table[] = {
505 {"Base Options", P_SEP, P_SEPARATOR},
507 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
508 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
509 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
510 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
511 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
512 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
513 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
514 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
515 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
516 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
517 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
518 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
519 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
520 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
521 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
522 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
523 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
524 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
525 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
527 {"Security Options", P_SEP, P_SEPARATOR},
529 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
530 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
531 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
532 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
533 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
538 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
546 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
560 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
561 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
563 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
564 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
565 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
567 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
569 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
571 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
573 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
574 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
575 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
576 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
578 {"Logging Options", P_SEP, P_SEPARATOR},
580 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
582 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"Protocol Options", P_SEP, P_SEPARATOR},
586 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
588 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
589 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
590 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
591 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
592 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
593 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
595 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
597 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
598 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
599 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
600 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
602 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
603 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
605 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
606 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
608 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
609 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
610 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
611 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
613 {"Tuning Options", P_SEP, P_SEPARATOR},
615 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
616 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
617 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
618 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
620 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
621 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
622 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
624 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
625 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
627 {"Printing Options", P_SEP, P_SEPARATOR},
629 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
630 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
631 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
632 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
633 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
634 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
635 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
636 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
637 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
638 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
639 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
640 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
641 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
642 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
643 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
645 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
646 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
648 {"Filename Handling", P_SEP, P_SEPARATOR},
650 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
651 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
652 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
654 {"Domain Options", P_SEP, P_SEPARATOR},
656 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
658 {"Logon Options", P_SEP, P_SEPARATOR},
660 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
661 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
663 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
664 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
665 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
666 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
667 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
669 {"Browse Options", P_SEP, P_SEPARATOR},
671 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
672 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
673 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
674 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
675 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
676 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
677 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
678 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
679 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
680 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
682 {"WINS Options", P_SEP, P_SEPARATOR},
683 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
684 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
686 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
687 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
688 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
689 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
691 {"Locking Options", P_SEP, P_SEPARATOR},
693 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
694 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
695 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
696 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
698 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
699 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
700 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
701 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
702 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
704 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
706 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
707 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
708 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
709 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
710 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
714 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
715 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
717 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
718 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
719 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
721 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
722 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
724 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
725 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
726 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
728 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
729 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
731 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
732 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
733 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734 {"Winbind options", P_SEP, P_SEPARATOR},
736 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
737 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
739 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
749 /***************************************************************************
750 Initialise the sDefault parameter structure for the printer values.
751 ***************************************************************************/
753 static void init_printer_values(void)
755 /* choose defaults depending on the type of printing */
756 switch (sDefault.iPrinting) {
761 do_parameter("Lpqcommand", "lpq -P'%p'");
762 do_parameter("Lprmcommand", "lprm -P'%p' %j");
763 do_parameter("Printcommand",
769 do_parameter("Lpqcommand", "lpq -P'%p'");
770 do_parameter("Lprmcommand", "lprm -P'%p' %j");
771 do_parameter("Printcommand",
773 do_parameter("Queuepausecommand",
775 do_parameter("Queueresumecommand",
777 do_parameter("Lppausecommand",
779 do_parameter("Lpresumecommand",
780 "lpc release '%p' %j");
785 do_parameter("Lpqcommand", "");
786 do_parameter("Lprmcommand", "");
787 do_parameter("Printcommand", "");
788 do_parameter("Lppausecommand", "");
789 do_parameter("Lpresumecommand", "");
790 do_parameter("Queuepausecommand", "");
791 do_parameter("Queueresumecommand", "");
793 do_parameter("Printcapname", "cups");
795 do_parameter("Lpqcommand",
796 "/usr/bin/lpstat -o '%p'");
797 do_parameter("Lprmcommand",
798 "/usr/bin/cancel '%p-%j'");
799 do_parameter("Printcommand",
800 "/usr/bin/lp -d '%p' %s; rm %s");
801 do_parameter("Lppausecommand",
802 "lp -i '%p-%j' -H hold");
803 do_parameter("Lpresumecommand",
804 "lp -i '%p-%j' -H resume");
805 do_parameter("Queuepausecommand",
806 "/usr/bin/disable '%p'");
807 do_parameter("Queueresumecommand",
808 "/usr/bin/enable '%p'");
809 do_parameter("Printcapname", "lpstat");
810 #endif /* HAVE_CUPS */
815 do_parameter("Lpqcommand", "lpstat -o%p");
816 do_parameter("Lprmcommand", "cancel %p-%j");
817 do_parameter("Printcommand",
818 "lp -c -d%p %s; rm %s");
819 do_parameter("Queuepausecommand",
821 do_parameter("Queueresumecommand",
824 do_parameter("Lppausecommand",
825 "lp -i %p-%j -H hold");
826 do_parameter("Lpresumecommand",
827 "lp -i %p-%j -H resume");
832 do_parameter("Lpqcommand", "lpq -P%p");
833 do_parameter("Lprmcommand", "lprm -P%p %j");
834 do_parameter("Printcommand", "lp -r -P%p %s");
838 do_parameter("Lpqcommand", "qstat -l -d%p");
839 do_parameter("Lprmcommand",
841 do_parameter("Printcommand",
842 "lp -d%p -s %s; rm %s");
843 do_parameter("Lppausecommand",
845 do_parameter("Lpresumecommand",
851 do_parameter("Printcommand", "vlp print %p %s");
852 do_parameter("Lpqcommand", "vlp lpq %p");
853 do_parameter("Lprmcommand", "vlp lprm %p %j");
854 do_parameter("Lppausecommand", "vlp lppause %p %j");
855 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
856 do_parameter("Queuepausecommand", "vlp queuepause %p");
857 do_parameter("Queueresumecommand", "vlp queueresume %p");
859 #endif /* DEVELOPER */
865 /***************************************************************************
866 Initialise the global parameter structure.
867 ***************************************************************************/
868 static void init_globals(void)
872 DEBUG(3, ("Initialising global parameters\n"));
874 for (i = 0; parm_table[i].label; i++) {
875 if ((parm_table[i].type == P_STRING ||
876 parm_table[i].type == P_USTRING) &&
878 !(parm_table[i].flags & FLAG_CMDLINE)) {
879 string_set(parm_table[i].ptr, "");
883 /* options that can be set on the command line must be initialised via
884 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
885 do_parameter("socket options", DEFAULT_SOCKET_OPTIONS);
886 do_parameter("workgroup", DEFAULT_WORKGROUP);
887 do_parameter("netbios name", get_myname());
888 do_parameter("max protocol", "NT1");
889 do_parameter("name resolve order", "lmhosts wins host bcast");
891 init_printer_values();
893 do_parameter("fstype", FSTYPE_STRING);
894 do_parameter("ntvfs handler", "unixuid default");
896 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi");
897 do_parameter("server services", "smb rpc");
898 do_parameter("auth methods", "guest sam_ignoredomain");
899 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
900 do_parameter("private dir", dyn_PRIVATE_DIR);
901 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
902 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
903 do_parameter("guest account", GUEST_ACCOUNT);
905 /* using UTF8 by default allows us to support all chars */
906 do_parameter("unix charset", "UTF8");
908 /* Use codepage 850 as a default for the dos character set */
909 do_parameter("dos charset", "CP850");
912 * Allow the default PASSWD_CHAT to be overridden in local.h.
914 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
916 do_parameter("passwd program", "");
917 do_parameter("printcap name", PRINTCAP_NAME);
919 do_parameter("pid directory", dyn_PIDDIR);
920 do_parameter("lock dir", dyn_LOCKDIR);
921 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
923 do_parameter("socket address", "0.0.0.0");
924 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
926 do_parameter_var("announce version", "%d.%d",
927 DEFAULT_MAJOR_VERSION,
928 DEFAULT_MINOR_VERSION);
930 do_parameter("logon drive", "");
932 do_parameter("logon home", "\\\\%N\\%U");
933 do_parameter("logon path", "\\\\%N\\%U\\profile");
934 do_parameter("password server", "*");
936 do_parameter("load printers", "True");
938 do_parameter("max mux", "50");
939 do_parameter("max xmit", "4356");
940 do_parameter("lpqcachetime", "10");
941 do_parameter("DisableSpoolss", "False");
942 do_parameter("password level", "0");
943 do_parameter("username level", "0");
944 do_parameter("LargeReadwrite", "True");
945 do_parameter("minprotocol", "CORE");
946 do_parameter("security", "USER");
947 do_parameter("paranoid server security", "True");
948 do_parameter("EncryptPasswords", "True");
949 do_parameter("ReadRaw", "True");
950 do_parameter("WriteRaw", "True");
951 do_parameter("NullPasswords", "False");
952 do_parameter("ObeyPamRestrictions", "False");
953 do_parameter("lm announce", "Auto");
954 do_parameter("lm interval", "60");
955 do_parameter("announce as", "NT SERVER");
957 do_parameter("TimeServer", "False");
958 do_parameter("BindInterfacesOnly", "False");
959 do_parameter("PamPasswordChange", "False");
960 do_parameter("Unicode", "True");
961 do_parameter("restrict anonymous", "0");
962 do_parameter("ClientLanManAuth", "True");
963 do_parameter("LanmanAuth", "True");
964 do_parameter("NTLMAuth", "True");
966 do_parameter("enhanced browsing", "True");
967 do_parameter("LockSpinCount", "3");
968 do_parameter("LockSpinTime", "10");
969 #ifdef MMAP_BLACKLIST
970 do_parameter("UseMmap", "False");
972 do_parameter("UseMmap", "True");
974 do_parameter("UnixExtensions", "False");
976 /* hostname lookups can be very expensive and are broken on
977 a large number of sites (tridge) */
978 do_parameter("HostnameLookups", "False");
980 do_parameter("PreferredMaster", "Auto");
981 do_parameter("os level", "20");
982 do_parameter("LocalMaster", "True");
983 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
984 do_parameter("DomainLogons", "False");
985 do_parameter("WINSsupport", "False");
986 do_parameter("WINSproxy", "False");
988 do_parameter("DNSproxy", "True");
990 do_parameter("AllowTrustedDomains", "True");
992 do_parameter("TemplateShell", "/bin/false");
993 do_parameter("TemplateHomedir", "/home/%D/%U");
994 do_parameter("WinbindSeparator", "\\");
996 do_parameter("winbind cache time", "15");
997 do_parameter("WinbindEnumUsers", "True");
998 do_parameter("WinbindEnumGroups", "True");
999 do_parameter("WinbindUseDefaultDomain", "False");
1001 do_parameter("IDMapBackend", "tdb");
1003 do_parameter("name cache timeout", "660"); /* In seconds */
1005 do_parameter("client signing", "Yes");
1006 do_parameter("server signing", "Yes");
1008 do_parameter("use spnego", "True");
1010 do_parameter("smb ports", SMB_PORTS);
1012 do_parameter("nt status support", "True");
1015 static TALLOC_CTX *lp_talloc;
1017 /******************************************************************* a
1018 Free up temporary memory - called from the main loop.
1019 ********************************************************************/
1021 void lp_talloc_free(void)
1025 talloc_free(lp_talloc);
1029 /*******************************************************************
1030 Convenience routine to grab string parameters into temporary memory
1031 and run standard_sub_basic on them. The buffers can be written to by
1032 callers without affecting the source string.
1033 ********************************************************************/
1035 static const char *lp_string(const char *s)
1037 #if 0 /* until REWRITE done to make thread-safe */
1038 size_t len = s ? strlen(s) : 0;
1042 /* The follow debug is useful for tracking down memory problems
1043 especially if you have an inner loop that is calling a lp_*()
1044 function that returns a string. Perhaps this debug should be
1045 present all the time? */
1048 DEBUG(10, ("lp_string(%s)\n", s));
1051 #if 0 /* until REWRITE done to make thread-safe */
1053 lp_talloc = talloc_init("lp_talloc");
1055 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1063 StrnCpy(ret, s, len);
1065 if (trim_string(ret, "\"", "\"")) {
1066 if (strchr(ret,'"') != NULL)
1067 StrnCpy(ret, s, len);
1070 standard_sub_basic(ret,len+100);
1077 In this section all the functions that are used to access the
1078 parameters from the rest of the program are defined
1081 #define FN_GLOBAL_STRING(fn_name,ptr) \
1082 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1083 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1084 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1085 #define FN_GLOBAL_LIST(fn_name,ptr) \
1086 const char **fn_name(void) {return(*(const char ***)(ptr));}
1087 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1088 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1089 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1090 char fn_name(void) {return(*(char *)(ptr));}
1091 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1092 int fn_name(void) {return(*(int *)(ptr));}
1094 #define FN_LOCAL_STRING(fn_name,val) \
1095 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1096 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1097 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1098 #define FN_LOCAL_LIST(fn_name,val) \
1099 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1100 #define FN_LOCAL_BOOL(fn_name,val) \
1101 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1102 #define FN_LOCAL_CHAR(fn_name,val) \
1103 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1104 #define FN_LOCAL_INTEGER(fn_name,val) \
1105 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1107 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1108 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1109 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1110 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1111 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1112 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1113 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1114 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1115 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1116 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1117 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1118 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1119 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1120 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1121 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1122 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1123 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1124 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1125 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1126 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1127 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1128 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1129 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1130 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1131 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1132 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1133 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1134 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1135 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1136 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1137 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1138 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1139 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1140 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1141 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1142 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1143 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1144 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1145 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1146 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1147 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1148 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1149 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1150 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1151 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1153 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1155 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1157 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1158 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1159 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1160 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1161 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1162 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1163 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1164 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1165 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1167 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1168 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1169 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1170 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1171 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1172 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1173 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1174 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1175 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1176 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1177 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1178 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1179 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1180 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1181 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1182 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1183 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1184 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1185 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1186 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1187 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1188 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1189 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1190 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1191 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1192 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1193 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1194 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1195 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1196 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1197 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1198 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1199 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1200 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1201 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1202 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1203 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1204 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1205 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1206 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1207 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1208 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1209 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1210 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1211 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1212 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1213 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1214 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1215 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1216 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1217 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1218 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1219 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1220 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1221 FN_LOCAL_STRING(lp_servicename, szService)
1222 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1223 FN_LOCAL_STRING(lp_pathname, szPath)
1224 FN_LOCAL_STRING(lp_username, szUsername)
1225 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1226 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1227 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1228 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1229 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1230 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1231 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1232 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1233 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1234 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1235 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1236 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1237 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1238 FN_LOCAL_STRING(lp_comment, comment)
1239 FN_LOCAL_STRING(lp_fstype, fstype)
1240 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1241 static FN_LOCAL_STRING(lp_volume, volume)
1242 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1243 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1244 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1245 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1246 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1247 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1248 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1249 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1250 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1251 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1252 FN_LOCAL_BOOL(lp_locking, bLocking)
1253 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1254 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1255 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1256 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1257 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1258 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1259 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1260 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1261 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1262 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1263 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1264 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1265 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1266 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1267 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1268 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1269 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1271 /* local prototypes */
1273 static int map_parameter(const char *pszParmName);
1274 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1275 static int getservicebyname(const char *pszServiceName,
1276 service * pserviceDest);
1277 static void copy_service(service * pserviceDest,
1278 service * pserviceSource, BOOL *pcopymapDest);
1279 static BOOL service_ok(int iService);
1280 static BOOL do_section(const char *pszSectionName);
1281 static void init_copymap(service * pservice);
1283 /* This is a helper function for parametrical options support. */
1284 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1285 /* Actual parametrical functions are quite simple */
1286 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1289 struct param_opt *data;
1291 if (lookup_service >= iNumServices) return NULL;
1293 data = (lookup_service < 0) ?
1294 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1296 asprintf(&vfskey, "%s:%s", type, option);
1300 if (strcmp(data->key, vfskey) == 0) {
1307 if (lookup_service >= 0) {
1308 /* Try to fetch the same option but from globals */
1309 /* but only if we are not already working with Globals */
1310 data = Globals.param_opt;
1312 if (strcmp(data->key, vfskey) == 0) {
1326 /*******************************************************************
1327 convenience routine to return int parameters.
1328 ********************************************************************/
1329 static int lp_int(const char *s)
1333 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1340 /*******************************************************************
1341 convenience routine to return unsigned long parameters.
1342 ********************************************************************/
1343 static int lp_ulong(const char *s)
1347 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1351 return strtoul(s, NULL, 10);
1354 /*******************************************************************
1355 convenience routine to return boolean parameters.
1356 ********************************************************************/
1357 static BOOL lp_bool(const char *s)
1362 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1366 if (!set_boolean(&ret,s)) {
1367 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1374 /*******************************************************************
1375 convenience routine to return enum parameters.
1376 ********************************************************************/
1377 static int lp_enum(const char *s,const struct enum_list *_enum)
1382 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1386 for (i=0; _enum[i].name; i++) {
1387 if (strcasecmp(_enum[i].name,s)==0)
1388 return _enum[i].value;
1391 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1395 /* Return parametric option from a given service. Type is a part of option before ':' */
1396 /* Parametric option has following syntax: 'Type: option = value' */
1397 /* Returned value is allocated in 'lp_talloc' context */
1399 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1401 const char *value = get_parametrics(lookup_service, type, option);
1404 return lp_string(value);
1409 /* Return parametric option from a given service. Type is a part of option before ':' */
1410 /* Parametric option has following syntax: 'Type: option = value' */
1411 /* Returned value is allocated in 'lp_talloc' context */
1413 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1414 const char *separator)
1416 const char *value = get_parametrics(lookup_service, type, option);
1419 return str_list_make(value, separator);
1424 /* Return parametric option from a given service. Type is a part of option before ':' */
1425 /* Parametric option has following syntax: 'Type: option = value' */
1427 int lp_parm_int(int lookup_service, const char *type, const char *option)
1429 const char *value = get_parametrics(lookup_service, type, option);
1432 return lp_int(value);
1437 /* Return parametric option from a given service. Type is a part of option before ':' */
1438 /* Parametric option has following syntax: 'Type: option = value' */
1440 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1442 const char *value = get_parametrics(lookup_service, type, option);
1445 return lp_ulong(value);
1450 /* Return parametric option from a given service. Type is a part of option before ':' */
1451 /* Parametric option has following syntax: 'Type: option = value' */
1453 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1455 const char *value = get_parametrics(lookup_service, type, option);
1458 return lp_bool(value);
1463 /* Return parametric option from a given service. Type is a part of option before ':' */
1464 /* Parametric option has following syntax: 'Type: option = value' */
1466 int lp_parm_enum(int lookup_service, const char *type, const char *option,
1467 const struct enum_list *_enum)
1469 const char *value = get_parametrics(lookup_service, type, option);
1472 return lp_enum(value, _enum);
1478 /***************************************************************************
1479 Initialise a service to the defaults.
1480 ***************************************************************************/
1482 static void init_service(service * pservice)
1484 memset((char *)pservice, '\0', sizeof(service));
1485 copy_service(pservice, &sDefault, NULL);
1488 /***************************************************************************
1489 Free the dynamically allocated parts of a service struct.
1490 ***************************************************************************/
1492 static void free_service(service *pservice)
1495 struct param_opt *data, *pdata;
1499 if (pservice->szService)
1500 DEBUG(5, ("free_service: Freeing service %s\n",
1501 pservice->szService));
1503 string_free(&pservice->szService);
1504 SAFE_FREE(pservice->copymap);
1506 for (i = 0; parm_table[i].label; i++) {
1507 if ((parm_table[i].type == P_STRING ||
1508 parm_table[i].type == P_USTRING) &&
1509 parm_table[i].class == P_LOCAL)
1510 string_free((char **)
1511 (((char *)pservice) +
1512 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1513 else if (parm_table[i].type == P_LIST &&
1514 parm_table[i].class == P_LOCAL)
1515 str_list_free((char ***)
1516 (((char *)pservice) +
1517 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1520 DEBUG(5,("Freeing parametrics:\n"));
1521 data = pservice->param_opt;
1523 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1524 string_free(&data->key);
1525 string_free(&data->value);
1531 ZERO_STRUCTP(pservice);
1534 /***************************************************************************
1535 Add a new service to the services array initialising it with the given
1537 ***************************************************************************/
1539 static int add_a_service(const service *pservice, const char *name)
1543 int num_to_alloc = iNumServices + 1;
1544 struct param_opt *data, *pdata;
1546 tservice = *pservice;
1548 /* it might already exist */
1550 i = getservicebyname(name, NULL);
1552 /* Clean all parametric options for service */
1553 /* They will be added during parsing again */
1554 data = ServicePtrs[i]->param_opt;
1556 string_free(&data->key);
1557 string_free(&data->value);
1562 ServicePtrs[i]->param_opt = NULL;
1567 /* find an invalid one */
1568 for (i = 0; i < iNumServices; i++)
1569 if (!ServicePtrs[i]->valid)
1572 /* if not, then create one */
1573 if (i == iNumServices) {
1576 tsp = (service **) Realloc(ServicePtrs,
1581 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1586 ServicePtrs[iNumServices] =
1587 (service *) malloc(sizeof(service));
1589 if (!ServicePtrs[iNumServices]) {
1590 DEBUG(0,("add_a_service: out of memory!\n"));
1596 free_service(ServicePtrs[i]);
1598 ServicePtrs[i]->valid = True;
1600 init_service(ServicePtrs[i]);
1601 copy_service(ServicePtrs[i], &tservice, NULL);
1603 string_set(&ServicePtrs[i]->szService, name);
1607 /***************************************************************************
1608 Add a new home service, with the specified home directory, defaults coming
1610 ***************************************************************************/
1612 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1613 const char *user, const char *pszHomedir)
1618 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1623 if (!(*(ServicePtrs[iDefaultService]->szPath))
1624 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1625 pstrcpy(newHomedir, pszHomedir);
1627 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1628 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1631 string_set(&ServicePtrs[i]->szPath, newHomedir);
1633 if (!(*(ServicePtrs[i]->comment))) {
1635 slprintf(comment, sizeof(comment) - 1,
1636 "Home directory of %s", user);
1637 string_set(&ServicePtrs[i]->comment, comment);
1639 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1640 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1642 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1648 /***************************************************************************
1649 Add a new service, based on an old one.
1650 ***************************************************************************/
1652 int lp_add_service(const char *pszService, int iDefaultService)
1654 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1657 /***************************************************************************
1658 Add the IPC service.
1659 ***************************************************************************/
1661 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1664 int i = add_a_service(&sDefault, ipc_name);
1669 slprintf(comment, sizeof(comment) - 1,
1670 "IPC Service (%s)", Globals.szServerString);
1672 string_set(&ServicePtrs[i]->szPath, tmpdir());
1673 string_set(&ServicePtrs[i]->szUsername, "");
1674 string_set(&ServicePtrs[i]->comment, comment);
1675 string_set(&ServicePtrs[i]->fstype, "IPC");
1676 ServicePtrs[i]->iMaxConnections = 0;
1677 ServicePtrs[i]->bAvailable = True;
1678 ServicePtrs[i]->bRead_only = True;
1679 ServicePtrs[i]->bGuest_only = False;
1680 ServicePtrs[i]->bGuest_ok = guest_ok;
1681 ServicePtrs[i]->bPrint_ok = False;
1682 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1684 DEBUG(3, ("adding IPC service\n"));
1689 /***************************************************************************
1690 Add a new printer service, with defaults coming from service iFrom.
1691 ***************************************************************************/
1693 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1695 const char *comment = "From Printcap";
1696 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1701 /* note that we do NOT default the availability flag to True - */
1702 /* we take it from the default service passed. This allows all */
1703 /* dynamic printers to be disabled by disabling the [printers] */
1704 /* entry (if/when the 'available' keyword is implemented!). */
1706 /* the printer name is set to the service name. */
1707 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1708 string_set(&ServicePtrs[i]->comment, comment);
1709 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1710 /* Printers cannot be read_only. */
1711 ServicePtrs[i]->bRead_only = False;
1712 /* No share modes on printer services. */
1713 ServicePtrs[i]->bShareModes = False;
1714 /* No oplocks on printer services. */
1715 ServicePtrs[i]->bOpLocks = False;
1716 /* Printer services must be printable. */
1717 ServicePtrs[i]->bPrint_ok = True;
1719 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1721 update_server_announce_as_printserver();
1726 /***************************************************************************
1727 Map a parameter's string representation to something we can use.
1728 Returns False if the parameter string is not recognised, else TRUE.
1729 ***************************************************************************/
1731 static int map_parameter(const char *pszParmName)
1735 if (*pszParmName == '-')
1738 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1739 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1742 /* Warn only if it isn't parametric option */
1743 if (strchr(pszParmName, ':') == NULL)
1744 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1745 /* We do return 'fail' for parametric options as well because they are
1746 stored in different storage
1751 /***************************************************************************
1752 Set a boolean variable from the text value stored in the passed string.
1753 Returns True in success, False if the passed string does not correctly
1754 represent a boolean.
1755 ***************************************************************************/
1757 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1762 if (strwicmp(pszParmValue, "yes") == 0 ||
1763 strwicmp(pszParmValue, "true") == 0 ||
1764 strwicmp(pszParmValue, "1") == 0)
1766 else if (strwicmp(pszParmValue, "no") == 0 ||
1767 strwicmp(pszParmValue, "False") == 0 ||
1768 strwicmp(pszParmValue, "0") == 0)
1772 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1779 /***************************************************************************
1780 Find a service by name. Otherwise works like get_service.
1781 ***************************************************************************/
1783 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1787 for (iService = iNumServices - 1; iService >= 0; iService--)
1788 if (VALID(iService) &&
1789 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1790 if (pserviceDest != NULL)
1791 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1798 /***************************************************************************
1799 Copy a service structure to another.
1800 If pcopymapDest is NULL then copy all fields
1801 ***************************************************************************/
1803 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1806 BOOL bcopyall = (pcopymapDest == NULL);
1807 struct param_opt *data, *pdata, *paramo;
1810 for (i = 0; parm_table[i].label; i++)
1811 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1812 (bcopyall || pcopymapDest[i])) {
1813 void *def_ptr = parm_table[i].ptr;
1815 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1818 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1821 switch (parm_table[i].type) {
1824 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1830 *(int *)dest_ptr = *(int *)src_ptr;
1834 *(char *)dest_ptr = *(char *)src_ptr;
1838 string_set(dest_ptr,
1843 string_set(dest_ptr,
1845 strupper(*(char **)dest_ptr);
1848 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1856 init_copymap(pserviceDest);
1857 if (pserviceSource->copymap)
1858 memcpy((void *)pserviceDest->copymap,
1859 (void *)pserviceSource->copymap,
1860 sizeof(BOOL) * NUMPARAMETERS);
1863 data = pserviceSource->param_opt;
1866 pdata = pserviceDest->param_opt;
1867 /* Traverse destination */
1869 /* If we already have same option, override it */
1870 if (strcmp(pdata->key, data->key) == 0) {
1871 string_free(&pdata->value);
1872 pdata->value = strdup(data->value);
1876 pdata = pdata->next;
1879 paramo = smb_xmalloc(sizeof(*paramo));
1880 paramo->key = strdup(data->key);
1881 paramo->value = strdup(data->value);
1882 DLIST_ADD(pserviceDest->param_opt, paramo);
1888 /***************************************************************************
1889 Check a service for consistency. Return False if the service is in any way
1890 incomplete or faulty, else True.
1891 ***************************************************************************/
1893 static BOOL service_ok(int iService)
1898 if (ServicePtrs[iService]->szService[0] == '\0') {
1899 DEBUG(0, ("The following message indicates an internal error:\n"));
1900 DEBUG(0, ("No service name in service entry.\n"));
1904 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1905 /* I can't see why you'd want a non-printable printer service... */
1906 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1907 if (!ServicePtrs[iService]->bPrint_ok) {
1908 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1909 ServicePtrs[iService]->szService));
1910 ServicePtrs[iService]->bPrint_ok = True;
1912 /* [printers] service must also be non-browsable. */
1913 if (ServicePtrs[iService]->bBrowseable)
1914 ServicePtrs[iService]->bBrowseable = False;
1917 /* If a service is flagged unavailable, log the fact at level 0. */
1918 if (!ServicePtrs[iService]->bAvailable)
1919 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1920 ServicePtrs[iService]->szService));
1925 static struct file_lists {
1926 struct file_lists *next;
1930 } *file_lists = NULL;
1932 /*******************************************************************
1933 Keep a linked list of all config files so we know when one has changed
1934 it's date and needs to be reloaded.
1935 ********************************************************************/
1937 static void add_to_file_list(const char *fname, const char *subfname)
1939 struct file_lists *f = file_lists;
1942 if (f->name && !strcmp(f->name, fname))
1948 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1951 f->next = file_lists;
1952 f->name = strdup(fname);
1957 f->subfname = strdup(subfname);
1963 f->modtime = file_modtime(subfname);
1965 time_t t = file_modtime(subfname);
1971 /*******************************************************************
1972 Check if a config file has changed date.
1973 ********************************************************************/
1975 BOOL lp_file_list_changed(void)
1977 struct file_lists *f = file_lists;
1978 DEBUG(6, ("lp_file_list_changed()\n"));
1984 pstrcpy(n2, f->name);
1985 standard_sub_basic(n2,sizeof(n2));
1987 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1988 f->name, n2, ctime(&f->modtime)));
1990 mod_time = file_modtime(n2);
1992 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1994 ("file %s modified: %s\n", n2,
1996 f->modtime = mod_time;
1997 SAFE_FREE(f->subfname);
1998 f->subfname = strdup(n2);
2006 /***************************************************************************
2007 Handle the include operation.
2008 ***************************************************************************/
2010 static BOOL handle_include(const char *pszParmValue, char **ptr)
2013 pstrcpy(fname, pszParmValue);
2015 standard_sub_basic(fname,sizeof(fname));
2017 add_to_file_list(pszParmValue, fname);
2019 string_set(ptr, fname);
2021 if (file_exist(fname, NULL))
2022 return (pm_process(fname, do_section, do_parameter));
2024 DEBUG(2, ("Can't find include file %s\n", fname));
2029 /***************************************************************************
2030 Handle the interpretation of the copy parameter.
2031 ***************************************************************************/
2033 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2037 service serviceTemp;
2039 string_set(ptr, pszParmValue);
2041 init_service(&serviceTemp);
2045 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2047 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2048 if (iTemp == iServiceIndex) {
2049 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2051 copy_service(ServicePtrs[iServiceIndex],
2053 ServicePtrs[iServiceIndex]->copymap);
2057 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2061 free_service(&serviceTemp);
2065 /***************************************************************************
2066 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2071 winbind uid = 1000-1999
2072 winbind gid = 700-899
2074 We only do simple parsing checks here. The strings are parsed into useful
2075 structures in the winbind daemon code.
2077 ***************************************************************************/
2079 /* Some lp_ routines to return winbind [ug]id information */
2081 static uid_t winbind_uid_low, winbind_uid_high;
2082 static gid_t winbind_gid_low, winbind_gid_high;
2083 static uint32_t non_unix_account_low, non_unix_account_high;
2085 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2087 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2091 *low = winbind_uid_low;
2094 *high = winbind_uid_high;
2099 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2101 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2105 *low = winbind_gid_low;
2108 *high = winbind_gid_high;
2113 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2115 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2119 *low = non_unix_account_low;
2122 *high = non_unix_account_high;
2127 /* Do some simple checks on "winbind [ug]id" parameter values */
2129 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2133 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2138 string_set(ptr, pszParmValue);
2140 winbind_uid_low = low;
2141 winbind_uid_high = high;
2146 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2150 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2155 string_set(ptr, pszParmValue);
2157 winbind_gid_low = low;
2158 winbind_gid_high = high;
2163 /***************************************************************************
2164 Do some simple checks on "non unix account range" parameter values.
2165 ***************************************************************************/
2167 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2171 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2176 string_set(ptr, pszParmValue);
2178 non_unix_account_low = low;
2179 non_unix_account_high = high;
2185 /***************************************************************************
2186 Initialise a copymap.
2187 ***************************************************************************/
2189 static void init_copymap(service * pservice)
2192 SAFE_FREE(pservice->copymap);
2193 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2194 if (!pservice->copymap)
2196 ("Couldn't allocate copymap!! (size %d)\n",
2197 (int)NUMPARAMETERS));
2199 for (i = 0; i < NUMPARAMETERS; i++)
2200 pservice->copymap[i] = True;
2203 /***************************************************************************
2204 Return the local pointer to a parameter given the service number and the
2205 pointer into the default structure.
2206 ***************************************************************************/
2208 void *lp_local_ptr(int snum, void *ptr)
2210 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2214 /***************************************************************************
2215 Process a parametric option
2216 ***************************************************************************/
2217 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2219 struct param_opt *paramo, *data;
2222 while (isspace(*pszParmName)) {
2226 name = strdup(pszParmName);
2227 if (!name) return False;
2232 data = Globals.param_opt;
2234 data = ServicePtrs[snum]->param_opt;
2237 /* Traverse destination */
2238 for (paramo=data; paramo; paramo=paramo->next) {
2239 /* If we already have the option set, override it unless
2240 it was a command line option and the new one isn't */
2241 if (strcmp(paramo->key, name) == 0) {
2242 if ((paramo->flags & FLAG_CMDLINE) &&
2243 !(flags & FLAG_CMDLINE)) {
2247 free(paramo->value);
2248 paramo->value = strdup(pszParmValue);
2249 paramo->flags = flags;
2255 paramo = smb_xmalloc(sizeof(*paramo));
2256 paramo->key = strdup(name);
2257 paramo->value = strdup(pszParmValue);
2258 paramo->flags = flags;
2260 DLIST_ADD(Globals.param_opt, paramo);
2262 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2270 /***************************************************************************
2271 Process a parameter for a particular service number. If snum < 0
2272 then assume we are in the globals.
2273 ***************************************************************************/
2274 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2277 void *parm_ptr = NULL; /* where we are going to store the result */
2278 void *def_ptr = NULL;
2280 parmnum = map_parameter(pszParmName);
2283 if (strchr(pszParmName, ':')) {
2284 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2286 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2290 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2291 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2295 /* if the flag has been set on the command line, then don't allow override,
2296 but don't report an error */
2297 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2301 def_ptr = parm_table[parmnum].ptr;
2303 /* we might point at a service, the default service or a global */
2307 if (parm_table[parmnum].class == P_GLOBAL) {
2309 ("Global parameter %s found in service section!\n",
2314 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2319 if (!ServicePtrs[snum]->copymap)
2320 init_copymap(ServicePtrs[snum]);
2322 /* this handles the aliases - set the copymap for other entries with
2323 the same data pointer */
2324 for (i = 0; parm_table[i].label; i++)
2325 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2326 ServicePtrs[snum]->copymap[i] = False;
2329 /* if it is a special case then go ahead */
2330 if (parm_table[parmnum].special) {
2331 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2335 /* now switch on the type of variable it is */
2336 switch (parm_table[parmnum].type)
2339 set_boolean(parm_ptr, pszParmValue);
2343 set_boolean(parm_ptr, pszParmValue);
2344 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2348 *(int *)parm_ptr = atoi(pszParmValue);
2352 *(char *)parm_ptr = *pszParmValue;
2356 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2360 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2364 string_set(parm_ptr, pszParmValue);
2368 string_set(parm_ptr, pszParmValue);
2369 strupper(*(char **)parm_ptr);
2373 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2376 parm_table[parmnum].enum_list[i].name)) {
2378 parm_table[parmnum].
2383 if (!parm_table[parmnum].enum_list[i].name) {
2384 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2385 pszParmValue, pszParmName));
2396 /***************************************************************************
2397 Process a parameter.
2398 ***************************************************************************/
2400 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2402 if (!bInGlobalSection && bGlobalOnly)
2405 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2406 pszParmName, pszParmValue));
2410 variable argument do parameter
2412 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2414 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2421 s = talloc_vasprintf(NULL, fmt, ap);
2423 ret = do_parameter(pszParmName, s);
2430 set a parameter from the commandline - this is called from command line parameter
2431 parsing code. It sets the parameter then marks the parameter as unable to be modified
2432 by smb.conf processing
2434 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2436 int parmnum = map_parameter(pszParmName);
2439 while (isspace(*pszParmValue)) pszParmValue++;
2442 if (parmnum < 0 && strchr(pszParmName, ':')) {
2443 /* set a parametric option */
2444 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2447 /* reset the CMDLINE flag in case this has been called before */
2448 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2450 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2454 parm_table[parmnum].flags |= FLAG_CMDLINE;
2456 /* we have to also set FLAG_CMDLINE on aliases */
2457 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2458 parm_table[i].flags |= FLAG_CMDLINE;
2460 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2461 parm_table[i].flags |= FLAG_CMDLINE;
2468 set a option from the commandline in 'a=b' format. Use to support --option
2470 BOOL lp_set_option(const char *option)
2488 ret = lp_set_cmdline(s, p+1);
2494 /***************************************************************************
2495 Print a parameter of the specified type.
2496 ***************************************************************************/
2498 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2504 for (i = 0; p->enum_list[i].name; i++) {
2505 if (*(int *)ptr == p->enum_list[i].value) {
2507 p->enum_list[i].name);
2514 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2518 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2522 fprintf(f, "%d", *(int *)ptr);
2526 fprintf(f, "%c", *(char *)ptr);
2530 if (*(int *)ptr == -1) {
2533 fprintf(f, "0%o", *(int *)ptr);
2538 if ((char ***)ptr && *(char ***)ptr) {
2539 char **list = *(char ***)ptr;
2541 for (; *list; list++)
2542 fprintf(f, "%s%s", *list,
2543 ((*(list+1))?", ":""));
2549 if (*(char **)ptr) {
2550 fprintf(f, "%s", *(char **)ptr);
2558 /***************************************************************************
2559 Check if two parameters are equal.
2560 ***************************************************************************/
2562 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2567 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2572 return (*((int *)ptr1) == *((int *)ptr2));
2575 return (*((char *)ptr1) == *((char *)ptr2));
2578 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2583 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2588 return (p1 == p2 || strequal(p1, p2));
2596 /***************************************************************************
2597 Process a new section (service). At this stage all sections are services.
2598 Later we'll have special sections that permit server parameters to be set.
2599 Returns True on success, False on failure.
2600 ***************************************************************************/
2602 static BOOL do_section(const char *pszSectionName)
2605 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2606 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2609 /* if we've just struck a global section, note the fact. */
2610 bInGlobalSection = isglobal;
2612 /* check for multiple global sections */
2613 if (bInGlobalSection) {
2614 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2618 if (!bInGlobalSection && bGlobalOnly)
2621 /* if we have a current service, tidy it up before moving on */
2624 if (iServiceIndex >= 0)
2625 bRetval = service_ok(iServiceIndex);
2627 /* if all is still well, move to the next record in the services array */
2629 /* We put this here to avoid an odd message order if messages are */
2630 /* issued by the post-processing of a previous section. */
2631 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2633 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2635 DEBUG(0, ("Failed to add a new service\n"));
2644 /***************************************************************************
2645 Determine if a partcular base parameter is currentl set to the default value.
2646 ***************************************************************************/
2648 static BOOL is_default(int i)
2650 if (!defaults_saved)
2652 switch (parm_table[i].type) {
2654 return str_list_compare (parm_table[i].def.lvalue,
2655 *(char ***)parm_table[i].ptr);
2658 return strequal(parm_table[i].def.svalue,
2659 *(char **)parm_table[i].ptr);
2662 return parm_table[i].def.bvalue ==
2663 *(BOOL *)parm_table[i].ptr;
2665 return parm_table[i].def.cvalue ==
2666 *(char *)parm_table[i].ptr;
2670 return parm_table[i].def.ivalue ==
2671 *(int *)parm_table[i].ptr;
2678 /***************************************************************************
2679 Display the contents of the global structure.
2680 ***************************************************************************/
2682 static void dump_globals(FILE *f)
2685 struct param_opt *data;
2687 fprintf(f, "# Global parameters\n[global]\n");
2689 for (i = 0; parm_table[i].label; i++)
2690 if (parm_table[i].class == P_GLOBAL &&
2691 parm_table[i].ptr &&
2692 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2693 if (defaults_saved && is_default(i))
2695 fprintf(f, "\t%s = ", parm_table[i].label);
2696 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2699 if (Globals.param_opt != NULL) {
2700 data = Globals.param_opt;
2702 fprintf(f, "\t%s = %s\n", data->key, data->value);
2709 /***************************************************************************
2710 Return True if a local parameter is currently set to the global default.
2711 ***************************************************************************/
2713 BOOL lp_is_default(int snum, struct parm_struct *parm)
2715 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
2717 return equal_parameter(parm->type,
2718 ((char *)ServicePtrs[snum]) + pdiff,
2719 ((char *)&sDefault) + pdiff);
2722 /***************************************************************************
2723 Display the contents of a single services record.
2724 ***************************************************************************/
2726 static void dump_a_service(service * pService, FILE * f)
2729 struct param_opt *data;
2731 if (pService != &sDefault)
2732 fprintf(f, "\n[%s]\n", pService->szService);
2734 for (i = 0; parm_table[i].label; i++)
2735 if (parm_table[i].class == P_LOCAL &&
2736 parm_table[i].ptr &&
2737 (*parm_table[i].label != '-') &&
2738 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2739 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2741 if (pService == &sDefault) {
2742 if (defaults_saved && is_default(i))
2745 if (equal_parameter(parm_table[i].type,
2746 ((char *)pService) +
2748 ((char *)&sDefault) +
2753 fprintf(f, "\t%s = ", parm_table[i].label);
2754 print_parameter(&parm_table[i],
2755 ((char *)pService) + pdiff, f);
2758 if (pService->param_opt != NULL) {
2759 data = pService->param_opt;
2761 fprintf(f, "\t%s = %s\n", data->key, data->value);
2768 /***************************************************************************
2769 Return info about the next service in a service. snum==-1 gives the globals.
2770 Return NULL when out of parameters.
2771 ***************************************************************************/
2773 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2776 /* do the globals */
2777 for (; parm_table[*i].label; (*i)++) {
2778 if (parm_table[*i].class == P_SEPARATOR)
2779 return &parm_table[(*i)++];
2781 if (!parm_table[*i].ptr
2782 || (*parm_table[*i].label == '-'))
2786 && (parm_table[*i].ptr ==
2787 parm_table[(*i) - 1].ptr))
2790 return &parm_table[(*i)++];
2793 service *pService = ServicePtrs[snum];
2795 for (; parm_table[*i].label; (*i)++) {
2796 if (parm_table[*i].class == P_SEPARATOR)
2797 return &parm_table[(*i)++];
2799 if (parm_table[*i].class == P_LOCAL &&
2800 parm_table[*i].ptr &&
2801 (*parm_table[*i].label != '-') &&
2803 (parm_table[*i].ptr !=
2804 parm_table[(*i) - 1].ptr)))
2807 PTR_DIFF(parm_table[*i].ptr,
2810 if (allparameters ||
2811 !equal_parameter(parm_table[*i].type,
2812 ((char *)pService) +
2814 ((char *)&sDefault) +
2817 return &parm_table[(*i)++];
2828 /***************************************************************************
2829 Display the contents of a single copy structure.
2830 ***************************************************************************/
2831 static void dump_copy_map(BOOL *pcopymap)
2837 printf("\n\tNon-Copied parameters:\n");
2839 for (i = 0; parm_table[i].label; i++)
2840 if (parm_table[i].class == P_LOCAL &&
2841 parm_table[i].ptr && !pcopymap[i] &&
2842 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2844 printf("\t\t%s\n", parm_table[i].label);
2849 /***************************************************************************
2850 Return TRUE if the passed service number is within range.
2851 ***************************************************************************/
2853 BOOL lp_snum_ok(int iService)
2855 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2858 /***************************************************************************
2859 Auto-load some home services.
2860 ***************************************************************************/
2862 static void lp_add_auto_services(const char *str)
2867 /***************************************************************************
2868 Auto-load one printer.
2869 ***************************************************************************/
2871 void lp_add_one_printer(char *name, char *comment)
2873 int printers = lp_servicenumber(PRINTERS_NAME);
2876 if (lp_servicenumber(name) < 0) {
2877 lp_add_printer(name, printers);
2878 if ((i = lp_servicenumber(name)) >= 0) {
2879 string_set(&ServicePtrs[i]->comment, comment);
2880 ServicePtrs[i]->autoloaded = True;
2885 /***************************************************************************
2886 Announce ourselves as a print server.
2887 ***************************************************************************/
2889 void update_server_announce_as_printserver(void)
2891 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2894 /***************************************************************************
2895 Have we loaded a services file yet?
2896 ***************************************************************************/
2898 BOOL lp_loaded(void)
2903 /***************************************************************************
2904 Unload unused services.
2905 ***************************************************************************/
2907 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2910 for (i = 0; i < iNumServices; i++) {
2914 if (!snumused || !snumused(smb, i)) {
2915 ServicePtrs[i]->valid = False;
2916 free_service(ServicePtrs[i]);
2921 /***************************************************************************
2923 ***************************************************************************/
2925 void lp_killservice(int iServiceIn)
2927 if (VALID(iServiceIn)) {
2928 ServicePtrs[iServiceIn]->valid = False;
2929 free_service(ServicePtrs[iServiceIn]);
2933 /***************************************************************************
2934 Save the curent values of all global and sDefault parameters into the
2935 defaults union. This allows swat and testparm to show only the
2936 changed (ie. non-default) parameters.
2937 ***************************************************************************/
2939 static void lp_save_defaults(void)
2942 for (i = 0; parm_table[i].label; i++) {
2943 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2945 switch (parm_table[i].type) {
2947 str_list_copy(&(parm_table[i].def.lvalue),
2948 *(const char ***)parm_table[i].ptr);
2952 if (parm_table[i].ptr) {
2953 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2955 parm_table[i].def.svalue = NULL;
2960 parm_table[i].def.bvalue =
2961 *(BOOL *)parm_table[i].ptr;
2964 parm_table[i].def.cvalue =
2965 *(char *)parm_table[i].ptr;
2970 parm_table[i].def.ivalue =
2971 *(int *)parm_table[i].ptr;
2977 defaults_saved = True;
2980 /*******************************************************************
2981 Set the server type we will announce as via nmbd.
2982 ********************************************************************/
2984 static void set_server_role(void)
2986 server_role = ROLE_STANDALONE;
2988 switch (lp_security()) {
2990 if (lp_domain_logons())
2991 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2996 if (lp_domain_logons()) {
2997 server_role = ROLE_DOMAIN_PDC;
3000 server_role = ROLE_DOMAIN_MEMBER;
3003 if (lp_domain_logons()) {
3005 if (Globals.bDomainMaster) /* auto or yes */
3006 server_role = ROLE_DOMAIN_PDC;
3008 server_role = ROLE_DOMAIN_BDC;
3012 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3016 DEBUG(10, ("set_server_role: role = "));
3018 switch(server_role) {
3019 case ROLE_STANDALONE:
3020 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3022 case ROLE_DOMAIN_MEMBER:
3023 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3025 case ROLE_DOMAIN_BDC:
3026 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3028 case ROLE_DOMAIN_PDC:
3029 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3034 /***************************************************************************
3035 Load the services array from the services file. Return True on success,
3037 ***************************************************************************/
3039 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3044 struct param_opt *data;
3046 pstrcpy(n2, pszFname);
3047 standard_sub_basic(n2,sizeof(n2));
3049 add_to_file_list(pszFname, n2);
3053 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3055 bInGlobalSection = True;
3056 bGlobalOnly = global_only;
3065 if (Globals.param_opt != NULL) {
3066 struct param_opt *next;
3067 for (data=Globals.param_opt; data; data=next) {
3069 if (data->flags & FLAG_CMDLINE) continue;
3072 DLIST_REMOVE(Globals.param_opt, data);
3077 /* We get sections first, so have to start 'behind' to make up */
3079 bRetval = pm_process(n2, do_section, do_parameter);
3081 /* finish up the last section */
3082 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3084 if (iServiceIndex >= 0)
3085 bRetval = service_ok(iServiceIndex);
3087 lp_add_auto_services(lp_auto_services());
3090 /* When 'restrict anonymous = 2' guest connections to ipc$
3092 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3093 lp_add_ipc("ADMIN$", False);
3097 set_default_server_announce_type();
3101 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3102 /* if bWINSsupport is true and we are in the client */
3103 if (in_client && Globals.bWINSsupport) {
3104 lp_do_parameter(-1, "wins server", "127.0.0.1");
3112 /***************************************************************************
3113 Reset the max number of services.
3114 ***************************************************************************/
3116 void lp_resetnumservices(void)
3121 /***************************************************************************
3122 Return the max number of services.
3123 ***************************************************************************/
3125 int lp_numservices(void)
3127 return (iNumServices);
3130 /***************************************************************************
3131 Display the contents of the services array in human-readable form.
3132 ***************************************************************************/
3134 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3139 defaults_saved = False;
3143 dump_a_service(&sDefault, f);
3145 for (iService = 0; iService < maxtoprint; iService++)
3146 lp_dump_one(f, show_defaults, iService);
3149 /***************************************************************************
3150 Display the contents of one service in human-readable form.
3151 ***************************************************************************/
3153 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3156 if (ServicePtrs[snum]->szService[0] == '\0')
3158 dump_a_service(ServicePtrs[snum], f);
3162 /***************************************************************************
3163 Return the number of the service with the given name, or -1 if it doesn't
3164 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3165 getservicebyname()! This works ONLY if all services have been loaded, and
3166 does not copy the found service.
3167 ***************************************************************************/
3169 int lp_servicenumber(const char *pszServiceName)
3172 fstring serviceName;
3175 for (iService = iNumServices - 1; iService >= 0; iService--) {
3176 if (VALID(iService) && ServicePtrs[iService]->szService) {
3178 * The substitution here is used to support %U is
3181 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3182 standard_sub_basic(serviceName,sizeof(serviceName));
3183 if (strequal(serviceName, pszServiceName))
3189 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3194 /*******************************************************************
3195 A useful volume label function.
3196 ********************************************************************/
3197 const char *volume_label(int snum)
3199 const char *ret = lp_volume(snum);
3201 return lp_servicename(snum);
3206 /*******************************************************************
3207 Set the server type we will announce as via nmbd.
3208 ********************************************************************/
3210 static void set_default_server_announce_type(void)
3212 default_server_announce = 0;
3213 default_server_announce |= SV_TYPE_WORKSTATION;
3214 default_server_announce |= SV_TYPE_SERVER;
3215 default_server_announce |= SV_TYPE_SERVER_UNIX;
3217 switch (lp_announce_as()) {
3218 case ANNOUNCE_AS_NT_SERVER:
3219 default_server_announce |= SV_TYPE_SERVER_NT;
3220 /* fall through... */
3221 case ANNOUNCE_AS_NT_WORKSTATION:
3222 default_server_announce |= SV_TYPE_NT;
3224 case ANNOUNCE_AS_WIN95:
3225 default_server_announce |= SV_TYPE_WIN95_PLUS;
3227 case ANNOUNCE_AS_WFW:
3228 default_server_announce |= SV_TYPE_WFW;
3234 switch (lp_server_role()) {
3235 case ROLE_DOMAIN_MEMBER:
3236 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3238 case ROLE_DOMAIN_PDC:
3239 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3241 case ROLE_DOMAIN_BDC:
3242 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3244 case ROLE_STANDALONE:
3248 if (lp_time_server())
3249 default_server_announce |= SV_TYPE_TIME_SOURCE;
3251 if (lp_host_msdfs())
3252 default_server_announce |= SV_TYPE_DFS_SERVER;
3255 /***********************************************************
3256 returns role of Samba server
3257 ************************************************************/
3259 int lp_server_role(void)
3264 /***********************************************************
3265 If we are PDC then prefer us as DMB
3266 ************************************************************/
3268 BOOL lp_domain_master(void)
3270 if (Globals.bDomainMaster == Auto)
3271 return (lp_server_role() == ROLE_DOMAIN_PDC);
3273 return Globals.bDomainMaster;
3276 /***********************************************************
3277 If we are DMB then prefer us as LMB
3278 ************************************************************/
3280 BOOL lp_preferred_master(void)
3282 if (Globals.bPreferredMaster == Auto)
3283 return (lp_local_master() && lp_domain_master());
3285 return Globals.bPreferredMaster;
3288 /*******************************************************************
3290 ********************************************************************/
3292 void lp_remove_service(int snum)
3294 ServicePtrs[snum]->valid = False;
3297 /*******************************************************************
3299 ********************************************************************/
3301 void lp_copy_service(int snum, const char *new_name)
3303 const char *oldname = lp_servicename(snum);
3304 do_section(new_name);
3306 snum = lp_servicenumber(new_name);
3308 lp_do_parameter(snum, "copy", oldname);
3313 /*******************************************************************
3314 Get the default server type we will announce as via nmbd.
3315 ********************************************************************/
3317 int lp_default_server_announce(void)
3319 return default_server_announce;
3322 /*******************************************************************
3323 Split the announce version into major and minor numbers.
3324 ********************************************************************/
3326 int lp_major_announce_version(void)
3328 static BOOL got_major = False;
3329 static int major_version = DEFAULT_MAJOR_VERSION;
3334 return major_version;
3337 if ((vers = lp_announce_version()) == NULL)
3338 return major_version;
3340 if ((p = strchr_m(vers, '.')) == 0)
3341 return major_version;
3344 major_version = atoi(vers);
3345 return major_version;
3348 int lp_minor_announce_version(void)
3350 static BOOL got_minor = False;
3351 static int minor_version = DEFAULT_MINOR_VERSION;
3356 return minor_version;
3359 if ((vers = lp_announce_version()) == NULL)
3360 return minor_version;
3362 if ((p = strchr_m(vers, '.')) == 0)
3363 return minor_version;
3366 minor_version = atoi(p);
3367 return minor_version;
3370 const char *lp_printername(int snum)
3372 const char *ret = _lp_printername(snum);
3373 if (ret == NULL || (ret != NULL && *ret == '\0'))
3374 ret = lp_const_servicename(snum);
3380 /*******************************************************************
3381 Return the max print jobs per queue.
3382 ********************************************************************/
3384 int lp_maxprintjobs(int snum)
3386 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3387 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3388 maxjobs = PRINT_MAX_JOBID - 1;