2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/iconv.h"
60 #include "system/network.h"
61 #include "system/printing.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "dlinklist.h"
66 BOOL in_client = False; /* Not in the client by default */
67 static BOOL bLoaded = False;
70 #define GLOBAL_NAME "global"
74 #define PRINTERS_NAME "printers"
78 #define HOMES_NAME "homes"
81 /* some helpful bits */
82 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
83 #define VALID(i) ServicePtrs[i]->valid
85 static BOOL do_parameter(const char *, const char *);
86 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
88 static BOOL defaults_saved = False;
91 #define FLAG_BASIC 0x0001 /* fundamental options */
92 #define FLAG_SHARE 0x0002 /* file sharing options */
93 #define FLAG_PRINT 0x0004 /* printing options */
94 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
95 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
96 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
97 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
98 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
99 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
100 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
101 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
104 /* the following are used by loadparm for option lists */
107 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
108 P_STRING,P_USTRING,P_ENUM,P_SEP
113 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
127 BOOL (*special)(const char *, char **);
128 const struct enum_list *enum_list;
141 struct param_opt *prev, *next;
148 * This structure describes global (ie., server-wide) parameters.
156 char *display_charset;
157 char *szPrintcapname;
161 char *szDefaultService;
163 char *szServerString;
164 char *szAutoServices;
165 char *szPasswdProgram;
169 char *szSMBPasswdFile;
173 char **szPreloadModules;
174 char **szPasswordServers;
175 char *szSocketOptions;
182 char **szWINSservers;
184 char *szRemoteAnnounce;
185 char *szRemoteBrowseSync;
186 char *szSocketAddress;
187 char *szAnnounceVersion; /* This is initialised in init_globals */
190 char **szNetbiosAliases;
191 char *szNetbiosScope;
192 char *szDomainOtherSIDs;
193 char **szNameResolveOrder;
195 char *szAddUserScript;
196 char *szAddMachineScript;
198 char *szWINSPartners;
199 char **dcerpc_ep_servers;
200 char **server_services;
203 char *szNonUnixAccountRange;
204 char *szTemplateHomedir;
205 char *szTemplateShell;
206 char *szWinbindSeparator;
207 BOOL bWinbindEnumUsers;
208 BOOL bWinbindEnumGroups;
209 BOOL bWinbindUseDefaultDomain;
210 char *szIDMapBackend;
211 char *szGuestaccount;
220 BOOL paranoid_server_security;
222 BOOL bDisableSpoolss;
224 int enhanced_browsing;
231 int announce_as; /* This is initialised in init_globals */
232 int machine_password_timeout;
233 int winbind_cache_time;
236 char *socket_options;
241 BOOL bPreferredMaster;
244 BOOL bEncryptPasswords;
246 BOOL bObeyPamRestrictions;
248 BOOL bLargeReadwrite;
252 BOOL bBindInterfacesOnly;
253 BOOL bPamPasswordChange;
255 BOOL bNTStatusSupport;
256 BOOL bAllowTrustedDomains;
262 BOOL bClientLanManAuth;
263 BOOL bClientNTLMv2Auth;
265 BOOL bHideLocalUsers;
268 BOOL bHostnameLookups;
269 BOOL bUnixExtensions;
270 BOOL bDisableNetbios;
272 int restrict_anonymous;
273 int name_cache_timeout;
274 struct param_opt *param_opt;
278 static global Globals;
281 * This structure describes a single service.
290 char **szInvalidUsers;
295 char *szPrintcommand;
298 char *szLppausecommand;
299 char *szLpresumecommand;
300 char *szQueuepausecommand;
301 char *szQueueresumecommand;
309 char **ntvfs_handler;
335 struct param_opt *param_opt;
337 char dummy[3]; /* for alignment */
342 /* This is a default service used to prime a services structure */
343 static service sDefault = {
345 False, /* not autoloaded */
346 NULL, /* szService */
348 NULL, /* szUsername */
349 NULL, /* szInvalidUsers */
350 NULL, /* szValidUsers */
351 NULL, /* szAdminUsers */
353 NULL, /* szInclude */
354 NULL, /* szPrintcommand */
355 NULL, /* szLpqcommand */
356 NULL, /* szLprmcommand */
357 NULL, /* szLppausecommand */
358 NULL, /* szLpresumecommand */
359 NULL, /* szQueuepausecommand */
360 NULL, /* szQueueresumecommand */
361 NULL, /* szPrintername */
362 NULL, /* szHostsallow */
363 NULL, /* szHostsdeny */
367 NULL, /* szMSDfsProxy */
368 NULL, /* ntvfs_handler */
369 0, /* iMinPrintSpace */
370 1000, /* iMaxPrintJobs */
371 0, /* iMaxConnections */
372 DEFAULT_PRINTING, /* iPrinting */
374 True, /* bAvailable */
375 True, /* bBrowseable */
376 True, /* bRead_only */
377 False, /* bPrint_ok */
378 False, /* bMap_system */
379 False, /* bMap_hidden */
380 True, /* bMap_archive */
382 True, /* bStrictLocking */
383 True, /* bPosixLocking */
385 True, /* bLevel2OpLocks */
386 False, /* bOnlyUser */
387 False, /* bGuest_only */
388 False, /* bGuest_ok */
390 False, /* bMSDfsRoot */
391 True, /* bShareModes */
392 False, /* bStrictSync */
393 False, /* bCIFileSystem */
394 NULL, /* Parametric options */
399 /* local variables */
400 static service **ServicePtrs = NULL;
401 static int iNumServices = 0;
402 static int iServiceIndex = 0;
403 static BOOL bInGlobalSection = True;
404 static BOOL bGlobalOnly = False;
405 static int server_role;
406 static int default_server_announce;
408 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
410 /* prototypes for the special type handlers */
411 static BOOL handle_include(const char *pszParmValue, char **ptr);
412 static BOOL handle_copy(const char *pszParmValue, char **ptr);
413 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
414 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
415 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
417 static void set_server_role(void);
418 static void set_default_server_announce_type(void);
420 static const struct enum_list enum_protocol[] = {
421 {PROTOCOL_NT1, "NT1"},
422 {PROTOCOL_LANMAN2, "LANMAN2"},
423 {PROTOCOL_LANMAN1, "LANMAN1"},
424 {PROTOCOL_CORE, "CORE"},
425 {PROTOCOL_COREPLUS, "COREPLUS"},
426 {PROTOCOL_COREPLUS, "CORE+"},
430 static const struct enum_list enum_security[] = {
431 {SEC_SHARE, "SHARE"},
433 {SEC_SERVER, "SERVER"},
434 {SEC_DOMAIN, "DOMAIN"},
441 static const struct enum_list enum_printing[] = {
442 {PRINT_SYSV, "sysv"},
444 {PRINT_HPUX, "hpux"},
448 {PRINT_LPRNG, "lprng"},
449 {PRINT_SOFTQ, "softq"},
450 {PRINT_CUPS, "cups"},
452 {PRINT_LPROS2, "os2"},
454 {PRINT_TEST, "test"},
456 #endif /* DEVELOPER */
460 /* Types of machine we can announce as. */
461 #define ANNOUNCE_AS_NT_SERVER 1
462 #define ANNOUNCE_AS_WIN95 2
463 #define ANNOUNCE_AS_WFW 3
464 #define ANNOUNCE_AS_NT_WORKSTATION 4
466 static const struct enum_list enum_announce_as[] = {
467 {ANNOUNCE_AS_NT_SERVER, "NT"},
468 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
469 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
470 {ANNOUNCE_AS_WIN95, "win95"},
471 {ANNOUNCE_AS_WFW, "WfW"},
475 static const struct enum_list enum_bool_auto[] = {
486 /* Client-side offline caching policy types */
487 #define CSC_POLICY_MANUAL 0
488 #define CSC_POLICY_DOCUMENTS 1
489 #define CSC_POLICY_PROGRAMS 2
490 #define CSC_POLICY_DISABLE 3
492 static const struct enum_list enum_csc_policy[] = {
493 {CSC_POLICY_MANUAL, "manual"},
494 {CSC_POLICY_DOCUMENTS, "documents"},
495 {CSC_POLICY_PROGRAMS, "programs"},
496 {CSC_POLICY_DISABLE, "disable"},
500 /* SMB signing types. */
501 static const struct enum_list enum_smb_signing_vals[] = {
502 {SMB_SIGNING_OFF, "No"},
503 {SMB_SIGNING_OFF, "False"},
504 {SMB_SIGNING_OFF, "0"},
505 {SMB_SIGNING_OFF, "Off"},
506 {SMB_SIGNING_OFF, "disabled"},
507 {SMB_SIGNING_SUPPORTED, "Yes"},
508 {SMB_SIGNING_SUPPORTED, "True"},
509 {SMB_SIGNING_SUPPORTED, "1"},
510 {SMB_SIGNING_SUPPORTED, "On"},
511 {SMB_SIGNING_SUPPORTED, "enabled"},
512 {SMB_SIGNING_REQUIRED, "required"},
513 {SMB_SIGNING_REQUIRED, "mandatory"},
514 {SMB_SIGNING_REQUIRED, "force"},
515 {SMB_SIGNING_REQUIRED, "forced"},
516 {SMB_SIGNING_REQUIRED, "enforced"},
517 {SMB_SIGNING_AUTO, "auto"},
522 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
524 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
525 * is implied in current control logic. This may change at some later time. A
526 * flag value of 0 means - show as development option only.
528 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
529 * screen in SWAT. This is used to exclude parameters as well as to squash all
530 * parameters that have been duplicated by pseudonyms.
532 static struct parm_struct parm_table[] = {
533 {"Base Options", P_SEP, P_SEPARATOR},
535 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
540 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
541 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
542 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
543 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
544 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
546 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
547 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
550 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
551 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
552 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
553 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
555 {"Security Options", P_SEP, P_SEPARATOR},
557 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
558 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
559 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
560 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
566 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
574 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
588 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
589 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
591 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
592 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
593 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
595 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
597 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
599 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
601 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
602 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
603 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
604 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
606 {"Logging Options", P_SEP, P_SEPARATOR},
608 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
609 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
610 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
612 {"Protocol Options", P_SEP, P_SEPARATOR},
614 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
615 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
616 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
617 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
618 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
619 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
620 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
621 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
625 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
626 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
627 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
631 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
635 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
636 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
637 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
638 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
639 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
641 {"Tuning Options", P_SEP, P_SEPARATOR},
643 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
644 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
645 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
646 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
648 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
649 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
650 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
652 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
653 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
654 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
656 {"Printing Options", P_SEP, P_SEPARATOR},
658 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
659 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
660 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
661 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
662 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
663 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
664 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
665 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
666 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
667 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
668 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
671 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
674 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
675 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
677 {"Filename Handling", P_SEP, P_SEPARATOR},
679 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
680 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
681 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
683 {"Domain Options", P_SEP, P_SEPARATOR},
685 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
687 {"Logon Options", P_SEP, P_SEPARATOR},
689 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
690 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"Browse Options", P_SEP, P_SEPARATOR},
700 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
703 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
705 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
706 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
708 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
709 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
711 {"WINS Options", P_SEP, P_SEPARATOR},
712 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
715 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
716 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
717 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
718 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
720 {"Locking Options", P_SEP, P_SEPARATOR},
722 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
723 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
724 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
725 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
727 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
729 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
730 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
731 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
733 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
735 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
736 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
737 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
739 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
744 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
747 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
748 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
750 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
751 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
753 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
754 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
755 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
757 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
761 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
762 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"Winbind options", P_SEP, P_SEPARATOR},
765 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
778 /***************************************************************************
779 Initialise the sDefault parameter structure for the printer values.
780 ***************************************************************************/
782 static void init_printer_values(void)
784 /* choose defaults depending on the type of printing */
785 switch (sDefault.iPrinting) {
790 do_parameter("Lpqcommand", "lpq -P'%p'");
791 do_parameter("Lprmcommand", "lprm -P'%p' %j");
792 do_parameter("Printcommand",
798 do_parameter("Lpqcommand", "lpq -P'%p'");
799 do_parameter("Lprmcommand", "lprm -P'%p' %j");
800 do_parameter("Printcommand",
802 do_parameter("Queuepausecommand",
804 do_parameter("Queueresumecommand",
806 do_parameter("Lppausecommand",
808 do_parameter("Lpresumecommand",
809 "lpc release '%p' %j");
814 do_parameter("Lpqcommand", "");
815 do_parameter("Lprmcommand", "");
816 do_parameter("Printcommand", "");
817 do_parameter("Lppausecommand", "");
818 do_parameter("Lpresumecommand", "");
819 do_parameter("Queuepausecommand", "");
820 do_parameter("Queueresumecommand", "");
822 do_parameter("Printcapname", "cups");
824 do_parameter("Lpqcommand",
825 "/usr/bin/lpstat -o '%p'");
826 do_parameter("Lprmcommand",
827 "/usr/bin/cancel '%p-%j'");
828 do_parameter("Printcommand",
829 "/usr/bin/lp -d '%p' %s; rm %s");
830 do_parameter("Lppausecommand",
831 "lp -i '%p-%j' -H hold");
832 do_parameter("Lpresumecommand",
833 "lp -i '%p-%j' -H resume");
834 do_parameter("Queuepausecommand",
835 "/usr/bin/disable '%p'");
836 do_parameter("Queueresumecommand",
837 "/usr/bin/enable '%p'");
838 do_parameter("Printcapname", "lpstat");
839 #endif /* HAVE_CUPS */
844 do_parameter("Lpqcommand", "lpstat -o%p");
845 do_parameter("Lprmcommand", "cancel %p-%j");
846 do_parameter("Printcommand",
847 "lp -c -d%p %s; rm %s");
848 do_parameter("Queuepausecommand",
850 do_parameter("Queueresumecommand",
853 do_parameter("Lppausecommand",
854 "lp -i %p-%j -H hold");
855 do_parameter("Lpresumecommand",
856 "lp -i %p-%j -H resume");
861 do_parameter("Lpqcommand", "lpq -P%p");
862 do_parameter("Lprmcommand", "lprm -P%p %j");
863 do_parameter("Printcommand", "lp -r -P%p %s");
867 do_parameter("Lpqcommand", "qstat -l -d%p");
868 do_parameter("Lprmcommand",
870 do_parameter("Printcommand",
871 "lp -d%p -s %s; rm %s");
872 do_parameter("Lppausecommand",
874 do_parameter("Lpresumecommand",
880 do_parameter("Printcommand", "vlp print %p %s");
881 do_parameter("Lpqcommand", "vlp lpq %p");
882 do_parameter("Lprmcommand", "vlp lprm %p %j");
883 do_parameter("Lppausecommand", "vlp lppause %p %j");
884 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
885 do_parameter("Queuepausecommand", "vlp queuepause %p");
886 do_parameter("Queueresumecommand", "vlp queueresume %p");
888 #endif /* DEVELOPER */
894 /***************************************************************************
895 Initialise the global parameter structure.
896 ***************************************************************************/
897 static void init_globals(void)
902 DEBUG(3, ("Initialising global parameters\n"));
904 for (i = 0; parm_table[i].label; i++) {
905 if ((parm_table[i].type == P_STRING ||
906 parm_table[i].type == P_USTRING) &&
908 !(parm_table[i].flags & FLAG_CMDLINE)) {
909 string_set(parm_table[i].ptr, "");
913 /* options that can be set on the command line must be initialised via
914 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
916 do_parameter("socket options", "TCP_NODELAY");
918 do_parameter("workgroup", DEFAULT_WORKGROUP);
919 myname = get_myname();
920 do_parameter("netbios name", myname);
922 do_parameter("max protocol", "NT1");
923 do_parameter("name resolve order", "lmhosts wins host bcast");
925 init_printer_values();
927 do_parameter("fstype", FSTYPE_STRING);
928 do_parameter("ntvfs handler", "unixuid default");
929 do_parameter("max connections", "-1");
931 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg IOXIDResolver IRemoteActivation dssetup");
932 do_parameter("server services", "smb rpc");
933 do_parameter("auth methods", "anonymous sam_ignoredomain");
934 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
935 do_parameter("private dir", dyn_PRIVATE_DIR);
936 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
937 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
938 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
939 do_parameter("guest account", GUEST_ACCOUNT);
941 /* using UTF8 by default allows us to support all chars */
942 do_parameter("unix charset", "UTF8");
944 /* Use codepage 850 as a default for the dos character set */
945 do_parameter("dos charset", "CP850");
948 * Allow the default PASSWD_CHAT to be overridden in local.h.
950 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
952 do_parameter("passwd program", "");
953 do_parameter("printcap name", PRINTCAP_NAME);
955 do_parameter("pid directory", dyn_PIDDIR);
956 do_parameter("lock dir", dyn_LOCKDIR);
957 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
959 do_parameter("socket address", "0.0.0.0");
960 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
962 do_parameter_var("announce version", "%d.%d",
963 DEFAULT_MAJOR_VERSION,
964 DEFAULT_MINOR_VERSION);
966 do_parameter("logon drive", "");
968 do_parameter("logon home", "\\\\%N\\%U");
969 do_parameter("logon path", "\\\\%N\\%U\\profile");
970 do_parameter("password server", "*");
972 do_parameter("load printers", "True");
974 do_parameter("max mux", "50");
975 do_parameter("max xmit", "12288");
976 do_parameter("lpqcachetime", "10");
977 do_parameter("DisableSpoolss", "False");
978 do_parameter("password level", "0");
979 do_parameter("username level", "0");
980 do_parameter("LargeReadwrite", "True");
981 do_parameter("minprotocol", "CORE");
982 do_parameter("security", "USER");
983 do_parameter("paranoid server security", "True");
984 do_parameter("EncryptPasswords", "True");
985 do_parameter("ReadRaw", "True");
986 do_parameter("WriteRaw", "True");
987 do_parameter("NullPasswords", "False");
988 do_parameter("ObeyPamRestrictions", "False");
989 do_parameter("lm announce", "Auto");
990 do_parameter("lm interval", "60");
991 do_parameter("announce as", "NT SERVER");
993 do_parameter("TimeServer", "False");
994 do_parameter("BindInterfacesOnly", "False");
995 do_parameter("PamPasswordChange", "False");
996 do_parameter("Unicode", "True");
997 do_parameter("restrict anonymous", "0");
998 do_parameter("ClientLanManAuth", "True");
999 do_parameter("LanmanAuth", "True");
1000 do_parameter("NTLMAuth", "True");
1002 do_parameter("enhanced browsing", "True");
1003 do_parameter("LockSpinCount", "3");
1004 do_parameter("LockSpinTime", "10");
1005 #ifdef MMAP_BLACKLIST
1006 do_parameter("UseMmap", "False");
1008 do_parameter("UseMmap", "True");
1010 do_parameter("UnixExtensions", "False");
1012 /* hostname lookups can be very expensive and are broken on
1013 a large number of sites (tridge) */
1014 do_parameter("HostnameLookups", "False");
1016 do_parameter("PreferredMaster", "Auto");
1017 do_parameter("os level", "20");
1018 do_parameter("LocalMaster", "True");
1019 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1020 do_parameter("DomainLogons", "False");
1021 do_parameter("WINSsupport", "False");
1022 do_parameter("WINSproxy", "False");
1024 do_parameter("DNSproxy", "True");
1026 do_parameter("AllowTrustedDomains", "True");
1028 do_parameter("TemplateShell", "/bin/false");
1029 do_parameter("TemplateHomedir", "/home/%D/%U");
1030 do_parameter("WinbindSeparator", "\\");
1032 do_parameter("winbind cache time", "15");
1033 do_parameter("WinbindEnumUsers", "True");
1034 do_parameter("WinbindEnumGroups", "True");
1035 do_parameter("WinbindUseDefaultDomain", "False");
1037 do_parameter("IDMapBackend", "tdb");
1039 do_parameter("name cache timeout", "660"); /* In seconds */
1041 do_parameter("client signing", "Yes");
1042 do_parameter("server signing", "auto");
1044 do_parameter("use spnego", "True");
1046 do_parameter("smb ports", SMB_PORTS);
1048 do_parameter("nt status support", "True");
1051 static TALLOC_CTX *lp_talloc;
1053 /******************************************************************* a
1054 Free up temporary memory - called from the main loop.
1055 ********************************************************************/
1057 void lp_talloc_free(void)
1061 talloc_free(lp_talloc);
1065 /*******************************************************************
1066 Convenience routine to grab string parameters into temporary memory
1067 and run standard_sub_basic on them. The buffers can be written to by
1068 callers without affecting the source string.
1069 ********************************************************************/
1071 static const char *lp_string(const char *s)
1073 #if 0 /* until REWRITE done to make thread-safe */
1074 size_t len = s ? strlen(s) : 0;
1078 /* The follow debug is useful for tracking down memory problems
1079 especially if you have an inner loop that is calling a lp_*()
1080 function that returns a string. Perhaps this debug should be
1081 present all the time? */
1084 DEBUG(10, ("lp_string(%s)\n", s));
1087 #if 0 /* until REWRITE done to make thread-safe */
1089 lp_talloc = talloc_init("lp_talloc");
1091 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1099 StrnCpy(ret, s, len);
1101 if (trim_string(ret, "\"", "\"")) {
1102 if (strchr(ret,'"') != NULL)
1103 StrnCpy(ret, s, len);
1106 standard_sub_basic(ret,len+100);
1113 In this section all the functions that are used to access the
1114 parameters from the rest of the program are defined
1117 #define FN_GLOBAL_STRING(fn_name,ptr) \
1118 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1119 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1120 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1121 #define FN_GLOBAL_LIST(fn_name,ptr) \
1122 const char **fn_name(void) {return(*(const char ***)(ptr));}
1123 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1124 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1125 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1126 char fn_name(void) {return(*(char *)(ptr));}
1127 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1128 int fn_name(void) {return(*(int *)(ptr));}
1130 #define FN_LOCAL_STRING(fn_name,val) \
1131 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1132 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1133 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1134 #define FN_LOCAL_LIST(fn_name,val) \
1135 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1136 #define FN_LOCAL_BOOL(fn_name,val) \
1137 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1138 #define FN_LOCAL_CHAR(fn_name,val) \
1139 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1140 #define FN_LOCAL_INTEGER(fn_name,val) \
1141 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1143 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1144 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1145 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1146 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1147 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1148 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1149 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1150 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1151 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1152 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1153 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1154 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1155 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1156 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1157 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1158 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1159 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1160 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1161 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1162 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1163 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1164 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1165 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1166 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1167 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1168 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1169 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1170 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1171 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1172 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1173 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1174 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1175 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1176 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1177 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1178 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1179 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1180 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1181 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1182 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1183 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1184 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1185 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1186 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1188 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1190 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1192 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1193 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1194 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1195 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1196 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1197 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1198 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1199 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1200 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1202 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1203 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1204 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1205 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1206 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1207 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1208 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1209 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1210 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1211 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1212 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1213 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1214 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1215 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1216 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1217 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1218 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1219 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1220 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1221 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1222 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1223 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1224 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1225 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1226 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1227 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1228 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1229 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1230 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1231 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1232 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1233 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1234 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1235 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1236 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1237 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1238 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1239 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1240 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1241 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1242 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1243 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1244 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1245 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1246 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1247 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1248 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1249 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1250 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1251 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1252 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1253 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1254 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1255 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1256 FN_LOCAL_STRING(lp_servicename, szService)
1257 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1258 FN_LOCAL_STRING(lp_pathname, szPath)
1259 FN_LOCAL_STRING(lp_username, szUsername)
1260 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1261 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1262 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1263 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1264 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1265 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1266 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1267 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1268 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1269 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1270 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1271 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1272 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1273 FN_LOCAL_STRING(lp_comment, comment)
1274 FN_LOCAL_STRING(lp_fstype, fstype)
1275 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1276 static FN_LOCAL_STRING(lp_volume, volume)
1277 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1278 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1279 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1280 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1281 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1282 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1283 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1284 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1285 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1286 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1287 FN_LOCAL_BOOL(lp_locking, bLocking)
1288 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1289 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1290 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1291 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1292 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1293 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1294 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1295 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1296 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1297 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1298 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1299 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1300 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1301 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1302 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1303 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1304 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1305 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1307 /* local prototypes */
1309 static int map_parameter(const char *pszParmName);
1310 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1311 static int getservicebyname(const char *pszServiceName,
1312 service * pserviceDest);
1313 static void copy_service(service * pserviceDest,
1314 service * pserviceSource, BOOL *pcopymapDest);
1315 static BOOL service_ok(int iService);
1316 static BOOL do_section(const char *pszSectionName);
1317 static void init_copymap(service * pservice);
1319 /* This is a helper function for parametrical options support. */
1320 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1321 /* Actual parametrical functions are quite simple */
1322 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1325 struct param_opt *data;
1327 if (lookup_service >= iNumServices) return NULL;
1329 data = (lookup_service < 0) ?
1330 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1332 asprintf(&vfskey, "%s:%s", type, option);
1336 if (strcmp(data->key, vfskey) == 0) {
1343 if (lookup_service >= 0) {
1344 /* Try to fetch the same option but from globals */
1345 /* but only if we are not already working with Globals */
1346 data = Globals.param_opt;
1348 if (strcmp(data->key, vfskey) == 0) {
1362 /*******************************************************************
1363 convenience routine to return int parameters.
1364 ********************************************************************/
1365 static int lp_int(const char *s)
1369 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1376 /*******************************************************************
1377 convenience routine to return unsigned long parameters.
1378 ********************************************************************/
1379 static int lp_ulong(const char *s)
1383 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1387 return strtoul(s, NULL, 10);
1390 /*******************************************************************
1391 convenience routine to return boolean parameters.
1392 ********************************************************************/
1393 static BOOL lp_bool(const char *s)
1398 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1402 if (!set_boolean(&ret,s)) {
1403 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1411 /* Return parametric option from a given service. Type is a part of option before ':' */
1412 /* Parametric option has following syntax: 'Type: option = value' */
1413 /* Returned value is allocated in 'lp_talloc' context */
1415 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1417 const char *value = get_parametrics(lookup_service, type, option);
1420 return lp_string(value);
1425 /* Return parametric option from a given service. Type is a part of option before ':' */
1426 /* Parametric option has following syntax: 'Type: option = value' */
1427 /* Returned value is allocated in 'lp_talloc' context */
1429 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1430 const char *separator)
1432 const char *value = get_parametrics(lookup_service, type, option);
1435 return str_list_make(value, separator);
1440 /* Return parametric option from a given service. Type is a part of option before ':' */
1441 /* Parametric option has following syntax: 'Type: option = value' */
1443 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1445 const char *value = get_parametrics(lookup_service, type, option);
1448 return lp_int(value);
1453 /* Return parametric option from a given service. Type is a part of option before ':' */
1454 /* Parametric option has following syntax: 'Type: option = value' */
1456 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1458 const char *value = get_parametrics(lookup_service, type, option);
1461 return lp_ulong(value);
1466 /* Return parametric option from a given service. Type is a part of option before ':' */
1467 /* Parametric option has following syntax: 'Type: option = value' */
1469 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1471 const char *value = get_parametrics(lookup_service, type, option);
1474 return lp_bool(value);
1480 /***************************************************************************
1481 Initialise a service to the defaults.
1482 ***************************************************************************/
1484 static void init_service(service * pservice)
1486 memset((char *)pservice, '\0', sizeof(service));
1487 copy_service(pservice, &sDefault, NULL);
1490 /***************************************************************************
1491 Free the dynamically allocated parts of a service struct.
1492 ***************************************************************************/
1494 static void free_service(service *pservice)
1497 struct param_opt *data, *pdata;
1501 if (pservice->szService)
1502 DEBUG(5, ("free_service: Freeing service %s\n",
1503 pservice->szService));
1505 string_free(&pservice->szService);
1506 SAFE_FREE(pservice->copymap);
1508 for (i = 0; parm_table[i].label; i++) {
1509 if ((parm_table[i].type == P_STRING ||
1510 parm_table[i].type == P_USTRING) &&
1511 parm_table[i].class == P_LOCAL)
1512 string_free((char **)
1513 (((char *)pservice) +
1514 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1515 else if (parm_table[i].type == P_LIST &&
1516 parm_table[i].class == P_LOCAL)
1517 str_list_free((char ***)
1518 (((char *)pservice) +
1519 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1522 DEBUG(5,("Freeing parametrics:\n"));
1523 data = pservice->param_opt;
1525 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1526 string_free(&data->key);
1527 string_free(&data->value);
1533 ZERO_STRUCTP(pservice);
1536 /***************************************************************************
1537 Add a new service to the services array initialising it with the given
1539 ***************************************************************************/
1541 static int add_a_service(const service *pservice, const char *name)
1545 int num_to_alloc = iNumServices + 1;
1546 struct param_opt *data, *pdata;
1548 tservice = *pservice;
1550 /* it might already exist */
1552 i = getservicebyname(name, NULL);
1554 /* Clean all parametric options for service */
1555 /* They will be added during parsing again */
1556 data = ServicePtrs[i]->param_opt;
1558 string_free(&data->key);
1559 string_free(&data->value);
1564 ServicePtrs[i]->param_opt = NULL;
1569 /* find an invalid one */
1570 for (i = 0; i < iNumServices; i++)
1571 if (!ServicePtrs[i]->valid)
1574 /* if not, then create one */
1575 if (i == iNumServices) {
1578 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1581 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1586 ServicePtrs[iNumServices] = malloc_p(service);
1588 if (!ServicePtrs[iNumServices]) {
1589 DEBUG(0,("add_a_service: out of memory!\n"));
1595 free_service(ServicePtrs[i]);
1597 ServicePtrs[i]->valid = True;
1599 init_service(ServicePtrs[i]);
1600 copy_service(ServicePtrs[i], &tservice, NULL);
1602 string_set(&ServicePtrs[i]->szService, name);
1606 /***************************************************************************
1607 Add a new home service, with the specified home directory, defaults coming
1609 ***************************************************************************/
1611 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1612 const char *user, const char *pszHomedir)
1617 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1622 if (!(*(ServicePtrs[iDefaultService]->szPath))
1623 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1624 pstrcpy(newHomedir, pszHomedir);
1626 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1627 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1630 string_set(&ServicePtrs[i]->szPath, newHomedir);
1632 if (!(*(ServicePtrs[i]->comment))) {
1634 slprintf(comment, sizeof(comment) - 1,
1635 "Home directory of %s", user);
1636 string_set(&ServicePtrs[i]->comment, comment);
1638 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1639 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1641 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1647 /***************************************************************************
1648 Add a new service, based on an old one.
1649 ***************************************************************************/
1651 int lp_add_service(const char *pszService, int iDefaultService)
1653 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1656 /***************************************************************************
1657 Add the IPC service.
1658 ***************************************************************************/
1660 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1663 int i = add_a_service(&sDefault, name);
1668 slprintf(comment, sizeof(comment) - 1,
1669 "%s Service (%s)", fstype, Globals.szServerString);
1671 string_set(&ServicePtrs[i]->szPath, tmpdir());
1672 string_set(&ServicePtrs[i]->szUsername, "");
1673 string_set(&ServicePtrs[i]->comment, comment);
1674 string_set(&ServicePtrs[i]->fstype, fstype);
1675 ServicePtrs[i]->iMaxConnections = -1;
1676 ServicePtrs[i]->bAvailable = True;
1677 ServicePtrs[i]->bRead_only = True;
1678 ServicePtrs[i]->bGuest_only = False;
1679 ServicePtrs[i]->bGuest_ok = guest_ok;
1680 ServicePtrs[i]->bPrint_ok = False;
1681 ServicePtrs[i]->bBrowseable = False;
1683 if (strcasecmp(fstype, "IPC") == 0) {
1684 lp_do_parameter(i, "ntvfs handler", "default");
1687 DEBUG(3, ("adding hidden service %s\n", name));
1692 /***************************************************************************
1693 Add a new printer service, with defaults coming from service iFrom.
1694 ***************************************************************************/
1696 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1698 const char *comment = "From Printcap";
1699 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1704 /* note that we do NOT default the availability flag to True - */
1705 /* we take it from the default service passed. This allows all */
1706 /* dynamic printers to be disabled by disabling the [printers] */
1707 /* entry (if/when the 'available' keyword is implemented!). */
1709 /* the printer name is set to the service name. */
1710 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1711 string_set(&ServicePtrs[i]->comment, comment);
1712 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1713 /* Printers cannot be read_only. */
1714 ServicePtrs[i]->bRead_only = False;
1715 /* No share modes on printer services. */
1716 ServicePtrs[i]->bShareModes = False;
1717 /* No oplocks on printer services. */
1718 ServicePtrs[i]->bOpLocks = False;
1719 /* Printer services must be printable. */
1720 ServicePtrs[i]->bPrint_ok = True;
1722 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1724 update_server_announce_as_printserver();
1729 /***************************************************************************
1730 Map a parameter's string representation to something we can use.
1731 Returns False if the parameter string is not recognised, else TRUE.
1732 ***************************************************************************/
1734 static int map_parameter(const char *pszParmName)
1738 if (*pszParmName == '-')
1741 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1742 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1745 /* Warn only if it isn't parametric option */
1746 if (strchr(pszParmName, ':') == NULL)
1747 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1748 /* We do return 'fail' for parametric options as well because they are
1749 stored in different storage
1754 /***************************************************************************
1755 Set a boolean variable from the text value stored in the passed string.
1756 Returns True in success, False if the passed string does not correctly
1757 represent a boolean.
1758 ***************************************************************************/
1760 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1765 if (strwicmp(pszParmValue, "yes") == 0 ||
1766 strwicmp(pszParmValue, "true") == 0 ||
1767 strwicmp(pszParmValue, "1") == 0)
1769 else if (strwicmp(pszParmValue, "no") == 0 ||
1770 strwicmp(pszParmValue, "False") == 0 ||
1771 strwicmp(pszParmValue, "0") == 0)
1775 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1782 /***************************************************************************
1783 Find a service by name. Otherwise works like get_service.
1784 ***************************************************************************/
1786 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1790 for (iService = iNumServices - 1; iService >= 0; iService--)
1791 if (VALID(iService) &&
1792 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1793 if (pserviceDest != NULL)
1794 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1801 /***************************************************************************
1802 Copy a service structure to another.
1803 If pcopymapDest is NULL then copy all fields
1804 ***************************************************************************/
1806 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1809 BOOL bcopyall = (pcopymapDest == NULL);
1810 struct param_opt *data, *pdata, *paramo;
1813 for (i = 0; parm_table[i].label; i++)
1814 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1815 (bcopyall || pcopymapDest[i])) {
1816 void *def_ptr = parm_table[i].ptr;
1818 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1821 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1824 switch (parm_table[i].type) {
1827 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1833 *(int *)dest_ptr = *(int *)src_ptr;
1837 *(char *)dest_ptr = *(char *)src_ptr;
1841 string_set(dest_ptr,
1846 string_set(dest_ptr,
1848 strupper(*(char **)dest_ptr);
1851 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1859 init_copymap(pserviceDest);
1860 if (pserviceSource->copymap)
1861 memcpy((void *)pserviceDest->copymap,
1862 (void *)pserviceSource->copymap,
1863 sizeof(BOOL) * NUMPARAMETERS);
1866 data = pserviceSource->param_opt;
1869 pdata = pserviceDest->param_opt;
1870 /* Traverse destination */
1872 /* If we already have same option, override it */
1873 if (strcmp(pdata->key, data->key) == 0) {
1874 string_free(&pdata->value);
1875 pdata->value = strdup(data->value);
1879 pdata = pdata->next;
1882 paramo = smb_xmalloc_p(struct param_opt);
1883 paramo->key = strdup(data->key);
1884 paramo->value = strdup(data->value);
1885 DLIST_ADD(pserviceDest->param_opt, paramo);
1891 /***************************************************************************
1892 Check a service for consistency. Return False if the service is in any way
1893 incomplete or faulty, else True.
1894 ***************************************************************************/
1896 static BOOL service_ok(int iService)
1901 if (ServicePtrs[iService]->szService[0] == '\0') {
1902 DEBUG(0, ("The following message indicates an internal error:\n"));
1903 DEBUG(0, ("No service name in service entry.\n"));
1907 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1908 /* I can't see why you'd want a non-printable printer service... */
1909 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1910 if (!ServicePtrs[iService]->bPrint_ok) {
1911 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1912 ServicePtrs[iService]->szService));
1913 ServicePtrs[iService]->bPrint_ok = True;
1915 /* [printers] service must also be non-browsable. */
1916 if (ServicePtrs[iService]->bBrowseable)
1917 ServicePtrs[iService]->bBrowseable = False;
1920 /* If a service is flagged unavailable, log the fact at level 0. */
1921 if (!ServicePtrs[iService]->bAvailable)
1922 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1923 ServicePtrs[iService]->szService));
1928 static struct file_lists {
1929 struct file_lists *next;
1933 } *file_lists = NULL;
1935 /*******************************************************************
1936 Keep a linked list of all config files so we know when one has changed
1937 it's date and needs to be reloaded.
1938 ********************************************************************/
1940 static void add_to_file_list(const char *fname, const char *subfname)
1942 struct file_lists *f = file_lists;
1945 if (f->name && !strcmp(f->name, fname))
1951 f = malloc_p(struct file_lists);
1954 f->next = file_lists;
1955 f->name = strdup(fname);
1960 f->subfname = strdup(subfname);
1966 f->modtime = file_modtime(subfname);
1968 time_t t = file_modtime(subfname);
1974 /*******************************************************************
1975 Check if a config file has changed date.
1976 ********************************************************************/
1978 BOOL lp_file_list_changed(void)
1980 struct file_lists *f = file_lists;
1981 DEBUG(6, ("lp_file_list_changed()\n"));
1987 pstrcpy(n2, f->name);
1988 standard_sub_basic(n2,sizeof(n2));
1990 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1991 f->name, n2, ctime(&f->modtime)));
1993 mod_time = file_modtime(n2);
1995 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1997 ("file %s modified: %s\n", n2,
1999 f->modtime = mod_time;
2000 SAFE_FREE(f->subfname);
2001 f->subfname = strdup(n2);
2009 /***************************************************************************
2010 Handle the include operation.
2011 ***************************************************************************/
2013 static BOOL handle_include(const char *pszParmValue, char **ptr)
2016 pstrcpy(fname, pszParmValue);
2018 standard_sub_basic(fname,sizeof(fname));
2020 add_to_file_list(pszParmValue, fname);
2022 string_set(ptr, fname);
2024 if (file_exist(fname, NULL))
2025 return (pm_process(fname, do_section, do_parameter));
2027 DEBUG(2, ("Can't find include file %s\n", fname));
2032 /***************************************************************************
2033 Handle the interpretation of the copy parameter.
2034 ***************************************************************************/
2036 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2040 service serviceTemp;
2042 string_set(ptr, pszParmValue);
2044 init_service(&serviceTemp);
2048 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2050 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2051 if (iTemp == iServiceIndex) {
2052 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2054 copy_service(ServicePtrs[iServiceIndex],
2056 ServicePtrs[iServiceIndex]->copymap);
2060 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2064 free_service(&serviceTemp);
2068 /***************************************************************************
2069 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2074 winbind uid = 1000-1999
2075 winbind gid = 700-899
2077 We only do simple parsing checks here. The strings are parsed into useful
2078 structures in the winbind daemon code.
2080 ***************************************************************************/
2082 /* Some lp_ routines to return winbind [ug]id information */
2084 static uid_t winbind_uid_low, winbind_uid_high;
2085 static gid_t winbind_gid_low, winbind_gid_high;
2086 static uint32_t non_unix_account_low, non_unix_account_high;
2088 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2090 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2094 *low = winbind_uid_low;
2097 *high = winbind_uid_high;
2102 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2104 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2108 *low = winbind_gid_low;
2111 *high = winbind_gid_high;
2116 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2118 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2122 *low = non_unix_account_low;
2125 *high = non_unix_account_high;
2130 /* Do some simple checks on "winbind [ug]id" parameter values */
2132 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2136 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2141 string_set(ptr, pszParmValue);
2143 winbind_uid_low = low;
2144 winbind_uid_high = high;
2149 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2153 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2158 string_set(ptr, pszParmValue);
2160 winbind_gid_low = low;
2161 winbind_gid_high = high;
2166 /***************************************************************************
2167 Do some simple checks on "non unix account range" parameter values.
2168 ***************************************************************************/
2170 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2174 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2179 string_set(ptr, pszParmValue);
2181 non_unix_account_low = low;
2182 non_unix_account_high = high;
2188 /***************************************************************************
2189 Initialise a copymap.
2190 ***************************************************************************/
2192 static void init_copymap(service * pservice)
2195 SAFE_FREE(pservice->copymap);
2196 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2197 if (!pservice->copymap)
2199 ("Couldn't allocate copymap!! (size %d)\n",
2200 (int)NUMPARAMETERS));
2202 for (i = 0; i < NUMPARAMETERS; i++)
2203 pservice->copymap[i] = True;
2206 /***************************************************************************
2207 Return the local pointer to a parameter given the service number and the
2208 pointer into the default structure.
2209 ***************************************************************************/
2211 void *lp_local_ptr(int snum, void *ptr)
2213 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2217 /***************************************************************************
2218 Process a parametric option
2219 ***************************************************************************/
2220 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2222 struct param_opt *paramo, *data;
2225 while (isspace(*pszParmName)) {
2229 name = strdup(pszParmName);
2230 if (!name) return False;
2235 data = Globals.param_opt;
2237 data = ServicePtrs[snum]->param_opt;
2240 /* Traverse destination */
2241 for (paramo=data; paramo; paramo=paramo->next) {
2242 /* If we already have the option set, override it unless
2243 it was a command line option and the new one isn't */
2244 if (strcmp(paramo->key, name) == 0) {
2245 if ((paramo->flags & FLAG_CMDLINE) &&
2246 !(flags & FLAG_CMDLINE)) {
2250 free(paramo->value);
2251 paramo->value = strdup(pszParmValue);
2252 paramo->flags = flags;
2258 paramo = smb_xmalloc_p(struct param_opt);
2259 paramo->key = strdup(name);
2260 paramo->value = strdup(pszParmValue);
2261 paramo->flags = flags;
2263 DLIST_ADD(Globals.param_opt, paramo);
2265 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2273 /***************************************************************************
2274 Process a parameter for a particular service number. If snum < 0
2275 then assume we are in the globals.
2276 ***************************************************************************/
2277 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2280 void *parm_ptr = NULL; /* where we are going to store the result */
2281 void *def_ptr = NULL;
2283 parmnum = map_parameter(pszParmName);
2286 if (strchr(pszParmName, ':')) {
2287 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2289 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2293 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2294 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2298 /* if the flag has been set on the command line, then don't allow override,
2299 but don't report an error */
2300 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2304 def_ptr = parm_table[parmnum].ptr;
2306 /* we might point at a service, the default service or a global */
2310 if (parm_table[parmnum].class == P_GLOBAL) {
2312 ("Global parameter %s found in service section!\n",
2317 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2322 if (!ServicePtrs[snum]->copymap)
2323 init_copymap(ServicePtrs[snum]);
2325 /* this handles the aliases - set the copymap for other entries with
2326 the same data pointer */
2327 for (i = 0; parm_table[i].label; i++)
2328 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2329 ServicePtrs[snum]->copymap[i] = False;
2332 /* if it is a special case then go ahead */
2333 if (parm_table[parmnum].special) {
2334 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2338 /* now switch on the type of variable it is */
2339 switch (parm_table[parmnum].type)
2342 set_boolean(parm_ptr, pszParmValue);
2346 set_boolean(parm_ptr, pszParmValue);
2347 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2351 *(int *)parm_ptr = atoi(pszParmValue);
2355 *(char *)parm_ptr = *pszParmValue;
2359 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2363 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2367 string_set(parm_ptr, pszParmValue);
2371 string_set(parm_ptr, pszParmValue);
2372 strupper(*(char **)parm_ptr);
2376 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2379 parm_table[parmnum].enum_list[i].name)) {
2381 parm_table[parmnum].
2386 if (!parm_table[parmnum].enum_list[i].name) {
2387 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2388 pszParmValue, pszParmName));
2399 /***************************************************************************
2400 Process a parameter.
2401 ***************************************************************************/
2403 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2405 if (!bInGlobalSection && bGlobalOnly)
2408 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2409 pszParmName, pszParmValue));
2413 variable argument do parameter
2415 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2417 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2424 s = talloc_vasprintf(NULL, fmt, ap);
2426 ret = do_parameter(pszParmName, s);
2433 set a parameter from the commandline - this is called from command line parameter
2434 parsing code. It sets the parameter then marks the parameter as unable to be modified
2435 by smb.conf processing
2437 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2439 int parmnum = map_parameter(pszParmName);
2442 while (isspace(*pszParmValue)) pszParmValue++;
2445 if (parmnum < 0 && strchr(pszParmName, ':')) {
2446 /* set a parametric option */
2447 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2451 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2455 /* reset the CMDLINE flag in case this has been called before */
2456 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2458 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2462 parm_table[parmnum].flags |= FLAG_CMDLINE;
2464 /* we have to also set FLAG_CMDLINE on aliases */
2465 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2466 parm_table[i].flags |= FLAG_CMDLINE;
2468 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2469 parm_table[i].flags |= FLAG_CMDLINE;
2476 set a option from the commandline in 'a=b' format. Use to support --option
2478 BOOL lp_set_option(const char *option)
2496 ret = lp_set_cmdline(s, p+1);
2502 /***************************************************************************
2503 Print a parameter of the specified type.
2504 ***************************************************************************/
2506 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2512 for (i = 0; p->enum_list[i].name; i++) {
2513 if (*(int *)ptr == p->enum_list[i].value) {
2515 p->enum_list[i].name);
2522 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2526 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2530 fprintf(f, "%d", *(int *)ptr);
2534 fprintf(f, "%c", *(char *)ptr);
2538 if (*(int *)ptr == -1) {
2541 fprintf(f, "0%o", *(int *)ptr);
2546 if ((char ***)ptr && *(char ***)ptr) {
2547 char **list = *(char ***)ptr;
2549 for (; *list; list++)
2550 fprintf(f, "%s%s", *list,
2551 ((*(list+1))?", ":""));
2557 if (*(char **)ptr) {
2558 fprintf(f, "%s", *(char **)ptr);
2566 /***************************************************************************
2567 Check if two parameters are equal.
2568 ***************************************************************************/
2570 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2575 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2580 return (*((int *)ptr1) == *((int *)ptr2));
2583 return (*((char *)ptr1) == *((char *)ptr2));
2586 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2591 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2596 return (p1 == p2 || strequal(p1, p2));
2604 /***************************************************************************
2605 Process a new section (service). At this stage all sections are services.
2606 Later we'll have special sections that permit server parameters to be set.
2607 Returns True on success, False on failure.
2608 ***************************************************************************/
2610 static BOOL do_section(const char *pszSectionName)
2613 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2614 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2617 /* if we've just struck a global section, note the fact. */
2618 bInGlobalSection = isglobal;
2620 /* check for multiple global sections */
2621 if (bInGlobalSection) {
2622 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2626 if (!bInGlobalSection && bGlobalOnly)
2629 /* if we have a current service, tidy it up before moving on */
2632 if (iServiceIndex >= 0)
2633 bRetval = service_ok(iServiceIndex);
2635 /* if all is still well, move to the next record in the services array */
2637 /* We put this here to avoid an odd message order if messages are */
2638 /* issued by the post-processing of a previous section. */
2639 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2641 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2643 DEBUG(0, ("Failed to add a new service\n"));
2652 /***************************************************************************
2653 Determine if a partcular base parameter is currentl set to the default value.
2654 ***************************************************************************/
2656 static BOOL is_default(int i)
2658 if (!defaults_saved)
2660 switch (parm_table[i].type) {
2662 return str_list_compare (parm_table[i].def.lvalue,
2663 *(char ***)parm_table[i].ptr);
2666 return strequal(parm_table[i].def.svalue,
2667 *(char **)parm_table[i].ptr);
2670 return parm_table[i].def.bvalue ==
2671 *(BOOL *)parm_table[i].ptr;
2673 return parm_table[i].def.cvalue ==
2674 *(char *)parm_table[i].ptr;
2678 return parm_table[i].def.ivalue ==
2679 *(int *)parm_table[i].ptr;
2686 /***************************************************************************
2687 Display the contents of the global structure.
2688 ***************************************************************************/
2690 static void dump_globals(FILE *f)
2693 struct param_opt *data;
2695 fprintf(f, "# Global parameters\n[global]\n");
2697 for (i = 0; parm_table[i].label; i++)
2698 if (parm_table[i].class == P_GLOBAL &&
2699 parm_table[i].ptr &&
2700 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2701 if (defaults_saved && is_default(i))
2703 fprintf(f, "\t%s = ", parm_table[i].label);
2704 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2707 if (Globals.param_opt != NULL) {
2708 data = Globals.param_opt;
2710 fprintf(f, "\t%s = %s\n", data->key, data->value);
2717 /***************************************************************************
2718 Display the contents of a single services record.
2719 ***************************************************************************/
2721 static void dump_a_service(service * pService, FILE * f)
2724 struct param_opt *data;
2726 if (pService != &sDefault)
2727 fprintf(f, "\n[%s]\n", pService->szService);
2729 for (i = 0; parm_table[i].label; i++)
2730 if (parm_table[i].class == P_LOCAL &&
2731 parm_table[i].ptr &&
2732 (*parm_table[i].label != '-') &&
2733 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2734 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2736 if (pService == &sDefault) {
2737 if (defaults_saved && is_default(i))
2740 if (equal_parameter(parm_table[i].type,
2741 ((char *)pService) +
2743 ((char *)&sDefault) +
2748 fprintf(f, "\t%s = ", parm_table[i].label);
2749 print_parameter(&parm_table[i],
2750 ((char *)pService) + pdiff, f);
2753 if (pService->param_opt != NULL) {
2754 data = pService->param_opt;
2756 fprintf(f, "\t%s = %s\n", data->key, data->value);
2763 /***************************************************************************
2764 Return info about the next service in a service. snum==-1 gives the globals.
2765 Return NULL when out of parameters.
2766 ***************************************************************************/
2768 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2771 /* do the globals */
2772 for (; parm_table[*i].label; (*i)++) {
2773 if (parm_table[*i].class == P_SEPARATOR)
2774 return &parm_table[(*i)++];
2776 if (!parm_table[*i].ptr
2777 || (*parm_table[*i].label == '-'))
2781 && (parm_table[*i].ptr ==
2782 parm_table[(*i) - 1].ptr))
2785 return &parm_table[(*i)++];
2788 service *pService = ServicePtrs[snum];
2790 for (; parm_table[*i].label; (*i)++) {
2791 if (parm_table[*i].class == P_SEPARATOR)
2792 return &parm_table[(*i)++];
2794 if (parm_table[*i].class == P_LOCAL &&
2795 parm_table[*i].ptr &&
2796 (*parm_table[*i].label != '-') &&
2798 (parm_table[*i].ptr !=
2799 parm_table[(*i) - 1].ptr)))
2802 PTR_DIFF(parm_table[*i].ptr,
2805 if (allparameters ||
2806 !equal_parameter(parm_table[*i].type,
2807 ((char *)pService) +
2809 ((char *)&sDefault) +
2812 return &parm_table[(*i)++];
2822 /***************************************************************************
2823 Return TRUE if the passed service number is within range.
2824 ***************************************************************************/
2826 BOOL lp_snum_ok(int iService)
2828 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2831 /***************************************************************************
2832 Auto-load some home services.
2833 ***************************************************************************/
2835 static void lp_add_auto_services(const char *str)
2840 /***************************************************************************
2841 Auto-load one printer.
2842 ***************************************************************************/
2844 void lp_add_one_printer(char *name, char *comment)
2846 int printers = lp_servicenumber(PRINTERS_NAME);
2849 if (lp_servicenumber(name) < 0) {
2850 lp_add_printer(name, printers);
2851 if ((i = lp_servicenumber(name)) >= 0) {
2852 string_set(&ServicePtrs[i]->comment, comment);
2853 ServicePtrs[i]->autoloaded = True;
2858 /***************************************************************************
2859 Announce ourselves as a print server.
2860 ***************************************************************************/
2862 void update_server_announce_as_printserver(void)
2864 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2867 /***************************************************************************
2868 Have we loaded a services file yet?
2869 ***************************************************************************/
2871 BOOL lp_loaded(void)
2876 /***************************************************************************
2877 Unload unused services.
2878 ***************************************************************************/
2880 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2883 for (i = 0; i < iNumServices; i++) {
2887 if (!snumused || !snumused(smb, i)) {
2888 ServicePtrs[i]->valid = False;
2889 free_service(ServicePtrs[i]);
2894 /***************************************************************************
2896 ***************************************************************************/
2898 void lp_killservice(int iServiceIn)
2900 if (VALID(iServiceIn)) {
2901 ServicePtrs[iServiceIn]->valid = False;
2902 free_service(ServicePtrs[iServiceIn]);
2906 /***************************************************************************
2907 Save the curent values of all global and sDefault parameters into the
2908 defaults union. This allows swat and testparm to show only the
2909 changed (ie. non-default) parameters.
2910 ***************************************************************************/
2912 static void lp_save_defaults(void)
2915 for (i = 0; parm_table[i].label; i++) {
2916 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2918 switch (parm_table[i].type) {
2920 str_list_copy(&(parm_table[i].def.lvalue),
2921 *(const char ***)parm_table[i].ptr);
2925 if (parm_table[i].ptr) {
2926 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2928 parm_table[i].def.svalue = NULL;
2933 parm_table[i].def.bvalue =
2934 *(BOOL *)parm_table[i].ptr;
2937 parm_table[i].def.cvalue =
2938 *(char *)parm_table[i].ptr;
2943 parm_table[i].def.ivalue =
2944 *(int *)parm_table[i].ptr;
2950 defaults_saved = True;
2953 /*******************************************************************
2954 Set the server type we will announce as via nmbd.
2955 ********************************************************************/
2957 static void set_server_role(void)
2959 server_role = ROLE_STANDALONE;
2961 switch (lp_security()) {
2963 if (lp_domain_logons())
2964 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2969 if (lp_domain_logons()) {
2970 if (Globals.bDomainMaster) /* auto or yes */
2971 server_role = ROLE_DOMAIN_PDC;
2973 server_role = ROLE_DOMAIN_BDC;
2976 server_role = ROLE_DOMAIN_MEMBER;
2979 if (lp_domain_logons()) {
2981 if (Globals.bDomainMaster) /* auto or yes */
2982 server_role = ROLE_DOMAIN_PDC;
2984 server_role = ROLE_DOMAIN_BDC;
2988 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2992 DEBUG(10, ("set_server_role: role = "));
2994 switch(server_role) {
2995 case ROLE_STANDALONE:
2996 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2998 case ROLE_DOMAIN_MEMBER:
2999 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3001 case ROLE_DOMAIN_BDC:
3002 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3004 case ROLE_DOMAIN_PDC:
3005 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3010 /***************************************************************************
3011 Load the services array from the services file. Return True on success,
3013 ***************************************************************************/
3015 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3020 struct param_opt *data;
3022 pstrcpy(n2, pszFname);
3023 standard_sub_basic(n2,sizeof(n2));
3025 add_to_file_list(pszFname, n2);
3029 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3031 bInGlobalSection = True;
3032 bGlobalOnly = global_only;
3034 if (Globals.param_opt != NULL) {
3035 struct param_opt *next;
3036 for (data=Globals.param_opt; data; data=next) {
3038 if (data->flags & FLAG_CMDLINE) continue;
3041 DLIST_REMOVE(Globals.param_opt, data);
3053 /* We get sections first, so have to start 'behind' to make up */
3055 bRetval = pm_process(n2, do_section, do_parameter);
3057 /* finish up the last section */
3058 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3060 if (iServiceIndex >= 0)
3061 bRetval = service_ok(iServiceIndex);
3063 lp_add_auto_services(lp_auto_services());
3066 /* When 'restrict anonymous = 2' guest connections to ipc$
3068 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3069 lp_add_hidden("ADMIN$", "DISK", False);
3073 set_default_server_announce_type();
3077 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3078 /* if bWINSsupport is true and we are in the client */
3079 if (in_client && Globals.bWINSsupport) {
3080 lp_do_parameter(-1, "wins server", "127.0.0.1");
3088 /***************************************************************************
3089 Reset the max number of services.
3090 ***************************************************************************/
3092 void lp_resetnumservices(void)
3097 /***************************************************************************
3098 Return the max number of services.
3099 ***************************************************************************/
3101 int lp_numservices(void)
3103 return (iNumServices);
3106 /***************************************************************************
3107 Display the contents of the services array in human-readable form.
3108 ***************************************************************************/
3110 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3115 defaults_saved = False;
3119 dump_a_service(&sDefault, f);
3121 for (iService = 0; iService < maxtoprint; iService++)
3122 lp_dump_one(f, show_defaults, iService);
3125 /***************************************************************************
3126 Display the contents of one service in human-readable form.
3127 ***************************************************************************/
3129 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3132 if (ServicePtrs[snum]->szService[0] == '\0')
3134 dump_a_service(ServicePtrs[snum], f);
3138 /***************************************************************************
3139 Return the number of the service with the given name, or -1 if it doesn't
3140 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3141 getservicebyname()! This works ONLY if all services have been loaded, and
3142 does not copy the found service.
3143 ***************************************************************************/
3145 int lp_servicenumber(const char *pszServiceName)
3148 fstring serviceName;
3151 for (iService = iNumServices - 1; iService >= 0; iService--) {
3152 if (VALID(iService) && ServicePtrs[iService]->szService) {
3154 * The substitution here is used to support %U is
3157 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3158 standard_sub_basic(serviceName,sizeof(serviceName));
3159 if (strequal(serviceName, pszServiceName))
3165 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3170 /*******************************************************************
3171 A useful volume label function.
3172 ********************************************************************/
3173 const char *volume_label(int snum)
3175 const char *ret = lp_volume(snum);
3177 return lp_servicename(snum);
3182 /*******************************************************************
3183 Set the server type we will announce as via nmbd.
3184 ********************************************************************/
3186 static void set_default_server_announce_type(void)
3188 default_server_announce = 0;
3189 default_server_announce |= SV_TYPE_WORKSTATION;
3190 default_server_announce |= SV_TYPE_SERVER;
3191 default_server_announce |= SV_TYPE_SERVER_UNIX;
3193 switch (lp_announce_as()) {
3194 case ANNOUNCE_AS_NT_SERVER:
3195 default_server_announce |= SV_TYPE_SERVER_NT;
3196 /* fall through... */
3197 case ANNOUNCE_AS_NT_WORKSTATION:
3198 default_server_announce |= SV_TYPE_NT;
3200 case ANNOUNCE_AS_WIN95:
3201 default_server_announce |= SV_TYPE_WIN95_PLUS;
3203 case ANNOUNCE_AS_WFW:
3204 default_server_announce |= SV_TYPE_WFW;
3210 switch (lp_server_role()) {
3211 case ROLE_DOMAIN_MEMBER:
3212 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3214 case ROLE_DOMAIN_PDC:
3215 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3217 case ROLE_DOMAIN_BDC:
3218 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3220 case ROLE_STANDALONE:
3224 if (lp_time_server())
3225 default_server_announce |= SV_TYPE_TIME_SOURCE;
3227 if (lp_host_msdfs())
3228 default_server_announce |= SV_TYPE_DFS_SERVER;
3231 /***********************************************************
3232 returns role of Samba server
3233 ************************************************************/
3235 int lp_server_role(void)
3240 /***********************************************************
3241 If we are PDC then prefer us as DMB
3242 ************************************************************/
3244 BOOL lp_domain_master(void)
3246 if (Globals.bDomainMaster == Auto)
3247 return (lp_server_role() == ROLE_DOMAIN_PDC);
3249 return Globals.bDomainMaster;
3252 /***********************************************************
3253 If we are DMB then prefer us as LMB
3254 ************************************************************/
3256 BOOL lp_preferred_master(void)
3258 if (Globals.bPreferredMaster == Auto)
3259 return (lp_local_master() && lp_domain_master());
3261 return Globals.bPreferredMaster;
3264 /*******************************************************************
3266 ********************************************************************/
3268 void lp_remove_service(int snum)
3270 ServicePtrs[snum]->valid = False;
3273 /*******************************************************************
3275 ********************************************************************/
3277 void lp_copy_service(int snum, const char *new_name)
3279 const char *oldname = lp_servicename(snum);
3280 do_section(new_name);
3282 snum = lp_servicenumber(new_name);
3284 lp_do_parameter(snum, "copy", oldname);
3289 /*******************************************************************
3290 Get the default server type we will announce as via nmbd.
3291 ********************************************************************/
3292 int lp_default_server_announce(void)
3294 return default_server_announce;
3297 const char *lp_printername(int snum)
3299 const char *ret = _lp_printername(snum);
3300 if (ret == NULL || (ret != NULL && *ret == '\0'))
3301 ret = lp_const_servicename(snum);
3307 /*******************************************************************
3308 Return the max print jobs per queue.
3309 ********************************************************************/
3311 int lp_maxprintjobs(int snum)
3313 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3314 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3315 maxjobs = PRINT_MAX_JOBID - 1;