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_bool_auto[] = {
484 /* Client-side offline caching policy types */
485 #define CSC_POLICY_MANUAL 0
486 #define CSC_POLICY_DOCUMENTS 1
487 #define CSC_POLICY_PROGRAMS 2
488 #define CSC_POLICY_DISABLE 3
490 static const struct enum_list enum_csc_policy[] = {
491 {CSC_POLICY_MANUAL, "manual"},
492 {CSC_POLICY_DOCUMENTS, "documents"},
493 {CSC_POLICY_PROGRAMS, "programs"},
494 {CSC_POLICY_DISABLE, "disable"},
498 /* SMB signing types. */
499 static const struct enum_list enum_smb_signing_vals[] = {
500 {SMB_SIGNING_OFF, "No"},
501 {SMB_SIGNING_OFF, "False"},
502 {SMB_SIGNING_OFF, "0"},
503 {SMB_SIGNING_OFF, "Off"},
504 {SMB_SIGNING_OFF, "disabled"},
505 {SMB_SIGNING_SUPPORTED, "Yes"},
506 {SMB_SIGNING_SUPPORTED, "True"},
507 {SMB_SIGNING_SUPPORTED, "1"},
508 {SMB_SIGNING_SUPPORTED, "On"},
509 {SMB_SIGNING_SUPPORTED, "enabled"},
510 {SMB_SIGNING_REQUIRED, "required"},
511 {SMB_SIGNING_REQUIRED, "mandatory"},
512 {SMB_SIGNING_REQUIRED, "force"},
513 {SMB_SIGNING_REQUIRED, "forced"},
514 {SMB_SIGNING_REQUIRED, "enforced"},
515 {SMB_SIGNING_AUTO, "auto"},
520 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
522 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
523 * is implied in current control logic. This may change at some later time. A
524 * flag value of 0 means - show as development option only.
526 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
527 * screen in SWAT. This is used to exclude parameters as well as to squash all
528 * parameters that have been duplicated by pseudonyms.
530 static struct parm_struct parm_table[] = {
531 {"Base Options", P_SEP, P_SEPARATOR},
533 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
538 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
539 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
540 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
541 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
542 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
543 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
544 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
550 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
551 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
553 {"Security Options", P_SEP, P_SEPARATOR},
555 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
556 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
557 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
558 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
572 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
586 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
587 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
589 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
590 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
591 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
593 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
595 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
597 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
599 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
600 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
601 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
602 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
604 {"Logging Options", P_SEP, P_SEPARATOR},
606 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
608 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"Protocol Options", P_SEP, P_SEPARATOR},
612 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
614 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
615 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
616 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
617 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
618 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
619 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
621 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
624 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
625 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
629 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
635 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
636 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
637 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
639 {"Tuning Options", P_SEP, P_SEPARATOR},
641 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
642 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
643 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
644 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
646 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
647 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
648 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
650 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
651 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
652 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
654 {"Printing Options", P_SEP, P_SEPARATOR},
656 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
657 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
658 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
659 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
660 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
661 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
662 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
663 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
664 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
666 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
667 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
668 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
673 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
675 {"Filename Handling", P_SEP, P_SEPARATOR},
677 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
678 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
679 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
681 {"Domain Options", P_SEP, P_SEPARATOR},
683 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
685 {"Logon Options", P_SEP, P_SEPARATOR},
687 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
688 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
690 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
691 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"Browse Options", P_SEP, P_SEPARATOR},
698 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
703 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
706 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
707 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
709 {"WINS Options", P_SEP, P_SEPARATOR},
710 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
714 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
715 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
718 {"Locking Options", P_SEP, P_SEPARATOR},
720 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
721 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
722 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
723 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
725 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
726 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
727 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
729 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
731 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
733 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
734 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
737 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
742 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
745 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
748 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
749 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
751 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
752 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
753 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
755 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
759 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
760 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"Winbind options", P_SEP, P_SEPARATOR},
763 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
776 /***************************************************************************
777 Initialise the sDefault parameter structure for the printer values.
778 ***************************************************************************/
780 static void init_printer_values(void)
782 /* choose defaults depending on the type of printing */
783 switch (sDefault.iPrinting) {
788 do_parameter("Lpqcommand", "lpq -P'%p'");
789 do_parameter("Lprmcommand", "lprm -P'%p' %j");
790 do_parameter("Printcommand",
796 do_parameter("Lpqcommand", "lpq -P'%p'");
797 do_parameter("Lprmcommand", "lprm -P'%p' %j");
798 do_parameter("Printcommand",
800 do_parameter("Queuepausecommand",
802 do_parameter("Queueresumecommand",
804 do_parameter("Lppausecommand",
806 do_parameter("Lpresumecommand",
807 "lpc release '%p' %j");
812 do_parameter("Lpqcommand", "");
813 do_parameter("Lprmcommand", "");
814 do_parameter("Printcommand", "");
815 do_parameter("Lppausecommand", "");
816 do_parameter("Lpresumecommand", "");
817 do_parameter("Queuepausecommand", "");
818 do_parameter("Queueresumecommand", "");
820 do_parameter("Printcapname", "cups");
822 do_parameter("Lpqcommand",
823 "/usr/bin/lpstat -o '%p'");
824 do_parameter("Lprmcommand",
825 "/usr/bin/cancel '%p-%j'");
826 do_parameter("Printcommand",
827 "/usr/bin/lp -d '%p' %s; rm %s");
828 do_parameter("Lppausecommand",
829 "lp -i '%p-%j' -H hold");
830 do_parameter("Lpresumecommand",
831 "lp -i '%p-%j' -H resume");
832 do_parameter("Queuepausecommand",
833 "/usr/bin/disable '%p'");
834 do_parameter("Queueresumecommand",
835 "/usr/bin/enable '%p'");
836 do_parameter("Printcapname", "lpstat");
837 #endif /* HAVE_CUPS */
842 do_parameter("Lpqcommand", "lpstat -o%p");
843 do_parameter("Lprmcommand", "cancel %p-%j");
844 do_parameter("Printcommand",
845 "lp -c -d%p %s; rm %s");
846 do_parameter("Queuepausecommand",
848 do_parameter("Queueresumecommand",
851 do_parameter("Lppausecommand",
852 "lp -i %p-%j -H hold");
853 do_parameter("Lpresumecommand",
854 "lp -i %p-%j -H resume");
859 do_parameter("Lpqcommand", "lpq -P%p");
860 do_parameter("Lprmcommand", "lprm -P%p %j");
861 do_parameter("Printcommand", "lp -r -P%p %s");
865 do_parameter("Lpqcommand", "qstat -l -d%p");
866 do_parameter("Lprmcommand",
868 do_parameter("Printcommand",
869 "lp -d%p -s %s; rm %s");
870 do_parameter("Lppausecommand",
872 do_parameter("Lpresumecommand",
878 do_parameter("Printcommand", "vlp print %p %s");
879 do_parameter("Lpqcommand", "vlp lpq %p");
880 do_parameter("Lprmcommand", "vlp lprm %p %j");
881 do_parameter("Lppausecommand", "vlp lppause %p %j");
882 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
883 do_parameter("Queuepausecommand", "vlp queuepause %p");
884 do_parameter("Queueresumecommand", "vlp queueresume %p");
886 #endif /* DEVELOPER */
892 /***************************************************************************
893 Initialise the global parameter structure.
894 ***************************************************************************/
895 static void init_globals(void)
900 DEBUG(3, ("Initialising global parameters\n"));
902 for (i = 0; parm_table[i].label; i++) {
903 if ((parm_table[i].type == P_STRING ||
904 parm_table[i].type == P_USTRING) &&
906 !(parm_table[i].flags & FLAG_CMDLINE)) {
907 string_set(parm_table[i].ptr, "");
911 /* options that can be set on the command line must be initialised via
912 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
914 do_parameter("socket options", "TCP_NODELAY");
916 do_parameter("workgroup", DEFAULT_WORKGROUP);
917 myname = get_myname();
918 do_parameter("netbios name", myname);
920 do_parameter("max protocol", "NT1");
921 do_parameter("name resolve order", "lmhosts wins host bcast");
923 init_printer_values();
925 do_parameter("fstype", FSTYPE_STRING);
926 do_parameter("ntvfs handler", "unixuid default");
927 do_parameter("max connections", "-1");
929 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg IOXIDResolver IRemoteActivation dssetup");
930 do_parameter("server services", "smb rpc");
931 do_parameter("auth methods", "anonymous sam_ignoredomain");
932 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
933 do_parameter("private dir", dyn_PRIVATE_DIR);
934 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
935 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
936 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
937 do_parameter("guest account", GUEST_ACCOUNT);
939 /* using UTF8 by default allows us to support all chars */
940 do_parameter("unix charset", "UTF8");
942 /* Use codepage 850 as a default for the dos character set */
943 do_parameter("dos charset", "CP850");
946 * Allow the default PASSWD_CHAT to be overridden in local.h.
948 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
950 do_parameter("passwd program", "");
951 do_parameter("printcap name", PRINTCAP_NAME);
953 do_parameter("pid directory", dyn_PIDDIR);
954 do_parameter("lock dir", dyn_LOCKDIR);
955 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
957 do_parameter("socket address", "0.0.0.0");
958 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
960 do_parameter_var("announce version", "%d.%d",
961 DEFAULT_MAJOR_VERSION,
962 DEFAULT_MINOR_VERSION);
964 do_parameter("logon drive", "");
966 do_parameter("logon home", "\\\\%N\\%U");
967 do_parameter("logon path", "\\\\%N\\%U\\profile");
968 do_parameter("password server", "*");
970 do_parameter("load printers", "True");
972 do_parameter("max mux", "50");
973 do_parameter("max xmit", "12288");
974 do_parameter("lpqcachetime", "10");
975 do_parameter("DisableSpoolss", "False");
976 do_parameter("password level", "0");
977 do_parameter("username level", "0");
978 do_parameter("LargeReadwrite", "True");
979 do_parameter("minprotocol", "CORE");
980 do_parameter("security", "USER");
981 do_parameter("paranoid server security", "True");
982 do_parameter("EncryptPasswords", "True");
983 do_parameter("ReadRaw", "True");
984 do_parameter("WriteRaw", "True");
985 do_parameter("NullPasswords", "False");
986 do_parameter("ObeyPamRestrictions", "False");
987 do_parameter("lm announce", "Auto");
988 do_parameter("lm interval", "60");
989 do_parameter("announce as", "NT SERVER");
991 do_parameter("TimeServer", "False");
992 do_parameter("BindInterfacesOnly", "False");
993 do_parameter("PamPasswordChange", "False");
994 do_parameter("Unicode", "True");
995 do_parameter("restrict anonymous", "0");
996 do_parameter("ClientLanManAuth", "True");
997 do_parameter("LanmanAuth", "True");
998 do_parameter("NTLMAuth", "True");
1000 do_parameter("enhanced browsing", "True");
1001 do_parameter("LockSpinCount", "3");
1002 do_parameter("LockSpinTime", "10");
1003 #ifdef MMAP_BLACKLIST
1004 do_parameter("UseMmap", "False");
1006 do_parameter("UseMmap", "True");
1008 do_parameter("UnixExtensions", "False");
1010 /* hostname lookups can be very expensive and are broken on
1011 a large number of sites (tridge) */
1012 do_parameter("HostnameLookups", "False");
1014 do_parameter("PreferredMaster", "Auto");
1015 do_parameter("os level", "20");
1016 do_parameter("LocalMaster", "True");
1017 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1018 do_parameter("DomainLogons", "False");
1019 do_parameter("WINSsupport", "False");
1020 do_parameter("WINSproxy", "False");
1022 do_parameter("DNSproxy", "True");
1024 do_parameter("AllowTrustedDomains", "True");
1026 do_parameter("TemplateShell", "/bin/false");
1027 do_parameter("TemplateHomedir", "/home/%D/%U");
1028 do_parameter("WinbindSeparator", "\\");
1030 do_parameter("winbind cache time", "15");
1031 do_parameter("WinbindEnumUsers", "True");
1032 do_parameter("WinbindEnumGroups", "True");
1033 do_parameter("WinbindUseDefaultDomain", "False");
1035 do_parameter("IDMapBackend", "tdb");
1037 do_parameter("name cache timeout", "660"); /* In seconds */
1039 do_parameter("client signing", "Yes");
1040 do_parameter("server signing", "auto");
1042 do_parameter("use spnego", "True");
1044 do_parameter("smb ports", SMB_PORTS);
1046 do_parameter("nt status support", "True");
1049 static TALLOC_CTX *lp_talloc;
1051 /******************************************************************* a
1052 Free up temporary memory - called from the main loop.
1053 ********************************************************************/
1055 void lp_talloc_free(void)
1059 talloc_free(lp_talloc);
1063 /*******************************************************************
1064 Convenience routine to grab string parameters into temporary memory
1065 and run standard_sub_basic on them. The buffers can be written to by
1066 callers without affecting the source string.
1067 ********************************************************************/
1069 static const char *lp_string(const char *s)
1071 #if 0 /* until REWRITE done to make thread-safe */
1072 size_t len = s ? strlen(s) : 0;
1076 /* The follow debug is useful for tracking down memory problems
1077 especially if you have an inner loop that is calling a lp_*()
1078 function that returns a string. Perhaps this debug should be
1079 present all the time? */
1082 DEBUG(10, ("lp_string(%s)\n", s));
1085 #if 0 /* until REWRITE done to make thread-safe */
1087 lp_talloc = talloc_init("lp_talloc");
1089 ret = talloc_array_p(lp_talloc, char, len + 100); /* leave room for substitution */
1097 StrnCpy(ret, s, len);
1099 if (trim_string(ret, "\"", "\"")) {
1100 if (strchr(ret,'"') != NULL)
1101 StrnCpy(ret, s, len);
1104 standard_sub_basic(ret,len+100);
1111 In this section all the functions that are used to access the
1112 parameters from the rest of the program are defined
1115 #define FN_GLOBAL_STRING(fn_name,ptr) \
1116 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1117 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1118 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1119 #define FN_GLOBAL_LIST(fn_name,ptr) \
1120 const char **fn_name(void) {return(*(const char ***)(ptr));}
1121 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1122 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1123 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1124 char fn_name(void) {return(*(char *)(ptr));}
1125 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1126 int fn_name(void) {return(*(int *)(ptr));}
1128 #define FN_LOCAL_STRING(fn_name,val) \
1129 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1130 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1131 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1132 #define FN_LOCAL_LIST(fn_name,val) \
1133 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1134 #define FN_LOCAL_BOOL(fn_name,val) \
1135 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1136 #define FN_LOCAL_CHAR(fn_name,val) \
1137 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1138 #define FN_LOCAL_INTEGER(fn_name,val) \
1139 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1141 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1142 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1143 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1144 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1145 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1146 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1147 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1148 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1149 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1150 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1151 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1152 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1153 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1154 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1155 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1156 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1157 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1158 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1159 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1160 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1161 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1162 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1163 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1164 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1165 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1166 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1167 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1168 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1169 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1170 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1171 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1172 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1173 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1174 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1175 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1176 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1177 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1178 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1179 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1180 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1181 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1182 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1183 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1184 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1186 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1188 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1190 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1191 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1192 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1193 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1194 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1195 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1196 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1197 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1198 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1200 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1201 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1202 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1203 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1204 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1205 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1206 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1207 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1208 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1209 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1210 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1211 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1212 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1213 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1214 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1215 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1216 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1217 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1218 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1219 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1220 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1221 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1222 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1223 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1224 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1225 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1226 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1227 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1228 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1229 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1230 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1231 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1232 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1233 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1234 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1235 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1236 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1237 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1238 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1239 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1240 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1241 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1242 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1243 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1244 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1245 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1246 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1247 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1248 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1249 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1250 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1251 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1252 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1253 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1254 FN_LOCAL_STRING(lp_servicename, szService)
1255 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1256 FN_LOCAL_STRING(lp_pathname, szPath)
1257 FN_LOCAL_STRING(lp_username, szUsername)
1258 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1259 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1260 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1261 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1262 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1263 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1264 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1265 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1266 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1267 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1268 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1269 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1270 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1271 FN_LOCAL_STRING(lp_comment, comment)
1272 FN_LOCAL_STRING(lp_fstype, fstype)
1273 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1274 static FN_LOCAL_STRING(lp_volume, volume)
1275 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1276 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1277 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1278 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1279 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1280 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1281 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1282 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1283 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1284 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1285 FN_LOCAL_BOOL(lp_locking, bLocking)
1286 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1287 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1288 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1289 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1290 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1291 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1292 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1293 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1294 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1295 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1296 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1297 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1298 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1299 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1300 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1301 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1302 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1303 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1305 /* local prototypes */
1307 static int map_parameter(const char *pszParmName);
1308 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1309 static int getservicebyname(const char *pszServiceName,
1310 service * pserviceDest);
1311 static void copy_service(service * pserviceDest,
1312 service * pserviceSource, BOOL *pcopymapDest);
1313 static BOOL service_ok(int iService);
1314 static BOOL do_section(const char *pszSectionName);
1315 static void init_copymap(service * pservice);
1317 /* This is a helper function for parametrical options support. */
1318 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1319 /* Actual parametrical functions are quite simple */
1320 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1323 struct param_opt *data;
1325 if (lookup_service >= iNumServices) return NULL;
1327 data = (lookup_service < 0) ?
1328 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1330 asprintf(&vfskey, "%s:%s", type, option);
1334 if (strcmp(data->key, vfskey) == 0) {
1341 if (lookup_service >= 0) {
1342 /* Try to fetch the same option but from globals */
1343 /* but only if we are not already working with Globals */
1344 data = Globals.param_opt;
1346 if (strcmp(data->key, vfskey) == 0) {
1360 /*******************************************************************
1361 convenience routine to return int parameters.
1362 ********************************************************************/
1363 static int lp_int(const char *s)
1367 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1374 /*******************************************************************
1375 convenience routine to return unsigned long parameters.
1376 ********************************************************************/
1377 static int lp_ulong(const char *s)
1381 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1385 return strtoul(s, NULL, 10);
1388 /*******************************************************************
1389 convenience routine to return boolean parameters.
1390 ********************************************************************/
1391 static BOOL lp_bool(const char *s)
1396 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1400 if (!set_boolean(&ret,s)) {
1401 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1409 /* Return parametric option from a given service. Type is a part of option before ':' */
1410 /* Parametric option has following syntax: 'Type: option = value' */
1411 /* Returned value is allocated in 'lp_talloc' context */
1413 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1415 const char *value = get_parametrics(lookup_service, type, option);
1418 return lp_string(value);
1423 /* Return parametric option from a given service. Type is a part of option before ':' */
1424 /* Parametric option has following syntax: 'Type: option = value' */
1425 /* Returned value is allocated in 'lp_talloc' context */
1427 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1428 const char *separator)
1430 const char *value = get_parametrics(lookup_service, type, option);
1433 return str_list_make(value, separator);
1438 /* Return parametric option from a given service. Type is a part of option before ':' */
1439 /* Parametric option has following syntax: 'Type: option = value' */
1441 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1443 const char *value = get_parametrics(lookup_service, type, option);
1446 return lp_int(value);
1451 /* Return parametric option from a given service. Type is a part of option before ':' */
1452 /* Parametric option has following syntax: 'Type: option = value' */
1454 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1456 const char *value = get_parametrics(lookup_service, type, option);
1459 return lp_ulong(value);
1464 /* Return parametric option from a given service. Type is a part of option before ':' */
1465 /* Parametric option has following syntax: 'Type: option = value' */
1467 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1469 const char *value = get_parametrics(lookup_service, type, option);
1472 return lp_bool(value);
1478 /***************************************************************************
1479 Initialise a service to the defaults.
1480 ***************************************************************************/
1482 static void init_service(service * pservice)
1484 memset((char *)pservice, '\0', sizeof(service));
1485 copy_service(pservice, &sDefault, NULL);
1488 /***************************************************************************
1489 Free the dynamically allocated parts of a service struct.
1490 ***************************************************************************/
1492 static void free_service(service *pservice)
1495 struct param_opt *data, *pdata;
1499 if (pservice->szService)
1500 DEBUG(5, ("free_service: Freeing service %s\n",
1501 pservice->szService));
1503 string_free(&pservice->szService);
1504 SAFE_FREE(pservice->copymap);
1506 for (i = 0; parm_table[i].label; i++) {
1507 if ((parm_table[i].type == P_STRING ||
1508 parm_table[i].type == P_USTRING) &&
1509 parm_table[i].class == P_LOCAL)
1510 string_free((char **)
1511 (((char *)pservice) +
1512 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1513 else if (parm_table[i].type == P_LIST &&
1514 parm_table[i].class == P_LOCAL)
1515 str_list_free((char ***)
1516 (((char *)pservice) +
1517 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1520 DEBUG(5,("Freeing parametrics:\n"));
1521 data = pservice->param_opt;
1523 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1524 string_free(&data->key);
1525 string_free(&data->value);
1531 ZERO_STRUCTP(pservice);
1534 /***************************************************************************
1535 Add a new service to the services array initialising it with the given
1537 ***************************************************************************/
1539 static int add_a_service(const service *pservice, const char *name)
1543 int num_to_alloc = iNumServices + 1;
1544 struct param_opt *data, *pdata;
1546 tservice = *pservice;
1548 /* it might already exist */
1550 i = getservicebyname(name, NULL);
1552 /* Clean all parametric options for service */
1553 /* They will be added during parsing again */
1554 data = ServicePtrs[i]->param_opt;
1556 string_free(&data->key);
1557 string_free(&data->value);
1562 ServicePtrs[i]->param_opt = NULL;
1567 /* find an invalid one */
1568 for (i = 0; i < iNumServices; i++)
1569 if (!ServicePtrs[i]->valid)
1572 /* if not, then create one */
1573 if (i == iNumServices) {
1576 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1579 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1584 ServicePtrs[iNumServices] = malloc_p(service);
1586 if (!ServicePtrs[iNumServices]) {
1587 DEBUG(0,("add_a_service: out of memory!\n"));
1593 free_service(ServicePtrs[i]);
1595 ServicePtrs[i]->valid = True;
1597 init_service(ServicePtrs[i]);
1598 copy_service(ServicePtrs[i], &tservice, NULL);
1600 string_set(&ServicePtrs[i]->szService, name);
1604 /***************************************************************************
1605 Add a new home service, with the specified home directory, defaults coming
1607 ***************************************************************************/
1609 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1610 const char *user, const char *pszHomedir)
1615 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1620 if (!(*(ServicePtrs[iDefaultService]->szPath))
1621 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1622 pstrcpy(newHomedir, pszHomedir);
1624 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1625 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1628 string_set(&ServicePtrs[i]->szPath, newHomedir);
1630 if (!(*(ServicePtrs[i]->comment))) {
1632 slprintf(comment, sizeof(comment) - 1,
1633 "Home directory of %s", user);
1634 string_set(&ServicePtrs[i]->comment, comment);
1636 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1637 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1639 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1645 /***************************************************************************
1646 Add a new service, based on an old one.
1647 ***************************************************************************/
1649 int lp_add_service(const char *pszService, int iDefaultService)
1651 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1654 /***************************************************************************
1655 Add the IPC service.
1656 ***************************************************************************/
1658 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1661 int i = add_a_service(&sDefault, name);
1666 slprintf(comment, sizeof(comment) - 1,
1667 "%s Service (%s)", fstype, Globals.szServerString);
1669 string_set(&ServicePtrs[i]->szPath, tmpdir());
1670 string_set(&ServicePtrs[i]->szUsername, "");
1671 string_set(&ServicePtrs[i]->comment, comment);
1672 string_set(&ServicePtrs[i]->fstype, fstype);
1673 ServicePtrs[i]->iMaxConnections = -1;
1674 ServicePtrs[i]->bAvailable = True;
1675 ServicePtrs[i]->bRead_only = True;
1676 ServicePtrs[i]->bGuest_only = False;
1677 ServicePtrs[i]->bGuest_ok = guest_ok;
1678 ServicePtrs[i]->bPrint_ok = False;
1679 ServicePtrs[i]->bBrowseable = False;
1681 if (strcasecmp(fstype, "IPC") == 0) {
1682 lp_do_parameter(i, "ntvfs handler", "default");
1685 DEBUG(3, ("adding hidden service %s\n", name));
1690 /***************************************************************************
1691 Add a new printer service, with defaults coming from service iFrom.
1692 ***************************************************************************/
1694 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1696 const char *comment = "From Printcap";
1697 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1702 /* note that we do NOT default the availability flag to True - */
1703 /* we take it from the default service passed. This allows all */
1704 /* dynamic printers to be disabled by disabling the [printers] */
1705 /* entry (if/when the 'available' keyword is implemented!). */
1707 /* the printer name is set to the service name. */
1708 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1709 string_set(&ServicePtrs[i]->comment, comment);
1710 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1711 /* Printers cannot be read_only. */
1712 ServicePtrs[i]->bRead_only = False;
1713 /* No share modes on printer services. */
1714 ServicePtrs[i]->bShareModes = False;
1715 /* No oplocks on printer services. */
1716 ServicePtrs[i]->bOpLocks = False;
1717 /* Printer services must be printable. */
1718 ServicePtrs[i]->bPrint_ok = True;
1720 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1722 update_server_announce_as_printserver();
1727 /***************************************************************************
1728 Map a parameter's string representation to something we can use.
1729 Returns False if the parameter string is not recognised, else TRUE.
1730 ***************************************************************************/
1732 static int map_parameter(const char *pszParmName)
1736 if (*pszParmName == '-')
1739 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1740 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1743 /* Warn only if it isn't parametric option */
1744 if (strchr(pszParmName, ':') == NULL)
1745 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1746 /* We do return 'fail' for parametric options as well because they are
1747 stored in different storage
1752 /***************************************************************************
1753 Set a boolean variable from the text value stored in the passed string.
1754 Returns True in success, False if the passed string does not correctly
1755 represent a boolean.
1756 ***************************************************************************/
1758 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1763 if (strwicmp(pszParmValue, "yes") == 0 ||
1764 strwicmp(pszParmValue, "true") == 0 ||
1765 strwicmp(pszParmValue, "1") == 0)
1767 else if (strwicmp(pszParmValue, "no") == 0 ||
1768 strwicmp(pszParmValue, "False") == 0 ||
1769 strwicmp(pszParmValue, "0") == 0)
1773 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1780 /***************************************************************************
1781 Find a service by name. Otherwise works like get_service.
1782 ***************************************************************************/
1784 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1788 for (iService = iNumServices - 1; iService >= 0; iService--)
1789 if (VALID(iService) &&
1790 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1791 if (pserviceDest != NULL)
1792 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1799 /***************************************************************************
1800 Copy a service structure to another.
1801 If pcopymapDest is NULL then copy all fields
1802 ***************************************************************************/
1804 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1807 BOOL bcopyall = (pcopymapDest == NULL);
1808 struct param_opt *data, *pdata, *paramo;
1811 for (i = 0; parm_table[i].label; i++)
1812 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1813 (bcopyall || pcopymapDest[i])) {
1814 void *def_ptr = parm_table[i].ptr;
1816 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1819 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1822 switch (parm_table[i].type) {
1825 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1831 *(int *)dest_ptr = *(int *)src_ptr;
1835 *(char *)dest_ptr = *(char *)src_ptr;
1839 string_set(dest_ptr,
1844 string_set(dest_ptr,
1846 strupper(*(char **)dest_ptr);
1849 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1857 init_copymap(pserviceDest);
1858 if (pserviceSource->copymap)
1859 memcpy((void *)pserviceDest->copymap,
1860 (void *)pserviceSource->copymap,
1861 sizeof(BOOL) * NUMPARAMETERS);
1864 data = pserviceSource->param_opt;
1867 pdata = pserviceDest->param_opt;
1868 /* Traverse destination */
1870 /* If we already have same option, override it */
1871 if (strcmp(pdata->key, data->key) == 0) {
1872 string_free(&pdata->value);
1873 pdata->value = strdup(data->value);
1877 pdata = pdata->next;
1880 paramo = smb_xmalloc_p(struct param_opt);
1881 paramo->key = strdup(data->key);
1882 paramo->value = strdup(data->value);
1883 DLIST_ADD(pserviceDest->param_opt, paramo);
1889 /***************************************************************************
1890 Check a service for consistency. Return False if the service is in any way
1891 incomplete or faulty, else True.
1892 ***************************************************************************/
1894 static BOOL service_ok(int iService)
1899 if (ServicePtrs[iService]->szService[0] == '\0') {
1900 DEBUG(0, ("The following message indicates an internal error:\n"));
1901 DEBUG(0, ("No service name in service entry.\n"));
1905 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1906 /* I can't see why you'd want a non-printable printer service... */
1907 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1908 if (!ServicePtrs[iService]->bPrint_ok) {
1909 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1910 ServicePtrs[iService]->szService));
1911 ServicePtrs[iService]->bPrint_ok = True;
1913 /* [printers] service must also be non-browsable. */
1914 if (ServicePtrs[iService]->bBrowseable)
1915 ServicePtrs[iService]->bBrowseable = False;
1918 /* If a service is flagged unavailable, log the fact at level 0. */
1919 if (!ServicePtrs[iService]->bAvailable)
1920 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1921 ServicePtrs[iService]->szService));
1926 static struct file_lists {
1927 struct file_lists *next;
1931 } *file_lists = NULL;
1933 /*******************************************************************
1934 Keep a linked list of all config files so we know when one has changed
1935 it's date and needs to be reloaded.
1936 ********************************************************************/
1938 static void add_to_file_list(const char *fname, const char *subfname)
1940 struct file_lists *f = file_lists;
1943 if (f->name && !strcmp(f->name, fname))
1949 f = malloc_p(struct file_lists);
1952 f->next = file_lists;
1953 f->name = strdup(fname);
1958 f->subfname = strdup(subfname);
1964 f->modtime = file_modtime(subfname);
1966 time_t t = file_modtime(subfname);
1972 /*******************************************************************
1973 Check if a config file has changed date.
1974 ********************************************************************/
1976 BOOL lp_file_list_changed(void)
1978 struct file_lists *f = file_lists;
1979 DEBUG(6, ("lp_file_list_changed()\n"));
1985 pstrcpy(n2, f->name);
1986 standard_sub_basic(n2,sizeof(n2));
1988 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1989 f->name, n2, ctime(&f->modtime)));
1991 mod_time = file_modtime(n2);
1993 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1995 ("file %s modified: %s\n", n2,
1997 f->modtime = mod_time;
1998 SAFE_FREE(f->subfname);
1999 f->subfname = strdup(n2);
2007 /***************************************************************************
2008 Handle the include operation.
2009 ***************************************************************************/
2011 static BOOL handle_include(const char *pszParmValue, char **ptr)
2014 pstrcpy(fname, pszParmValue);
2016 standard_sub_basic(fname,sizeof(fname));
2018 add_to_file_list(pszParmValue, fname);
2020 string_set(ptr, fname);
2022 if (file_exist(fname, NULL))
2023 return (pm_process(fname, do_section, do_parameter));
2025 DEBUG(2, ("Can't find include file %s\n", fname));
2030 /***************************************************************************
2031 Handle the interpretation of the copy parameter.
2032 ***************************************************************************/
2034 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2038 service serviceTemp;
2040 string_set(ptr, pszParmValue);
2042 init_service(&serviceTemp);
2046 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2048 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2049 if (iTemp == iServiceIndex) {
2050 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2052 copy_service(ServicePtrs[iServiceIndex],
2054 ServicePtrs[iServiceIndex]->copymap);
2058 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2062 free_service(&serviceTemp);
2066 /***************************************************************************
2067 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2072 winbind uid = 1000-1999
2073 winbind gid = 700-899
2075 We only do simple parsing checks here. The strings are parsed into useful
2076 structures in the winbind daemon code.
2078 ***************************************************************************/
2080 /* Some lp_ routines to return winbind [ug]id information */
2082 static uid_t winbind_uid_low, winbind_uid_high;
2083 static gid_t winbind_gid_low, winbind_gid_high;
2084 static uint32_t non_unix_account_low, non_unix_account_high;
2086 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2088 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2092 *low = winbind_uid_low;
2095 *high = winbind_uid_high;
2100 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2102 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2106 *low = winbind_gid_low;
2109 *high = winbind_gid_high;
2114 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2116 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2120 *low = non_unix_account_low;
2123 *high = non_unix_account_high;
2128 /* Do some simple checks on "winbind [ug]id" parameter values */
2130 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2134 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2139 string_set(ptr, pszParmValue);
2141 winbind_uid_low = low;
2142 winbind_uid_high = high;
2147 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2151 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2156 string_set(ptr, pszParmValue);
2158 winbind_gid_low = low;
2159 winbind_gid_high = high;
2164 /***************************************************************************
2165 Do some simple checks on "non unix account range" parameter values.
2166 ***************************************************************************/
2168 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2172 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2177 string_set(ptr, pszParmValue);
2179 non_unix_account_low = low;
2180 non_unix_account_high = high;
2186 /***************************************************************************
2187 Initialise a copymap.
2188 ***************************************************************************/
2190 static void init_copymap(service * pservice)
2193 SAFE_FREE(pservice->copymap);
2194 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2195 if (!pservice->copymap)
2197 ("Couldn't allocate copymap!! (size %d)\n",
2198 (int)NUMPARAMETERS));
2200 for (i = 0; i < NUMPARAMETERS; i++)
2201 pservice->copymap[i] = True;
2204 /***************************************************************************
2205 Return the local pointer to a parameter given the service number and the
2206 pointer into the default structure.
2207 ***************************************************************************/
2209 void *lp_local_ptr(int snum, void *ptr)
2211 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2215 /***************************************************************************
2216 Process a parametric option
2217 ***************************************************************************/
2218 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2220 struct param_opt *paramo, *data;
2223 while (isspace(*pszParmName)) {
2227 name = strdup(pszParmName);
2228 if (!name) return False;
2233 data = Globals.param_opt;
2235 data = ServicePtrs[snum]->param_opt;
2238 /* Traverse destination */
2239 for (paramo=data; paramo; paramo=paramo->next) {
2240 /* If we already have the option set, override it unless
2241 it was a command line option and the new one isn't */
2242 if (strcmp(paramo->key, name) == 0) {
2243 if ((paramo->flags & FLAG_CMDLINE) &&
2244 !(flags & FLAG_CMDLINE)) {
2248 free(paramo->value);
2249 paramo->value = strdup(pszParmValue);
2250 paramo->flags = flags;
2256 paramo = smb_xmalloc_p(struct param_opt);
2257 paramo->key = strdup(name);
2258 paramo->value = strdup(pszParmValue);
2259 paramo->flags = flags;
2261 DLIST_ADD(Globals.param_opt, paramo);
2263 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2271 /***************************************************************************
2272 Process a parameter for a particular service number. If snum < 0
2273 then assume we are in the globals.
2274 ***************************************************************************/
2275 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2278 void *parm_ptr = NULL; /* where we are going to store the result */
2279 void *def_ptr = NULL;
2281 parmnum = map_parameter(pszParmName);
2284 if (strchr(pszParmName, ':')) {
2285 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2287 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2291 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2292 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2296 /* if the flag has been set on the command line, then don't allow override,
2297 but don't report an error */
2298 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2302 def_ptr = parm_table[parmnum].ptr;
2304 /* we might point at a service, the default service or a global */
2308 if (parm_table[parmnum].class == P_GLOBAL) {
2310 ("Global parameter %s found in service section!\n",
2315 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2320 if (!ServicePtrs[snum]->copymap)
2321 init_copymap(ServicePtrs[snum]);
2323 /* this handles the aliases - set the copymap for other entries with
2324 the same data pointer */
2325 for (i = 0; parm_table[i].label; i++)
2326 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2327 ServicePtrs[snum]->copymap[i] = False;
2330 /* if it is a special case then go ahead */
2331 if (parm_table[parmnum].special) {
2332 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2336 /* now switch on the type of variable it is */
2337 switch (parm_table[parmnum].type)
2340 set_boolean(parm_ptr, pszParmValue);
2344 set_boolean(parm_ptr, pszParmValue);
2345 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2349 *(int *)parm_ptr = atoi(pszParmValue);
2353 *(char *)parm_ptr = *pszParmValue;
2357 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2361 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2365 string_set(parm_ptr, pszParmValue);
2369 string_set(parm_ptr, pszParmValue);
2370 strupper(*(char **)parm_ptr);
2374 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2377 parm_table[parmnum].enum_list[i].name)) {
2379 parm_table[parmnum].
2384 if (!parm_table[parmnum].enum_list[i].name) {
2385 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2386 pszParmValue, pszParmName));
2397 /***************************************************************************
2398 Process a parameter.
2399 ***************************************************************************/
2401 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2403 if (!bInGlobalSection && bGlobalOnly)
2406 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2407 pszParmName, pszParmValue));
2411 variable argument do parameter
2413 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2415 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2422 s = talloc_vasprintf(NULL, fmt, ap);
2424 ret = do_parameter(pszParmName, s);
2431 set a parameter from the commandline - this is called from command line parameter
2432 parsing code. It sets the parameter then marks the parameter as unable to be modified
2433 by smb.conf processing
2435 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2437 int parmnum = map_parameter(pszParmName);
2440 while (isspace(*pszParmValue)) pszParmValue++;
2443 if (parmnum < 0 && strchr(pszParmName, ':')) {
2444 /* set a parametric option */
2445 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2449 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2453 /* reset the CMDLINE flag in case this has been called before */
2454 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2456 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2460 parm_table[parmnum].flags |= FLAG_CMDLINE;
2462 /* we have to also set FLAG_CMDLINE on aliases */
2463 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2464 parm_table[i].flags |= FLAG_CMDLINE;
2466 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2467 parm_table[i].flags |= FLAG_CMDLINE;
2474 set a option from the commandline in 'a=b' format. Use to support --option
2476 BOOL lp_set_option(const char *option)
2494 ret = lp_set_cmdline(s, p+1);
2500 /***************************************************************************
2501 Print a parameter of the specified type.
2502 ***************************************************************************/
2504 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2510 for (i = 0; p->enum_list[i].name; i++) {
2511 if (*(int *)ptr == p->enum_list[i].value) {
2513 p->enum_list[i].name);
2520 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2524 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2528 fprintf(f, "%d", *(int *)ptr);
2532 fprintf(f, "%c", *(char *)ptr);
2536 if (*(int *)ptr == -1) {
2539 fprintf(f, "0%o", *(int *)ptr);
2544 if ((char ***)ptr && *(char ***)ptr) {
2545 char **list = *(char ***)ptr;
2547 for (; *list; list++)
2548 fprintf(f, "%s%s", *list,
2549 ((*(list+1))?", ":""));
2555 if (*(char **)ptr) {
2556 fprintf(f, "%s", *(char **)ptr);
2564 /***************************************************************************
2565 Check if two parameters are equal.
2566 ***************************************************************************/
2568 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2573 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2578 return (*((int *)ptr1) == *((int *)ptr2));
2581 return (*((char *)ptr1) == *((char *)ptr2));
2584 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2589 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2594 return (p1 == p2 || strequal(p1, p2));
2602 /***************************************************************************
2603 Process a new section (service). At this stage all sections are services.
2604 Later we'll have special sections that permit server parameters to be set.
2605 Returns True on success, False on failure.
2606 ***************************************************************************/
2608 static BOOL do_section(const char *pszSectionName)
2611 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2612 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2615 /* if we've just struck a global section, note the fact. */
2616 bInGlobalSection = isglobal;
2618 /* check for multiple global sections */
2619 if (bInGlobalSection) {
2620 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2624 if (!bInGlobalSection && bGlobalOnly)
2627 /* if we have a current service, tidy it up before moving on */
2630 if (iServiceIndex >= 0)
2631 bRetval = service_ok(iServiceIndex);
2633 /* if all is still well, move to the next record in the services array */
2635 /* We put this here to avoid an odd message order if messages are */
2636 /* issued by the post-processing of a previous section. */
2637 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2639 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2641 DEBUG(0, ("Failed to add a new service\n"));
2650 /***************************************************************************
2651 Determine if a partcular base parameter is currentl set to the default value.
2652 ***************************************************************************/
2654 static BOOL is_default(int i)
2656 if (!defaults_saved)
2658 switch (parm_table[i].type) {
2660 return str_list_compare (parm_table[i].def.lvalue,
2661 *(char ***)parm_table[i].ptr);
2664 return strequal(parm_table[i].def.svalue,
2665 *(char **)parm_table[i].ptr);
2668 return parm_table[i].def.bvalue ==
2669 *(BOOL *)parm_table[i].ptr;
2671 return parm_table[i].def.cvalue ==
2672 *(char *)parm_table[i].ptr;
2676 return parm_table[i].def.ivalue ==
2677 *(int *)parm_table[i].ptr;
2684 /***************************************************************************
2685 Display the contents of the global structure.
2686 ***************************************************************************/
2688 static void dump_globals(FILE *f)
2691 struct param_opt *data;
2693 fprintf(f, "# Global parameters\n[global]\n");
2695 for (i = 0; parm_table[i].label; i++)
2696 if (parm_table[i].class == P_GLOBAL &&
2697 parm_table[i].ptr &&
2698 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2699 if (defaults_saved && is_default(i))
2701 fprintf(f, "\t%s = ", parm_table[i].label);
2702 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2705 if (Globals.param_opt != NULL) {
2706 data = Globals.param_opt;
2708 fprintf(f, "\t%s = %s\n", data->key, data->value);
2715 /***************************************************************************
2716 Display the contents of a single services record.
2717 ***************************************************************************/
2719 static void dump_a_service(service * pService, FILE * f)
2722 struct param_opt *data;
2724 if (pService != &sDefault)
2725 fprintf(f, "\n[%s]\n", pService->szService);
2727 for (i = 0; parm_table[i].label; i++)
2728 if (parm_table[i].class == P_LOCAL &&
2729 parm_table[i].ptr &&
2730 (*parm_table[i].label != '-') &&
2731 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2732 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2734 if (pService == &sDefault) {
2735 if (defaults_saved && is_default(i))
2738 if (equal_parameter(parm_table[i].type,
2739 ((char *)pService) +
2741 ((char *)&sDefault) +
2746 fprintf(f, "\t%s = ", parm_table[i].label);
2747 print_parameter(&parm_table[i],
2748 ((char *)pService) + pdiff, f);
2751 if (pService->param_opt != NULL) {
2752 data = pService->param_opt;
2754 fprintf(f, "\t%s = %s\n", data->key, data->value);
2761 /***************************************************************************
2762 Return info about the next service in a service. snum==-1 gives the globals.
2763 Return NULL when out of parameters.
2764 ***************************************************************************/
2766 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2769 /* do the globals */
2770 for (; parm_table[*i].label; (*i)++) {
2771 if (parm_table[*i].class == P_SEPARATOR)
2772 return &parm_table[(*i)++];
2774 if (!parm_table[*i].ptr
2775 || (*parm_table[*i].label == '-'))
2779 && (parm_table[*i].ptr ==
2780 parm_table[(*i) - 1].ptr))
2783 return &parm_table[(*i)++];
2786 service *pService = ServicePtrs[snum];
2788 for (; parm_table[*i].label; (*i)++) {
2789 if (parm_table[*i].class == P_SEPARATOR)
2790 return &parm_table[(*i)++];
2792 if (parm_table[*i].class == P_LOCAL &&
2793 parm_table[*i].ptr &&
2794 (*parm_table[*i].label != '-') &&
2796 (parm_table[*i].ptr !=
2797 parm_table[(*i) - 1].ptr)))
2800 PTR_DIFF(parm_table[*i].ptr,
2803 if (allparameters ||
2804 !equal_parameter(parm_table[*i].type,
2805 ((char *)pService) +
2807 ((char *)&sDefault) +
2810 return &parm_table[(*i)++];
2820 /***************************************************************************
2821 Return TRUE if the passed service number is within range.
2822 ***************************************************************************/
2824 BOOL lp_snum_ok(int iService)
2826 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2829 /***************************************************************************
2830 Auto-load some home services.
2831 ***************************************************************************/
2833 static void lp_add_auto_services(const char *str)
2838 /***************************************************************************
2839 Auto-load one printer.
2840 ***************************************************************************/
2842 void lp_add_one_printer(char *name, char *comment)
2844 int printers = lp_servicenumber(PRINTERS_NAME);
2847 if (lp_servicenumber(name) < 0) {
2848 lp_add_printer(name, printers);
2849 if ((i = lp_servicenumber(name)) >= 0) {
2850 string_set(&ServicePtrs[i]->comment, comment);
2851 ServicePtrs[i]->autoloaded = True;
2856 /***************************************************************************
2857 Announce ourselves as a print server.
2858 ***************************************************************************/
2860 void update_server_announce_as_printserver(void)
2862 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2865 /***************************************************************************
2866 Have we loaded a services file yet?
2867 ***************************************************************************/
2869 BOOL lp_loaded(void)
2874 /***************************************************************************
2875 Unload unused services.
2876 ***************************************************************************/
2878 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2881 for (i = 0; i < iNumServices; i++) {
2885 if (!snumused || !snumused(smb, i)) {
2886 ServicePtrs[i]->valid = False;
2887 free_service(ServicePtrs[i]);
2892 /***************************************************************************
2894 ***************************************************************************/
2896 void lp_killservice(int iServiceIn)
2898 if (VALID(iServiceIn)) {
2899 ServicePtrs[iServiceIn]->valid = False;
2900 free_service(ServicePtrs[iServiceIn]);
2904 /***************************************************************************
2905 Save the curent values of all global and sDefault parameters into the
2906 defaults union. This allows swat and testparm to show only the
2907 changed (ie. non-default) parameters.
2908 ***************************************************************************/
2910 static void lp_save_defaults(void)
2913 for (i = 0; parm_table[i].label; i++) {
2914 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2916 switch (parm_table[i].type) {
2918 str_list_copy(&(parm_table[i].def.lvalue),
2919 *(const char ***)parm_table[i].ptr);
2923 if (parm_table[i].ptr) {
2924 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2926 parm_table[i].def.svalue = NULL;
2931 parm_table[i].def.bvalue =
2932 *(BOOL *)parm_table[i].ptr;
2935 parm_table[i].def.cvalue =
2936 *(char *)parm_table[i].ptr;
2941 parm_table[i].def.ivalue =
2942 *(int *)parm_table[i].ptr;
2948 defaults_saved = True;
2951 /*******************************************************************
2952 Set the server type we will announce as via nmbd.
2953 ********************************************************************/
2955 static void set_server_role(void)
2957 server_role = ROLE_STANDALONE;
2959 switch (lp_security()) {
2961 if (lp_domain_logons())
2962 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2967 if (lp_domain_logons()) {
2968 if (Globals.bDomainMaster) /* auto or yes */
2969 server_role = ROLE_DOMAIN_PDC;
2971 server_role = ROLE_DOMAIN_BDC;
2974 server_role = ROLE_DOMAIN_MEMBER;
2977 if (lp_domain_logons()) {
2979 if (Globals.bDomainMaster) /* auto or yes */
2980 server_role = ROLE_DOMAIN_PDC;
2982 server_role = ROLE_DOMAIN_BDC;
2986 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2990 DEBUG(10, ("set_server_role: role = "));
2992 switch(server_role) {
2993 case ROLE_STANDALONE:
2994 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2996 case ROLE_DOMAIN_MEMBER:
2997 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2999 case ROLE_DOMAIN_BDC:
3000 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3002 case ROLE_DOMAIN_PDC:
3003 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3008 /***************************************************************************
3009 Load the services array from the services file. Return True on success,
3011 ***************************************************************************/
3013 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3018 struct param_opt *data;
3020 pstrcpy(n2, pszFname);
3021 standard_sub_basic(n2,sizeof(n2));
3023 add_to_file_list(pszFname, n2);
3027 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3029 bInGlobalSection = True;
3030 bGlobalOnly = global_only;
3032 if (Globals.param_opt != NULL) {
3033 struct param_opt *next;
3034 for (data=Globals.param_opt; data; data=next) {
3036 if (data->flags & FLAG_CMDLINE) continue;
3039 DLIST_REMOVE(Globals.param_opt, data);
3051 /* We get sections first, so have to start 'behind' to make up */
3053 bRetval = pm_process(n2, do_section, do_parameter);
3055 /* finish up the last section */
3056 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3058 if (iServiceIndex >= 0)
3059 bRetval = service_ok(iServiceIndex);
3061 lp_add_auto_services(lp_auto_services());
3064 /* When 'restrict anonymous = 2' guest connections to ipc$
3066 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3067 lp_add_hidden("ADMIN$", "DISK", False);
3071 set_default_server_announce_type();
3075 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3076 /* if bWINSsupport is true and we are in the client */
3077 if (in_client && Globals.bWINSsupport) {
3078 lp_do_parameter(-1, "wins server", "127.0.0.1");
3086 /***************************************************************************
3087 Reset the max number of services.
3088 ***************************************************************************/
3090 void lp_resetnumservices(void)
3095 /***************************************************************************
3096 Return the max number of services.
3097 ***************************************************************************/
3099 int lp_numservices(void)
3101 return (iNumServices);
3104 /***************************************************************************
3105 Display the contents of the services array in human-readable form.
3106 ***************************************************************************/
3108 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3113 defaults_saved = False;
3117 dump_a_service(&sDefault, f);
3119 for (iService = 0; iService < maxtoprint; iService++)
3120 lp_dump_one(f, show_defaults, iService);
3123 /***************************************************************************
3124 Display the contents of one service in human-readable form.
3125 ***************************************************************************/
3127 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3130 if (ServicePtrs[snum]->szService[0] == '\0')
3132 dump_a_service(ServicePtrs[snum], f);
3136 /***************************************************************************
3137 Return the number of the service with the given name, or -1 if it doesn't
3138 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3139 getservicebyname()! This works ONLY if all services have been loaded, and
3140 does not copy the found service.
3141 ***************************************************************************/
3143 int lp_servicenumber(const char *pszServiceName)
3146 fstring serviceName;
3149 for (iService = iNumServices - 1; iService >= 0; iService--) {
3150 if (VALID(iService) && ServicePtrs[iService]->szService) {
3152 * The substitution here is used to support %U is
3155 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3156 standard_sub_basic(serviceName,sizeof(serviceName));
3157 if (strequal(serviceName, pszServiceName))
3163 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3168 /*******************************************************************
3169 A useful volume label function.
3170 ********************************************************************/
3171 const char *volume_label(int snum)
3173 const char *ret = lp_volume(snum);
3175 return lp_servicename(snum);
3180 /*******************************************************************
3181 Set the server type we will announce as via nmbd.
3182 ********************************************************************/
3184 static void set_default_server_announce_type(void)
3186 default_server_announce = 0;
3187 default_server_announce |= SV_TYPE_WORKSTATION;
3188 default_server_announce |= SV_TYPE_SERVER;
3189 default_server_announce |= SV_TYPE_SERVER_UNIX;
3191 switch (lp_announce_as()) {
3192 case ANNOUNCE_AS_NT_SERVER:
3193 default_server_announce |= SV_TYPE_SERVER_NT;
3194 /* fall through... */
3195 case ANNOUNCE_AS_NT_WORKSTATION:
3196 default_server_announce |= SV_TYPE_NT;
3198 case ANNOUNCE_AS_WIN95:
3199 default_server_announce |= SV_TYPE_WIN95_PLUS;
3201 case ANNOUNCE_AS_WFW:
3202 default_server_announce |= SV_TYPE_WFW;
3208 switch (lp_server_role()) {
3209 case ROLE_DOMAIN_MEMBER:
3210 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3212 case ROLE_DOMAIN_PDC:
3213 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3215 case ROLE_DOMAIN_BDC:
3216 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3218 case ROLE_STANDALONE:
3222 if (lp_time_server())
3223 default_server_announce |= SV_TYPE_TIME_SOURCE;
3225 if (lp_host_msdfs())
3226 default_server_announce |= SV_TYPE_DFS_SERVER;
3229 /***********************************************************
3230 returns role of Samba server
3231 ************************************************************/
3233 int lp_server_role(void)
3238 /***********************************************************
3239 If we are PDC then prefer us as DMB
3240 ************************************************************/
3242 BOOL lp_domain_master(void)
3244 if (Globals.bDomainMaster == Auto)
3245 return (lp_server_role() == ROLE_DOMAIN_PDC);
3247 return Globals.bDomainMaster;
3250 /***********************************************************
3251 If we are DMB then prefer us as LMB
3252 ************************************************************/
3254 BOOL lp_preferred_master(void)
3256 if (Globals.bPreferredMaster == Auto)
3257 return (lp_local_master() && lp_domain_master());
3259 return Globals.bPreferredMaster;
3262 /*******************************************************************
3264 ********************************************************************/
3266 void lp_remove_service(int snum)
3268 ServicePtrs[snum]->valid = False;
3271 /*******************************************************************
3273 ********************************************************************/
3275 void lp_copy_service(int snum, const char *new_name)
3277 const char *oldname = lp_servicename(snum);
3278 do_section(new_name);
3280 snum = lp_servicenumber(new_name);
3282 lp_do_parameter(snum, "copy", oldname);
3287 /*******************************************************************
3288 Get the default server type we will announce as via nmbd.
3289 ********************************************************************/
3290 int lp_default_server_announce(void)
3292 return default_server_announce;
3295 const char *lp_printername(int snum)
3297 const char *ret = _lp_printername(snum);
3298 if (ret == NULL || (ret != NULL && *ret == '\0'))
3299 ret = lp_const_servicename(snum);
3305 /*******************************************************************
3306 Return the max print jobs per queue.
3307 ********************************************************************/
3309 int lp_maxprintjobs(int snum)
3311 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3312 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3313 maxjobs = PRINT_MAX_JOBID - 1;