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
56 #include "librpc/gen_ndr/ndr_svcctl.h"
58 BOOL in_client = False; /* Not in the client by default */
59 static BOOL bLoaded = False;
62 #define GLOBAL_NAME "global"
66 #define PRINTERS_NAME "printers"
70 #define HOMES_NAME "homes"
73 /* some helpful bits */
74 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
75 #define VALID(i) ServicePtrs[i]->valid
77 static BOOL do_parameter(const char *, const char *);
78 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
80 static BOOL defaults_saved = False;
83 #define FLAG_BASIC 0x0001 /* fundamental options */
84 #define FLAG_SHARE 0x0002 /* file sharing options */
85 #define FLAG_PRINT 0x0004 /* printing options */
86 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
87 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
88 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
89 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
90 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
91 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
92 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
93 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
96 /* the following are used by loadparm for option lists */
99 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
100 P_STRING,P_USTRING,P_ENUM,P_SEP
105 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
119 BOOL (*special)(const char *, char **);
120 const struct enum_list *enum_list;
133 struct param_opt *prev, *next;
140 * This structure describes global (ie., server-wide) parameters.
148 char *display_charset;
149 char *szPrintcapname;
153 char *szDefaultService;
155 char *szServerString;
156 char *szAutoServices;
157 char *szPasswdProgram;
161 char *szSMBPasswdFile;
165 char **szPreloadModules;
166 char *szPasswordServer;
167 char *szSocketOptions;
174 char **szWINSservers;
176 char *szRemoteAnnounce;
177 char *szRemoteBrowseSync;
178 char *szSocketAddress;
179 char *szAnnounceVersion; /* This is initialised in init_globals */
182 char **szNetbiosAliases;
183 char *szNetbiosScope;
184 char *szDomainOtherSIDs;
185 char *szNameResolveOrder;
187 char *szAddUserScript;
188 char *szAddMachineScript;
190 char *szWINSPartners;
191 char **dcerpc_ep_servers;
192 char **server_services;
195 char *szNonUnixAccountRange;
196 char *szTemplateHomedir;
197 char *szTemplateShell;
198 char *szWinbindSeparator;
199 BOOL bWinbindEnumUsers;
200 BOOL bWinbindEnumGroups;
201 BOOL bWinbindUseDefaultDomain;
202 char *szIDMapBackend;
203 char *szGuestaccount;
212 BOOL paranoid_server_security;
214 BOOL bDisableSpoolss;
216 int enhanced_browsing;
223 int announce_as; /* This is initialised in init_globals */
224 int machine_password_timeout;
225 int winbind_cache_time;
228 char *socket_options;
233 BOOL bPreferredMaster;
236 BOOL bEncryptPasswords;
238 BOOL bObeyPamRestrictions;
240 BOOL bLargeReadwrite;
244 BOOL bBindInterfacesOnly;
245 BOOL bPamPasswordChange;
247 BOOL bNTStatusSupport;
248 BOOL bAllowTrustedDomains;
254 BOOL bClientLanManAuth;
255 BOOL bClientNTLMv2Auth;
257 BOOL bHideLocalUsers;
260 BOOL bHostnameLookups;
261 BOOL bUnixExtensions;
262 BOOL bDisableNetbios;
264 int restrict_anonymous;
265 int name_cache_timeout;
266 struct param_opt *param_opt;
270 static global Globals;
273 * This structure describes a single service.
282 char **szInvalidUsers;
287 char *szPrintcommand;
290 char *szLppausecommand;
291 char *szLpresumecommand;
292 char *szQueuepausecommand;
293 char *szQueueresumecommand;
301 char **ntvfs_handler;
327 struct param_opt *param_opt;
329 char dummy[3]; /* for alignment */
334 /* This is a default service used to prime a services structure */
335 static service sDefault = {
337 False, /* not autoloaded */
338 NULL, /* szService */
340 NULL, /* szUsername */
341 NULL, /* szInvalidUsers */
342 NULL, /* szValidUsers */
343 NULL, /* szAdminUsers */
345 NULL, /* szInclude */
346 NULL, /* szPrintcommand */
347 NULL, /* szLpqcommand */
348 NULL, /* szLprmcommand */
349 NULL, /* szLppausecommand */
350 NULL, /* szLpresumecommand */
351 NULL, /* szQueuepausecommand */
352 NULL, /* szQueueresumecommand */
353 NULL, /* szPrintername */
354 NULL, /* szHostsallow */
355 NULL, /* szHostsdeny */
359 NULL, /* szMSDfsProxy */
360 NULL, /* ntvfs_handler */
361 0, /* iMinPrintSpace */
362 1000, /* iMaxPrintJobs */
363 0, /* iMaxConnections */
364 DEFAULT_PRINTING, /* iPrinting */
366 True, /* bAvailable */
367 True, /* bBrowseable */
368 True, /* bRead_only */
369 False, /* bPrint_ok */
370 False, /* bMap_system */
371 False, /* bMap_hidden */
372 True, /* bMap_archive */
374 True, /* bStrictLocking */
375 True, /* bPosixLocking */
377 True, /* bLevel2OpLocks */
378 False, /* bOnlyUser */
379 False, /* bGuest_only */
380 False, /* bGuest_ok */
382 False, /* bMSDfsRoot */
383 True, /* bShareModes */
384 False, /* bStrictSync */
385 False, /* bCIFileSystem */
386 NULL, /* Parametric options */
391 /* local variables */
392 static service **ServicePtrs = NULL;
393 static int iNumServices = 0;
394 static int iServiceIndex = 0;
395 static BOOL bInGlobalSection = True;
396 static BOOL bGlobalOnly = False;
397 static int server_role;
398 static int default_server_announce;
400 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
402 /* prototypes for the special type handlers */
403 static BOOL handle_include(const char *pszParmValue, char **ptr);
404 static BOOL handle_copy(const char *pszParmValue, char **ptr);
405 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
406 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
407 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
409 static void set_server_role(void);
410 static void set_default_server_announce_type(void);
412 static const struct enum_list enum_protocol[] = {
413 {PROTOCOL_NT1, "NT1"},
414 {PROTOCOL_LANMAN2, "LANMAN2"},
415 {PROTOCOL_LANMAN1, "LANMAN1"},
416 {PROTOCOL_CORE, "CORE"},
417 {PROTOCOL_COREPLUS, "COREPLUS"},
418 {PROTOCOL_COREPLUS, "CORE+"},
422 static const struct enum_list enum_security[] = {
423 {SEC_SHARE, "SHARE"},
425 {SEC_SERVER, "SERVER"},
426 {SEC_DOMAIN, "DOMAIN"},
433 static const struct enum_list enum_printing[] = {
434 {PRINT_SYSV, "sysv"},
436 {PRINT_HPUX, "hpux"},
440 {PRINT_LPRNG, "lprng"},
441 {PRINT_SOFTQ, "softq"},
442 {PRINT_CUPS, "cups"},
444 {PRINT_LPROS2, "os2"},
446 {PRINT_TEST, "test"},
448 #endif /* DEVELOPER */
452 /* Types of machine we can announce as. */
453 #define ANNOUNCE_AS_NT_SERVER 1
454 #define ANNOUNCE_AS_WIN95 2
455 #define ANNOUNCE_AS_WFW 3
456 #define ANNOUNCE_AS_NT_WORKSTATION 4
458 static const struct enum_list enum_announce_as[] = {
459 {ANNOUNCE_AS_NT_SERVER, "NT"},
460 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
461 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
462 {ANNOUNCE_AS_WIN95, "win95"},
463 {ANNOUNCE_AS_WFW, "WfW"},
467 static const struct enum_list enum_case[] = {
468 {CASE_LOWER, "lower"},
469 {CASE_UPPER, "upper"},
473 static const struct enum_list enum_bool_auto[] = {
484 /* Client-side offline caching policy types */
485 #define CSC_POLICY_MANUAL 0
486 #define CSC_POLICY_DOCUMENTS 1
487 #define CSC_POLICY_PROGRAMS 2
488 #define CSC_POLICY_DISABLE 3
490 static const struct enum_list enum_csc_policy[] = {
491 {CSC_POLICY_MANUAL, "manual"},
492 {CSC_POLICY_DOCUMENTS, "documents"},
493 {CSC_POLICY_PROGRAMS, "programs"},
494 {CSC_POLICY_DISABLE, "disable"},
498 /* SMB signing types. */
499 static const struct enum_list enum_smb_signing_vals[] = {
500 {SMB_SIGNING_OFF, "No"},
501 {SMB_SIGNING_OFF, "False"},
502 {SMB_SIGNING_OFF, "0"},
503 {SMB_SIGNING_OFF, "Off"},
504 {SMB_SIGNING_OFF, "disabled"},
505 {SMB_SIGNING_SUPPORTED, "Yes"},
506 {SMB_SIGNING_SUPPORTED, "True"},
507 {SMB_SIGNING_SUPPORTED, "1"},
508 {SMB_SIGNING_SUPPORTED, "On"},
509 {SMB_SIGNING_SUPPORTED, "enabled"},
510 {SMB_SIGNING_REQUIRED, "required"},
511 {SMB_SIGNING_REQUIRED, "mandatory"},
512 {SMB_SIGNING_REQUIRED, "force"},
513 {SMB_SIGNING_REQUIRED, "forced"},
514 {SMB_SIGNING_REQUIRED, "enforced"},
515 {SMB_SIGNING_AUTO, "auto"},
520 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
522 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
523 * is implied in current control logic. This may change at some later time. A
524 * flag value of 0 means - show as development option only.
526 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
527 * screen in SWAT. This is used to exclude parameters as well as to squash all
528 * parameters that have been duplicated by pseudonyms.
530 static struct parm_struct parm_table[] = {
531 {"Base Options", P_SEP, P_SEPARATOR},
533 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
538 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
539 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
540 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
541 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
542 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
543 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
544 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
550 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
551 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
553 {"Security Options", P_SEP, P_SEPARATOR},
555 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
556 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
557 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
558 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
572 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
586 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
587 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
589 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
590 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
591 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
593 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
595 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
597 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
599 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
600 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
601 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
602 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
604 {"Logging Options", P_SEP, P_SEPARATOR},
606 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
608 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"Protocol Options", P_SEP, P_SEPARATOR},
612 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
614 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
615 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
616 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
617 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
618 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
619 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
621 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
624 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
625 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
629 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
635 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
636 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
637 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
639 {"Tuning Options", P_SEP, P_SEPARATOR},
641 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
642 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
643 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
644 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
646 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
647 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
648 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
650 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
651 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
652 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
654 {"Printing Options", P_SEP, P_SEPARATOR},
656 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
657 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
658 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
659 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
660 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
661 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
662 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
663 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
664 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
666 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
667 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
668 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
673 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
675 {"Filename Handling", P_SEP, P_SEPARATOR},
677 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
678 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
679 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
681 {"Domain Options", P_SEP, P_SEPARATOR},
683 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
685 {"Logon Options", P_SEP, P_SEPARATOR},
687 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
688 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
690 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
691 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"Browse Options", P_SEP, P_SEPARATOR},
698 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
703 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
706 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
707 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
709 {"WINS Options", P_SEP, P_SEPARATOR},
710 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
714 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
715 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
718 {"Locking Options", P_SEP, P_SEPARATOR},
720 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
721 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
722 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
723 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
725 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
726 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
727 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
729 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
731 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
733 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
734 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
737 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
742 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
745 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
748 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
749 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
751 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
752 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
753 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
755 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
759 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
760 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"Winbind options", P_SEP, P_SEPARATOR},
763 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
776 /***************************************************************************
777 Initialise the sDefault parameter structure for the printer values.
778 ***************************************************************************/
780 static void init_printer_values(void)
782 /* choose defaults depending on the type of printing */
783 switch (sDefault.iPrinting) {
788 do_parameter("Lpqcommand", "lpq -P'%p'");
789 do_parameter("Lprmcommand", "lprm -P'%p' %j");
790 do_parameter("Printcommand",
796 do_parameter("Lpqcommand", "lpq -P'%p'");
797 do_parameter("Lprmcommand", "lprm -P'%p' %j");
798 do_parameter("Printcommand",
800 do_parameter("Queuepausecommand",
802 do_parameter("Queueresumecommand",
804 do_parameter("Lppausecommand",
806 do_parameter("Lpresumecommand",
807 "lpc release '%p' %j");
812 do_parameter("Lpqcommand", "");
813 do_parameter("Lprmcommand", "");
814 do_parameter("Printcommand", "");
815 do_parameter("Lppausecommand", "");
816 do_parameter("Lpresumecommand", "");
817 do_parameter("Queuepausecommand", "");
818 do_parameter("Queueresumecommand", "");
820 do_parameter("Printcapname", "cups");
822 do_parameter("Lpqcommand",
823 "/usr/bin/lpstat -o '%p'");
824 do_parameter("Lprmcommand",
825 "/usr/bin/cancel '%p-%j'");
826 do_parameter("Printcommand",
827 "/usr/bin/lp -d '%p' %s; rm %s");
828 do_parameter("Lppausecommand",
829 "lp -i '%p-%j' -H hold");
830 do_parameter("Lpresumecommand",
831 "lp -i '%p-%j' -H resume");
832 do_parameter("Queuepausecommand",
833 "/usr/bin/disable '%p'");
834 do_parameter("Queueresumecommand",
835 "/usr/bin/enable '%p'");
836 do_parameter("Printcapname", "lpstat");
837 #endif /* HAVE_CUPS */
842 do_parameter("Lpqcommand", "lpstat -o%p");
843 do_parameter("Lprmcommand", "cancel %p-%j");
844 do_parameter("Printcommand",
845 "lp -c -d%p %s; rm %s");
846 do_parameter("Queuepausecommand",
848 do_parameter("Queueresumecommand",
851 do_parameter("Lppausecommand",
852 "lp -i %p-%j -H hold");
853 do_parameter("Lpresumecommand",
854 "lp -i %p-%j -H resume");
859 do_parameter("Lpqcommand", "lpq -P%p");
860 do_parameter("Lprmcommand", "lprm -P%p %j");
861 do_parameter("Printcommand", "lp -r -P%p %s");
865 do_parameter("Lpqcommand", "qstat -l -d%p");
866 do_parameter("Lprmcommand",
868 do_parameter("Printcommand",
869 "lp -d%p -s %s; rm %s");
870 do_parameter("Lppausecommand",
872 do_parameter("Lpresumecommand",
878 do_parameter("Printcommand", "vlp print %p %s");
879 do_parameter("Lpqcommand", "vlp lpq %p");
880 do_parameter("Lprmcommand", "vlp lprm %p %j");
881 do_parameter("Lppausecommand", "vlp lppause %p %j");
882 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
883 do_parameter("Queuepausecommand", "vlp queuepause %p");
884 do_parameter("Queueresumecommand", "vlp queueresume %p");
886 #endif /* DEVELOPER */
892 /***************************************************************************
893 Initialise the global parameter structure.
894 ***************************************************************************/
895 static void init_globals(void)
899 DEBUG(3, ("Initialising global parameters\n"));
901 for (i = 0; parm_table[i].label; i++) {
902 if ((parm_table[i].type == P_STRING ||
903 parm_table[i].type == P_USTRING) &&
905 !(parm_table[i].flags & FLAG_CMDLINE)) {
906 string_set(parm_table[i].ptr, "");
910 /* options that can be set on the command line must be initialised via
911 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
912 do_parameter("socket options", DEFAULT_SOCKET_OPTIONS);
913 do_parameter("workgroup", DEFAULT_WORKGROUP);
914 do_parameter("netbios name", get_myname());
915 do_parameter("max protocol", "NT1");
916 do_parameter("name resolve order", "lmhosts wins host bcast");
918 init_printer_values();
920 do_parameter("fstype", FSTYPE_STRING);
921 do_parameter("ntvfs handler", "unixuid default");
923 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg");
924 do_parameter("server services", "smb rpc");
925 do_parameter("auth methods", "guest sam_ignoredomain");
926 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
927 do_parameter("private dir", dyn_PRIVATE_DIR);
928 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
929 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
930 do_parameter("guest account", GUEST_ACCOUNT);
932 /* using UTF8 by default allows us to support all chars */
933 do_parameter("unix charset", "UTF8");
935 /* Use codepage 850 as a default for the dos character set */
936 do_parameter("dos charset", "CP850");
939 * Allow the default PASSWD_CHAT to be overridden in local.h.
941 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
943 do_parameter("passwd program", "");
944 do_parameter("printcap name", PRINTCAP_NAME);
946 do_parameter("pid directory", dyn_PIDDIR);
947 do_parameter("lock dir", dyn_LOCKDIR);
948 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
950 do_parameter("socket address", "0.0.0.0");
951 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
953 do_parameter_var("announce version", "%d.%d",
954 DEFAULT_MAJOR_VERSION,
955 DEFAULT_MINOR_VERSION);
957 do_parameter("logon drive", "");
959 do_parameter("logon home", "\\\\%N\\%U");
960 do_parameter("logon path", "\\\\%N\\%U\\profile");
961 do_parameter("password server", "*");
963 do_parameter("load printers", "True");
965 do_parameter("max mux", "50");
966 do_parameter("max xmit", "12288");
967 do_parameter("lpqcachetime", "10");
968 do_parameter("DisableSpoolss", "False");
969 do_parameter("password level", "0");
970 do_parameter("username level", "0");
971 do_parameter("LargeReadwrite", "True");
972 do_parameter("minprotocol", "CORE");
973 do_parameter("security", "USER");
974 do_parameter("paranoid server security", "True");
975 do_parameter("EncryptPasswords", "True");
976 do_parameter("ReadRaw", "True");
977 do_parameter("WriteRaw", "True");
978 do_parameter("NullPasswords", "False");
979 do_parameter("ObeyPamRestrictions", "False");
980 do_parameter("lm announce", "Auto");
981 do_parameter("lm interval", "60");
982 do_parameter("announce as", "NT SERVER");
984 do_parameter("TimeServer", "False");
985 do_parameter("BindInterfacesOnly", "False");
986 do_parameter("PamPasswordChange", "False");
987 do_parameter("Unicode", "True");
988 do_parameter("restrict anonymous", "0");
989 do_parameter("ClientLanManAuth", "True");
990 do_parameter("LanmanAuth", "True");
991 do_parameter("NTLMAuth", "True");
993 do_parameter("enhanced browsing", "True");
994 do_parameter("LockSpinCount", "3");
995 do_parameter("LockSpinTime", "10");
996 #ifdef MMAP_BLACKLIST
997 do_parameter("UseMmap", "False");
999 do_parameter("UseMmap", "True");
1001 do_parameter("UnixExtensions", "False");
1003 /* hostname lookups can be very expensive and are broken on
1004 a large number of sites (tridge) */
1005 do_parameter("HostnameLookups", "False");
1007 do_parameter("PreferredMaster", "Auto");
1008 do_parameter("os level", "20");
1009 do_parameter("LocalMaster", "True");
1010 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1011 do_parameter("DomainLogons", "False");
1012 do_parameter("WINSsupport", "False");
1013 do_parameter("WINSproxy", "False");
1015 do_parameter("DNSproxy", "True");
1017 do_parameter("AllowTrustedDomains", "True");
1019 do_parameter("TemplateShell", "/bin/false");
1020 do_parameter("TemplateHomedir", "/home/%D/%U");
1021 do_parameter("WinbindSeparator", "\\");
1023 do_parameter("winbind cache time", "15");
1024 do_parameter("WinbindEnumUsers", "True");
1025 do_parameter("WinbindEnumGroups", "True");
1026 do_parameter("WinbindUseDefaultDomain", "False");
1028 do_parameter("IDMapBackend", "tdb");
1030 do_parameter("name cache timeout", "660"); /* In seconds */
1032 do_parameter("client signing", "Yes");
1033 do_parameter("server signing", "auto");
1035 do_parameter("use spnego", "True");
1037 do_parameter("smb ports", SMB_PORTS);
1039 do_parameter("nt status support", "True");
1042 static TALLOC_CTX *lp_talloc;
1044 /******************************************************************* a
1045 Free up temporary memory - called from the main loop.
1046 ********************************************************************/
1048 void lp_talloc_free(void)
1052 talloc_free(lp_talloc);
1056 /*******************************************************************
1057 Convenience routine to grab string parameters into temporary memory
1058 and run standard_sub_basic on them. The buffers can be written to by
1059 callers without affecting the source string.
1060 ********************************************************************/
1062 static const char *lp_string(const char *s)
1064 #if 0 /* until REWRITE done to make thread-safe */
1065 size_t len = s ? strlen(s) : 0;
1069 /* The follow debug is useful for tracking down memory problems
1070 especially if you have an inner loop that is calling a lp_*()
1071 function that returns a string. Perhaps this debug should be
1072 present all the time? */
1075 DEBUG(10, ("lp_string(%s)\n", s));
1078 #if 0 /* until REWRITE done to make thread-safe */
1080 lp_talloc = talloc_init("lp_talloc");
1082 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1090 StrnCpy(ret, s, len);
1092 if (trim_string(ret, "\"", "\"")) {
1093 if (strchr(ret,'"') != NULL)
1094 StrnCpy(ret, s, len);
1097 standard_sub_basic(ret,len+100);
1104 In this section all the functions that are used to access the
1105 parameters from the rest of the program are defined
1108 #define FN_GLOBAL_STRING(fn_name,ptr) \
1109 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1110 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1111 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1112 #define FN_GLOBAL_LIST(fn_name,ptr) \
1113 const char **fn_name(void) {return(*(const char ***)(ptr));}
1114 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1115 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1116 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1117 char fn_name(void) {return(*(char *)(ptr));}
1118 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1119 int fn_name(void) {return(*(int *)(ptr));}
1121 #define FN_LOCAL_STRING(fn_name,val) \
1122 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1123 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1124 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1125 #define FN_LOCAL_LIST(fn_name,val) \
1126 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1127 #define FN_LOCAL_BOOL(fn_name,val) \
1128 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1129 #define FN_LOCAL_CHAR(fn_name,val) \
1130 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1131 #define FN_LOCAL_INTEGER(fn_name,val) \
1132 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1134 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1135 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1136 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1137 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1138 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1139 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1140 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1141 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1142 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1143 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1144 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1145 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1146 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1147 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1148 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1149 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1150 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1151 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1152 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1153 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1154 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1155 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1156 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1157 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1158 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1159 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1160 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1161 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1162 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1163 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1164 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1165 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1166 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1167 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1168 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1169 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1170 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1171 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1172 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1173 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1174 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1175 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1176 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1177 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1178 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1180 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1182 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1184 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1185 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1186 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1187 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1188 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1189 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1190 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1191 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1192 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1194 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1195 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1196 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1197 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1198 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1199 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1200 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1201 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1202 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1203 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1204 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1205 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1206 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1207 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1208 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1209 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1210 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1211 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1212 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1213 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1214 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1215 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1216 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1217 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1218 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1219 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1220 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1221 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1222 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1223 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1224 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1225 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1226 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1227 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1228 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1229 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1230 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1231 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1232 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1233 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1234 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1235 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1236 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1237 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1238 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1239 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1240 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1241 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1242 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1243 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1244 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1245 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1246 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1247 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1248 FN_LOCAL_STRING(lp_servicename, szService)
1249 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1250 FN_LOCAL_STRING(lp_pathname, szPath)
1251 FN_LOCAL_STRING(lp_username, szUsername)
1252 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1253 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1254 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1255 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1256 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1257 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1258 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1259 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1260 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1261 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1262 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1263 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1264 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1265 FN_LOCAL_STRING(lp_comment, comment)
1266 FN_LOCAL_STRING(lp_fstype, fstype)
1267 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1268 static FN_LOCAL_STRING(lp_volume, volume)
1269 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1270 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1271 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1272 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1273 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1274 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1275 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1276 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1277 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1278 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1279 FN_LOCAL_BOOL(lp_locking, bLocking)
1280 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1281 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1282 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1283 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1284 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1285 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1286 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1287 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1288 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1289 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1290 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1291 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1292 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1293 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1294 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1295 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1296 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1297 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1299 /* local prototypes */
1301 static int map_parameter(const char *pszParmName);
1302 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1303 static int getservicebyname(const char *pszServiceName,
1304 service * pserviceDest);
1305 static void copy_service(service * pserviceDest,
1306 service * pserviceSource, BOOL *pcopymapDest);
1307 static BOOL service_ok(int iService);
1308 static BOOL do_section(const char *pszSectionName);
1309 static void init_copymap(service * pservice);
1311 /* This is a helper function for parametrical options support. */
1312 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1313 /* Actual parametrical functions are quite simple */
1314 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1317 struct param_opt *data;
1319 if (lookup_service >= iNumServices) return NULL;
1321 data = (lookup_service < 0) ?
1322 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1324 asprintf(&vfskey, "%s:%s", type, option);
1328 if (strcmp(data->key, vfskey) == 0) {
1335 if (lookup_service >= 0) {
1336 /* Try to fetch the same option but from globals */
1337 /* but only if we are not already working with Globals */
1338 data = Globals.param_opt;
1340 if (strcmp(data->key, vfskey) == 0) {
1354 /*******************************************************************
1355 convenience routine to return int parameters.
1356 ********************************************************************/
1357 static int lp_int(const char *s)
1361 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1368 /*******************************************************************
1369 convenience routine to return unsigned long parameters.
1370 ********************************************************************/
1371 static int lp_ulong(const char *s)
1375 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1379 return strtoul(s, NULL, 10);
1382 /*******************************************************************
1383 convenience routine to return boolean parameters.
1384 ********************************************************************/
1385 static BOOL lp_bool(const char *s)
1390 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1394 if (!set_boolean(&ret,s)) {
1395 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1403 /* Return parametric option from a given service. Type is a part of option before ':' */
1404 /* Parametric option has following syntax: 'Type: option = value' */
1405 /* Returned value is allocated in 'lp_talloc' context */
1407 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1409 const char *value = get_parametrics(lookup_service, type, option);
1412 return lp_string(value);
1417 /* Return parametric option from a given service. Type is a part of option before ':' */
1418 /* Parametric option has following syntax: 'Type: option = value' */
1419 /* Returned value is allocated in 'lp_talloc' context */
1421 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1422 const char *separator)
1424 const char *value = get_parametrics(lookup_service, type, option);
1427 return str_list_make(value, separator);
1432 /* Return parametric option from a given service. Type is a part of option before ':' */
1433 /* Parametric option has following syntax: 'Type: option = value' */
1435 int lp_parm_int(int lookup_service, const char *type, const char *option)
1437 const char *value = get_parametrics(lookup_service, type, option);
1440 return lp_int(value);
1445 /* Return parametric option from a given service. Type is a part of option before ':' */
1446 /* Parametric option has following syntax: 'Type: option = value' */
1448 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1450 const char *value = get_parametrics(lookup_service, type, option);
1453 return lp_ulong(value);
1458 /* Return parametric option from a given service. Type is a part of option before ':' */
1459 /* Parametric option has following syntax: 'Type: option = value' */
1461 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1463 const char *value = get_parametrics(lookup_service, type, option);
1466 return lp_bool(value);
1472 /***************************************************************************
1473 Initialise a service to the defaults.
1474 ***************************************************************************/
1476 static void init_service(service * pservice)
1478 memset((char *)pservice, '\0', sizeof(service));
1479 copy_service(pservice, &sDefault, NULL);
1482 /***************************************************************************
1483 Free the dynamically allocated parts of a service struct.
1484 ***************************************************************************/
1486 static void free_service(service *pservice)
1489 struct param_opt *data, *pdata;
1493 if (pservice->szService)
1494 DEBUG(5, ("free_service: Freeing service %s\n",
1495 pservice->szService));
1497 string_free(&pservice->szService);
1498 SAFE_FREE(pservice->copymap);
1500 for (i = 0; parm_table[i].label; i++) {
1501 if ((parm_table[i].type == P_STRING ||
1502 parm_table[i].type == P_USTRING) &&
1503 parm_table[i].class == P_LOCAL)
1504 string_free((char **)
1505 (((char *)pservice) +
1506 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1507 else if (parm_table[i].type == P_LIST &&
1508 parm_table[i].class == P_LOCAL)
1509 str_list_free((char ***)
1510 (((char *)pservice) +
1511 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1514 DEBUG(5,("Freeing parametrics:\n"));
1515 data = pservice->param_opt;
1517 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1518 string_free(&data->key);
1519 string_free(&data->value);
1525 ZERO_STRUCTP(pservice);
1528 /***************************************************************************
1529 Add a new service to the services array initialising it with the given
1531 ***************************************************************************/
1533 static int add_a_service(const service *pservice, const char *name)
1537 int num_to_alloc = iNumServices + 1;
1538 struct param_opt *data, *pdata;
1540 tservice = *pservice;
1542 /* it might already exist */
1544 i = getservicebyname(name, NULL);
1546 /* Clean all parametric options for service */
1547 /* They will be added during parsing again */
1548 data = ServicePtrs[i]->param_opt;
1550 string_free(&data->key);
1551 string_free(&data->value);
1556 ServicePtrs[i]->param_opt = NULL;
1561 /* find an invalid one */
1562 for (i = 0; i < iNumServices; i++)
1563 if (!ServicePtrs[i]->valid)
1566 /* if not, then create one */
1567 if (i == iNumServices) {
1570 tsp = (service **) Realloc(ServicePtrs,
1575 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1580 ServicePtrs[iNumServices] =
1581 (service *) malloc(sizeof(service));
1583 if (!ServicePtrs[iNumServices]) {
1584 DEBUG(0,("add_a_service: out of memory!\n"));
1590 free_service(ServicePtrs[i]);
1592 ServicePtrs[i]->valid = True;
1594 init_service(ServicePtrs[i]);
1595 copy_service(ServicePtrs[i], &tservice, NULL);
1597 string_set(&ServicePtrs[i]->szService, name);
1601 /***************************************************************************
1602 Add a new home service, with the specified home directory, defaults coming
1604 ***************************************************************************/
1606 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1607 const char *user, const char *pszHomedir)
1612 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1617 if (!(*(ServicePtrs[iDefaultService]->szPath))
1618 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1619 pstrcpy(newHomedir, pszHomedir);
1621 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1622 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1625 string_set(&ServicePtrs[i]->szPath, newHomedir);
1627 if (!(*(ServicePtrs[i]->comment))) {
1629 slprintf(comment, sizeof(comment) - 1,
1630 "Home directory of %s", user);
1631 string_set(&ServicePtrs[i]->comment, comment);
1633 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1634 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1636 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1642 /***************************************************************************
1643 Add a new service, based on an old one.
1644 ***************************************************************************/
1646 int lp_add_service(const char *pszService, int iDefaultService)
1648 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1651 /***************************************************************************
1652 Add the IPC service.
1653 ***************************************************************************/
1655 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1658 int i = add_a_service(&sDefault, ipc_name);
1663 slprintf(comment, sizeof(comment) - 1,
1664 "IPC Service (%s)", Globals.szServerString);
1666 string_set(&ServicePtrs[i]->szPath, tmpdir());
1667 string_set(&ServicePtrs[i]->szUsername, "");
1668 string_set(&ServicePtrs[i]->comment, comment);
1669 string_set(&ServicePtrs[i]->fstype, "IPC");
1670 ServicePtrs[i]->iMaxConnections = 0;
1671 ServicePtrs[i]->bAvailable = True;
1672 ServicePtrs[i]->bRead_only = True;
1673 ServicePtrs[i]->bGuest_only = False;
1674 ServicePtrs[i]->bGuest_ok = guest_ok;
1675 ServicePtrs[i]->bPrint_ok = False;
1676 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1678 lp_do_parameter(i, "ntvfs handler", "default");
1680 DEBUG(3, ("adding IPC service\n"));
1685 /***************************************************************************
1686 Add a new printer service, with defaults coming from service iFrom.
1687 ***************************************************************************/
1689 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1691 const char *comment = "From Printcap";
1692 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1697 /* note that we do NOT default the availability flag to True - */
1698 /* we take it from the default service passed. This allows all */
1699 /* dynamic printers to be disabled by disabling the [printers] */
1700 /* entry (if/when the 'available' keyword is implemented!). */
1702 /* the printer name is set to the service name. */
1703 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1704 string_set(&ServicePtrs[i]->comment, comment);
1705 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1706 /* Printers cannot be read_only. */
1707 ServicePtrs[i]->bRead_only = False;
1708 /* No share modes on printer services. */
1709 ServicePtrs[i]->bShareModes = False;
1710 /* No oplocks on printer services. */
1711 ServicePtrs[i]->bOpLocks = False;
1712 /* Printer services must be printable. */
1713 ServicePtrs[i]->bPrint_ok = True;
1715 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1717 update_server_announce_as_printserver();
1722 /***************************************************************************
1723 Map a parameter's string representation to something we can use.
1724 Returns False if the parameter string is not recognised, else TRUE.
1725 ***************************************************************************/
1727 static int map_parameter(const char *pszParmName)
1731 if (*pszParmName == '-')
1734 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1735 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1738 /* Warn only if it isn't parametric option */
1739 if (strchr(pszParmName, ':') == NULL)
1740 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1741 /* We do return 'fail' for parametric options as well because they are
1742 stored in different storage
1747 /***************************************************************************
1748 Set a boolean variable from the text value stored in the passed string.
1749 Returns True in success, False if the passed string does not correctly
1750 represent a boolean.
1751 ***************************************************************************/
1753 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1758 if (strwicmp(pszParmValue, "yes") == 0 ||
1759 strwicmp(pszParmValue, "true") == 0 ||
1760 strwicmp(pszParmValue, "1") == 0)
1762 else if (strwicmp(pszParmValue, "no") == 0 ||
1763 strwicmp(pszParmValue, "False") == 0 ||
1764 strwicmp(pszParmValue, "0") == 0)
1768 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1775 /***************************************************************************
1776 Find a service by name. Otherwise works like get_service.
1777 ***************************************************************************/
1779 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1783 for (iService = iNumServices - 1; iService >= 0; iService--)
1784 if (VALID(iService) &&
1785 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1786 if (pserviceDest != NULL)
1787 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1794 /***************************************************************************
1795 Copy a service structure to another.
1796 If pcopymapDest is NULL then copy all fields
1797 ***************************************************************************/
1799 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1802 BOOL bcopyall = (pcopymapDest == NULL);
1803 struct param_opt *data, *pdata, *paramo;
1806 for (i = 0; parm_table[i].label; i++)
1807 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1808 (bcopyall || pcopymapDest[i])) {
1809 void *def_ptr = parm_table[i].ptr;
1811 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1814 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1817 switch (parm_table[i].type) {
1820 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1826 *(int *)dest_ptr = *(int *)src_ptr;
1830 *(char *)dest_ptr = *(char *)src_ptr;
1834 string_set(dest_ptr,
1839 string_set(dest_ptr,
1841 strupper(*(char **)dest_ptr);
1844 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1852 init_copymap(pserviceDest);
1853 if (pserviceSource->copymap)
1854 memcpy((void *)pserviceDest->copymap,
1855 (void *)pserviceSource->copymap,
1856 sizeof(BOOL) * NUMPARAMETERS);
1859 data = pserviceSource->param_opt;
1862 pdata = pserviceDest->param_opt;
1863 /* Traverse destination */
1865 /* If we already have same option, override it */
1866 if (strcmp(pdata->key, data->key) == 0) {
1867 string_free(&pdata->value);
1868 pdata->value = strdup(data->value);
1872 pdata = pdata->next;
1875 paramo = smb_xmalloc(sizeof(*paramo));
1876 paramo->key = strdup(data->key);
1877 paramo->value = strdup(data->value);
1878 DLIST_ADD(pserviceDest->param_opt, paramo);
1884 /***************************************************************************
1885 Check a service for consistency. Return False if the service is in any way
1886 incomplete or faulty, else True.
1887 ***************************************************************************/
1889 static BOOL service_ok(int iService)
1894 if (ServicePtrs[iService]->szService[0] == '\0') {
1895 DEBUG(0, ("The following message indicates an internal error:\n"));
1896 DEBUG(0, ("No service name in service entry.\n"));
1900 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1901 /* I can't see why you'd want a non-printable printer service... */
1902 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1903 if (!ServicePtrs[iService]->bPrint_ok) {
1904 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1905 ServicePtrs[iService]->szService));
1906 ServicePtrs[iService]->bPrint_ok = True;
1908 /* [printers] service must also be non-browsable. */
1909 if (ServicePtrs[iService]->bBrowseable)
1910 ServicePtrs[iService]->bBrowseable = False;
1913 /* If a service is flagged unavailable, log the fact at level 0. */
1914 if (!ServicePtrs[iService]->bAvailable)
1915 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1916 ServicePtrs[iService]->szService));
1921 static struct file_lists {
1922 struct file_lists *next;
1926 } *file_lists = NULL;
1928 /*******************************************************************
1929 Keep a linked list of all config files so we know when one has changed
1930 it's date and needs to be reloaded.
1931 ********************************************************************/
1933 static void add_to_file_list(const char *fname, const char *subfname)
1935 struct file_lists *f = file_lists;
1938 if (f->name && !strcmp(f->name, fname))
1944 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1947 f->next = file_lists;
1948 f->name = strdup(fname);
1953 f->subfname = strdup(subfname);
1959 f->modtime = file_modtime(subfname);
1961 time_t t = file_modtime(subfname);
1967 /*******************************************************************
1968 Check if a config file has changed date.
1969 ********************************************************************/
1971 BOOL lp_file_list_changed(void)
1973 struct file_lists *f = file_lists;
1974 DEBUG(6, ("lp_file_list_changed()\n"));
1980 pstrcpy(n2, f->name);
1981 standard_sub_basic(n2,sizeof(n2));
1983 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1984 f->name, n2, ctime(&f->modtime)));
1986 mod_time = file_modtime(n2);
1988 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1990 ("file %s modified: %s\n", n2,
1992 f->modtime = mod_time;
1993 SAFE_FREE(f->subfname);
1994 f->subfname = strdup(n2);
2002 /***************************************************************************
2003 Handle the include operation.
2004 ***************************************************************************/
2006 static BOOL handle_include(const char *pszParmValue, char **ptr)
2009 pstrcpy(fname, pszParmValue);
2011 standard_sub_basic(fname,sizeof(fname));
2013 add_to_file_list(pszParmValue, fname);
2015 string_set(ptr, fname);
2017 if (file_exist(fname, NULL))
2018 return (pm_process(fname, do_section, do_parameter));
2020 DEBUG(2, ("Can't find include file %s\n", fname));
2025 /***************************************************************************
2026 Handle the interpretation of the copy parameter.
2027 ***************************************************************************/
2029 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2033 service serviceTemp;
2035 string_set(ptr, pszParmValue);
2037 init_service(&serviceTemp);
2041 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2043 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2044 if (iTemp == iServiceIndex) {
2045 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2047 copy_service(ServicePtrs[iServiceIndex],
2049 ServicePtrs[iServiceIndex]->copymap);
2053 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2057 free_service(&serviceTemp);
2061 /***************************************************************************
2062 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2067 winbind uid = 1000-1999
2068 winbind gid = 700-899
2070 We only do simple parsing checks here. The strings are parsed into useful
2071 structures in the winbind daemon code.
2073 ***************************************************************************/
2075 /* Some lp_ routines to return winbind [ug]id information */
2077 static uid_t winbind_uid_low, winbind_uid_high;
2078 static gid_t winbind_gid_low, winbind_gid_high;
2079 static uint32_t non_unix_account_low, non_unix_account_high;
2081 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2083 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2087 *low = winbind_uid_low;
2090 *high = winbind_uid_high;
2095 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2097 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2101 *low = winbind_gid_low;
2104 *high = winbind_gid_high;
2109 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2111 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2115 *low = non_unix_account_low;
2118 *high = non_unix_account_high;
2123 /* Do some simple checks on "winbind [ug]id" parameter values */
2125 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2129 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2134 string_set(ptr, pszParmValue);
2136 winbind_uid_low = low;
2137 winbind_uid_high = high;
2142 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2146 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2151 string_set(ptr, pszParmValue);
2153 winbind_gid_low = low;
2154 winbind_gid_high = high;
2159 /***************************************************************************
2160 Do some simple checks on "non unix account range" parameter values.
2161 ***************************************************************************/
2163 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2167 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2172 string_set(ptr, pszParmValue);
2174 non_unix_account_low = low;
2175 non_unix_account_high = high;
2181 /***************************************************************************
2182 Initialise a copymap.
2183 ***************************************************************************/
2185 static void init_copymap(service * pservice)
2188 SAFE_FREE(pservice->copymap);
2189 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2190 if (!pservice->copymap)
2192 ("Couldn't allocate copymap!! (size %d)\n",
2193 (int)NUMPARAMETERS));
2195 for (i = 0; i < NUMPARAMETERS; i++)
2196 pservice->copymap[i] = True;
2199 /***************************************************************************
2200 Return the local pointer to a parameter given the service number and the
2201 pointer into the default structure.
2202 ***************************************************************************/
2204 void *lp_local_ptr(int snum, void *ptr)
2206 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2210 /***************************************************************************
2211 Process a parametric option
2212 ***************************************************************************/
2213 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2215 struct param_opt *paramo, *data;
2218 while (isspace(*pszParmName)) {
2222 name = strdup(pszParmName);
2223 if (!name) return False;
2228 data = Globals.param_opt;
2230 data = ServicePtrs[snum]->param_opt;
2233 /* Traverse destination */
2234 for (paramo=data; paramo; paramo=paramo->next) {
2235 /* If we already have the option set, override it unless
2236 it was a command line option and the new one isn't */
2237 if (strcmp(paramo->key, name) == 0) {
2238 if ((paramo->flags & FLAG_CMDLINE) &&
2239 !(flags & FLAG_CMDLINE)) {
2243 free(paramo->value);
2244 paramo->value = strdup(pszParmValue);
2245 paramo->flags = flags;
2251 paramo = smb_xmalloc(sizeof(*paramo));
2252 paramo->key = strdup(name);
2253 paramo->value = strdup(pszParmValue);
2254 paramo->flags = flags;
2256 DLIST_ADD(Globals.param_opt, paramo);
2258 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2266 /***************************************************************************
2267 Process a parameter for a particular service number. If snum < 0
2268 then assume we are in the globals.
2269 ***************************************************************************/
2270 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2273 void *parm_ptr = NULL; /* where we are going to store the result */
2274 void *def_ptr = NULL;
2276 parmnum = map_parameter(pszParmName);
2279 if (strchr(pszParmName, ':')) {
2280 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2282 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2286 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2287 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2291 /* if the flag has been set on the command line, then don't allow override,
2292 but don't report an error */
2293 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2297 def_ptr = parm_table[parmnum].ptr;
2299 /* we might point at a service, the default service or a global */
2303 if (parm_table[parmnum].class == P_GLOBAL) {
2305 ("Global parameter %s found in service section!\n",
2310 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2315 if (!ServicePtrs[snum]->copymap)
2316 init_copymap(ServicePtrs[snum]);
2318 /* this handles the aliases - set the copymap for other entries with
2319 the same data pointer */
2320 for (i = 0; parm_table[i].label; i++)
2321 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2322 ServicePtrs[snum]->copymap[i] = False;
2325 /* if it is a special case then go ahead */
2326 if (parm_table[parmnum].special) {
2327 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2331 /* now switch on the type of variable it is */
2332 switch (parm_table[parmnum].type)
2335 set_boolean(parm_ptr, pszParmValue);
2339 set_boolean(parm_ptr, pszParmValue);
2340 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2344 *(int *)parm_ptr = atoi(pszParmValue);
2348 *(char *)parm_ptr = *pszParmValue;
2352 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2356 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2360 string_set(parm_ptr, pszParmValue);
2364 string_set(parm_ptr, pszParmValue);
2365 strupper(*(char **)parm_ptr);
2369 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2372 parm_table[parmnum].enum_list[i].name)) {
2374 parm_table[parmnum].
2379 if (!parm_table[parmnum].enum_list[i].name) {
2380 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2381 pszParmValue, pszParmName));
2392 /***************************************************************************
2393 Process a parameter.
2394 ***************************************************************************/
2396 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2398 if (!bInGlobalSection && bGlobalOnly)
2401 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2402 pszParmName, pszParmValue));
2406 variable argument do parameter
2408 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2410 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2417 s = talloc_vasprintf(NULL, fmt, ap);
2419 ret = do_parameter(pszParmName, s);
2426 set a parameter from the commandline - this is called from command line parameter
2427 parsing code. It sets the parameter then marks the parameter as unable to be modified
2428 by smb.conf processing
2430 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2432 int parmnum = map_parameter(pszParmName);
2435 while (isspace(*pszParmValue)) pszParmValue++;
2438 if (parmnum < 0 && strchr(pszParmName, ':')) {
2439 /* set a parametric option */
2440 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2444 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2448 /* reset the CMDLINE flag in case this has been called before */
2449 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2451 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2455 parm_table[parmnum].flags |= FLAG_CMDLINE;
2457 /* we have to also set FLAG_CMDLINE on aliases */
2458 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2459 parm_table[i].flags |= FLAG_CMDLINE;
2461 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2462 parm_table[i].flags |= FLAG_CMDLINE;
2469 set a option from the commandline in 'a=b' format. Use to support --option
2471 BOOL lp_set_option(const char *option)
2489 ret = lp_set_cmdline(s, p+1);
2495 /***************************************************************************
2496 Print a parameter of the specified type.
2497 ***************************************************************************/
2499 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2505 for (i = 0; p->enum_list[i].name; i++) {
2506 if (*(int *)ptr == p->enum_list[i].value) {
2508 p->enum_list[i].name);
2515 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2519 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2523 fprintf(f, "%d", *(int *)ptr);
2527 fprintf(f, "%c", *(char *)ptr);
2531 if (*(int *)ptr == -1) {
2534 fprintf(f, "0%o", *(int *)ptr);
2539 if ((char ***)ptr && *(char ***)ptr) {
2540 char **list = *(char ***)ptr;
2542 for (; *list; list++)
2543 fprintf(f, "%s%s", *list,
2544 ((*(list+1))?", ":""));
2550 if (*(char **)ptr) {
2551 fprintf(f, "%s", *(char **)ptr);
2559 /***************************************************************************
2560 Check if two parameters are equal.
2561 ***************************************************************************/
2563 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2568 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2573 return (*((int *)ptr1) == *((int *)ptr2));
2576 return (*((char *)ptr1) == *((char *)ptr2));
2579 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2584 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2589 return (p1 == p2 || strequal(p1, p2));
2597 /***************************************************************************
2598 Process a new section (service). At this stage all sections are services.
2599 Later we'll have special sections that permit server parameters to be set.
2600 Returns True on success, False on failure.
2601 ***************************************************************************/
2603 static BOOL do_section(const char *pszSectionName)
2606 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2607 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2610 /* if we've just struck a global section, note the fact. */
2611 bInGlobalSection = isglobal;
2613 /* check for multiple global sections */
2614 if (bInGlobalSection) {
2615 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2619 if (!bInGlobalSection && bGlobalOnly)
2622 /* if we have a current service, tidy it up before moving on */
2625 if (iServiceIndex >= 0)
2626 bRetval = service_ok(iServiceIndex);
2628 /* if all is still well, move to the next record in the services array */
2630 /* We put this here to avoid an odd message order if messages are */
2631 /* issued by the post-processing of a previous section. */
2632 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2634 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2636 DEBUG(0, ("Failed to add a new service\n"));
2645 /***************************************************************************
2646 Determine if a partcular base parameter is currentl set to the default value.
2647 ***************************************************************************/
2649 static BOOL is_default(int i)
2651 if (!defaults_saved)
2653 switch (parm_table[i].type) {
2655 return str_list_compare (parm_table[i].def.lvalue,
2656 *(char ***)parm_table[i].ptr);
2659 return strequal(parm_table[i].def.svalue,
2660 *(char **)parm_table[i].ptr);
2663 return parm_table[i].def.bvalue ==
2664 *(BOOL *)parm_table[i].ptr;
2666 return parm_table[i].def.cvalue ==
2667 *(char *)parm_table[i].ptr;
2671 return parm_table[i].def.ivalue ==
2672 *(int *)parm_table[i].ptr;
2679 /***************************************************************************
2680 Display the contents of the global structure.
2681 ***************************************************************************/
2683 static void dump_globals(FILE *f)
2686 struct param_opt *data;
2688 fprintf(f, "# Global parameters\n[global]\n");
2690 for (i = 0; parm_table[i].label; i++)
2691 if (parm_table[i].class == P_GLOBAL &&
2692 parm_table[i].ptr &&
2693 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2694 if (defaults_saved && is_default(i))
2696 fprintf(f, "\t%s = ", parm_table[i].label);
2697 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2700 if (Globals.param_opt != NULL) {
2701 data = Globals.param_opt;
2703 fprintf(f, "\t%s = %s\n", data->key, data->value);
2710 /***************************************************************************
2711 Display the contents of a single services record.
2712 ***************************************************************************/
2714 static void dump_a_service(service * pService, FILE * f)
2717 struct param_opt *data;
2719 if (pService != &sDefault)
2720 fprintf(f, "\n[%s]\n", pService->szService);
2722 for (i = 0; parm_table[i].label; i++)
2723 if (parm_table[i].class == P_LOCAL &&
2724 parm_table[i].ptr &&
2725 (*parm_table[i].label != '-') &&
2726 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2727 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2729 if (pService == &sDefault) {
2730 if (defaults_saved && is_default(i))
2733 if (equal_parameter(parm_table[i].type,
2734 ((char *)pService) +
2736 ((char *)&sDefault) +
2741 fprintf(f, "\t%s = ", parm_table[i].label);
2742 print_parameter(&parm_table[i],
2743 ((char *)pService) + pdiff, f);
2746 if (pService->param_opt != NULL) {
2747 data = pService->param_opt;
2749 fprintf(f, "\t%s = %s\n", data->key, data->value);
2756 /***************************************************************************
2757 Return info about the next service in a service. snum==-1 gives the globals.
2758 Return NULL when out of parameters.
2759 ***************************************************************************/
2761 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2764 /* do the globals */
2765 for (; parm_table[*i].label; (*i)++) {
2766 if (parm_table[*i].class == P_SEPARATOR)
2767 return &parm_table[(*i)++];
2769 if (!parm_table[*i].ptr
2770 || (*parm_table[*i].label == '-'))
2774 && (parm_table[*i].ptr ==
2775 parm_table[(*i) - 1].ptr))
2778 return &parm_table[(*i)++];
2781 service *pService = ServicePtrs[snum];
2783 for (; parm_table[*i].label; (*i)++) {
2784 if (parm_table[*i].class == P_SEPARATOR)
2785 return &parm_table[(*i)++];
2787 if (parm_table[*i].class == P_LOCAL &&
2788 parm_table[*i].ptr &&
2789 (*parm_table[*i].label != '-') &&
2791 (parm_table[*i].ptr !=
2792 parm_table[(*i) - 1].ptr)))
2795 PTR_DIFF(parm_table[*i].ptr,
2798 if (allparameters ||
2799 !equal_parameter(parm_table[*i].type,
2800 ((char *)pService) +
2802 ((char *)&sDefault) +
2805 return &parm_table[(*i)++];
2816 /***************************************************************************
2817 Display the contents of a single copy structure.
2818 ***************************************************************************/
2819 static void dump_copy_map(BOOL *pcopymap)
2825 printf("\n\tNon-Copied parameters:\n");
2827 for (i = 0; parm_table[i].label; i++)
2828 if (parm_table[i].class == P_LOCAL &&
2829 parm_table[i].ptr && !pcopymap[i] &&
2830 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2832 printf("\t\t%s\n", parm_table[i].label);
2837 /***************************************************************************
2838 Return TRUE if the passed service number is within range.
2839 ***************************************************************************/
2841 BOOL lp_snum_ok(int iService)
2843 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2846 /***************************************************************************
2847 Auto-load some home services.
2848 ***************************************************************************/
2850 static void lp_add_auto_services(const char *str)
2855 /***************************************************************************
2856 Auto-load one printer.
2857 ***************************************************************************/
2859 void lp_add_one_printer(char *name, char *comment)
2861 int printers = lp_servicenumber(PRINTERS_NAME);
2864 if (lp_servicenumber(name) < 0) {
2865 lp_add_printer(name, printers);
2866 if ((i = lp_servicenumber(name)) >= 0) {
2867 string_set(&ServicePtrs[i]->comment, comment);
2868 ServicePtrs[i]->autoloaded = True;
2873 /***************************************************************************
2874 Announce ourselves as a print server.
2875 ***************************************************************************/
2877 void update_server_announce_as_printserver(void)
2879 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2882 /***************************************************************************
2883 Have we loaded a services file yet?
2884 ***************************************************************************/
2886 BOOL lp_loaded(void)
2891 /***************************************************************************
2892 Unload unused services.
2893 ***************************************************************************/
2895 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2898 for (i = 0; i < iNumServices; i++) {
2902 if (!snumused || !snumused(smb, i)) {
2903 ServicePtrs[i]->valid = False;
2904 free_service(ServicePtrs[i]);
2909 /***************************************************************************
2911 ***************************************************************************/
2913 void lp_killservice(int iServiceIn)
2915 if (VALID(iServiceIn)) {
2916 ServicePtrs[iServiceIn]->valid = False;
2917 free_service(ServicePtrs[iServiceIn]);
2921 /***************************************************************************
2922 Save the curent values of all global and sDefault parameters into the
2923 defaults union. This allows swat and testparm to show only the
2924 changed (ie. non-default) parameters.
2925 ***************************************************************************/
2927 static void lp_save_defaults(void)
2930 for (i = 0; parm_table[i].label; i++) {
2931 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2933 switch (parm_table[i].type) {
2935 str_list_copy(&(parm_table[i].def.lvalue),
2936 *(const char ***)parm_table[i].ptr);
2940 if (parm_table[i].ptr) {
2941 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2943 parm_table[i].def.svalue = NULL;
2948 parm_table[i].def.bvalue =
2949 *(BOOL *)parm_table[i].ptr;
2952 parm_table[i].def.cvalue =
2953 *(char *)parm_table[i].ptr;
2958 parm_table[i].def.ivalue =
2959 *(int *)parm_table[i].ptr;
2965 defaults_saved = True;
2968 /*******************************************************************
2969 Set the server type we will announce as via nmbd.
2970 ********************************************************************/
2972 static void set_server_role(void)
2974 server_role = ROLE_STANDALONE;
2976 switch (lp_security()) {
2978 if (lp_domain_logons())
2979 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2984 if (lp_domain_logons()) {
2985 server_role = ROLE_DOMAIN_PDC;
2988 server_role = ROLE_DOMAIN_MEMBER;
2991 if (lp_domain_logons()) {
2993 if (Globals.bDomainMaster) /* auto or yes */
2994 server_role = ROLE_DOMAIN_PDC;
2996 server_role = ROLE_DOMAIN_BDC;
3000 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3004 DEBUG(10, ("set_server_role: role = "));
3006 switch(server_role) {
3007 case ROLE_STANDALONE:
3008 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3010 case ROLE_DOMAIN_MEMBER:
3011 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3013 case ROLE_DOMAIN_BDC:
3014 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3016 case ROLE_DOMAIN_PDC:
3017 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3022 /***************************************************************************
3023 Load the services array from the services file. Return True on success,
3025 ***************************************************************************/
3027 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3032 struct param_opt *data;
3034 pstrcpy(n2, pszFname);
3035 standard_sub_basic(n2,sizeof(n2));
3037 add_to_file_list(pszFname, n2);
3041 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3043 bInGlobalSection = True;
3044 bGlobalOnly = global_only;
3053 if (Globals.param_opt != NULL) {
3054 struct param_opt *next;
3055 for (data=Globals.param_opt; data; data=next) {
3057 if (data->flags & FLAG_CMDLINE) continue;
3060 DLIST_REMOVE(Globals.param_opt, data);
3065 /* We get sections first, so have to start 'behind' to make up */
3067 bRetval = pm_process(n2, do_section, do_parameter);
3069 /* finish up the last section */
3070 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3072 if (iServiceIndex >= 0)
3073 bRetval = service_ok(iServiceIndex);
3075 lp_add_auto_services(lp_auto_services());
3078 /* When 'restrict anonymous = 2' guest connections to ipc$
3080 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3081 lp_add_ipc("ADMIN$", False);
3085 set_default_server_announce_type();
3089 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3090 /* if bWINSsupport is true and we are in the client */
3091 if (in_client && Globals.bWINSsupport) {
3092 lp_do_parameter(-1, "wins server", "127.0.0.1");
3100 /***************************************************************************
3101 Reset the max number of services.
3102 ***************************************************************************/
3104 void lp_resetnumservices(void)
3109 /***************************************************************************
3110 Return the max number of services.
3111 ***************************************************************************/
3113 int lp_numservices(void)
3115 return (iNumServices);
3118 /***************************************************************************
3119 Display the contents of the services array in human-readable form.
3120 ***************************************************************************/
3122 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3127 defaults_saved = False;
3131 dump_a_service(&sDefault, f);
3133 for (iService = 0; iService < maxtoprint; iService++)
3134 lp_dump_one(f, show_defaults, iService);
3137 /***************************************************************************
3138 Display the contents of one service in human-readable form.
3139 ***************************************************************************/
3141 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3144 if (ServicePtrs[snum]->szService[0] == '\0')
3146 dump_a_service(ServicePtrs[snum], f);
3150 /***************************************************************************
3151 Return the number of the service with the given name, or -1 if it doesn't
3152 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3153 getservicebyname()! This works ONLY if all services have been loaded, and
3154 does not copy the found service.
3155 ***************************************************************************/
3157 int lp_servicenumber(const char *pszServiceName)
3160 fstring serviceName;
3163 for (iService = iNumServices - 1; iService >= 0; iService--) {
3164 if (VALID(iService) && ServicePtrs[iService]->szService) {
3166 * The substitution here is used to support %U is
3169 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3170 standard_sub_basic(serviceName,sizeof(serviceName));
3171 if (strequal(serviceName, pszServiceName))
3177 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3182 /*******************************************************************
3183 A useful volume label function.
3184 ********************************************************************/
3185 const char *volume_label(int snum)
3187 const char *ret = lp_volume(snum);
3189 return lp_servicename(snum);
3194 /*******************************************************************
3195 Set the server type we will announce as via nmbd.
3196 ********************************************************************/
3198 static void set_default_server_announce_type(void)
3200 default_server_announce = 0;
3201 default_server_announce |= SV_TYPE_WORKSTATION;
3202 default_server_announce |= SV_TYPE_SERVER;
3203 default_server_announce |= SV_TYPE_SERVER_UNIX;
3205 switch (lp_announce_as()) {
3206 case ANNOUNCE_AS_NT_SERVER:
3207 default_server_announce |= SV_TYPE_SERVER_NT;
3208 /* fall through... */
3209 case ANNOUNCE_AS_NT_WORKSTATION:
3210 default_server_announce |= SV_TYPE_NT;
3212 case ANNOUNCE_AS_WIN95:
3213 default_server_announce |= SV_TYPE_WIN95_PLUS;
3215 case ANNOUNCE_AS_WFW:
3216 default_server_announce |= SV_TYPE_WFW;
3222 switch (lp_server_role()) {
3223 case ROLE_DOMAIN_MEMBER:
3224 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3226 case ROLE_DOMAIN_PDC:
3227 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3229 case ROLE_DOMAIN_BDC:
3230 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3232 case ROLE_STANDALONE:
3236 if (lp_time_server())
3237 default_server_announce |= SV_TYPE_TIME_SOURCE;
3239 if (lp_host_msdfs())
3240 default_server_announce |= SV_TYPE_DFS_SERVER;
3243 /***********************************************************
3244 returns role of Samba server
3245 ************************************************************/
3247 int lp_server_role(void)
3252 /***********************************************************
3253 If we are PDC then prefer us as DMB
3254 ************************************************************/
3256 BOOL lp_domain_master(void)
3258 if (Globals.bDomainMaster == Auto)
3259 return (lp_server_role() == ROLE_DOMAIN_PDC);
3261 return Globals.bDomainMaster;
3264 /***********************************************************
3265 If we are DMB then prefer us as LMB
3266 ************************************************************/
3268 BOOL lp_preferred_master(void)
3270 if (Globals.bPreferredMaster == Auto)
3271 return (lp_local_master() && lp_domain_master());
3273 return Globals.bPreferredMaster;
3276 /*******************************************************************
3278 ********************************************************************/
3280 void lp_remove_service(int snum)
3282 ServicePtrs[snum]->valid = False;
3285 /*******************************************************************
3287 ********************************************************************/
3289 void lp_copy_service(int snum, const char *new_name)
3291 const char *oldname = lp_servicename(snum);
3292 do_section(new_name);
3294 snum = lp_servicenumber(new_name);
3296 lp_do_parameter(snum, "copy", oldname);
3301 /*******************************************************************
3302 Get the default server type we will announce as via nmbd.
3303 ********************************************************************/
3305 int lp_default_server_announce(void)
3307 return default_server_announce;
3310 /*******************************************************************
3311 Split the announce version into major and minor numbers.
3312 ********************************************************************/
3314 int lp_major_announce_version(void)
3316 static BOOL got_major = False;
3317 static int major_version = DEFAULT_MAJOR_VERSION;
3322 return major_version;
3325 if ((vers = lp_announce_version()) == NULL)
3326 return major_version;
3328 if ((p = strchr_m(vers, '.')) == 0)
3329 return major_version;
3332 major_version = atoi(vers);
3333 return major_version;
3336 int lp_minor_announce_version(void)
3338 static BOOL got_minor = False;
3339 static int minor_version = DEFAULT_MINOR_VERSION;
3344 return minor_version;
3347 if ((vers = lp_announce_version()) == NULL)
3348 return minor_version;
3350 if ((p = strchr_m(vers, '.')) == 0)
3351 return minor_version;
3354 minor_version = atoi(p);
3355 return minor_version;
3358 const char *lp_printername(int snum)
3360 const char *ret = _lp_printername(snum);
3361 if (ret == NULL || (ret != NULL && *ret == '\0'))
3362 ret = lp_const_servicename(snum);
3368 /*******************************************************************
3369 Return the max print jobs per queue.
3370 ********************************************************************/
3372 int lp_maxprintjobs(int snum)
3374 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3375 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3376 maxjobs = PRINT_MAX_JOBID - 1;