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;
276 struct param_opt *param_opt;
278 char dummy[3]; /* for alignment */
283 /* This is a default service used to prime a services structure */
284 static service sDefault = {
286 False, /* not autoloaded */
287 NULL, /* szService */
289 NULL, /* szUsername */
290 NULL, /* szInvalidUsers */
291 NULL, /* szValidUsers */
292 NULL, /* szAdminUsers */
294 NULL, /* szInclude */
295 NULL, /* szPrintcommand */
296 NULL, /* szLpqcommand */
297 NULL, /* szLprmcommand */
298 NULL, /* szLppausecommand */
299 NULL, /* szLpresumecommand */
300 NULL, /* szQueuepausecommand */
301 NULL, /* szQueueresumecommand */
302 NULL, /* szPrintername */
303 NULL, /* szHostsallow */
304 NULL, /* szHostsdeny */
308 NULL, /* szMSDfsProxy */
309 NULL, /* ntvfs_handler */
310 0, /* iMinPrintSpace */
311 1000, /* iMaxPrintJobs */
312 0, /* iMaxConnections */
313 DEFAULT_PRINTING, /* iPrinting */
315 True, /* bAvailable */
316 True, /* bBrowseable */
317 True, /* bRead_only */
318 False, /* bPrint_ok */
319 False, /* bMap_system */
320 False, /* bMap_hidden */
321 True, /* bMap_archive */
323 True, /* bStrictLocking */
324 True, /* bPosixLocking */
326 True, /* bLevel2OpLocks */
327 False, /* bOnlyUser */
328 False, /* bGuest_only */
329 False, /* bGuest_ok */
331 False, /* bMSDfsRoot */
332 True, /* bShareModes */
333 False, /* bStrictSync */
334 False, /* bCIFileSystem */
335 NULL, /* Parametric options */
340 /* local variables */
341 static service **ServicePtrs = NULL;
342 static int iNumServices = 0;
343 static int iServiceIndex = 0;
344 static BOOL bInGlobalSection = True;
345 static BOOL bGlobalOnly = False;
346 static int server_role;
347 static int default_server_announce;
349 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
351 /* prototypes for the special type handlers */
352 static BOOL handle_include(const char *pszParmValue, char **ptr);
353 static BOOL handle_copy(const char *pszParmValue, char **ptr);
354 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
355 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
356 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
358 static void set_server_role(void);
359 static void set_default_server_announce_type(void);
361 static const struct enum_list enum_protocol[] = {
362 {PROTOCOL_NT1, "NT1"},
363 {PROTOCOL_LANMAN2, "LANMAN2"},
364 {PROTOCOL_LANMAN1, "LANMAN1"},
365 {PROTOCOL_CORE, "CORE"},
366 {PROTOCOL_COREPLUS, "COREPLUS"},
367 {PROTOCOL_COREPLUS, "CORE+"},
371 static const struct enum_list enum_security[] = {
372 {SEC_SHARE, "SHARE"},
374 {SEC_SERVER, "SERVER"},
375 {SEC_DOMAIN, "DOMAIN"},
382 static const struct enum_list enum_printing[] = {
383 {PRINT_SYSV, "sysv"},
385 {PRINT_HPUX, "hpux"},
389 {PRINT_LPRNG, "lprng"},
390 {PRINT_SOFTQ, "softq"},
391 {PRINT_CUPS, "cups"},
393 {PRINT_LPROS2, "os2"},
395 {PRINT_TEST, "test"},
397 #endif /* DEVELOPER */
401 /* Types of machine we can announce as. */
402 #define ANNOUNCE_AS_NT_SERVER 1
403 #define ANNOUNCE_AS_WIN95 2
404 #define ANNOUNCE_AS_WFW 3
405 #define ANNOUNCE_AS_NT_WORKSTATION 4
407 static const struct enum_list enum_announce_as[] = {
408 {ANNOUNCE_AS_NT_SERVER, "NT"},
409 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
410 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
411 {ANNOUNCE_AS_WIN95, "win95"},
412 {ANNOUNCE_AS_WFW, "WfW"},
416 static const struct enum_list enum_case[] = {
417 {CASE_LOWER, "lower"},
418 {CASE_UPPER, "upper"},
422 static const struct enum_list enum_bool_auto[] = {
433 /* Client-side offline caching policy types */
434 #define CSC_POLICY_MANUAL 0
435 #define CSC_POLICY_DOCUMENTS 1
436 #define CSC_POLICY_PROGRAMS 2
437 #define CSC_POLICY_DISABLE 3
439 static const struct enum_list enum_csc_policy[] = {
440 {CSC_POLICY_MANUAL, "manual"},
441 {CSC_POLICY_DOCUMENTS, "documents"},
442 {CSC_POLICY_PROGRAMS, "programs"},
443 {CSC_POLICY_DISABLE, "disable"},
447 /* SMB signing types. */
448 static const struct enum_list enum_smb_signing_vals[] = {
449 {SMB_SIGNING_OFF, "No"},
450 {SMB_SIGNING_OFF, "False"},
451 {SMB_SIGNING_OFF, "0"},
452 {SMB_SIGNING_OFF, "Off"},
453 {SMB_SIGNING_OFF, "disabled"},
454 {SMB_SIGNING_SUPPORTED, "Yes"},
455 {SMB_SIGNING_SUPPORTED, "True"},
456 {SMB_SIGNING_SUPPORTED, "1"},
457 {SMB_SIGNING_SUPPORTED, "On"},
458 {SMB_SIGNING_SUPPORTED, "enabled"},
459 {SMB_SIGNING_REQUIRED, "required"},
460 {SMB_SIGNING_REQUIRED, "mandatory"},
461 {SMB_SIGNING_REQUIRED, "force"},
462 {SMB_SIGNING_REQUIRED, "forced"},
463 {SMB_SIGNING_REQUIRED, "enforced"},
464 {SMB_SIGNING_AUTO, "auto"},
469 Do you want session setups at user level security with a invalid
470 password to be rejected or allowed in as guest? WinNT rejects them
471 but it can be a pain as it means "net view" needs to use a password
473 You have 3 choices in the setting of map_to_guest:
475 "Never" means session setups with an invalid password
476 are rejected. This is the default.
478 "Bad User" means session setups with an invalid password
479 are rejected, unless the username does not exist, in which case it
480 is treated as a guest login
482 "Bad Password" means session setups with an invalid password
483 are treated as a guest login
485 Note that map_to_guest only has an effect in user or server
489 static const struct enum_list enum_map_to_guest[] = {
490 {NEVER_MAP_TO_GUEST, "Never"},
491 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
492 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
496 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
498 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
499 * is implied in current control logic. This may change at some later time. A
500 * flag value of 0 means - show as development option only.
502 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
503 * screen in SWAT. This is used to exclude parameters as well as to squash all
504 * parameters that have been duplicated by pseudonyms.
506 static struct parm_struct parm_table[] = {
507 {"Base Options", P_SEP, P_SEPARATOR},
509 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
510 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
511 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
512 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
513 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
514 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
515 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
516 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
517 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
518 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
519 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
520 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
521 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
522 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
523 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
524 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
525 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
526 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
527 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
529 {"Security Options", P_SEP, P_SEPARATOR},
531 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
532 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
533 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
534 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
540 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
548 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
558 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
562 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
563 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
565 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
566 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
567 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
569 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
571 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
573 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
575 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
576 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
577 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
578 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
580 {"Logging Options", P_SEP, P_SEPARATOR},
582 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
584 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"Protocol Options", P_SEP, P_SEPARATOR},
588 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
590 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
591 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
592 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
593 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
594 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
595 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
597 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
599 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
600 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
601 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
602 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
605 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
606 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
608 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
609 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
611 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
612 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
613 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
615 {"Tuning Options", P_SEP, P_SEPARATOR},
617 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
618 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
619 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
620 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
622 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
623 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
624 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
627 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
628 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
630 {"Printing Options", P_SEP, P_SEPARATOR},
632 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
633 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
634 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
635 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
636 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
637 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
638 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
639 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
640 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
641 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
642 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
643 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
644 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
645 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
646 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
648 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
649 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
651 {"Filename Handling", P_SEP, P_SEPARATOR},
653 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
654 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
655 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
657 {"Domain Options", P_SEP, P_SEPARATOR},
659 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
661 {"Logon Options", P_SEP, P_SEPARATOR},
663 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
664 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
666 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
667 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
668 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
669 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
670 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
672 {"Browse Options", P_SEP, P_SEPARATOR},
674 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
675 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
676 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
677 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
678 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
679 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
680 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
681 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
682 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
683 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
685 {"WINS Options", P_SEP, P_SEPARATOR},
686 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
687 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
689 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
690 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
691 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
694 {"Locking Options", P_SEP, P_SEPARATOR},
696 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
697 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
698 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
699 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
701 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
702 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
703 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
704 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
705 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
707 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
709 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
710 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
712 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
713 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
714 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
717 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
718 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
719 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
720 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
721 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
722 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
724 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
725 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
727 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
728 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
729 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
731 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
732 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
735 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
736 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
737 {"Winbind options", P_SEP, P_SEPARATOR},
739 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
752 /***************************************************************************
753 Initialise the sDefault parameter structure for the printer values.
754 ***************************************************************************/
756 static void init_printer_values(void)
758 /* choose defaults depending on the type of printing */
759 switch (sDefault.iPrinting) {
764 do_parameter("Lpqcommand", "lpq -P'%p'");
765 do_parameter("Lprmcommand", "lprm -P'%p' %j");
766 do_parameter("Printcommand",
772 do_parameter("Lpqcommand", "lpq -P'%p'");
773 do_parameter("Lprmcommand", "lprm -P'%p' %j");
774 do_parameter("Printcommand",
776 do_parameter("Queuepausecommand",
778 do_parameter("Queueresumecommand",
780 do_parameter("Lppausecommand",
782 do_parameter("Lpresumecommand",
783 "lpc release '%p' %j");
788 do_parameter("Lpqcommand", "");
789 do_parameter("Lprmcommand", "");
790 do_parameter("Printcommand", "");
791 do_parameter("Lppausecommand", "");
792 do_parameter("Lpresumecommand", "");
793 do_parameter("Queuepausecommand", "");
794 do_parameter("Queueresumecommand", "");
796 do_parameter("Printcapname", "cups");
798 do_parameter("Lpqcommand",
799 "/usr/bin/lpstat -o '%p'");
800 do_parameter("Lprmcommand",
801 "/usr/bin/cancel '%p-%j'");
802 do_parameter("Printcommand",
803 "/usr/bin/lp -d '%p' %s; rm %s");
804 do_parameter("Lppausecommand",
805 "lp -i '%p-%j' -H hold");
806 do_parameter("Lpresumecommand",
807 "lp -i '%p-%j' -H resume");
808 do_parameter("Queuepausecommand",
809 "/usr/bin/disable '%p'");
810 do_parameter("Queueresumecommand",
811 "/usr/bin/enable '%p'");
812 do_parameter("Printcapname", "lpstat");
813 #endif /* HAVE_CUPS */
818 do_parameter("Lpqcommand", "lpstat -o%p");
819 do_parameter("Lprmcommand", "cancel %p-%j");
820 do_parameter("Printcommand",
821 "lp -c -d%p %s; rm %s");
822 do_parameter("Queuepausecommand",
824 do_parameter("Queueresumecommand",
827 do_parameter("Lppausecommand",
828 "lp -i %p-%j -H hold");
829 do_parameter("Lpresumecommand",
830 "lp -i %p-%j -H resume");
835 do_parameter("Lpqcommand", "lpq -P%p");
836 do_parameter("Lprmcommand", "lprm -P%p %j");
837 do_parameter("Printcommand", "lp -r -P%p %s");
841 do_parameter("Lpqcommand", "qstat -l -d%p");
842 do_parameter("Lprmcommand",
844 do_parameter("Printcommand",
845 "lp -d%p -s %s; rm %s");
846 do_parameter("Lppausecommand",
848 do_parameter("Lpresumecommand",
854 do_parameter("Printcommand", "vlp print %p %s");
855 do_parameter("Lpqcommand", "vlp lpq %p");
856 do_parameter("Lprmcommand", "vlp lprm %p %j");
857 do_parameter("Lppausecommand", "vlp lppause %p %j");
858 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
859 do_parameter("Queuepausecommand", "vlp queuepause %p");
860 do_parameter("Queueresumecommand", "vlp queueresume %p");
862 #endif /* DEVELOPER */
868 /***************************************************************************
869 Initialise the global parameter structure.
870 ***************************************************************************/
871 static void init_globals(void)
875 DEBUG(3, ("Initialising global parameters\n"));
877 for (i = 0; parm_table[i].label; i++) {
878 if ((parm_table[i].type == P_STRING ||
879 parm_table[i].type == P_USTRING) &&
881 !(parm_table[i].flags & FLAG_CMDLINE)) {
882 string_set(parm_table[i].ptr, "");
886 /* options that can be set on the command line must be initialised via
887 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
888 do_parameter("socket options", DEFAULT_SOCKET_OPTIONS);
889 do_parameter("workgroup", DEFAULT_WORKGROUP);
890 do_parameter("netbios name", get_myname());
891 do_parameter("max protocol", "NT1");
892 do_parameter("name resolve order", "lmhosts wins host bcast");
894 init_printer_values();
896 do_parameter("fstype", FSTYPE_STRING);
897 do_parameter("ntvfs handler", "unixuid default");
899 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg");
900 do_parameter("server services", "smb rpc");
901 do_parameter("auth methods", "guest sam_ignoredomain");
902 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
903 do_parameter("private dir", dyn_PRIVATE_DIR);
904 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
905 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
906 do_parameter("guest account", GUEST_ACCOUNT);
908 /* using UTF8 by default allows us to support all chars */
909 do_parameter("unix charset", "UTF8");
911 /* Use codepage 850 as a default for the dos character set */
912 do_parameter("dos charset", "CP850");
915 * Allow the default PASSWD_CHAT to be overridden in local.h.
917 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
919 do_parameter("passwd program", "");
920 do_parameter("printcap name", PRINTCAP_NAME);
922 do_parameter("pid directory", dyn_PIDDIR);
923 do_parameter("lock dir", dyn_LOCKDIR);
924 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
926 do_parameter("socket address", "0.0.0.0");
927 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
929 do_parameter_var("announce version", "%d.%d",
930 DEFAULT_MAJOR_VERSION,
931 DEFAULT_MINOR_VERSION);
933 do_parameter("logon drive", "");
935 do_parameter("logon home", "\\\\%N\\%U");
936 do_parameter("logon path", "\\\\%N\\%U\\profile");
937 do_parameter("password server", "*");
939 do_parameter("load printers", "True");
941 do_parameter("max mux", "50");
942 do_parameter("max xmit", "12288");
943 do_parameter("lpqcachetime", "10");
944 do_parameter("DisableSpoolss", "False");
945 do_parameter("password level", "0");
946 do_parameter("username level", "0");
947 do_parameter("LargeReadwrite", "True");
948 do_parameter("minprotocol", "CORE");
949 do_parameter("security", "USER");
950 do_parameter("paranoid server security", "True");
951 do_parameter("EncryptPasswords", "True");
952 do_parameter("ReadRaw", "True");
953 do_parameter("WriteRaw", "True");
954 do_parameter("NullPasswords", "False");
955 do_parameter("ObeyPamRestrictions", "False");
956 do_parameter("lm announce", "Auto");
957 do_parameter("lm interval", "60");
958 do_parameter("announce as", "NT SERVER");
960 do_parameter("TimeServer", "False");
961 do_parameter("BindInterfacesOnly", "False");
962 do_parameter("PamPasswordChange", "False");
963 do_parameter("Unicode", "True");
964 do_parameter("restrict anonymous", "0");
965 do_parameter("ClientLanManAuth", "True");
966 do_parameter("LanmanAuth", "True");
967 do_parameter("NTLMAuth", "True");
969 do_parameter("enhanced browsing", "True");
970 do_parameter("LockSpinCount", "3");
971 do_parameter("LockSpinTime", "10");
972 #ifdef MMAP_BLACKLIST
973 do_parameter("UseMmap", "False");
975 do_parameter("UseMmap", "True");
977 do_parameter("UnixExtensions", "False");
979 /* hostname lookups can be very expensive and are broken on
980 a large number of sites (tridge) */
981 do_parameter("HostnameLookups", "False");
983 do_parameter("PreferredMaster", "Auto");
984 do_parameter("os level", "20");
985 do_parameter("LocalMaster", "True");
986 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
987 do_parameter("DomainLogons", "False");
988 do_parameter("WINSsupport", "False");
989 do_parameter("WINSproxy", "False");
991 do_parameter("DNSproxy", "True");
993 do_parameter("AllowTrustedDomains", "True");
995 do_parameter("TemplateShell", "/bin/false");
996 do_parameter("TemplateHomedir", "/home/%D/%U");
997 do_parameter("WinbindSeparator", "\\");
999 do_parameter("winbind cache time", "15");
1000 do_parameter("WinbindEnumUsers", "True");
1001 do_parameter("WinbindEnumGroups", "True");
1002 do_parameter("WinbindUseDefaultDomain", "False");
1004 do_parameter("IDMapBackend", "tdb");
1006 do_parameter("name cache timeout", "660"); /* In seconds */
1008 do_parameter("client signing", "Yes");
1009 do_parameter("server signing", "auto");
1011 do_parameter("use spnego", "True");
1013 do_parameter("smb ports", SMB_PORTS);
1015 do_parameter("nt status support", "True");
1018 static TALLOC_CTX *lp_talloc;
1020 /******************************************************************* a
1021 Free up temporary memory - called from the main loop.
1022 ********************************************************************/
1024 void lp_talloc_free(void)
1028 talloc_free(lp_talloc);
1032 /*******************************************************************
1033 Convenience routine to grab string parameters into temporary memory
1034 and run standard_sub_basic on them. The buffers can be written to by
1035 callers without affecting the source string.
1036 ********************************************************************/
1038 static const char *lp_string(const char *s)
1040 #if 0 /* until REWRITE done to make thread-safe */
1041 size_t len = s ? strlen(s) : 0;
1045 /* The follow debug is useful for tracking down memory problems
1046 especially if you have an inner loop that is calling a lp_*()
1047 function that returns a string. Perhaps this debug should be
1048 present all the time? */
1051 DEBUG(10, ("lp_string(%s)\n", s));
1054 #if 0 /* until REWRITE done to make thread-safe */
1056 lp_talloc = talloc_init("lp_talloc");
1058 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1066 StrnCpy(ret, s, len);
1068 if (trim_string(ret, "\"", "\"")) {
1069 if (strchr(ret,'"') != NULL)
1070 StrnCpy(ret, s, len);
1073 standard_sub_basic(ret,len+100);
1080 In this section all the functions that are used to access the
1081 parameters from the rest of the program are defined
1084 #define FN_GLOBAL_STRING(fn_name,ptr) \
1085 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1086 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1087 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1088 #define FN_GLOBAL_LIST(fn_name,ptr) \
1089 const char **fn_name(void) {return(*(const char ***)(ptr));}
1090 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1091 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1092 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1093 char fn_name(void) {return(*(char *)(ptr));}
1094 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1095 int fn_name(void) {return(*(int *)(ptr));}
1097 #define FN_LOCAL_STRING(fn_name,val) \
1098 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1099 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1100 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1101 #define FN_LOCAL_LIST(fn_name,val) \
1102 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1103 #define FN_LOCAL_BOOL(fn_name,val) \
1104 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1105 #define FN_LOCAL_CHAR(fn_name,val) \
1106 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1107 #define FN_LOCAL_INTEGER(fn_name,val) \
1108 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1110 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1111 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1112 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1113 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1114 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1115 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1116 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1117 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1118 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1119 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1120 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1121 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1122 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1123 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1124 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1125 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1126 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1127 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1128 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1129 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1130 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1131 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1132 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1133 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1134 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1135 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1136 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1137 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1138 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1139 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1140 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1141 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1142 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1143 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1144 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1145 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1146 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1147 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1148 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1149 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1150 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1151 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1152 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1153 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1154 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1156 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1158 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1160 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1161 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1162 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1163 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1164 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1165 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1166 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1167 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1168 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1170 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1171 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1172 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1173 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1174 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1175 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1176 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1177 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1178 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1179 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1180 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1181 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1182 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1183 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1184 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1185 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1186 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1187 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1188 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1189 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1190 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1191 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1192 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1193 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1194 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1195 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1196 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1197 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1198 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1199 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1200 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1201 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1202 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1203 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1204 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1205 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1206 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1207 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1208 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1209 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1210 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1211 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1212 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1213 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1214 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1215 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1216 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1217 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1218 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1219 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1220 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1221 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1222 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1223 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1224 FN_LOCAL_STRING(lp_servicename, szService)
1225 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1226 FN_LOCAL_STRING(lp_pathname, szPath)
1227 FN_LOCAL_STRING(lp_username, szUsername)
1228 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1229 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1230 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1231 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1232 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1233 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1234 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1235 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1236 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1237 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1238 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1239 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1240 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1241 FN_LOCAL_STRING(lp_comment, comment)
1242 FN_LOCAL_STRING(lp_fstype, fstype)
1243 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1244 static FN_LOCAL_STRING(lp_volume, volume)
1245 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1246 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1247 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1248 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1249 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1250 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1251 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1252 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1253 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1254 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1255 FN_LOCAL_BOOL(lp_locking, bLocking)
1256 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1257 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1258 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1259 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1260 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1261 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1262 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1263 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1264 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1265 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1266 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1267 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1268 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1269 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1270 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1271 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1272 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1273 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1275 /* local prototypes */
1277 static int map_parameter(const char *pszParmName);
1278 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1279 static int getservicebyname(const char *pszServiceName,
1280 service * pserviceDest);
1281 static void copy_service(service * pserviceDest,
1282 service * pserviceSource, BOOL *pcopymapDest);
1283 static BOOL service_ok(int iService);
1284 static BOOL do_section(const char *pszSectionName);
1285 static void init_copymap(service * pservice);
1287 /* This is a helper function for parametrical options support. */
1288 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1289 /* Actual parametrical functions are quite simple */
1290 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1293 struct param_opt *data;
1295 if (lookup_service >= iNumServices) return NULL;
1297 data = (lookup_service < 0) ?
1298 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1300 asprintf(&vfskey, "%s:%s", type, option);
1304 if (strcmp(data->key, vfskey) == 0) {
1311 if (lookup_service >= 0) {
1312 /* Try to fetch the same option but from globals */
1313 /* but only if we are not already working with Globals */
1314 data = Globals.param_opt;
1316 if (strcmp(data->key, vfskey) == 0) {
1330 /*******************************************************************
1331 convenience routine to return int parameters.
1332 ********************************************************************/
1333 static int lp_int(const char *s)
1337 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1344 /*******************************************************************
1345 convenience routine to return unsigned long parameters.
1346 ********************************************************************/
1347 static int lp_ulong(const char *s)
1351 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1355 return strtoul(s, NULL, 10);
1358 /*******************************************************************
1359 convenience routine to return boolean parameters.
1360 ********************************************************************/
1361 static BOOL lp_bool(const char *s)
1366 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1370 if (!set_boolean(&ret,s)) {
1371 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1378 /*******************************************************************
1379 convenience routine to return enum parameters.
1380 ********************************************************************/
1381 static int lp_enum(const char *s,const struct enum_list *_enum)
1386 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1390 for (i=0; _enum[i].name; i++) {
1391 if (strcasecmp(_enum[i].name,s)==0)
1392 return _enum[i].value;
1395 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1399 /* Return parametric option from a given service. Type is a part of option before ':' */
1400 /* Parametric option has following syntax: 'Type: option = value' */
1401 /* Returned value is allocated in 'lp_talloc' context */
1403 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1405 const char *value = get_parametrics(lookup_service, type, option);
1408 return lp_string(value);
1413 /* Return parametric option from a given service. Type is a part of option before ':' */
1414 /* Parametric option has following syntax: 'Type: option = value' */
1415 /* Returned value is allocated in 'lp_talloc' context */
1417 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1418 const char *separator)
1420 const char *value = get_parametrics(lookup_service, type, option);
1423 return str_list_make(value, separator);
1428 /* Return parametric option from a given service. Type is a part of option before ':' */
1429 /* Parametric option has following syntax: 'Type: option = value' */
1431 int lp_parm_int(int lookup_service, const char *type, const char *option)
1433 const char *value = get_parametrics(lookup_service, type, option);
1436 return lp_int(value);
1441 /* Return parametric option from a given service. Type is a part of option before ':' */
1442 /* Parametric option has following syntax: 'Type: option = value' */
1444 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1446 const char *value = get_parametrics(lookup_service, type, option);
1449 return lp_ulong(value);
1454 /* Return parametric option from a given service. Type is a part of option before ':' */
1455 /* Parametric option has following syntax: 'Type: option = value' */
1457 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1459 const char *value = get_parametrics(lookup_service, type, option);
1462 return lp_bool(value);
1467 /* Return parametric option from a given service. Type is a part of option before ':' */
1468 /* Parametric option has following syntax: 'Type: option = value' */
1470 int lp_parm_enum(int lookup_service, const char *type, const char *option,
1471 const struct enum_list *_enum)
1473 const char *value = get_parametrics(lookup_service, type, option);
1476 return lp_enum(value, _enum);
1482 /***************************************************************************
1483 Initialise a service to the defaults.
1484 ***************************************************************************/
1486 static void init_service(service * pservice)
1488 memset((char *)pservice, '\0', sizeof(service));
1489 copy_service(pservice, &sDefault, NULL);
1492 /***************************************************************************
1493 Free the dynamically allocated parts of a service struct.
1494 ***************************************************************************/
1496 static void free_service(service *pservice)
1499 struct param_opt *data, *pdata;
1503 if (pservice->szService)
1504 DEBUG(5, ("free_service: Freeing service %s\n",
1505 pservice->szService));
1507 string_free(&pservice->szService);
1508 SAFE_FREE(pservice->copymap);
1510 for (i = 0; parm_table[i].label; i++) {
1511 if ((parm_table[i].type == P_STRING ||
1512 parm_table[i].type == P_USTRING) &&
1513 parm_table[i].class == P_LOCAL)
1514 string_free((char **)
1515 (((char *)pservice) +
1516 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1517 else if (parm_table[i].type == P_LIST &&
1518 parm_table[i].class == P_LOCAL)
1519 str_list_free((char ***)
1520 (((char *)pservice) +
1521 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1524 DEBUG(5,("Freeing parametrics:\n"));
1525 data = pservice->param_opt;
1527 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1528 string_free(&data->key);
1529 string_free(&data->value);
1535 ZERO_STRUCTP(pservice);
1538 /***************************************************************************
1539 Add a new service to the services array initialising it with the given
1541 ***************************************************************************/
1543 static int add_a_service(const service *pservice, const char *name)
1547 int num_to_alloc = iNumServices + 1;
1548 struct param_opt *data, *pdata;
1550 tservice = *pservice;
1552 /* it might already exist */
1554 i = getservicebyname(name, NULL);
1556 /* Clean all parametric options for service */
1557 /* They will be added during parsing again */
1558 data = ServicePtrs[i]->param_opt;
1560 string_free(&data->key);
1561 string_free(&data->value);
1566 ServicePtrs[i]->param_opt = NULL;
1571 /* find an invalid one */
1572 for (i = 0; i < iNumServices; i++)
1573 if (!ServicePtrs[i]->valid)
1576 /* if not, then create one */
1577 if (i == iNumServices) {
1580 tsp = (service **) Realloc(ServicePtrs,
1585 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1590 ServicePtrs[iNumServices] =
1591 (service *) malloc(sizeof(service));
1593 if (!ServicePtrs[iNumServices]) {
1594 DEBUG(0,("add_a_service: out of memory!\n"));
1600 free_service(ServicePtrs[i]);
1602 ServicePtrs[i]->valid = True;
1604 init_service(ServicePtrs[i]);
1605 copy_service(ServicePtrs[i], &tservice, NULL);
1607 string_set(&ServicePtrs[i]->szService, name);
1611 /***************************************************************************
1612 Add a new home service, with the specified home directory, defaults coming
1614 ***************************************************************************/
1616 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1617 const char *user, const char *pszHomedir)
1622 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1627 if (!(*(ServicePtrs[iDefaultService]->szPath))
1628 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1629 pstrcpy(newHomedir, pszHomedir);
1631 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1632 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1635 string_set(&ServicePtrs[i]->szPath, newHomedir);
1637 if (!(*(ServicePtrs[i]->comment))) {
1639 slprintf(comment, sizeof(comment) - 1,
1640 "Home directory of %s", user);
1641 string_set(&ServicePtrs[i]->comment, comment);
1643 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1644 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1646 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1652 /***************************************************************************
1653 Add a new service, based on an old one.
1654 ***************************************************************************/
1656 int lp_add_service(const char *pszService, int iDefaultService)
1658 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1661 /***************************************************************************
1662 Add the IPC service.
1663 ***************************************************************************/
1665 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1668 int i = add_a_service(&sDefault, ipc_name);
1673 slprintf(comment, sizeof(comment) - 1,
1674 "IPC Service (%s)", Globals.szServerString);
1676 string_set(&ServicePtrs[i]->szPath, tmpdir());
1677 string_set(&ServicePtrs[i]->szUsername, "");
1678 string_set(&ServicePtrs[i]->comment, comment);
1679 string_set(&ServicePtrs[i]->fstype, "IPC");
1680 ServicePtrs[i]->iMaxConnections = 0;
1681 ServicePtrs[i]->bAvailable = True;
1682 ServicePtrs[i]->bRead_only = True;
1683 ServicePtrs[i]->bGuest_only = False;
1684 ServicePtrs[i]->bGuest_ok = guest_ok;
1685 ServicePtrs[i]->bPrint_ok = False;
1686 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1688 lp_do_parameter(i, "ntvfs handler", "default");
1690 DEBUG(3, ("adding IPC service\n"));
1695 /***************************************************************************
1696 Add a new printer service, with defaults coming from service iFrom.
1697 ***************************************************************************/
1699 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1701 const char *comment = "From Printcap";
1702 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1707 /* note that we do NOT default the availability flag to True - */
1708 /* we take it from the default service passed. This allows all */
1709 /* dynamic printers to be disabled by disabling the [printers] */
1710 /* entry (if/when the 'available' keyword is implemented!). */
1712 /* the printer name is set to the service name. */
1713 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1714 string_set(&ServicePtrs[i]->comment, comment);
1715 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1716 /* Printers cannot be read_only. */
1717 ServicePtrs[i]->bRead_only = False;
1718 /* No share modes on printer services. */
1719 ServicePtrs[i]->bShareModes = False;
1720 /* No oplocks on printer services. */
1721 ServicePtrs[i]->bOpLocks = False;
1722 /* Printer services must be printable. */
1723 ServicePtrs[i]->bPrint_ok = True;
1725 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1727 update_server_announce_as_printserver();
1732 /***************************************************************************
1733 Map a parameter's string representation to something we can use.
1734 Returns False if the parameter string is not recognised, else TRUE.
1735 ***************************************************************************/
1737 static int map_parameter(const char *pszParmName)
1741 if (*pszParmName == '-')
1744 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1745 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1748 /* Warn only if it isn't parametric option */
1749 if (strchr(pszParmName, ':') == NULL)
1750 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1751 /* We do return 'fail' for parametric options as well because they are
1752 stored in different storage
1757 /***************************************************************************
1758 Set a boolean variable from the text value stored in the passed string.
1759 Returns True in success, False if the passed string does not correctly
1760 represent a boolean.
1761 ***************************************************************************/
1763 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1768 if (strwicmp(pszParmValue, "yes") == 0 ||
1769 strwicmp(pszParmValue, "true") == 0 ||
1770 strwicmp(pszParmValue, "1") == 0)
1772 else if (strwicmp(pszParmValue, "no") == 0 ||
1773 strwicmp(pszParmValue, "False") == 0 ||
1774 strwicmp(pszParmValue, "0") == 0)
1778 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1785 /***************************************************************************
1786 Find a service by name. Otherwise works like get_service.
1787 ***************************************************************************/
1789 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1793 for (iService = iNumServices - 1; iService >= 0; iService--)
1794 if (VALID(iService) &&
1795 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1796 if (pserviceDest != NULL)
1797 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1804 /***************************************************************************
1805 Copy a service structure to another.
1806 If pcopymapDest is NULL then copy all fields
1807 ***************************************************************************/
1809 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1812 BOOL bcopyall = (pcopymapDest == NULL);
1813 struct param_opt *data, *pdata, *paramo;
1816 for (i = 0; parm_table[i].label; i++)
1817 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1818 (bcopyall || pcopymapDest[i])) {
1819 void *def_ptr = parm_table[i].ptr;
1821 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1824 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1827 switch (parm_table[i].type) {
1830 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1836 *(int *)dest_ptr = *(int *)src_ptr;
1840 *(char *)dest_ptr = *(char *)src_ptr;
1844 string_set(dest_ptr,
1849 string_set(dest_ptr,
1851 strupper(*(char **)dest_ptr);
1854 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1862 init_copymap(pserviceDest);
1863 if (pserviceSource->copymap)
1864 memcpy((void *)pserviceDest->copymap,
1865 (void *)pserviceSource->copymap,
1866 sizeof(BOOL) * NUMPARAMETERS);
1869 data = pserviceSource->param_opt;
1872 pdata = pserviceDest->param_opt;
1873 /* Traverse destination */
1875 /* If we already have same option, override it */
1876 if (strcmp(pdata->key, data->key) == 0) {
1877 string_free(&pdata->value);
1878 pdata->value = strdup(data->value);
1882 pdata = pdata->next;
1885 paramo = smb_xmalloc(sizeof(*paramo));
1886 paramo->key = strdup(data->key);
1887 paramo->value = strdup(data->value);
1888 DLIST_ADD(pserviceDest->param_opt, paramo);
1894 /***************************************************************************
1895 Check a service for consistency. Return False if the service is in any way
1896 incomplete or faulty, else True.
1897 ***************************************************************************/
1899 static BOOL service_ok(int iService)
1904 if (ServicePtrs[iService]->szService[0] == '\0') {
1905 DEBUG(0, ("The following message indicates an internal error:\n"));
1906 DEBUG(0, ("No service name in service entry.\n"));
1910 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1911 /* I can't see why you'd want a non-printable printer service... */
1912 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1913 if (!ServicePtrs[iService]->bPrint_ok) {
1914 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1915 ServicePtrs[iService]->szService));
1916 ServicePtrs[iService]->bPrint_ok = True;
1918 /* [printers] service must also be non-browsable. */
1919 if (ServicePtrs[iService]->bBrowseable)
1920 ServicePtrs[iService]->bBrowseable = False;
1923 /* If a service is flagged unavailable, log the fact at level 0. */
1924 if (!ServicePtrs[iService]->bAvailable)
1925 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1926 ServicePtrs[iService]->szService));
1931 static struct file_lists {
1932 struct file_lists *next;
1936 } *file_lists = NULL;
1938 /*******************************************************************
1939 Keep a linked list of all config files so we know when one has changed
1940 it's date and needs to be reloaded.
1941 ********************************************************************/
1943 static void add_to_file_list(const char *fname, const char *subfname)
1945 struct file_lists *f = file_lists;
1948 if (f->name && !strcmp(f->name, fname))
1954 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1957 f->next = file_lists;
1958 f->name = strdup(fname);
1963 f->subfname = strdup(subfname);
1969 f->modtime = file_modtime(subfname);
1971 time_t t = file_modtime(subfname);
1977 /*******************************************************************
1978 Check if a config file has changed date.
1979 ********************************************************************/
1981 BOOL lp_file_list_changed(void)
1983 struct file_lists *f = file_lists;
1984 DEBUG(6, ("lp_file_list_changed()\n"));
1990 pstrcpy(n2, f->name);
1991 standard_sub_basic(n2,sizeof(n2));
1993 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1994 f->name, n2, ctime(&f->modtime)));
1996 mod_time = file_modtime(n2);
1998 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2000 ("file %s modified: %s\n", n2,
2002 f->modtime = mod_time;
2003 SAFE_FREE(f->subfname);
2004 f->subfname = strdup(n2);
2012 /***************************************************************************
2013 Handle the include operation.
2014 ***************************************************************************/
2016 static BOOL handle_include(const char *pszParmValue, char **ptr)
2019 pstrcpy(fname, pszParmValue);
2021 standard_sub_basic(fname,sizeof(fname));
2023 add_to_file_list(pszParmValue, fname);
2025 string_set(ptr, fname);
2027 if (file_exist(fname, NULL))
2028 return (pm_process(fname, do_section, do_parameter));
2030 DEBUG(2, ("Can't find include file %s\n", fname));
2035 /***************************************************************************
2036 Handle the interpretation of the copy parameter.
2037 ***************************************************************************/
2039 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2043 service serviceTemp;
2045 string_set(ptr, pszParmValue);
2047 init_service(&serviceTemp);
2051 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2053 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2054 if (iTemp == iServiceIndex) {
2055 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2057 copy_service(ServicePtrs[iServiceIndex],
2059 ServicePtrs[iServiceIndex]->copymap);
2063 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2067 free_service(&serviceTemp);
2071 /***************************************************************************
2072 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2077 winbind uid = 1000-1999
2078 winbind gid = 700-899
2080 We only do simple parsing checks here. The strings are parsed into useful
2081 structures in the winbind daemon code.
2083 ***************************************************************************/
2085 /* Some lp_ routines to return winbind [ug]id information */
2087 static uid_t winbind_uid_low, winbind_uid_high;
2088 static gid_t winbind_gid_low, winbind_gid_high;
2089 static uint32_t non_unix_account_low, non_unix_account_high;
2091 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2093 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2097 *low = winbind_uid_low;
2100 *high = winbind_uid_high;
2105 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2107 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2111 *low = winbind_gid_low;
2114 *high = winbind_gid_high;
2119 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2121 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2125 *low = non_unix_account_low;
2128 *high = non_unix_account_high;
2133 /* Do some simple checks on "winbind [ug]id" parameter values */
2135 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2139 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2144 string_set(ptr, pszParmValue);
2146 winbind_uid_low = low;
2147 winbind_uid_high = high;
2152 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2156 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2161 string_set(ptr, pszParmValue);
2163 winbind_gid_low = low;
2164 winbind_gid_high = high;
2169 /***************************************************************************
2170 Do some simple checks on "non unix account range" parameter values.
2171 ***************************************************************************/
2173 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2177 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2182 string_set(ptr, pszParmValue);
2184 non_unix_account_low = low;
2185 non_unix_account_high = high;
2191 /***************************************************************************
2192 Initialise a copymap.
2193 ***************************************************************************/
2195 static void init_copymap(service * pservice)
2198 SAFE_FREE(pservice->copymap);
2199 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2200 if (!pservice->copymap)
2202 ("Couldn't allocate copymap!! (size %d)\n",
2203 (int)NUMPARAMETERS));
2205 for (i = 0; i < NUMPARAMETERS; i++)
2206 pservice->copymap[i] = True;
2209 /***************************************************************************
2210 Return the local pointer to a parameter given the service number and the
2211 pointer into the default structure.
2212 ***************************************************************************/
2214 void *lp_local_ptr(int snum, void *ptr)
2216 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2220 /***************************************************************************
2221 Process a parametric option
2222 ***************************************************************************/
2223 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2225 struct param_opt *paramo, *data;
2228 while (isspace(*pszParmName)) {
2232 name = strdup(pszParmName);
2233 if (!name) return False;
2238 data = Globals.param_opt;
2240 data = ServicePtrs[snum]->param_opt;
2243 /* Traverse destination */
2244 for (paramo=data; paramo; paramo=paramo->next) {
2245 /* If we already have the option set, override it unless
2246 it was a command line option and the new one isn't */
2247 if (strcmp(paramo->key, name) == 0) {
2248 if ((paramo->flags & FLAG_CMDLINE) &&
2249 !(flags & FLAG_CMDLINE)) {
2253 free(paramo->value);
2254 paramo->value = strdup(pszParmValue);
2255 paramo->flags = flags;
2261 paramo = smb_xmalloc(sizeof(*paramo));
2262 paramo->key = strdup(name);
2263 paramo->value = strdup(pszParmValue);
2264 paramo->flags = flags;
2266 DLIST_ADD(Globals.param_opt, paramo);
2268 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2276 /***************************************************************************
2277 Process a parameter for a particular service number. If snum < 0
2278 then assume we are in the globals.
2279 ***************************************************************************/
2280 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2283 void *parm_ptr = NULL; /* where we are going to store the result */
2284 void *def_ptr = NULL;
2286 parmnum = map_parameter(pszParmName);
2289 if (strchr(pszParmName, ':')) {
2290 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2292 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2296 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2297 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2301 /* if the flag has been set on the command line, then don't allow override,
2302 but don't report an error */
2303 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2307 def_ptr = parm_table[parmnum].ptr;
2309 /* we might point at a service, the default service or a global */
2313 if (parm_table[parmnum].class == P_GLOBAL) {
2315 ("Global parameter %s found in service section!\n",
2320 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2325 if (!ServicePtrs[snum]->copymap)
2326 init_copymap(ServicePtrs[snum]);
2328 /* this handles the aliases - set the copymap for other entries with
2329 the same data pointer */
2330 for (i = 0; parm_table[i].label; i++)
2331 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2332 ServicePtrs[snum]->copymap[i] = False;
2335 /* if it is a special case then go ahead */
2336 if (parm_table[parmnum].special) {
2337 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2341 /* now switch on the type of variable it is */
2342 switch (parm_table[parmnum].type)
2345 set_boolean(parm_ptr, pszParmValue);
2349 set_boolean(parm_ptr, pszParmValue);
2350 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2354 *(int *)parm_ptr = atoi(pszParmValue);
2358 *(char *)parm_ptr = *pszParmValue;
2362 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2366 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2370 string_set(parm_ptr, pszParmValue);
2374 string_set(parm_ptr, pszParmValue);
2375 strupper(*(char **)parm_ptr);
2379 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2382 parm_table[parmnum].enum_list[i].name)) {
2384 parm_table[parmnum].
2389 if (!parm_table[parmnum].enum_list[i].name) {
2390 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2391 pszParmValue, pszParmName));
2402 /***************************************************************************
2403 Process a parameter.
2404 ***************************************************************************/
2406 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2408 if (!bInGlobalSection && bGlobalOnly)
2411 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2412 pszParmName, pszParmValue));
2416 variable argument do parameter
2418 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2420 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2427 s = talloc_vasprintf(NULL, fmt, ap);
2429 ret = do_parameter(pszParmName, s);
2436 set a parameter from the commandline - this is called from command line parameter
2437 parsing code. It sets the parameter then marks the parameter as unable to be modified
2438 by smb.conf processing
2440 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2442 int parmnum = map_parameter(pszParmName);
2445 while (isspace(*pszParmValue)) pszParmValue++;
2448 if (parmnum < 0 && strchr(pszParmName, ':')) {
2449 /* set a parametric option */
2450 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2454 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2458 /* reset the CMDLINE flag in case this has been called before */
2459 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2461 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2465 parm_table[parmnum].flags |= FLAG_CMDLINE;
2467 /* we have to also set FLAG_CMDLINE on aliases */
2468 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2469 parm_table[i].flags |= FLAG_CMDLINE;
2471 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2472 parm_table[i].flags |= FLAG_CMDLINE;
2479 set a option from the commandline in 'a=b' format. Use to support --option
2481 BOOL lp_set_option(const char *option)
2499 ret = lp_set_cmdline(s, p+1);
2505 /***************************************************************************
2506 Print a parameter of the specified type.
2507 ***************************************************************************/
2509 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2515 for (i = 0; p->enum_list[i].name; i++) {
2516 if (*(int *)ptr == p->enum_list[i].value) {
2518 p->enum_list[i].name);
2525 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2529 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2533 fprintf(f, "%d", *(int *)ptr);
2537 fprintf(f, "%c", *(char *)ptr);
2541 if (*(int *)ptr == -1) {
2544 fprintf(f, "0%o", *(int *)ptr);
2549 if ((char ***)ptr && *(char ***)ptr) {
2550 char **list = *(char ***)ptr;
2552 for (; *list; list++)
2553 fprintf(f, "%s%s", *list,
2554 ((*(list+1))?", ":""));
2560 if (*(char **)ptr) {
2561 fprintf(f, "%s", *(char **)ptr);
2569 /***************************************************************************
2570 Check if two parameters are equal.
2571 ***************************************************************************/
2573 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2578 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2583 return (*((int *)ptr1) == *((int *)ptr2));
2586 return (*((char *)ptr1) == *((char *)ptr2));
2589 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2594 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2599 return (p1 == p2 || strequal(p1, p2));
2607 /***************************************************************************
2608 Process a new section (service). At this stage all sections are services.
2609 Later we'll have special sections that permit server parameters to be set.
2610 Returns True on success, False on failure.
2611 ***************************************************************************/
2613 static BOOL do_section(const char *pszSectionName)
2616 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2617 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2620 /* if we've just struck a global section, note the fact. */
2621 bInGlobalSection = isglobal;
2623 /* check for multiple global sections */
2624 if (bInGlobalSection) {
2625 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2629 if (!bInGlobalSection && bGlobalOnly)
2632 /* if we have a current service, tidy it up before moving on */
2635 if (iServiceIndex >= 0)
2636 bRetval = service_ok(iServiceIndex);
2638 /* if all is still well, move to the next record in the services array */
2640 /* We put this here to avoid an odd message order if messages are */
2641 /* issued by the post-processing of a previous section. */
2642 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2644 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2646 DEBUG(0, ("Failed to add a new service\n"));
2655 /***************************************************************************
2656 Determine if a partcular base parameter is currentl set to the default value.
2657 ***************************************************************************/
2659 static BOOL is_default(int i)
2661 if (!defaults_saved)
2663 switch (parm_table[i].type) {
2665 return str_list_compare (parm_table[i].def.lvalue,
2666 *(char ***)parm_table[i].ptr);
2669 return strequal(parm_table[i].def.svalue,
2670 *(char **)parm_table[i].ptr);
2673 return parm_table[i].def.bvalue ==
2674 *(BOOL *)parm_table[i].ptr;
2676 return parm_table[i].def.cvalue ==
2677 *(char *)parm_table[i].ptr;
2681 return parm_table[i].def.ivalue ==
2682 *(int *)parm_table[i].ptr;
2689 /***************************************************************************
2690 Display the contents of the global structure.
2691 ***************************************************************************/
2693 static void dump_globals(FILE *f)
2696 struct param_opt *data;
2698 fprintf(f, "# Global parameters\n[global]\n");
2700 for (i = 0; parm_table[i].label; i++)
2701 if (parm_table[i].class == P_GLOBAL &&
2702 parm_table[i].ptr &&
2703 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2704 if (defaults_saved && is_default(i))
2706 fprintf(f, "\t%s = ", parm_table[i].label);
2707 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2710 if (Globals.param_opt != NULL) {
2711 data = Globals.param_opt;
2713 fprintf(f, "\t%s = %s\n", data->key, data->value);
2720 /***************************************************************************
2721 Return True if a local parameter is currently set to the global default.
2722 ***************************************************************************/
2724 BOOL lp_is_default(int snum, struct parm_struct *parm)
2726 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
2728 return equal_parameter(parm->type,
2729 ((char *)ServicePtrs[snum]) + pdiff,
2730 ((char *)&sDefault) + pdiff);
2733 /***************************************************************************
2734 Display the contents of a single services record.
2735 ***************************************************************************/
2737 static void dump_a_service(service * pService, FILE * f)
2740 struct param_opt *data;
2742 if (pService != &sDefault)
2743 fprintf(f, "\n[%s]\n", pService->szService);
2745 for (i = 0; parm_table[i].label; i++)
2746 if (parm_table[i].class == P_LOCAL &&
2747 parm_table[i].ptr &&
2748 (*parm_table[i].label != '-') &&
2749 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2750 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2752 if (pService == &sDefault) {
2753 if (defaults_saved && is_default(i))
2756 if (equal_parameter(parm_table[i].type,
2757 ((char *)pService) +
2759 ((char *)&sDefault) +
2764 fprintf(f, "\t%s = ", parm_table[i].label);
2765 print_parameter(&parm_table[i],
2766 ((char *)pService) + pdiff, f);
2769 if (pService->param_opt != NULL) {
2770 data = pService->param_opt;
2772 fprintf(f, "\t%s = %s\n", data->key, data->value);
2779 /***************************************************************************
2780 Return info about the next service in a service. snum==-1 gives the globals.
2781 Return NULL when out of parameters.
2782 ***************************************************************************/
2784 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2787 /* do the globals */
2788 for (; parm_table[*i].label; (*i)++) {
2789 if (parm_table[*i].class == P_SEPARATOR)
2790 return &parm_table[(*i)++];
2792 if (!parm_table[*i].ptr
2793 || (*parm_table[*i].label == '-'))
2797 && (parm_table[*i].ptr ==
2798 parm_table[(*i) - 1].ptr))
2801 return &parm_table[(*i)++];
2804 service *pService = ServicePtrs[snum];
2806 for (; parm_table[*i].label; (*i)++) {
2807 if (parm_table[*i].class == P_SEPARATOR)
2808 return &parm_table[(*i)++];
2810 if (parm_table[*i].class == P_LOCAL &&
2811 parm_table[*i].ptr &&
2812 (*parm_table[*i].label != '-') &&
2814 (parm_table[*i].ptr !=
2815 parm_table[(*i) - 1].ptr)))
2818 PTR_DIFF(parm_table[*i].ptr,
2821 if (allparameters ||
2822 !equal_parameter(parm_table[*i].type,
2823 ((char *)pService) +
2825 ((char *)&sDefault) +
2828 return &parm_table[(*i)++];
2839 /***************************************************************************
2840 Display the contents of a single copy structure.
2841 ***************************************************************************/
2842 static void dump_copy_map(BOOL *pcopymap)
2848 printf("\n\tNon-Copied parameters:\n");
2850 for (i = 0; parm_table[i].label; i++)
2851 if (parm_table[i].class == P_LOCAL &&
2852 parm_table[i].ptr && !pcopymap[i] &&
2853 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2855 printf("\t\t%s\n", parm_table[i].label);
2860 /***************************************************************************
2861 Return TRUE if the passed service number is within range.
2862 ***************************************************************************/
2864 BOOL lp_snum_ok(int iService)
2866 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2869 /***************************************************************************
2870 Auto-load some home services.
2871 ***************************************************************************/
2873 static void lp_add_auto_services(const char *str)
2878 /***************************************************************************
2879 Auto-load one printer.
2880 ***************************************************************************/
2882 void lp_add_one_printer(char *name, char *comment)
2884 int printers = lp_servicenumber(PRINTERS_NAME);
2887 if (lp_servicenumber(name) < 0) {
2888 lp_add_printer(name, printers);
2889 if ((i = lp_servicenumber(name)) >= 0) {
2890 string_set(&ServicePtrs[i]->comment, comment);
2891 ServicePtrs[i]->autoloaded = True;
2896 /***************************************************************************
2897 Announce ourselves as a print server.
2898 ***************************************************************************/
2900 void update_server_announce_as_printserver(void)
2902 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2905 /***************************************************************************
2906 Have we loaded a services file yet?
2907 ***************************************************************************/
2909 BOOL lp_loaded(void)
2914 /***************************************************************************
2915 Unload unused services.
2916 ***************************************************************************/
2918 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2921 for (i = 0; i < iNumServices; i++) {
2925 if (!snumused || !snumused(smb, i)) {
2926 ServicePtrs[i]->valid = False;
2927 free_service(ServicePtrs[i]);
2932 /***************************************************************************
2934 ***************************************************************************/
2936 void lp_killservice(int iServiceIn)
2938 if (VALID(iServiceIn)) {
2939 ServicePtrs[iServiceIn]->valid = False;
2940 free_service(ServicePtrs[iServiceIn]);
2944 /***************************************************************************
2945 Save the curent values of all global and sDefault parameters into the
2946 defaults union. This allows swat and testparm to show only the
2947 changed (ie. non-default) parameters.
2948 ***************************************************************************/
2950 static void lp_save_defaults(void)
2953 for (i = 0; parm_table[i].label; i++) {
2954 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2956 switch (parm_table[i].type) {
2958 str_list_copy(&(parm_table[i].def.lvalue),
2959 *(const char ***)parm_table[i].ptr);
2963 if (parm_table[i].ptr) {
2964 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2966 parm_table[i].def.svalue = NULL;
2971 parm_table[i].def.bvalue =
2972 *(BOOL *)parm_table[i].ptr;
2975 parm_table[i].def.cvalue =
2976 *(char *)parm_table[i].ptr;
2981 parm_table[i].def.ivalue =
2982 *(int *)parm_table[i].ptr;
2988 defaults_saved = True;
2991 /*******************************************************************
2992 Set the server type we will announce as via nmbd.
2993 ********************************************************************/
2995 static void set_server_role(void)
2997 server_role = ROLE_STANDALONE;
2999 switch (lp_security()) {
3001 if (lp_domain_logons())
3002 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3007 if (lp_domain_logons()) {
3008 server_role = ROLE_DOMAIN_PDC;
3011 server_role = ROLE_DOMAIN_MEMBER;
3014 if (lp_domain_logons()) {
3016 if (Globals.bDomainMaster) /* auto or yes */
3017 server_role = ROLE_DOMAIN_PDC;
3019 server_role = ROLE_DOMAIN_BDC;
3023 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3027 DEBUG(10, ("set_server_role: role = "));
3029 switch(server_role) {
3030 case ROLE_STANDALONE:
3031 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3033 case ROLE_DOMAIN_MEMBER:
3034 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3036 case ROLE_DOMAIN_BDC:
3037 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3039 case ROLE_DOMAIN_PDC:
3040 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3045 /***************************************************************************
3046 Load the services array from the services file. Return True on success,
3048 ***************************************************************************/
3050 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3055 struct param_opt *data;
3057 pstrcpy(n2, pszFname);
3058 standard_sub_basic(n2,sizeof(n2));
3060 add_to_file_list(pszFname, n2);
3064 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3066 bInGlobalSection = True;
3067 bGlobalOnly = global_only;
3076 if (Globals.param_opt != NULL) {
3077 struct param_opt *next;
3078 for (data=Globals.param_opt; data; data=next) {
3080 if (data->flags & FLAG_CMDLINE) continue;
3083 DLIST_REMOVE(Globals.param_opt, data);
3088 /* We get sections first, so have to start 'behind' to make up */
3090 bRetval = pm_process(n2, do_section, do_parameter);
3092 /* finish up the last section */
3093 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3095 if (iServiceIndex >= 0)
3096 bRetval = service_ok(iServiceIndex);
3098 lp_add_auto_services(lp_auto_services());
3101 /* When 'restrict anonymous = 2' guest connections to ipc$
3103 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3104 lp_add_ipc("ADMIN$", False);
3108 set_default_server_announce_type();
3112 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3113 /* if bWINSsupport is true and we are in the client */
3114 if (in_client && Globals.bWINSsupport) {
3115 lp_do_parameter(-1, "wins server", "127.0.0.1");
3123 /***************************************************************************
3124 Reset the max number of services.
3125 ***************************************************************************/
3127 void lp_resetnumservices(void)
3132 /***************************************************************************
3133 Return the max number of services.
3134 ***************************************************************************/
3136 int lp_numservices(void)
3138 return (iNumServices);
3141 /***************************************************************************
3142 Display the contents of the services array in human-readable form.
3143 ***************************************************************************/
3145 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3150 defaults_saved = False;
3154 dump_a_service(&sDefault, f);
3156 for (iService = 0; iService < maxtoprint; iService++)
3157 lp_dump_one(f, show_defaults, iService);
3160 /***************************************************************************
3161 Display the contents of one service in human-readable form.
3162 ***************************************************************************/
3164 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3167 if (ServicePtrs[snum]->szService[0] == '\0')
3169 dump_a_service(ServicePtrs[snum], f);
3173 /***************************************************************************
3174 Return the number of the service with the given name, or -1 if it doesn't
3175 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3176 getservicebyname()! This works ONLY if all services have been loaded, and
3177 does not copy the found service.
3178 ***************************************************************************/
3180 int lp_servicenumber(const char *pszServiceName)
3183 fstring serviceName;
3186 for (iService = iNumServices - 1; iService >= 0; iService--) {
3187 if (VALID(iService) && ServicePtrs[iService]->szService) {
3189 * The substitution here is used to support %U is
3192 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3193 standard_sub_basic(serviceName,sizeof(serviceName));
3194 if (strequal(serviceName, pszServiceName))
3200 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3205 /*******************************************************************
3206 A useful volume label function.
3207 ********************************************************************/
3208 const char *volume_label(int snum)
3210 const char *ret = lp_volume(snum);
3212 return lp_servicename(snum);
3217 /*******************************************************************
3218 Set the server type we will announce as via nmbd.
3219 ********************************************************************/
3221 static void set_default_server_announce_type(void)
3223 default_server_announce = 0;
3224 default_server_announce |= SV_TYPE_WORKSTATION;
3225 default_server_announce |= SV_TYPE_SERVER;
3226 default_server_announce |= SV_TYPE_SERVER_UNIX;
3228 switch (lp_announce_as()) {
3229 case ANNOUNCE_AS_NT_SERVER:
3230 default_server_announce |= SV_TYPE_SERVER_NT;
3231 /* fall through... */
3232 case ANNOUNCE_AS_NT_WORKSTATION:
3233 default_server_announce |= SV_TYPE_NT;
3235 case ANNOUNCE_AS_WIN95:
3236 default_server_announce |= SV_TYPE_WIN95_PLUS;
3238 case ANNOUNCE_AS_WFW:
3239 default_server_announce |= SV_TYPE_WFW;
3245 switch (lp_server_role()) {
3246 case ROLE_DOMAIN_MEMBER:
3247 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3249 case ROLE_DOMAIN_PDC:
3250 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3252 case ROLE_DOMAIN_BDC:
3253 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3255 case ROLE_STANDALONE:
3259 if (lp_time_server())
3260 default_server_announce |= SV_TYPE_TIME_SOURCE;
3262 if (lp_host_msdfs())
3263 default_server_announce |= SV_TYPE_DFS_SERVER;
3266 /***********************************************************
3267 returns role of Samba server
3268 ************************************************************/
3270 int lp_server_role(void)
3275 /***********************************************************
3276 If we are PDC then prefer us as DMB
3277 ************************************************************/
3279 BOOL lp_domain_master(void)
3281 if (Globals.bDomainMaster == Auto)
3282 return (lp_server_role() == ROLE_DOMAIN_PDC);
3284 return Globals.bDomainMaster;
3287 /***********************************************************
3288 If we are DMB then prefer us as LMB
3289 ************************************************************/
3291 BOOL lp_preferred_master(void)
3293 if (Globals.bPreferredMaster == Auto)
3294 return (lp_local_master() && lp_domain_master());
3296 return Globals.bPreferredMaster;
3299 /*******************************************************************
3301 ********************************************************************/
3303 void lp_remove_service(int snum)
3305 ServicePtrs[snum]->valid = False;
3308 /*******************************************************************
3310 ********************************************************************/
3312 void lp_copy_service(int snum, const char *new_name)
3314 const char *oldname = lp_servicename(snum);
3315 do_section(new_name);
3317 snum = lp_servicenumber(new_name);
3319 lp_do_parameter(snum, "copy", oldname);
3324 /*******************************************************************
3325 Get the default server type we will announce as via nmbd.
3326 ********************************************************************/
3328 int lp_default_server_announce(void)
3330 return default_server_announce;
3333 /*******************************************************************
3334 Split the announce version into major and minor numbers.
3335 ********************************************************************/
3337 int lp_major_announce_version(void)
3339 static BOOL got_major = False;
3340 static int major_version = DEFAULT_MAJOR_VERSION;
3345 return major_version;
3348 if ((vers = lp_announce_version()) == NULL)
3349 return major_version;
3351 if ((p = strchr_m(vers, '.')) == 0)
3352 return major_version;
3355 major_version = atoi(vers);
3356 return major_version;
3359 int lp_minor_announce_version(void)
3361 static BOOL got_minor = False;
3362 static int minor_version = DEFAULT_MINOR_VERSION;
3367 return minor_version;
3370 if ((vers = lp_announce_version()) == NULL)
3371 return minor_version;
3373 if ((p = strchr_m(vers, '.')) == 0)
3374 return minor_version;
3377 minor_version = atoi(p);
3378 return minor_version;
3381 const char *lp_printername(int snum)
3383 const char *ret = _lp_printername(snum);
3384 if (ret == NULL || (ret != NULL && *ret == '\0'))
3385 ret = lp_const_servicename(snum);
3391 /*******************************************************************
3392 Return the max print jobs per queue.
3393 ********************************************************************/
3395 int lp_maxprintjobs(int snum)
3397 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3398 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3399 maxjobs = PRINT_MAX_JOBID - 1;