2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
56 #include "dynconfig.h"
57 #include "system/time.h"
58 #include "system/iconv.h"
59 #include "system/network.h"
60 #include "system/printing.h"
61 #include "librpc/gen_ndr/ndr_svcctl.h"
62 #include "dlinklist.h"
64 BOOL in_client = False; /* Not in the client by default */
65 static BOOL bLoaded = False;
68 #define GLOBAL_NAME "global"
72 #define PRINTERS_NAME "printers"
76 #define HOMES_NAME "homes"
79 /* some helpful bits */
80 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
81 #define VALID(i) ServicePtrs[i]->valid
83 static BOOL do_parameter(const char *, const char *);
84 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
86 static BOOL defaults_saved = False;
89 #define FLAG_BASIC 0x0001 /* fundamental options */
90 #define FLAG_SHARE 0x0002 /* file sharing options */
91 #define FLAG_PRINT 0x0004 /* printing options */
92 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
93 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
94 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
95 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
96 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
97 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
98 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
99 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
102 /* the following are used by loadparm for option lists */
105 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
106 P_STRING,P_USTRING,P_ENUM,P_SEP
111 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
125 BOOL (*special)(const char *, char **);
126 const struct enum_list *enum_list;
139 struct param_opt *prev, *next;
146 * This structure describes global (ie., server-wide) parameters.
154 char *display_charset;
155 char *szPrintcapname;
159 char *szDefaultService;
161 char *szServerString;
162 char *szAutoServices;
163 char *szPasswdProgram;
167 char *szSMBPasswdFile;
171 char **szPreloadModules;
172 char *szPasswordServer;
173 char *szSocketOptions;
180 char **szWINSservers;
182 char *szRemoteAnnounce;
183 char *szRemoteBrowseSync;
184 char *szSocketAddress;
185 char *szAnnounceVersion; /* This is initialised in init_globals */
188 char **szNetbiosAliases;
189 char *szNetbiosScope;
190 char *szDomainOtherSIDs;
191 char *szNameResolveOrder;
193 char *szAddUserScript;
194 char *szAddMachineScript;
196 char *szWINSPartners;
197 char **dcerpc_ep_servers;
198 char **server_services;
201 char *szNonUnixAccountRange;
202 char *szTemplateHomedir;
203 char *szTemplateShell;
204 char *szWinbindSeparator;
205 BOOL bWinbindEnumUsers;
206 BOOL bWinbindEnumGroups;
207 BOOL bWinbindUseDefaultDomain;
208 char *szIDMapBackend;
209 char *szGuestaccount;
218 BOOL paranoid_server_security;
220 BOOL bDisableSpoolss;
222 int enhanced_browsing;
229 int announce_as; /* This is initialised in init_globals */
230 int machine_password_timeout;
231 int winbind_cache_time;
234 char *socket_options;
239 BOOL bPreferredMaster;
242 BOOL bEncryptPasswords;
244 BOOL bObeyPamRestrictions;
246 BOOL bLargeReadwrite;
250 BOOL bBindInterfacesOnly;
251 BOOL bPamPasswordChange;
253 BOOL bNTStatusSupport;
254 BOOL bAllowTrustedDomains;
260 BOOL bClientLanManAuth;
261 BOOL bClientNTLMv2Auth;
263 BOOL bHideLocalUsers;
266 BOOL bHostnameLookups;
267 BOOL bUnixExtensions;
268 BOOL bDisableNetbios;
270 int restrict_anonymous;
271 int name_cache_timeout;
272 struct param_opt *param_opt;
276 static global Globals;
279 * This structure describes a single service.
288 char **szInvalidUsers;
293 char *szPrintcommand;
296 char *szLppausecommand;
297 char *szLpresumecommand;
298 char *szQueuepausecommand;
299 char *szQueueresumecommand;
307 char **ntvfs_handler;
333 struct param_opt *param_opt;
335 char dummy[3]; /* for alignment */
340 /* This is a default service used to prime a services structure */
341 static service sDefault = {
343 False, /* not autoloaded */
344 NULL, /* szService */
346 NULL, /* szUsername */
347 NULL, /* szInvalidUsers */
348 NULL, /* szValidUsers */
349 NULL, /* szAdminUsers */
351 NULL, /* szInclude */
352 NULL, /* szPrintcommand */
353 NULL, /* szLpqcommand */
354 NULL, /* szLprmcommand */
355 NULL, /* szLppausecommand */
356 NULL, /* szLpresumecommand */
357 NULL, /* szQueuepausecommand */
358 NULL, /* szQueueresumecommand */
359 NULL, /* szPrintername */
360 NULL, /* szHostsallow */
361 NULL, /* szHostsdeny */
365 NULL, /* szMSDfsProxy */
366 NULL, /* ntvfs_handler */
367 0, /* iMinPrintSpace */
368 1000, /* iMaxPrintJobs */
369 0, /* iMaxConnections */
370 DEFAULT_PRINTING, /* iPrinting */
372 True, /* bAvailable */
373 True, /* bBrowseable */
374 True, /* bRead_only */
375 False, /* bPrint_ok */
376 False, /* bMap_system */
377 False, /* bMap_hidden */
378 True, /* bMap_archive */
380 True, /* bStrictLocking */
381 True, /* bPosixLocking */
383 True, /* bLevel2OpLocks */
384 False, /* bOnlyUser */
385 False, /* bGuest_only */
386 False, /* bGuest_ok */
388 False, /* bMSDfsRoot */
389 True, /* bShareModes */
390 False, /* bStrictSync */
391 False, /* bCIFileSystem */
392 NULL, /* Parametric options */
397 /* local variables */
398 static service **ServicePtrs = NULL;
399 static int iNumServices = 0;
400 static int iServiceIndex = 0;
401 static BOOL bInGlobalSection = True;
402 static BOOL bGlobalOnly = False;
403 static int server_role;
404 static int default_server_announce;
406 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
408 /* prototypes for the special type handlers */
409 static BOOL handle_include(const char *pszParmValue, char **ptr);
410 static BOOL handle_copy(const char *pszParmValue, char **ptr);
411 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
412 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
413 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
415 static void set_server_role(void);
416 static void set_default_server_announce_type(void);
418 static const struct enum_list enum_protocol[] = {
419 {PROTOCOL_NT1, "NT1"},
420 {PROTOCOL_LANMAN2, "LANMAN2"},
421 {PROTOCOL_LANMAN1, "LANMAN1"},
422 {PROTOCOL_CORE, "CORE"},
423 {PROTOCOL_COREPLUS, "COREPLUS"},
424 {PROTOCOL_COREPLUS, "CORE+"},
428 static const struct enum_list enum_security[] = {
429 {SEC_SHARE, "SHARE"},
431 {SEC_SERVER, "SERVER"},
432 {SEC_DOMAIN, "DOMAIN"},
439 static const struct enum_list enum_printing[] = {
440 {PRINT_SYSV, "sysv"},
442 {PRINT_HPUX, "hpux"},
446 {PRINT_LPRNG, "lprng"},
447 {PRINT_SOFTQ, "softq"},
448 {PRINT_CUPS, "cups"},
450 {PRINT_LPROS2, "os2"},
452 {PRINT_TEST, "test"},
454 #endif /* DEVELOPER */
458 /* Types of machine we can announce as. */
459 #define ANNOUNCE_AS_NT_SERVER 1
460 #define ANNOUNCE_AS_WIN95 2
461 #define ANNOUNCE_AS_WFW 3
462 #define ANNOUNCE_AS_NT_WORKSTATION 4
464 static const struct enum_list enum_announce_as[] = {
465 {ANNOUNCE_AS_NT_SERVER, "NT"},
466 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
467 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
468 {ANNOUNCE_AS_WIN95, "win95"},
469 {ANNOUNCE_AS_WFW, "WfW"},
473 static const struct enum_list enum_case[] = {
474 {CASE_LOWER, "lower"},
475 {CASE_UPPER, "upper"},
479 static const struct enum_list enum_bool_auto[] = {
490 /* Client-side offline caching policy types */
491 #define CSC_POLICY_MANUAL 0
492 #define CSC_POLICY_DOCUMENTS 1
493 #define CSC_POLICY_PROGRAMS 2
494 #define CSC_POLICY_DISABLE 3
496 static const struct enum_list enum_csc_policy[] = {
497 {CSC_POLICY_MANUAL, "manual"},
498 {CSC_POLICY_DOCUMENTS, "documents"},
499 {CSC_POLICY_PROGRAMS, "programs"},
500 {CSC_POLICY_DISABLE, "disable"},
504 /* SMB signing types. */
505 static const struct enum_list enum_smb_signing_vals[] = {
506 {SMB_SIGNING_OFF, "No"},
507 {SMB_SIGNING_OFF, "False"},
508 {SMB_SIGNING_OFF, "0"},
509 {SMB_SIGNING_OFF, "Off"},
510 {SMB_SIGNING_OFF, "disabled"},
511 {SMB_SIGNING_SUPPORTED, "Yes"},
512 {SMB_SIGNING_SUPPORTED, "True"},
513 {SMB_SIGNING_SUPPORTED, "1"},
514 {SMB_SIGNING_SUPPORTED, "On"},
515 {SMB_SIGNING_SUPPORTED, "enabled"},
516 {SMB_SIGNING_REQUIRED, "required"},
517 {SMB_SIGNING_REQUIRED, "mandatory"},
518 {SMB_SIGNING_REQUIRED, "force"},
519 {SMB_SIGNING_REQUIRED, "forced"},
520 {SMB_SIGNING_REQUIRED, "enforced"},
521 {SMB_SIGNING_AUTO, "auto"},
526 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
528 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
529 * is implied in current control logic. This may change at some later time. A
530 * flag value of 0 means - show as development option only.
532 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
533 * screen in SWAT. This is used to exclude parameters as well as to squash all
534 * parameters that have been duplicated by pseudonyms.
536 static struct parm_struct parm_table[] = {
537 {"Base Options", P_SEP, P_SEPARATOR},
539 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
544 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
545 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
546 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
547 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
550 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
551 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
554 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
555 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
556 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
557 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
559 {"Security Options", P_SEP, P_SEPARATOR},
561 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
562 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
563 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
570 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
578 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
588 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
591 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
592 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
593 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
595 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
596 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
597 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
599 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
601 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
603 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
605 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
606 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
607 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
608 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
610 {"Logging Options", P_SEP, P_SEPARATOR},
612 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
614 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
616 {"Protocol Options", P_SEP, P_SEPARATOR},
618 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
619 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
620 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
621 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
622 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
623 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
624 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
625 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
627 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
629 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
630 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
631 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
635 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
636 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
637 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
638 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
639 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
640 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
641 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
642 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
643 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
645 {"Tuning Options", P_SEP, P_SEPARATOR},
647 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
648 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
649 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
650 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
652 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
653 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
654 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
656 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
657 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
658 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
660 {"Printing Options", P_SEP, P_SEPARATOR},
662 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
663 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
664 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
665 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
666 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
667 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
668 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
669 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
671 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
673 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
674 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
675 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
676 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
678 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
679 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
681 {"Filename Handling", P_SEP, P_SEPARATOR},
683 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
684 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
685 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
687 {"Domain Options", P_SEP, P_SEPARATOR},
689 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
691 {"Logon Options", P_SEP, P_SEPARATOR},
693 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
697 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"Browse Options", P_SEP, P_SEPARATOR},
704 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
706 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
708 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
709 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
712 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
713 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
715 {"WINS Options", P_SEP, P_SEPARATOR},
716 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
717 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
719 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
720 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
721 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
722 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
724 {"Locking Options", P_SEP, P_SEPARATOR},
726 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
727 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
729 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
731 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
732 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
733 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
734 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
735 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
737 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
739 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
740 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
743 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
748 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
750 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
751 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
752 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
754 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
755 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
757 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
758 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
759 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
761 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
762 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
765 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
766 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"Winbind options", P_SEP, P_SEPARATOR},
769 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
782 /***************************************************************************
783 Initialise the sDefault parameter structure for the printer values.
784 ***************************************************************************/
786 static void init_printer_values(void)
788 /* choose defaults depending on the type of printing */
789 switch (sDefault.iPrinting) {
794 do_parameter("Lpqcommand", "lpq -P'%p'");
795 do_parameter("Lprmcommand", "lprm -P'%p' %j");
796 do_parameter("Printcommand",
802 do_parameter("Lpqcommand", "lpq -P'%p'");
803 do_parameter("Lprmcommand", "lprm -P'%p' %j");
804 do_parameter("Printcommand",
806 do_parameter("Queuepausecommand",
808 do_parameter("Queueresumecommand",
810 do_parameter("Lppausecommand",
812 do_parameter("Lpresumecommand",
813 "lpc release '%p' %j");
818 do_parameter("Lpqcommand", "");
819 do_parameter("Lprmcommand", "");
820 do_parameter("Printcommand", "");
821 do_parameter("Lppausecommand", "");
822 do_parameter("Lpresumecommand", "");
823 do_parameter("Queuepausecommand", "");
824 do_parameter("Queueresumecommand", "");
826 do_parameter("Printcapname", "cups");
828 do_parameter("Lpqcommand",
829 "/usr/bin/lpstat -o '%p'");
830 do_parameter("Lprmcommand",
831 "/usr/bin/cancel '%p-%j'");
832 do_parameter("Printcommand",
833 "/usr/bin/lp -d '%p' %s; rm %s");
834 do_parameter("Lppausecommand",
835 "lp -i '%p-%j' -H hold");
836 do_parameter("Lpresumecommand",
837 "lp -i '%p-%j' -H resume");
838 do_parameter("Queuepausecommand",
839 "/usr/bin/disable '%p'");
840 do_parameter("Queueresumecommand",
841 "/usr/bin/enable '%p'");
842 do_parameter("Printcapname", "lpstat");
843 #endif /* HAVE_CUPS */
848 do_parameter("Lpqcommand", "lpstat -o%p");
849 do_parameter("Lprmcommand", "cancel %p-%j");
850 do_parameter("Printcommand",
851 "lp -c -d%p %s; rm %s");
852 do_parameter("Queuepausecommand",
854 do_parameter("Queueresumecommand",
857 do_parameter("Lppausecommand",
858 "lp -i %p-%j -H hold");
859 do_parameter("Lpresumecommand",
860 "lp -i %p-%j -H resume");
865 do_parameter("Lpqcommand", "lpq -P%p");
866 do_parameter("Lprmcommand", "lprm -P%p %j");
867 do_parameter("Printcommand", "lp -r -P%p %s");
871 do_parameter("Lpqcommand", "qstat -l -d%p");
872 do_parameter("Lprmcommand",
874 do_parameter("Printcommand",
875 "lp -d%p -s %s; rm %s");
876 do_parameter("Lppausecommand",
878 do_parameter("Lpresumecommand",
884 do_parameter("Printcommand", "vlp print %p %s");
885 do_parameter("Lpqcommand", "vlp lpq %p");
886 do_parameter("Lprmcommand", "vlp lprm %p %j");
887 do_parameter("Lppausecommand", "vlp lppause %p %j");
888 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
889 do_parameter("Queuepausecommand", "vlp queuepause %p");
890 do_parameter("Queueresumecommand", "vlp queueresume %p");
892 #endif /* DEVELOPER */
898 /***************************************************************************
899 Initialise the global parameter structure.
900 ***************************************************************************/
901 static void init_globals(void)
905 DEBUG(3, ("Initialising global parameters\n"));
907 for (i = 0; parm_table[i].label; i++) {
908 if ((parm_table[i].type == P_STRING ||
909 parm_table[i].type == P_USTRING) &&
911 !(parm_table[i].flags & FLAG_CMDLINE)) {
912 string_set(parm_table[i].ptr, "");
916 /* options that can be set on the command line must be initialised via
917 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
919 do_parameter("socket options", "TCP_NODELAY");
921 do_parameter("workgroup", DEFAULT_WORKGROUP);
922 do_parameter("netbios name", get_myname());
923 do_parameter("max protocol", "NT1");
924 do_parameter("name resolve order", "lmhosts wins host bcast");
926 init_printer_values();
928 do_parameter("fstype", FSTYPE_STRING);
929 do_parameter("ntvfs handler", "unixuid default");
931 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg IOXIDResolver IRemoteActivation");
932 do_parameter("server services", "smb rpc");
933 do_parameter("auth methods", "guest 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("guest account", GUEST_ACCOUNT);
940 /* using UTF8 by default allows us to support all chars */
941 do_parameter("unix charset", "UTF8");
943 /* Use codepage 850 as a default for the dos character set */
944 do_parameter("dos charset", "CP850");
947 * Allow the default PASSWD_CHAT to be overridden in local.h.
949 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
951 do_parameter("passwd program", "");
952 do_parameter("printcap name", PRINTCAP_NAME);
954 do_parameter("pid directory", dyn_PIDDIR);
955 do_parameter("lock dir", dyn_LOCKDIR);
956 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
958 do_parameter("socket address", "0.0.0.0");
959 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
961 do_parameter_var("announce version", "%d.%d",
962 DEFAULT_MAJOR_VERSION,
963 DEFAULT_MINOR_VERSION);
965 do_parameter("logon drive", "");
967 do_parameter("logon home", "\\\\%N\\%U");
968 do_parameter("logon path", "\\\\%N\\%U\\profile");
969 do_parameter("password server", "*");
971 do_parameter("load printers", "True");
973 do_parameter("max mux", "50");
974 do_parameter("max xmit", "12288");
975 do_parameter("lpqcachetime", "10");
976 do_parameter("DisableSpoolss", "False");
977 do_parameter("password level", "0");
978 do_parameter("username level", "0");
979 do_parameter("LargeReadwrite", "True");
980 do_parameter("minprotocol", "CORE");
981 do_parameter("security", "USER");
982 do_parameter("paranoid server security", "True");
983 do_parameter("EncryptPasswords", "True");
984 do_parameter("ReadRaw", "True");
985 do_parameter("WriteRaw", "True");
986 do_parameter("NullPasswords", "False");
987 do_parameter("ObeyPamRestrictions", "False");
988 do_parameter("lm announce", "Auto");
989 do_parameter("lm interval", "60");
990 do_parameter("announce as", "NT SERVER");
992 do_parameter("TimeServer", "False");
993 do_parameter("BindInterfacesOnly", "False");
994 do_parameter("PamPasswordChange", "False");
995 do_parameter("Unicode", "True");
996 do_parameter("restrict anonymous", "0");
997 do_parameter("ClientLanManAuth", "True");
998 do_parameter("LanmanAuth", "True");
999 do_parameter("NTLMAuth", "True");
1001 do_parameter("enhanced browsing", "True");
1002 do_parameter("LockSpinCount", "3");
1003 do_parameter("LockSpinTime", "10");
1004 #ifdef MMAP_BLACKLIST
1005 do_parameter("UseMmap", "False");
1007 do_parameter("UseMmap", "True");
1009 do_parameter("UnixExtensions", "False");
1011 /* hostname lookups can be very expensive and are broken on
1012 a large number of sites (tridge) */
1013 do_parameter("HostnameLookups", "False");
1015 do_parameter("PreferredMaster", "Auto");
1016 do_parameter("os level", "20");
1017 do_parameter("LocalMaster", "True");
1018 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1019 do_parameter("DomainLogons", "False");
1020 do_parameter("WINSsupport", "False");
1021 do_parameter("WINSproxy", "False");
1023 do_parameter("DNSproxy", "True");
1025 do_parameter("AllowTrustedDomains", "True");
1027 do_parameter("TemplateShell", "/bin/false");
1028 do_parameter("TemplateHomedir", "/home/%D/%U");
1029 do_parameter("WinbindSeparator", "\\");
1031 do_parameter("winbind cache time", "15");
1032 do_parameter("WinbindEnumUsers", "True");
1033 do_parameter("WinbindEnumGroups", "True");
1034 do_parameter("WinbindUseDefaultDomain", "False");
1036 do_parameter("IDMapBackend", "tdb");
1038 do_parameter("name cache timeout", "660"); /* In seconds */
1040 do_parameter("client signing", "Yes");
1041 do_parameter("server signing", "auto");
1043 do_parameter("use spnego", "True");
1045 do_parameter("smb ports", SMB_PORTS);
1047 do_parameter("nt status support", "True");
1050 static TALLOC_CTX *lp_talloc;
1052 /******************************************************************* a
1053 Free up temporary memory - called from the main loop.
1054 ********************************************************************/
1056 void lp_talloc_free(void)
1060 talloc_free(lp_talloc);
1064 /*******************************************************************
1065 Convenience routine to grab string parameters into temporary memory
1066 and run standard_sub_basic on them. The buffers can be written to by
1067 callers without affecting the source string.
1068 ********************************************************************/
1070 static const char *lp_string(const char *s)
1072 #if 0 /* until REWRITE done to make thread-safe */
1073 size_t len = s ? strlen(s) : 0;
1077 /* The follow debug is useful for tracking down memory problems
1078 especially if you have an inner loop that is calling a lp_*()
1079 function that returns a string. Perhaps this debug should be
1080 present all the time? */
1083 DEBUG(10, ("lp_string(%s)\n", s));
1086 #if 0 /* until REWRITE done to make thread-safe */
1088 lp_talloc = talloc_init("lp_talloc");
1090 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1098 StrnCpy(ret, s, len);
1100 if (trim_string(ret, "\"", "\"")) {
1101 if (strchr(ret,'"') != NULL)
1102 StrnCpy(ret, s, len);
1105 standard_sub_basic(ret,len+100);
1112 In this section all the functions that are used to access the
1113 parameters from the rest of the program are defined
1116 #define FN_GLOBAL_STRING(fn_name,ptr) \
1117 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1118 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1119 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1120 #define FN_GLOBAL_LIST(fn_name,ptr) \
1121 const char **fn_name(void) {return(*(const char ***)(ptr));}
1122 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1123 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1124 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1125 char fn_name(void) {return(*(char *)(ptr));}
1126 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1127 int fn_name(void) {return(*(int *)(ptr));}
1129 #define FN_LOCAL_STRING(fn_name,val) \
1130 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1131 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1132 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1133 #define FN_LOCAL_LIST(fn_name,val) \
1134 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1135 #define FN_LOCAL_BOOL(fn_name,val) \
1136 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1137 #define FN_LOCAL_CHAR(fn_name,val) \
1138 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1139 #define FN_LOCAL_INTEGER(fn_name,val) \
1140 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1142 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1143 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1144 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1145 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1146 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1147 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1148 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1149 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1150 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1151 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1152 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1153 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1154 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1155 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1156 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1157 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1158 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1159 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1160 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1161 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1162 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1163 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1164 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1165 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1166 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1167 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1168 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1169 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1170 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1171 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1172 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1173 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1174 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1175 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1176 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1177 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1178 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1179 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1180 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1181 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1182 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
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)
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)
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 = (service **) Realloc(ServicePtrs,
1583 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1588 ServicePtrs[iNumServices] =
1589 (service *) malloc(sizeof(service));
1591 if (!ServicePtrs[iNumServices]) {
1592 DEBUG(0,("add_a_service: out of memory!\n"));
1598 free_service(ServicePtrs[i]);
1600 ServicePtrs[i]->valid = True;
1602 init_service(ServicePtrs[i]);
1603 copy_service(ServicePtrs[i], &tservice, NULL);
1605 string_set(&ServicePtrs[i]->szService, name);
1609 /***************************************************************************
1610 Add a new home service, with the specified home directory, defaults coming
1612 ***************************************************************************/
1614 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1615 const char *user, const char *pszHomedir)
1620 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1625 if (!(*(ServicePtrs[iDefaultService]->szPath))
1626 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1627 pstrcpy(newHomedir, pszHomedir);
1629 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1630 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1633 string_set(&ServicePtrs[i]->szPath, newHomedir);
1635 if (!(*(ServicePtrs[i]->comment))) {
1637 slprintf(comment, sizeof(comment) - 1,
1638 "Home directory of %s", user);
1639 string_set(&ServicePtrs[i]->comment, comment);
1641 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1642 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1644 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1650 /***************************************************************************
1651 Add a new service, based on an old one.
1652 ***************************************************************************/
1654 int lp_add_service(const char *pszService, int iDefaultService)
1656 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1659 /***************************************************************************
1660 Add the IPC service.
1661 ***************************************************************************/
1663 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1666 int i = add_a_service(&sDefault, ipc_name);
1671 slprintf(comment, sizeof(comment) - 1,
1672 "IPC Service (%s)", Globals.szServerString);
1674 string_set(&ServicePtrs[i]->szPath, tmpdir());
1675 string_set(&ServicePtrs[i]->szUsername, "");
1676 string_set(&ServicePtrs[i]->comment, comment);
1677 string_set(&ServicePtrs[i]->fstype, "IPC");
1678 ServicePtrs[i]->iMaxConnections = 0;
1679 ServicePtrs[i]->bAvailable = True;
1680 ServicePtrs[i]->bRead_only = True;
1681 ServicePtrs[i]->bGuest_only = False;
1682 ServicePtrs[i]->bGuest_ok = guest_ok;
1683 ServicePtrs[i]->bPrint_ok = False;
1684 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1686 lp_do_parameter(i, "ntvfs handler", "default");
1688 DEBUG(3, ("adding IPC service\n"));
1693 /***************************************************************************
1694 Add a new printer service, with defaults coming from service iFrom.
1695 ***************************************************************************/
1697 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1699 const char *comment = "From Printcap";
1700 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1705 /* note that we do NOT default the availability flag to True - */
1706 /* we take it from the default service passed. This allows all */
1707 /* dynamic printers to be disabled by disabling the [printers] */
1708 /* entry (if/when the 'available' keyword is implemented!). */
1710 /* the printer name is set to the service name. */
1711 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1712 string_set(&ServicePtrs[i]->comment, comment);
1713 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1714 /* Printers cannot be read_only. */
1715 ServicePtrs[i]->bRead_only = False;
1716 /* No share modes on printer services. */
1717 ServicePtrs[i]->bShareModes = False;
1718 /* No oplocks on printer services. */
1719 ServicePtrs[i]->bOpLocks = False;
1720 /* Printer services must be printable. */
1721 ServicePtrs[i]->bPrint_ok = True;
1723 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1725 update_server_announce_as_printserver();
1730 /***************************************************************************
1731 Map a parameter's string representation to something we can use.
1732 Returns False if the parameter string is not recognised, else TRUE.
1733 ***************************************************************************/
1735 static int map_parameter(const char *pszParmName)
1739 if (*pszParmName == '-')
1742 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1743 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1746 /* Warn only if it isn't parametric option */
1747 if (strchr(pszParmName, ':') == NULL)
1748 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1749 /* We do return 'fail' for parametric options as well because they are
1750 stored in different storage
1755 /***************************************************************************
1756 Set a boolean variable from the text value stored in the passed string.
1757 Returns True in success, False if the passed string does not correctly
1758 represent a boolean.
1759 ***************************************************************************/
1761 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1766 if (strwicmp(pszParmValue, "yes") == 0 ||
1767 strwicmp(pszParmValue, "true") == 0 ||
1768 strwicmp(pszParmValue, "1") == 0)
1770 else if (strwicmp(pszParmValue, "no") == 0 ||
1771 strwicmp(pszParmValue, "False") == 0 ||
1772 strwicmp(pszParmValue, "0") == 0)
1776 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1783 /***************************************************************************
1784 Find a service by name. Otherwise works like get_service.
1785 ***************************************************************************/
1787 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1791 for (iService = iNumServices - 1; iService >= 0; iService--)
1792 if (VALID(iService) &&
1793 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1794 if (pserviceDest != NULL)
1795 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1802 /***************************************************************************
1803 Copy a service structure to another.
1804 If pcopymapDest is NULL then copy all fields
1805 ***************************************************************************/
1807 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1810 BOOL bcopyall = (pcopymapDest == NULL);
1811 struct param_opt *data, *pdata, *paramo;
1814 for (i = 0; parm_table[i].label; i++)
1815 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1816 (bcopyall || pcopymapDest[i])) {
1817 void *def_ptr = parm_table[i].ptr;
1819 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1822 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1825 switch (parm_table[i].type) {
1828 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1834 *(int *)dest_ptr = *(int *)src_ptr;
1838 *(char *)dest_ptr = *(char *)src_ptr;
1842 string_set(dest_ptr,
1847 string_set(dest_ptr,
1849 strupper(*(char **)dest_ptr);
1852 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1860 init_copymap(pserviceDest);
1861 if (pserviceSource->copymap)
1862 memcpy((void *)pserviceDest->copymap,
1863 (void *)pserviceSource->copymap,
1864 sizeof(BOOL) * NUMPARAMETERS);
1867 data = pserviceSource->param_opt;
1870 pdata = pserviceDest->param_opt;
1871 /* Traverse destination */
1873 /* If we already have same option, override it */
1874 if (strcmp(pdata->key, data->key) == 0) {
1875 string_free(&pdata->value);
1876 pdata->value = strdup(data->value);
1880 pdata = pdata->next;
1883 paramo = smb_xmalloc(sizeof(*paramo));
1884 paramo->key = strdup(data->key);
1885 paramo->value = strdup(data->value);
1886 DLIST_ADD(pserviceDest->param_opt, paramo);
1892 /***************************************************************************
1893 Check a service for consistency. Return False if the service is in any way
1894 incomplete or faulty, else True.
1895 ***************************************************************************/
1897 static BOOL service_ok(int iService)
1902 if (ServicePtrs[iService]->szService[0] == '\0') {
1903 DEBUG(0, ("The following message indicates an internal error:\n"));
1904 DEBUG(0, ("No service name in service entry.\n"));
1908 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1909 /* I can't see why you'd want a non-printable printer service... */
1910 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1911 if (!ServicePtrs[iService]->bPrint_ok) {
1912 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1913 ServicePtrs[iService]->szService));
1914 ServicePtrs[iService]->bPrint_ok = True;
1916 /* [printers] service must also be non-browsable. */
1917 if (ServicePtrs[iService]->bBrowseable)
1918 ServicePtrs[iService]->bBrowseable = False;
1921 /* If a service is flagged unavailable, log the fact at level 0. */
1922 if (!ServicePtrs[iService]->bAvailable)
1923 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1924 ServicePtrs[iService]->szService));
1929 static struct file_lists {
1930 struct file_lists *next;
1934 } *file_lists = NULL;
1936 /*******************************************************************
1937 Keep a linked list of all config files so we know when one has changed
1938 it's date and needs to be reloaded.
1939 ********************************************************************/
1941 static void add_to_file_list(const char *fname, const char *subfname)
1943 struct file_lists *f = file_lists;
1946 if (f->name && !strcmp(f->name, fname))
1952 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1955 f->next = file_lists;
1956 f->name = strdup(fname);
1961 f->subfname = strdup(subfname);
1967 f->modtime = file_modtime(subfname);
1969 time_t t = file_modtime(subfname);
1975 /*******************************************************************
1976 Check if a config file has changed date.
1977 ********************************************************************/
1979 BOOL lp_file_list_changed(void)
1981 struct file_lists *f = file_lists;
1982 DEBUG(6, ("lp_file_list_changed()\n"));
1988 pstrcpy(n2, f->name);
1989 standard_sub_basic(n2,sizeof(n2));
1991 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1992 f->name, n2, ctime(&f->modtime)));
1994 mod_time = file_modtime(n2);
1996 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1998 ("file %s modified: %s\n", n2,
2000 f->modtime = mod_time;
2001 SAFE_FREE(f->subfname);
2002 f->subfname = strdup(n2);
2010 /***************************************************************************
2011 Handle the include operation.
2012 ***************************************************************************/
2014 static BOOL handle_include(const char *pszParmValue, char **ptr)
2017 pstrcpy(fname, pszParmValue);
2019 standard_sub_basic(fname,sizeof(fname));
2021 add_to_file_list(pszParmValue, fname);
2023 string_set(ptr, fname);
2025 if (file_exist(fname, NULL))
2026 return (pm_process(fname, do_section, do_parameter));
2028 DEBUG(2, ("Can't find include file %s\n", fname));
2033 /***************************************************************************
2034 Handle the interpretation of the copy parameter.
2035 ***************************************************************************/
2037 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2041 service serviceTemp;
2043 string_set(ptr, pszParmValue);
2045 init_service(&serviceTemp);
2049 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2051 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2052 if (iTemp == iServiceIndex) {
2053 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2055 copy_service(ServicePtrs[iServiceIndex],
2057 ServicePtrs[iServiceIndex]->copymap);
2061 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2065 free_service(&serviceTemp);
2069 /***************************************************************************
2070 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2075 winbind uid = 1000-1999
2076 winbind gid = 700-899
2078 We only do simple parsing checks here. The strings are parsed into useful
2079 structures in the winbind daemon code.
2081 ***************************************************************************/
2083 /* Some lp_ routines to return winbind [ug]id information */
2085 static uid_t winbind_uid_low, winbind_uid_high;
2086 static gid_t winbind_gid_low, winbind_gid_high;
2087 static uint32_t non_unix_account_low, non_unix_account_high;
2089 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2091 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2095 *low = winbind_uid_low;
2098 *high = winbind_uid_high;
2103 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2105 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2109 *low = winbind_gid_low;
2112 *high = winbind_gid_high;
2117 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2119 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2123 *low = non_unix_account_low;
2126 *high = non_unix_account_high;
2131 /* Do some simple checks on "winbind [ug]id" parameter values */
2133 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2137 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2142 string_set(ptr, pszParmValue);
2144 winbind_uid_low = low;
2145 winbind_uid_high = high;
2150 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2154 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2159 string_set(ptr, pszParmValue);
2161 winbind_gid_low = low;
2162 winbind_gid_high = high;
2167 /***************************************************************************
2168 Do some simple checks on "non unix account range" parameter values.
2169 ***************************************************************************/
2171 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2175 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2180 string_set(ptr, pszParmValue);
2182 non_unix_account_low = low;
2183 non_unix_account_high = high;
2189 /***************************************************************************
2190 Initialise a copymap.
2191 ***************************************************************************/
2193 static void init_copymap(service * pservice)
2196 SAFE_FREE(pservice->copymap);
2197 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2198 if (!pservice->copymap)
2200 ("Couldn't allocate copymap!! (size %d)\n",
2201 (int)NUMPARAMETERS));
2203 for (i = 0; i < NUMPARAMETERS; i++)
2204 pservice->copymap[i] = True;
2207 /***************************************************************************
2208 Return the local pointer to a parameter given the service number and the
2209 pointer into the default structure.
2210 ***************************************************************************/
2212 void *lp_local_ptr(int snum, void *ptr)
2214 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2218 /***************************************************************************
2219 Process a parametric option
2220 ***************************************************************************/
2221 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2223 struct param_opt *paramo, *data;
2226 while (isspace(*pszParmName)) {
2230 name = strdup(pszParmName);
2231 if (!name) return False;
2236 data = Globals.param_opt;
2238 data = ServicePtrs[snum]->param_opt;
2241 /* Traverse destination */
2242 for (paramo=data; paramo; paramo=paramo->next) {
2243 /* If we already have the option set, override it unless
2244 it was a command line option and the new one isn't */
2245 if (strcmp(paramo->key, name) == 0) {
2246 if ((paramo->flags & FLAG_CMDLINE) &&
2247 !(flags & FLAG_CMDLINE)) {
2251 free(paramo->value);
2252 paramo->value = strdup(pszParmValue);
2253 paramo->flags = flags;
2259 paramo = smb_xmalloc(sizeof(*paramo));
2260 paramo->key = strdup(name);
2261 paramo->value = strdup(pszParmValue);
2262 paramo->flags = flags;
2264 DLIST_ADD(Globals.param_opt, paramo);
2266 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2274 /***************************************************************************
2275 Process a parameter for a particular service number. If snum < 0
2276 then assume we are in the globals.
2277 ***************************************************************************/
2278 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2281 void *parm_ptr = NULL; /* where we are going to store the result */
2282 void *def_ptr = NULL;
2284 parmnum = map_parameter(pszParmName);
2287 if (strchr(pszParmName, ':')) {
2288 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2290 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2294 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2295 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2299 /* if the flag has been set on the command line, then don't allow override,
2300 but don't report an error */
2301 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2305 def_ptr = parm_table[parmnum].ptr;
2307 /* we might point at a service, the default service or a global */
2311 if (parm_table[parmnum].class == P_GLOBAL) {
2313 ("Global parameter %s found in service section!\n",
2318 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2323 if (!ServicePtrs[snum]->copymap)
2324 init_copymap(ServicePtrs[snum]);
2326 /* this handles the aliases - set the copymap for other entries with
2327 the same data pointer */
2328 for (i = 0; parm_table[i].label; i++)
2329 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2330 ServicePtrs[snum]->copymap[i] = False;
2333 /* if it is a special case then go ahead */
2334 if (parm_table[parmnum].special) {
2335 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2339 /* now switch on the type of variable it is */
2340 switch (parm_table[parmnum].type)
2343 set_boolean(parm_ptr, pszParmValue);
2347 set_boolean(parm_ptr, pszParmValue);
2348 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2352 *(int *)parm_ptr = atoi(pszParmValue);
2356 *(char *)parm_ptr = *pszParmValue;
2360 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2364 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2368 string_set(parm_ptr, pszParmValue);
2372 string_set(parm_ptr, pszParmValue);
2373 strupper(*(char **)parm_ptr);
2377 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2380 parm_table[parmnum].enum_list[i].name)) {
2382 parm_table[parmnum].
2387 if (!parm_table[parmnum].enum_list[i].name) {
2388 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2389 pszParmValue, pszParmName));
2400 /***************************************************************************
2401 Process a parameter.
2402 ***************************************************************************/
2404 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2406 if (!bInGlobalSection && bGlobalOnly)
2409 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2410 pszParmName, pszParmValue));
2414 variable argument do parameter
2416 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2418 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2425 s = talloc_vasprintf(NULL, fmt, ap);
2427 ret = do_parameter(pszParmName, s);
2434 set a parameter from the commandline - this is called from command line parameter
2435 parsing code. It sets the parameter then marks the parameter as unable to be modified
2436 by smb.conf processing
2438 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2440 int parmnum = map_parameter(pszParmName);
2443 while (isspace(*pszParmValue)) pszParmValue++;
2446 if (parmnum < 0 && strchr(pszParmName, ':')) {
2447 /* set a parametric option */
2448 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2452 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2456 /* reset the CMDLINE flag in case this has been called before */
2457 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2459 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2463 parm_table[parmnum].flags |= FLAG_CMDLINE;
2465 /* we have to also set FLAG_CMDLINE on aliases */
2466 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2467 parm_table[i].flags |= FLAG_CMDLINE;
2469 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2470 parm_table[i].flags |= FLAG_CMDLINE;
2477 set a option from the commandline in 'a=b' format. Use to support --option
2479 BOOL lp_set_option(const char *option)
2497 ret = lp_set_cmdline(s, p+1);
2503 /***************************************************************************
2504 Print a parameter of the specified type.
2505 ***************************************************************************/
2507 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2513 for (i = 0; p->enum_list[i].name; i++) {
2514 if (*(int *)ptr == p->enum_list[i].value) {
2516 p->enum_list[i].name);
2523 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2527 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2531 fprintf(f, "%d", *(int *)ptr);
2535 fprintf(f, "%c", *(char *)ptr);
2539 if (*(int *)ptr == -1) {
2542 fprintf(f, "0%o", *(int *)ptr);
2547 if ((char ***)ptr && *(char ***)ptr) {
2548 char **list = *(char ***)ptr;
2550 for (; *list; list++)
2551 fprintf(f, "%s%s", *list,
2552 ((*(list+1))?", ":""));
2558 if (*(char **)ptr) {
2559 fprintf(f, "%s", *(char **)ptr);
2567 /***************************************************************************
2568 Check if two parameters are equal.
2569 ***************************************************************************/
2571 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2576 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2581 return (*((int *)ptr1) == *((int *)ptr2));
2584 return (*((char *)ptr1) == *((char *)ptr2));
2587 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2592 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2597 return (p1 == p2 || strequal(p1, p2));
2605 /***************************************************************************
2606 Process a new section (service). At this stage all sections are services.
2607 Later we'll have special sections that permit server parameters to be set.
2608 Returns True on success, False on failure.
2609 ***************************************************************************/
2611 static BOOL do_section(const char *pszSectionName)
2614 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2615 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2618 /* if we've just struck a global section, note the fact. */
2619 bInGlobalSection = isglobal;
2621 /* check for multiple global sections */
2622 if (bInGlobalSection) {
2623 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2627 if (!bInGlobalSection && bGlobalOnly)
2630 /* if we have a current service, tidy it up before moving on */
2633 if (iServiceIndex >= 0)
2634 bRetval = service_ok(iServiceIndex);
2636 /* if all is still well, move to the next record in the services array */
2638 /* We put this here to avoid an odd message order if messages are */
2639 /* issued by the post-processing of a previous section. */
2640 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2642 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2644 DEBUG(0, ("Failed to add a new service\n"));
2653 /***************************************************************************
2654 Determine if a partcular base parameter is currentl set to the default value.
2655 ***************************************************************************/
2657 static BOOL is_default(int i)
2659 if (!defaults_saved)
2661 switch (parm_table[i].type) {
2663 return str_list_compare (parm_table[i].def.lvalue,
2664 *(char ***)parm_table[i].ptr);
2667 return strequal(parm_table[i].def.svalue,
2668 *(char **)parm_table[i].ptr);
2671 return parm_table[i].def.bvalue ==
2672 *(BOOL *)parm_table[i].ptr;
2674 return parm_table[i].def.cvalue ==
2675 *(char *)parm_table[i].ptr;
2679 return parm_table[i].def.ivalue ==
2680 *(int *)parm_table[i].ptr;
2687 /***************************************************************************
2688 Display the contents of the global structure.
2689 ***************************************************************************/
2691 static void dump_globals(FILE *f)
2694 struct param_opt *data;
2696 fprintf(f, "# Global parameters\n[global]\n");
2698 for (i = 0; parm_table[i].label; i++)
2699 if (parm_table[i].class == P_GLOBAL &&
2700 parm_table[i].ptr &&
2701 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2702 if (defaults_saved && is_default(i))
2704 fprintf(f, "\t%s = ", parm_table[i].label);
2705 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2708 if (Globals.param_opt != NULL) {
2709 data = Globals.param_opt;
2711 fprintf(f, "\t%s = %s\n", data->key, data->value);
2718 /***************************************************************************
2719 Display the contents of a single services record.
2720 ***************************************************************************/
2722 static void dump_a_service(service * pService, FILE * f)
2725 struct param_opt *data;
2727 if (pService != &sDefault)
2728 fprintf(f, "\n[%s]\n", pService->szService);
2730 for (i = 0; parm_table[i].label; i++)
2731 if (parm_table[i].class == P_LOCAL &&
2732 parm_table[i].ptr &&
2733 (*parm_table[i].label != '-') &&
2734 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2735 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2737 if (pService == &sDefault) {
2738 if (defaults_saved && is_default(i))
2741 if (equal_parameter(parm_table[i].type,
2742 ((char *)pService) +
2744 ((char *)&sDefault) +
2749 fprintf(f, "\t%s = ", parm_table[i].label);
2750 print_parameter(&parm_table[i],
2751 ((char *)pService) + pdiff, f);
2754 if (pService->param_opt != NULL) {
2755 data = pService->param_opt;
2757 fprintf(f, "\t%s = %s\n", data->key, data->value);
2764 /***************************************************************************
2765 Return info about the next service in a service. snum==-1 gives the globals.
2766 Return NULL when out of parameters.
2767 ***************************************************************************/
2769 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2772 /* do the globals */
2773 for (; parm_table[*i].label; (*i)++) {
2774 if (parm_table[*i].class == P_SEPARATOR)
2775 return &parm_table[(*i)++];
2777 if (!parm_table[*i].ptr
2778 || (*parm_table[*i].label == '-'))
2782 && (parm_table[*i].ptr ==
2783 parm_table[(*i) - 1].ptr))
2786 return &parm_table[(*i)++];
2789 service *pService = ServicePtrs[snum];
2791 for (; parm_table[*i].label; (*i)++) {
2792 if (parm_table[*i].class == P_SEPARATOR)
2793 return &parm_table[(*i)++];
2795 if (parm_table[*i].class == P_LOCAL &&
2796 parm_table[*i].ptr &&
2797 (*parm_table[*i].label != '-') &&
2799 (parm_table[*i].ptr !=
2800 parm_table[(*i) - 1].ptr)))
2803 PTR_DIFF(parm_table[*i].ptr,
2806 if (allparameters ||
2807 !equal_parameter(parm_table[*i].type,
2808 ((char *)pService) +
2810 ((char *)&sDefault) +
2813 return &parm_table[(*i)++];
2824 /***************************************************************************
2825 Display the contents of a single copy structure.
2826 ***************************************************************************/
2827 static void dump_copy_map(BOOL *pcopymap)
2833 printf("\n\tNon-Copied parameters:\n");
2835 for (i = 0; parm_table[i].label; i++)
2836 if (parm_table[i].class == P_LOCAL &&
2837 parm_table[i].ptr && !pcopymap[i] &&
2838 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2840 printf("\t\t%s\n", parm_table[i].label);
2845 /***************************************************************************
2846 Return TRUE if the passed service number is within range.
2847 ***************************************************************************/
2849 BOOL lp_snum_ok(int iService)
2851 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2854 /***************************************************************************
2855 Auto-load some home services.
2856 ***************************************************************************/
2858 static void lp_add_auto_services(const char *str)
2863 /***************************************************************************
2864 Auto-load one printer.
2865 ***************************************************************************/
2867 void lp_add_one_printer(char *name, char *comment)
2869 int printers = lp_servicenumber(PRINTERS_NAME);
2872 if (lp_servicenumber(name) < 0) {
2873 lp_add_printer(name, printers);
2874 if ((i = lp_servicenumber(name)) >= 0) {
2875 string_set(&ServicePtrs[i]->comment, comment);
2876 ServicePtrs[i]->autoloaded = True;
2881 /***************************************************************************
2882 Announce ourselves as a print server.
2883 ***************************************************************************/
2885 void update_server_announce_as_printserver(void)
2887 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2890 /***************************************************************************
2891 Have we loaded a services file yet?
2892 ***************************************************************************/
2894 BOOL lp_loaded(void)
2899 /***************************************************************************
2900 Unload unused services.
2901 ***************************************************************************/
2903 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2906 for (i = 0; i < iNumServices; i++) {
2910 if (!snumused || !snumused(smb, i)) {
2911 ServicePtrs[i]->valid = False;
2912 free_service(ServicePtrs[i]);
2917 /***************************************************************************
2919 ***************************************************************************/
2921 void lp_killservice(int iServiceIn)
2923 if (VALID(iServiceIn)) {
2924 ServicePtrs[iServiceIn]->valid = False;
2925 free_service(ServicePtrs[iServiceIn]);
2929 /***************************************************************************
2930 Save the curent values of all global and sDefault parameters into the
2931 defaults union. This allows swat and testparm to show only the
2932 changed (ie. non-default) parameters.
2933 ***************************************************************************/
2935 static void lp_save_defaults(void)
2938 for (i = 0; parm_table[i].label; i++) {
2939 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2941 switch (parm_table[i].type) {
2943 str_list_copy(&(parm_table[i].def.lvalue),
2944 *(const char ***)parm_table[i].ptr);
2948 if (parm_table[i].ptr) {
2949 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2951 parm_table[i].def.svalue = NULL;
2956 parm_table[i].def.bvalue =
2957 *(BOOL *)parm_table[i].ptr;
2960 parm_table[i].def.cvalue =
2961 *(char *)parm_table[i].ptr;
2966 parm_table[i].def.ivalue =
2967 *(int *)parm_table[i].ptr;
2973 defaults_saved = True;
2976 /*******************************************************************
2977 Set the server type we will announce as via nmbd.
2978 ********************************************************************/
2980 static void set_server_role(void)
2982 server_role = ROLE_STANDALONE;
2984 switch (lp_security()) {
2986 if (lp_domain_logons())
2987 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2992 if (lp_domain_logons()) {
2993 server_role = ROLE_DOMAIN_PDC;
2996 server_role = ROLE_DOMAIN_MEMBER;
2999 if (lp_domain_logons()) {
3001 if (Globals.bDomainMaster) /* auto or yes */
3002 server_role = ROLE_DOMAIN_PDC;
3004 server_role = ROLE_DOMAIN_BDC;
3008 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3012 DEBUG(10, ("set_server_role: role = "));
3014 switch(server_role) {
3015 case ROLE_STANDALONE:
3016 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3018 case ROLE_DOMAIN_MEMBER:
3019 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3021 case ROLE_DOMAIN_BDC:
3022 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3024 case ROLE_DOMAIN_PDC:
3025 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3030 /***************************************************************************
3031 Load the services array from the services file. Return True on success,
3033 ***************************************************************************/
3035 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3040 struct param_opt *data;
3042 pstrcpy(n2, pszFname);
3043 standard_sub_basic(n2,sizeof(n2));
3045 add_to_file_list(pszFname, n2);
3049 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3051 bInGlobalSection = True;
3052 bGlobalOnly = global_only;
3061 if (Globals.param_opt != NULL) {
3062 struct param_opt *next;
3063 for (data=Globals.param_opt; data; data=next) {
3065 if (data->flags & FLAG_CMDLINE) continue;
3068 DLIST_REMOVE(Globals.param_opt, data);
3073 /* We get sections first, so have to start 'behind' to make up */
3075 bRetval = pm_process(n2, do_section, do_parameter);
3077 /* finish up the last section */
3078 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3080 if (iServiceIndex >= 0)
3081 bRetval = service_ok(iServiceIndex);
3083 lp_add_auto_services(lp_auto_services());
3086 /* When 'restrict anonymous = 2' guest connections to ipc$
3088 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3089 lp_add_ipc("ADMIN$", False);
3093 set_default_server_announce_type();
3097 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3098 /* if bWINSsupport is true and we are in the client */
3099 if (in_client && Globals.bWINSsupport) {
3100 lp_do_parameter(-1, "wins server", "127.0.0.1");
3108 /***************************************************************************
3109 Reset the max number of services.
3110 ***************************************************************************/
3112 void lp_resetnumservices(void)
3117 /***************************************************************************
3118 Return the max number of services.
3119 ***************************************************************************/
3121 int lp_numservices(void)
3123 return (iNumServices);
3126 /***************************************************************************
3127 Display the contents of the services array in human-readable form.
3128 ***************************************************************************/
3130 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3135 defaults_saved = False;
3139 dump_a_service(&sDefault, f);
3141 for (iService = 0; iService < maxtoprint; iService++)
3142 lp_dump_one(f, show_defaults, iService);
3145 /***************************************************************************
3146 Display the contents of one service in human-readable form.
3147 ***************************************************************************/
3149 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3152 if (ServicePtrs[snum]->szService[0] == '\0')
3154 dump_a_service(ServicePtrs[snum], f);
3158 /***************************************************************************
3159 Return the number of the service with the given name, or -1 if it doesn't
3160 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3161 getservicebyname()! This works ONLY if all services have been loaded, and
3162 does not copy the found service.
3163 ***************************************************************************/
3165 int lp_servicenumber(const char *pszServiceName)
3168 fstring serviceName;
3171 for (iService = iNumServices - 1; iService >= 0; iService--) {
3172 if (VALID(iService) && ServicePtrs[iService]->szService) {
3174 * The substitution here is used to support %U is
3177 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3178 standard_sub_basic(serviceName,sizeof(serviceName));
3179 if (strequal(serviceName, pszServiceName))
3185 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3190 /*******************************************************************
3191 A useful volume label function.
3192 ********************************************************************/
3193 const char *volume_label(int snum)
3195 const char *ret = lp_volume(snum);
3197 return lp_servicename(snum);
3202 /*******************************************************************
3203 Set the server type we will announce as via nmbd.
3204 ********************************************************************/
3206 static void set_default_server_announce_type(void)
3208 default_server_announce = 0;
3209 default_server_announce |= SV_TYPE_WORKSTATION;
3210 default_server_announce |= SV_TYPE_SERVER;
3211 default_server_announce |= SV_TYPE_SERVER_UNIX;
3213 switch (lp_announce_as()) {
3214 case ANNOUNCE_AS_NT_SERVER:
3215 default_server_announce |= SV_TYPE_SERVER_NT;
3216 /* fall through... */
3217 case ANNOUNCE_AS_NT_WORKSTATION:
3218 default_server_announce |= SV_TYPE_NT;
3220 case ANNOUNCE_AS_WIN95:
3221 default_server_announce |= SV_TYPE_WIN95_PLUS;
3223 case ANNOUNCE_AS_WFW:
3224 default_server_announce |= SV_TYPE_WFW;
3230 switch (lp_server_role()) {
3231 case ROLE_DOMAIN_MEMBER:
3232 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3234 case ROLE_DOMAIN_PDC:
3235 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3237 case ROLE_DOMAIN_BDC:
3238 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3240 case ROLE_STANDALONE:
3244 if (lp_time_server())
3245 default_server_announce |= SV_TYPE_TIME_SOURCE;
3247 if (lp_host_msdfs())
3248 default_server_announce |= SV_TYPE_DFS_SERVER;
3251 /***********************************************************
3252 returns role of Samba server
3253 ************************************************************/
3255 int lp_server_role(void)
3260 /***********************************************************
3261 If we are PDC then prefer us as DMB
3262 ************************************************************/
3264 BOOL lp_domain_master(void)
3266 if (Globals.bDomainMaster == Auto)
3267 return (lp_server_role() == ROLE_DOMAIN_PDC);
3269 return Globals.bDomainMaster;
3272 /***********************************************************
3273 If we are DMB then prefer us as LMB
3274 ************************************************************/
3276 BOOL lp_preferred_master(void)
3278 if (Globals.bPreferredMaster == Auto)
3279 return (lp_local_master() && lp_domain_master());
3281 return Globals.bPreferredMaster;
3284 /*******************************************************************
3286 ********************************************************************/
3288 void lp_remove_service(int snum)
3290 ServicePtrs[snum]->valid = False;
3293 /*******************************************************************
3295 ********************************************************************/
3297 void lp_copy_service(int snum, const char *new_name)
3299 const char *oldname = lp_servicename(snum);
3300 do_section(new_name);
3302 snum = lp_servicenumber(new_name);
3304 lp_do_parameter(snum, "copy", oldname);
3309 /*******************************************************************
3310 Get the default server type we will announce as via nmbd.
3311 ********************************************************************/
3313 int lp_default_server_announce(void)
3315 return default_server_announce;
3318 /*******************************************************************
3319 Split the announce version into major and minor numbers.
3320 ********************************************************************/
3322 int lp_major_announce_version(void)
3324 static BOOL got_major = False;
3325 static int major_version = DEFAULT_MAJOR_VERSION;
3330 return major_version;
3333 if ((vers = lp_announce_version()) == NULL)
3334 return major_version;
3336 if ((p = strchr_m(vers, '.')) == 0)
3337 return major_version;
3340 major_version = atoi(vers);
3341 return major_version;
3344 int lp_minor_announce_version(void)
3346 static BOOL got_minor = False;
3347 static int minor_version = DEFAULT_MINOR_VERSION;
3352 return minor_version;
3355 if ((vers = lp_announce_version()) == NULL)
3356 return minor_version;
3358 if ((p = strchr_m(vers, '.')) == 0)
3359 return minor_version;
3362 minor_version = atoi(p);
3363 return minor_version;
3366 const char *lp_printername(int snum)
3368 const char *ret = _lp_printername(snum);
3369 if (ret == NULL || (ret != NULL && *ret == '\0'))
3370 ret = lp_const_servicename(snum);
3376 /*******************************************************************
3377 Return the max print jobs per queue.
3378 ********************************************************************/
3380 int lp_maxprintjobs(int snum)
3382 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3383 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3384 maxjobs = PRINT_MAX_JOBID - 1;