2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/iconv.h"
60 #include "system/network.h"
61 #include "system/printing.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "librpc/gen_ndr/ndr_nbt.h"
65 #include "dlinklist.h"
67 BOOL in_client = False; /* Not in the client by default */
68 static BOOL bLoaded = False;
71 #define GLOBAL_NAME "global"
75 #define PRINTERS_NAME "printers"
79 #define HOMES_NAME "homes"
82 /* some helpful bits */
83 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
84 #define VALID(i) ServicePtrs[i]->valid
86 static BOOL do_parameter(const char *, const char *);
87 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
89 static BOOL defaults_saved = False;
92 #define FLAG_BASIC 0x0001 /* fundamental options */
93 #define FLAG_SHARE 0x0002 /* file sharing options */
94 #define FLAG_PRINT 0x0004 /* printing options */
95 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
96 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
97 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
98 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
99 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
100 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
101 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
102 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
105 /* the following are used by loadparm for option lists */
108 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
109 P_STRING,P_USTRING,P_ENUM,P_SEP
114 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
128 BOOL (*special)(const char *, char **);
129 const struct enum_list *enum_list;
142 struct param_opt *prev, *next;
149 * This structure describes global (ie., server-wide) parameters.
157 char *display_charset;
158 char *szPrintcapname;
162 char *szDefaultService;
164 char *szServerString;
165 char *szAutoServices;
166 char *szPasswdProgram;
170 char *szSMBPasswdFile;
175 char **szPreloadModules;
176 char **szPasswordServers;
177 char *szSocketOptions;
184 char **szWINSservers;
186 char *szRemoteAnnounce;
187 char *szRemoteBrowseSync;
188 char *szSocketAddress;
189 char *szAnnounceVersion; /* This is initialised in init_globals */
192 char **szNetbiosAliases;
193 char *szNetbiosScope;
194 char *szDomainOtherSIDs;
195 char **szNameResolveOrder;
197 char *szAddUserScript;
198 char *szAddMachineScript;
200 char *szWINSPartners;
201 char **dcerpc_ep_servers;
202 char **server_services;
205 char *szNonUnixAccountRange;
206 char *szTemplateHomedir;
207 char *szTemplateShell;
208 char *szWinbindSeparator;
209 BOOL bWinbindEnumUsers;
210 BOOL bWinbindEnumGroups;
211 BOOL bWinbindUseDefaultDomain;
212 char *szIDMapBackend;
213 char *szGuestaccount;
222 BOOL paranoid_server_security;
224 BOOL bDisableSpoolss;
226 int enhanced_browsing;
233 int announce_as; /* This is initialised in init_globals */
234 int machine_password_timeout;
235 int winbind_cache_time;
239 char *socket_options;
244 BOOL bPreferredMaster;
247 BOOL bEncryptPasswords;
249 BOOL bObeyPamRestrictions;
251 BOOL bLargeReadwrite;
255 BOOL bBindInterfacesOnly;
256 BOOL bPamPasswordChange;
258 BOOL bNTStatusSupport;
259 BOOL bAllowTrustedDomains;
265 BOOL bClientLanManAuth;
266 BOOL bClientNTLMv2Auth;
268 BOOL bHideLocalUsers;
271 BOOL bHostnameLookups;
272 BOOL bUnixExtensions;
273 BOOL bDisableNetbios;
275 int restrict_anonymous;
276 int name_cache_timeout;
277 struct param_opt *param_opt;
281 static global Globals;
284 * This structure describes a single service.
293 char **szInvalidUsers;
298 char *szPrintcommand;
301 char *szLppausecommand;
302 char *szLpresumecommand;
303 char *szQueuepausecommand;
304 char *szQueueresumecommand;
312 char **ntvfs_handler;
338 struct param_opt *param_opt;
340 char dummy[3]; /* for alignment */
345 /* This is a default service used to prime a services structure */
346 static service sDefault = {
348 False, /* not autoloaded */
349 NULL, /* szService */
351 NULL, /* szUsername */
352 NULL, /* szInvalidUsers */
353 NULL, /* szValidUsers */
354 NULL, /* szAdminUsers */
356 NULL, /* szInclude */
357 NULL, /* szPrintcommand */
358 NULL, /* szLpqcommand */
359 NULL, /* szLprmcommand */
360 NULL, /* szLppausecommand */
361 NULL, /* szLpresumecommand */
362 NULL, /* szQueuepausecommand */
363 NULL, /* szQueueresumecommand */
364 NULL, /* szPrintername */
365 NULL, /* szHostsallow */
366 NULL, /* szHostsdeny */
370 NULL, /* szMSDfsProxy */
371 NULL, /* ntvfs_handler */
372 0, /* iMinPrintSpace */
373 1000, /* iMaxPrintJobs */
374 0, /* iMaxConnections */
375 DEFAULT_PRINTING, /* iPrinting */
377 True, /* bAvailable */
378 True, /* bBrowseable */
379 True, /* bRead_only */
380 False, /* bPrint_ok */
381 False, /* bMap_system */
382 False, /* bMap_hidden */
383 True, /* bMap_archive */
385 True, /* bStrictLocking */
386 True, /* bPosixLocking */
388 True, /* bLevel2OpLocks */
389 False, /* bOnlyUser */
390 False, /* bGuest_only */
391 False, /* bGuest_ok */
393 False, /* bMSDfsRoot */
394 True, /* bShareModes */
395 False, /* bStrictSync */
396 False, /* bCIFileSystem */
397 NULL, /* Parametric options */
402 /* local variables */
403 static service **ServicePtrs = NULL;
404 static int iNumServices = 0;
405 static int iServiceIndex = 0;
406 static BOOL bInGlobalSection = True;
407 static BOOL bGlobalOnly = False;
408 static int server_role;
409 static int default_server_announce;
411 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
413 /* prototypes for the special type handlers */
414 static BOOL handle_include(const char *pszParmValue, char **ptr);
415 static BOOL handle_copy(const char *pszParmValue, char **ptr);
416 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
417 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
418 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
420 static void set_server_role(void);
421 static void set_default_server_announce_type(void);
423 static const struct enum_list enum_protocol[] = {
424 {PROTOCOL_NT1, "NT1"},
425 {PROTOCOL_LANMAN2, "LANMAN2"},
426 {PROTOCOL_LANMAN1, "LANMAN1"},
427 {PROTOCOL_CORE, "CORE"},
428 {PROTOCOL_COREPLUS, "COREPLUS"},
429 {PROTOCOL_COREPLUS, "CORE+"},
433 static const struct enum_list enum_security[] = {
434 {SEC_SHARE, "SHARE"},
436 {SEC_SERVER, "SERVER"},
437 {SEC_DOMAIN, "DOMAIN"},
444 static const struct enum_list enum_printing[] = {
445 {PRINT_SYSV, "sysv"},
447 {PRINT_HPUX, "hpux"},
451 {PRINT_LPRNG, "lprng"},
452 {PRINT_SOFTQ, "softq"},
453 {PRINT_CUPS, "cups"},
455 {PRINT_LPROS2, "os2"},
457 {PRINT_TEST, "test"},
459 #endif /* DEVELOPER */
463 /* Types of machine we can announce as. */
464 #define ANNOUNCE_AS_NT_SERVER 1
465 #define ANNOUNCE_AS_WIN95 2
466 #define ANNOUNCE_AS_WFW 3
467 #define ANNOUNCE_AS_NT_WORKSTATION 4
469 static const struct enum_list enum_announce_as[] = {
470 {ANNOUNCE_AS_NT_SERVER, "NT"},
471 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
472 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
473 {ANNOUNCE_AS_WIN95, "win95"},
474 {ANNOUNCE_AS_WFW, "WfW"},
478 static const struct enum_list enum_bool_auto[] = {
489 /* Client-side offline caching policy types */
490 #define CSC_POLICY_MANUAL 0
491 #define CSC_POLICY_DOCUMENTS 1
492 #define CSC_POLICY_PROGRAMS 2
493 #define CSC_POLICY_DISABLE 3
495 static const struct enum_list enum_csc_policy[] = {
496 {CSC_POLICY_MANUAL, "manual"},
497 {CSC_POLICY_DOCUMENTS, "documents"},
498 {CSC_POLICY_PROGRAMS, "programs"},
499 {CSC_POLICY_DISABLE, "disable"},
503 /* SMB signing types. */
504 static const struct enum_list enum_smb_signing_vals[] = {
505 {SMB_SIGNING_OFF, "No"},
506 {SMB_SIGNING_OFF, "False"},
507 {SMB_SIGNING_OFF, "0"},
508 {SMB_SIGNING_OFF, "Off"},
509 {SMB_SIGNING_OFF, "disabled"},
510 {SMB_SIGNING_SUPPORTED, "Yes"},
511 {SMB_SIGNING_SUPPORTED, "True"},
512 {SMB_SIGNING_SUPPORTED, "1"},
513 {SMB_SIGNING_SUPPORTED, "On"},
514 {SMB_SIGNING_SUPPORTED, "enabled"},
515 {SMB_SIGNING_REQUIRED, "required"},
516 {SMB_SIGNING_REQUIRED, "mandatory"},
517 {SMB_SIGNING_REQUIRED, "force"},
518 {SMB_SIGNING_REQUIRED, "forced"},
519 {SMB_SIGNING_REQUIRED, "enforced"},
520 {SMB_SIGNING_AUTO, "auto"},
525 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
527 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
528 * is implied in current control logic. This may change at some later time. A
529 * flag value of 0 means - show as development option only.
531 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
532 * screen in SWAT. This is used to exclude parameters as well as to squash all
533 * parameters that have been duplicated by pseudonyms.
535 static struct parm_struct parm_table[] = {
536 {"Base Options", P_SEP, P_SEPARATOR},
538 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
543 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
544 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
545 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
546 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
547 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
550 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
553 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
554 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
555 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
556 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
558 {"Security Options", P_SEP, P_SEPARATOR},
560 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
561 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
562 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
563 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
569 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
578 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
588 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
591 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
592 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
593 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
595 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
596 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
597 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
599 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
601 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
603 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
605 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
606 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
607 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
608 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
610 {"Logging Options", P_SEP, P_SEPARATOR},
612 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
614 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
616 {"Protocol Options", P_SEP, P_SEPARATOR},
618 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
619 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
620 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
621 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
622 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
623 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
624 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
625 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
626 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
631 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
632 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
635 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
636 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
637 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
638 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
639 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
640 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
641 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
642 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
643 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
644 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
646 {"Tuning Options", P_SEP, P_SEPARATOR},
648 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
649 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
650 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
651 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
653 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
654 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
655 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
657 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
658 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
659 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
661 {"Printing Options", P_SEP, P_SEPARATOR},
663 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
664 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
665 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
666 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
667 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
668 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
669 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
670 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
671 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
673 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
674 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
675 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
676 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
677 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
679 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
680 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
682 {"Filename Handling", P_SEP, P_SEPARATOR},
684 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
685 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
686 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
688 {"Domain Options", P_SEP, P_SEPARATOR},
690 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
692 {"Logon Options", P_SEP, P_SEPARATOR},
694 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
697 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
703 {"Browse Options", P_SEP, P_SEPARATOR},
705 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
706 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
708 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
709 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
710 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
712 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
713 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
714 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
716 {"WINS Options", P_SEP, P_SEPARATOR},
717 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
718 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
720 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
721 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
722 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
723 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
725 {"Locking Options", P_SEP, P_SEPARATOR},
727 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
728 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
729 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
730 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
732 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
733 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
734 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
735 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
736 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
738 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
740 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
741 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
744 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
748 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
749 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
750 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
751 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
752 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
753 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
755 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
756 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
758 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
759 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
760 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
762 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
766 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
767 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"Winbind options", P_SEP, P_SEPARATOR},
770 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
783 /***************************************************************************
784 Initialise the sDefault parameter structure for the printer values.
785 ***************************************************************************/
787 static void init_printer_values(void)
789 /* choose defaults depending on the type of printing */
790 switch (sDefault.iPrinting) {
795 do_parameter("Lpqcommand", "lpq -P'%p'");
796 do_parameter("Lprmcommand", "lprm -P'%p' %j");
797 do_parameter("Printcommand",
803 do_parameter("Lpqcommand", "lpq -P'%p'");
804 do_parameter("Lprmcommand", "lprm -P'%p' %j");
805 do_parameter("Printcommand",
807 do_parameter("Queuepausecommand",
809 do_parameter("Queueresumecommand",
811 do_parameter("Lppausecommand",
813 do_parameter("Lpresumecommand",
814 "lpc release '%p' %j");
819 do_parameter("Lpqcommand", "");
820 do_parameter("Lprmcommand", "");
821 do_parameter("Printcommand", "");
822 do_parameter("Lppausecommand", "");
823 do_parameter("Lpresumecommand", "");
824 do_parameter("Queuepausecommand", "");
825 do_parameter("Queueresumecommand", "");
827 do_parameter("Printcapname", "cups");
829 do_parameter("Lpqcommand",
830 "/usr/bin/lpstat -o '%p'");
831 do_parameter("Lprmcommand",
832 "/usr/bin/cancel '%p-%j'");
833 do_parameter("Printcommand",
834 "/usr/bin/lp -d '%p' %s; rm %s");
835 do_parameter("Lppausecommand",
836 "lp -i '%p-%j' -H hold");
837 do_parameter("Lpresumecommand",
838 "lp -i '%p-%j' -H resume");
839 do_parameter("Queuepausecommand",
840 "/usr/bin/disable '%p'");
841 do_parameter("Queueresumecommand",
842 "/usr/bin/enable '%p'");
843 do_parameter("Printcapname", "lpstat");
844 #endif /* HAVE_CUPS */
849 do_parameter("Lpqcommand", "lpstat -o%p");
850 do_parameter("Lprmcommand", "cancel %p-%j");
851 do_parameter("Printcommand",
852 "lp -c -d%p %s; rm %s");
853 do_parameter("Queuepausecommand",
855 do_parameter("Queueresumecommand",
858 do_parameter("Lppausecommand",
859 "lp -i %p-%j -H hold");
860 do_parameter("Lpresumecommand",
861 "lp -i %p-%j -H resume");
866 do_parameter("Lpqcommand", "lpq -P%p");
867 do_parameter("Lprmcommand", "lprm -P%p %j");
868 do_parameter("Printcommand", "lp -r -P%p %s");
872 do_parameter("Lpqcommand", "qstat -l -d%p");
873 do_parameter("Lprmcommand",
875 do_parameter("Printcommand",
876 "lp -d%p -s %s; rm %s");
877 do_parameter("Lppausecommand",
879 do_parameter("Lpresumecommand",
885 do_parameter("Printcommand", "vlp print %p %s");
886 do_parameter("Lpqcommand", "vlp lpq %p");
887 do_parameter("Lprmcommand", "vlp lprm %p %j");
888 do_parameter("Lppausecommand", "vlp lppause %p %j");
889 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
890 do_parameter("Queuepausecommand", "vlp queuepause %p");
891 do_parameter("Queueresumecommand", "vlp queueresume %p");
893 #endif /* DEVELOPER */
899 /***************************************************************************
900 Initialise the global parameter structure.
901 ***************************************************************************/
902 static void init_globals(void)
907 DEBUG(3, ("Initialising global parameters\n"));
909 for (i = 0; parm_table[i].label; i++) {
910 if ((parm_table[i].type == P_STRING ||
911 parm_table[i].type == P_USTRING) &&
913 !(parm_table[i].flags & FLAG_CMDLINE)) {
914 string_set(parm_table[i].ptr, "");
918 /* options that can be set on the command line must be initialised via
919 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
921 do_parameter("socket options", "TCP_NODELAY");
923 do_parameter("workgroup", DEFAULT_WORKGROUP);
924 myname = get_myname();
925 do_parameter("netbios name", myname);
927 do_parameter("max protocol", "NT1");
928 do_parameter("name resolve order", "lmhosts wins host bcast");
930 init_printer_values();
932 do_parameter("fstype", FSTYPE_STRING);
933 do_parameter("ntvfs handler", "unixuid default");
934 do_parameter("max connections", "-1");
936 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
937 do_parameter("server services", "smb rpc nbt");
938 do_parameter("auth methods", "anonymous sam_ignoredomain");
939 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
940 do_parameter("private dir", dyn_PRIVATE_DIR);
941 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
942 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
943 do_parameter_var("wins database", "tdb://%s/wins.ldb", dyn_PRIVATE_DIR);
944 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
945 do_parameter("guest account", GUEST_ACCOUNT);
947 /* using UTF8 by default allows us to support all chars */
948 do_parameter("unix charset", "UTF8");
950 /* Use codepage 850 as a default for the dos character set */
951 do_parameter("dos charset", "CP850");
954 * Allow the default PASSWD_CHAT to be overridden in local.h.
956 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
958 do_parameter("passwd program", "");
959 do_parameter("printcap name", PRINTCAP_NAME);
961 do_parameter("pid directory", dyn_PIDDIR);
962 do_parameter("lock dir", dyn_LOCKDIR);
963 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
965 do_parameter("socket address", "0.0.0.0");
966 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
968 do_parameter_var("announce version", "%d.%d",
969 DEFAULT_MAJOR_VERSION,
970 DEFAULT_MINOR_VERSION);
972 do_parameter("logon drive", "");
974 do_parameter("logon home", "\\\\%N\\%U");
975 do_parameter("logon path", "\\\\%N\\%U\\profile");
976 do_parameter("password server", "*");
978 do_parameter("load printers", "True");
980 do_parameter("max mux", "50");
981 do_parameter("max xmit", "12288");
982 do_parameter("lpqcachetime", "10");
983 do_parameter("DisableSpoolss", "False");
984 do_parameter("password level", "0");
985 do_parameter("username level", "0");
986 do_parameter("LargeReadwrite", "True");
987 do_parameter("minprotocol", "CORE");
988 do_parameter("security", "USER");
989 do_parameter("paranoid server security", "True");
990 do_parameter("EncryptPasswords", "True");
991 do_parameter("ReadRaw", "True");
992 do_parameter("WriteRaw", "True");
993 do_parameter("NullPasswords", "False");
994 do_parameter("ObeyPamRestrictions", "False");
995 do_parameter("lm announce", "Auto");
996 do_parameter("lm interval", "60");
997 do_parameter("announce as", "NT SERVER");
999 do_parameter("TimeServer", "False");
1000 do_parameter("BindInterfacesOnly", "False");
1001 do_parameter("PamPasswordChange", "False");
1002 do_parameter("Unicode", "True");
1003 do_parameter("restrict anonymous", "0");
1004 do_parameter("ClientLanManAuth", "True");
1005 do_parameter("LanmanAuth", "True");
1006 do_parameter("NTLMAuth", "True");
1008 do_parameter("enhanced browsing", "True");
1009 do_parameter("LockSpinCount", "3");
1010 do_parameter("LockSpinTime", "10");
1011 #ifdef MMAP_BLACKLIST
1012 do_parameter("UseMmap", "False");
1014 do_parameter("UseMmap", "True");
1016 do_parameter("UnixExtensions", "False");
1018 /* hostname lookups can be very expensive and are broken on
1019 a large number of sites (tridge) */
1020 do_parameter("HostnameLookups", "False");
1022 do_parameter("PreferredMaster", "Auto");
1023 do_parameter("os level", "20");
1024 do_parameter("LocalMaster", "True");
1025 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1026 do_parameter("DomainLogons", "False");
1027 do_parameter("WINSsupport", "False");
1028 do_parameter("WINSproxy", "False");
1030 do_parameter("DNSproxy", "True");
1032 do_parameter("AllowTrustedDomains", "True");
1034 do_parameter("TemplateShell", "/bin/false");
1035 do_parameter("TemplateHomedir", "/home/%D/%U");
1036 do_parameter("WinbindSeparator", "\\");
1038 do_parameter("winbind cache time", "15");
1039 do_parameter("WinbindEnumUsers", "True");
1040 do_parameter("WinbindEnumGroups", "True");
1041 do_parameter("WinbindUseDefaultDomain", "False");
1043 do_parameter("IDMapBackend", "tdb");
1045 do_parameter("name cache timeout", "660"); /* In seconds */
1047 do_parameter("client signing", "Yes");
1048 do_parameter("server signing", "auto");
1050 do_parameter("use spnego", "True");
1052 do_parameter("smb ports", SMB_PORTS);
1053 do_parameter("nbt port", "137");
1055 do_parameter("nt status support", "True");
1057 do_parameter("max wins ttl", "432000");
1058 do_parameter("min wins ttl", "10");
1061 static TALLOC_CTX *lp_talloc;
1063 /******************************************************************* a
1064 Free up temporary memory - called from the main loop.
1065 ********************************************************************/
1067 void lp_talloc_free(void)
1071 talloc_free(lp_talloc);
1075 /*******************************************************************
1076 Convenience routine to grab string parameters into temporary memory
1077 and run standard_sub_basic on them. The buffers can be written to by
1078 callers without affecting the source string.
1079 ********************************************************************/
1081 static const char *lp_string(const char *s)
1083 #if 0 /* until REWRITE done to make thread-safe */
1084 size_t len = s ? strlen(s) : 0;
1088 /* The follow debug is useful for tracking down memory problems
1089 especially if you have an inner loop that is calling a lp_*()
1090 function that returns a string. Perhaps this debug should be
1091 present all the time? */
1094 DEBUG(10, ("lp_string(%s)\n", s));
1097 #if 0 /* until REWRITE done to make thread-safe */
1099 lp_talloc = talloc_init("lp_talloc");
1101 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1109 StrnCpy(ret, s, len);
1111 if (trim_string(ret, "\"", "\"")) {
1112 if (strchr(ret,'"') != NULL)
1113 StrnCpy(ret, s, len);
1116 standard_sub_basic(ret,len+100);
1123 In this section all the functions that are used to access the
1124 parameters from the rest of the program are defined
1127 #define FN_GLOBAL_STRING(fn_name,ptr) \
1128 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1129 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1130 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1131 #define FN_GLOBAL_LIST(fn_name,ptr) \
1132 const char **fn_name(void) {return(*(const char ***)(ptr));}
1133 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1134 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1135 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1136 char fn_name(void) {return(*(char *)(ptr));}
1137 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1138 int fn_name(void) {return(*(int *)(ptr));}
1140 #define FN_LOCAL_STRING(fn_name,val) \
1141 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1142 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1143 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1144 #define FN_LOCAL_LIST(fn_name,val) \
1145 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1146 #define FN_LOCAL_BOOL(fn_name,val) \
1147 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1148 #define FN_LOCAL_CHAR(fn_name,val) \
1149 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1150 #define FN_LOCAL_INTEGER(fn_name,val) \
1151 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1153 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1154 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1155 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1156 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1157 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1158 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1159 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1160 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1161 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1162 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1163 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
1164 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1165 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1166 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1167 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1168 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1169 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1170 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1171 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1172 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1173 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1174 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1175 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1176 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1177 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1178 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1179 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1180 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1181 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1182 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1183 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1184 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1185 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1186 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1187 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1188 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1189 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1190 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1191 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1192 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1193 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1194 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1195 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1196 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1197 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1198 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1200 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1202 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1204 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1205 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1206 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1207 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1208 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1209 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1210 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1211 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1212 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1214 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1215 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1216 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1217 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1218 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1219 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1220 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1221 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1222 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1223 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1224 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1225 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1226 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1227 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1228 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1229 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1230 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1231 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1232 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1233 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1234 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1235 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1236 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1237 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1238 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1239 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1240 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1241 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1242 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1243 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1244 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1245 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1246 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1247 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1248 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1249 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1250 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1251 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1252 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1253 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1254 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1255 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1256 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1257 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1258 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1259 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1260 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1261 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1262 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1263 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1264 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1265 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1266 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1267 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1268 FN_LOCAL_STRING(lp_servicename, szService)
1269 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1270 FN_LOCAL_STRING(lp_pathname, szPath)
1271 FN_LOCAL_STRING(lp_username, szUsername)
1272 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1273 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1274 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1275 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1276 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1277 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1278 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1279 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1280 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1281 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1282 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1283 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1284 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1285 FN_LOCAL_STRING(lp_comment, comment)
1286 FN_LOCAL_STRING(lp_fstype, fstype)
1287 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1288 static FN_LOCAL_STRING(lp_volume, volume)
1289 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1290 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1291 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1292 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1293 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1294 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1295 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1296 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1297 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1298 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1299 FN_LOCAL_BOOL(lp_locking, bLocking)
1300 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1301 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1302 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1303 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1304 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1305 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1306 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1307 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1308 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1309 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1310 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1311 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1312 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1313 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1314 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1315 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1316 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1317 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1319 /* local prototypes */
1321 static int map_parameter(const char *pszParmName);
1322 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1323 static int getservicebyname(const char *pszServiceName,
1324 service * pserviceDest);
1325 static void copy_service(service * pserviceDest,
1326 service * pserviceSource, BOOL *pcopymapDest);
1327 static BOOL service_ok(int iService);
1328 static BOOL do_section(const char *pszSectionName);
1329 static void init_copymap(service * pservice);
1331 /* This is a helper function for parametrical options support. */
1332 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1333 /* Actual parametrical functions are quite simple */
1334 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1337 struct param_opt *data;
1339 if (lookup_service >= iNumServices) return NULL;
1341 data = (lookup_service < 0) ?
1342 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1344 asprintf(&vfskey, "%s:%s", type, option);
1348 if (strcmp(data->key, vfskey) == 0) {
1355 if (lookup_service >= 0) {
1356 /* Try to fetch the same option but from globals */
1357 /* but only if we are not already working with Globals */
1358 data = Globals.param_opt;
1360 if (strcmp(data->key, vfskey) == 0) {
1374 /*******************************************************************
1375 convenience routine to return int parameters.
1376 ********************************************************************/
1377 static int lp_int(const char *s)
1381 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1388 /*******************************************************************
1389 convenience routine to return unsigned long parameters.
1390 ********************************************************************/
1391 static int lp_ulong(const char *s)
1395 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1399 return strtoul(s, NULL, 10);
1402 /*******************************************************************
1403 convenience routine to return boolean parameters.
1404 ********************************************************************/
1405 static BOOL lp_bool(const char *s)
1410 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1414 if (!set_boolean(&ret,s)) {
1415 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
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 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1429 const char *value = get_parametrics(lookup_service, type, option);
1432 return lp_string(value);
1437 /* Return parametric option from a given service. Type is a part of option before ':' */
1438 /* Parametric option has following syntax: 'Type: option = value' */
1439 /* Returned value is allocated in 'lp_talloc' context */
1441 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1442 const char *separator)
1444 const char *value = get_parametrics(lookup_service, type, option);
1447 return str_list_make(talloc_autofree_context(), value, separator);
1452 /* Return parametric option from a given service. Type is a part of option before ':' */
1453 /* Parametric option has following syntax: 'Type: option = value' */
1455 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1457 const char *value = get_parametrics(lookup_service, type, option);
1460 return lp_int(value);
1465 /* Return parametric option from a given service. Type is a part of option before ':' */
1466 /* Parametric option has following syntax: 'Type: option = value' */
1468 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1470 const char *value = get_parametrics(lookup_service, type, option);
1473 return lp_ulong(value);
1478 /* Return parametric option from a given service. Type is a part of option before ':' */
1479 /* Parametric option has following syntax: 'Type: option = value' */
1481 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1483 const char *value = get_parametrics(lookup_service, type, option);
1486 return lp_bool(value);
1492 /***************************************************************************
1493 Initialise a service to the defaults.
1494 ***************************************************************************/
1496 static void init_service(service * pservice)
1498 memset((char *)pservice, '\0', sizeof(service));
1499 copy_service(pservice, &sDefault, NULL);
1502 /***************************************************************************
1503 Free the dynamically allocated parts of a service struct.
1504 ***************************************************************************/
1506 static void free_service(service *pservice)
1509 struct param_opt *data, *pdata;
1513 if (pservice->szService)
1514 DEBUG(5, ("free_service: Freeing service %s\n",
1515 pservice->szService));
1517 string_free(&pservice->szService);
1518 SAFE_FREE(pservice->copymap);
1520 for (i = 0; parm_table[i].label; i++) {
1521 if ((parm_table[i].type == P_STRING ||
1522 parm_table[i].type == P_USTRING) &&
1523 parm_table[i].class == P_LOCAL) {
1524 string_free((char **)
1525 (((char *)pservice) +
1526 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1527 } else if (parm_table[i].type == P_LIST &&
1528 parm_table[i].class == P_LOCAL) {
1529 char ***listp = (char ***)(((char *)pservice) +
1530 PTR_DIFF(parm_table[i].ptr, &sDefault));
1531 talloc_free(*listp);
1536 DEBUG(5,("Freeing parametrics:\n"));
1537 data = pservice->param_opt;
1539 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1540 string_free(&data->key);
1541 string_free(&data->value);
1547 ZERO_STRUCTP(pservice);
1550 /***************************************************************************
1551 Add a new service to the services array initialising it with the given
1553 ***************************************************************************/
1555 static int add_a_service(const service *pservice, const char *name)
1559 int num_to_alloc = iNumServices + 1;
1560 struct param_opt *data, *pdata;
1562 tservice = *pservice;
1564 /* it might already exist */
1566 i = getservicebyname(name, NULL);
1568 /* Clean all parametric options for service */
1569 /* They will be added during parsing again */
1570 data = ServicePtrs[i]->param_opt;
1572 string_free(&data->key);
1573 string_free(&data->value);
1578 ServicePtrs[i]->param_opt = NULL;
1583 /* find an invalid one */
1584 for (i = 0; i < iNumServices; i++)
1585 if (!ServicePtrs[i]->valid)
1588 /* if not, then create one */
1589 if (i == iNumServices) {
1592 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1595 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1600 ServicePtrs[iNumServices] = malloc_p(service);
1602 if (!ServicePtrs[iNumServices]) {
1603 DEBUG(0,("add_a_service: out of memory!\n"));
1609 free_service(ServicePtrs[i]);
1611 ServicePtrs[i]->valid = True;
1613 init_service(ServicePtrs[i]);
1614 copy_service(ServicePtrs[i], &tservice, NULL);
1616 string_set(&ServicePtrs[i]->szService, name);
1620 /***************************************************************************
1621 Add a new home service, with the specified home directory, defaults coming
1623 ***************************************************************************/
1625 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1626 const char *user, const char *pszHomedir)
1631 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1636 if (!(*(ServicePtrs[iDefaultService]->szPath))
1637 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1638 pstrcpy(newHomedir, pszHomedir);
1640 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1641 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1644 string_set(&ServicePtrs[i]->szPath, newHomedir);
1646 if (!(*(ServicePtrs[i]->comment))) {
1648 slprintf(comment, sizeof(comment) - 1,
1649 "Home directory of %s", user);
1650 string_set(&ServicePtrs[i]->comment, comment);
1652 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1653 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1655 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1661 /***************************************************************************
1662 Add a new service, based on an old one.
1663 ***************************************************************************/
1665 int lp_add_service(const char *pszService, int iDefaultService)
1667 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1670 /***************************************************************************
1671 Add the IPC service.
1672 ***************************************************************************/
1674 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1677 int i = add_a_service(&sDefault, name);
1682 slprintf(comment, sizeof(comment) - 1,
1683 "%s Service (%s)", fstype, Globals.szServerString);
1685 string_set(&ServicePtrs[i]->szPath, tmpdir());
1686 string_set(&ServicePtrs[i]->szUsername, "");
1687 string_set(&ServicePtrs[i]->comment, comment);
1688 string_set(&ServicePtrs[i]->fstype, fstype);
1689 ServicePtrs[i]->iMaxConnections = -1;
1690 ServicePtrs[i]->bAvailable = True;
1691 ServicePtrs[i]->bRead_only = True;
1692 ServicePtrs[i]->bGuest_only = False;
1693 ServicePtrs[i]->bGuest_ok = guest_ok;
1694 ServicePtrs[i]->bPrint_ok = False;
1695 ServicePtrs[i]->bBrowseable = False;
1697 if (strcasecmp(fstype, "IPC") == 0) {
1698 lp_do_parameter(i, "ntvfs handler", "default");
1701 DEBUG(3, ("adding hidden service %s\n", name));
1706 /***************************************************************************
1707 Add a new printer service, with defaults coming from service iFrom.
1708 ***************************************************************************/
1710 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1712 const char *comment = "From Printcap";
1713 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1718 /* note that we do NOT default the availability flag to True - */
1719 /* we take it from the default service passed. This allows all */
1720 /* dynamic printers to be disabled by disabling the [printers] */
1721 /* entry (if/when the 'available' keyword is implemented!). */
1723 /* the printer name is set to the service name. */
1724 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1725 string_set(&ServicePtrs[i]->comment, comment);
1726 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1727 /* Printers cannot be read_only. */
1728 ServicePtrs[i]->bRead_only = False;
1729 /* No share modes on printer services. */
1730 ServicePtrs[i]->bShareModes = False;
1731 /* No oplocks on printer services. */
1732 ServicePtrs[i]->bOpLocks = False;
1733 /* Printer services must be printable. */
1734 ServicePtrs[i]->bPrint_ok = True;
1736 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1738 update_server_announce_as_printserver();
1743 /***************************************************************************
1744 Map a parameter's string representation to something we can use.
1745 Returns False if the parameter string is not recognised, else TRUE.
1746 ***************************************************************************/
1748 static int map_parameter(const char *pszParmName)
1752 if (*pszParmName == '-')
1755 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1756 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1759 /* Warn only if it isn't parametric option */
1760 if (strchr(pszParmName, ':') == NULL)
1761 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1762 /* We do return 'fail' for parametric options as well because they are
1763 stored in different storage
1768 /***************************************************************************
1769 Set a boolean variable from the text value stored in the passed string.
1770 Returns True in success, False if the passed string does not correctly
1771 represent a boolean.
1772 ***************************************************************************/
1774 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1779 if (strwicmp(pszParmValue, "yes") == 0 ||
1780 strwicmp(pszParmValue, "true") == 0 ||
1781 strwicmp(pszParmValue, "1") == 0)
1783 else if (strwicmp(pszParmValue, "no") == 0 ||
1784 strwicmp(pszParmValue, "False") == 0 ||
1785 strwicmp(pszParmValue, "0") == 0)
1789 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1796 /***************************************************************************
1797 Find a service by name. Otherwise works like get_service.
1798 ***************************************************************************/
1800 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1804 for (iService = iNumServices - 1; iService >= 0; iService--)
1805 if (VALID(iService) &&
1806 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1807 if (pserviceDest != NULL)
1808 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1815 /***************************************************************************
1816 Copy a service structure to another.
1817 If pcopymapDest is NULL then copy all fields
1818 ***************************************************************************/
1820 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1823 BOOL bcopyall = (pcopymapDest == NULL);
1824 struct param_opt *data, *pdata, *paramo;
1827 for (i = 0; parm_table[i].label; i++)
1828 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1829 (bcopyall || pcopymapDest[i])) {
1830 void *def_ptr = parm_table[i].ptr;
1832 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1835 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1838 switch (parm_table[i].type) {
1841 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1847 *(int *)dest_ptr = *(int *)src_ptr;
1851 *(char *)dest_ptr = *(char *)src_ptr;
1855 string_set(dest_ptr,
1860 string_set(dest_ptr,
1862 strupper(*(char **)dest_ptr);
1865 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1866 *(const char ***)src_ptr);
1874 init_copymap(pserviceDest);
1875 if (pserviceSource->copymap)
1876 memcpy((void *)pserviceDest->copymap,
1877 (void *)pserviceSource->copymap,
1878 sizeof(BOOL) * NUMPARAMETERS);
1881 data = pserviceSource->param_opt;
1884 pdata = pserviceDest->param_opt;
1885 /* Traverse destination */
1887 /* If we already have same option, override it */
1888 if (strcmp(pdata->key, data->key) == 0) {
1889 string_free(&pdata->value);
1890 pdata->value = strdup(data->value);
1894 pdata = pdata->next;
1897 paramo = smb_xmalloc_p(struct param_opt);
1898 paramo->key = strdup(data->key);
1899 paramo->value = strdup(data->value);
1900 DLIST_ADD(pserviceDest->param_opt, paramo);
1906 /***************************************************************************
1907 Check a service for consistency. Return False if the service is in any way
1908 incomplete or faulty, else True.
1909 ***************************************************************************/
1911 static BOOL service_ok(int iService)
1916 if (ServicePtrs[iService]->szService[0] == '\0') {
1917 DEBUG(0, ("The following message indicates an internal error:\n"));
1918 DEBUG(0, ("No service name in service entry.\n"));
1922 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1923 /* I can't see why you'd want a non-printable printer service... */
1924 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1925 if (!ServicePtrs[iService]->bPrint_ok) {
1926 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1927 ServicePtrs[iService]->szService));
1928 ServicePtrs[iService]->bPrint_ok = True;
1929 update_server_announce_as_printserver();
1931 /* [printers] service must also be non-browsable. */
1932 if (ServicePtrs[iService]->bBrowseable)
1933 ServicePtrs[iService]->bBrowseable = False;
1936 /* If a service is flagged unavailable, log the fact at level 0. */
1937 if (!ServicePtrs[iService]->bAvailable)
1938 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1939 ServicePtrs[iService]->szService));
1944 static struct file_lists {
1945 struct file_lists *next;
1949 } *file_lists = NULL;
1951 /*******************************************************************
1952 Keep a linked list of all config files so we know when one has changed
1953 it's date and needs to be reloaded.
1954 ********************************************************************/
1956 static void add_to_file_list(const char *fname, const char *subfname)
1958 struct file_lists *f = file_lists;
1961 if (f->name && !strcmp(f->name, fname))
1967 f = malloc_p(struct file_lists);
1970 f->next = file_lists;
1971 f->name = strdup(fname);
1976 f->subfname = strdup(subfname);
1982 f->modtime = file_modtime(subfname);
1984 time_t t = file_modtime(subfname);
1990 /*******************************************************************
1991 Check if a config file has changed date.
1992 ********************************************************************/
1994 BOOL lp_file_list_changed(void)
1996 struct file_lists *f = file_lists;
1997 DEBUG(6, ("lp_file_list_changed()\n"));
2003 pstrcpy(n2, f->name);
2004 standard_sub_basic(n2,sizeof(n2));
2006 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2007 f->name, n2, ctime(&f->modtime)));
2009 mod_time = file_modtime(n2);
2011 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2013 ("file %s modified: %s\n", n2,
2015 f->modtime = mod_time;
2016 SAFE_FREE(f->subfname);
2017 f->subfname = strdup(n2);
2025 /***************************************************************************
2026 Handle the include operation.
2027 ***************************************************************************/
2029 static BOOL handle_include(const char *pszParmValue, char **ptr)
2032 pstrcpy(fname, pszParmValue);
2034 standard_sub_basic(fname,sizeof(fname));
2036 add_to_file_list(pszParmValue, fname);
2038 string_set(ptr, fname);
2040 if (file_exist(fname))
2041 return (pm_process(fname, do_section, do_parameter));
2043 DEBUG(2, ("Can't find include file %s\n", fname));
2048 /***************************************************************************
2049 Handle the interpretation of the copy parameter.
2050 ***************************************************************************/
2052 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2056 service serviceTemp;
2058 string_set(ptr, pszParmValue);
2060 init_service(&serviceTemp);
2064 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2066 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2067 if (iTemp == iServiceIndex) {
2068 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2070 copy_service(ServicePtrs[iServiceIndex],
2072 ServicePtrs[iServiceIndex]->copymap);
2076 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2080 free_service(&serviceTemp);
2084 /***************************************************************************
2085 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2090 winbind uid = 1000-1999
2091 winbind gid = 700-899
2093 We only do simple parsing checks here. The strings are parsed into useful
2094 structures in the winbind daemon code.
2096 ***************************************************************************/
2098 /* Some lp_ routines to return winbind [ug]id information */
2100 static uid_t winbind_uid_low, winbind_uid_high;
2101 static gid_t winbind_gid_low, winbind_gid_high;
2102 static uint32_t non_unix_account_low, non_unix_account_high;
2104 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2106 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2110 *low = winbind_uid_low;
2113 *high = winbind_uid_high;
2118 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2120 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2124 *low = winbind_gid_low;
2127 *high = winbind_gid_high;
2132 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2134 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2138 *low = non_unix_account_low;
2141 *high = non_unix_account_high;
2146 /* Do some simple checks on "winbind [ug]id" parameter values */
2148 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2152 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2157 string_set(ptr, pszParmValue);
2159 winbind_uid_low = low;
2160 winbind_uid_high = high;
2165 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2169 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2174 string_set(ptr, pszParmValue);
2176 winbind_gid_low = low;
2177 winbind_gid_high = high;
2182 /***************************************************************************
2183 Do some simple checks on "non unix account range" parameter values.
2184 ***************************************************************************/
2186 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2190 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2195 string_set(ptr, pszParmValue);
2197 non_unix_account_low = low;
2198 non_unix_account_high = high;
2204 /***************************************************************************
2205 Initialise a copymap.
2206 ***************************************************************************/
2208 static void init_copymap(service * pservice)
2211 SAFE_FREE(pservice->copymap);
2212 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2213 if (!pservice->copymap)
2215 ("Couldn't allocate copymap!! (size %d)\n",
2216 (int)NUMPARAMETERS));
2218 for (i = 0; i < NUMPARAMETERS; i++)
2219 pservice->copymap[i] = True;
2222 /***************************************************************************
2223 Return the local pointer to a parameter given the service number and the
2224 pointer into the default structure.
2225 ***************************************************************************/
2227 void *lp_local_ptr(int snum, void *ptr)
2229 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2233 /***************************************************************************
2234 Process a parametric option
2235 ***************************************************************************/
2236 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2238 struct param_opt *paramo, *data;
2241 while (isspace(*pszParmName)) {
2245 name = strdup(pszParmName);
2246 if (!name) return False;
2251 data = Globals.param_opt;
2253 data = ServicePtrs[snum]->param_opt;
2256 /* Traverse destination */
2257 for (paramo=data; paramo; paramo=paramo->next) {
2258 /* If we already have the option set, override it unless
2259 it was a command line option and the new one isn't */
2260 if (strcmp(paramo->key, name) == 0) {
2261 if ((paramo->flags & FLAG_CMDLINE) &&
2262 !(flags & FLAG_CMDLINE)) {
2266 free(paramo->value);
2267 paramo->value = strdup(pszParmValue);
2268 paramo->flags = flags;
2274 paramo = smb_xmalloc_p(struct param_opt);
2275 paramo->key = strdup(name);
2276 paramo->value = strdup(pszParmValue);
2277 paramo->flags = flags;
2279 DLIST_ADD(Globals.param_opt, paramo);
2281 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2289 /***************************************************************************
2290 Process a parameter for a particular service number. If snum < 0
2291 then assume we are in the globals.
2292 ***************************************************************************/
2293 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2296 void *parm_ptr = NULL; /* where we are going to store the result */
2297 void *def_ptr = NULL;
2299 parmnum = map_parameter(pszParmName);
2302 if (strchr(pszParmName, ':')) {
2303 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2305 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2309 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2310 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2314 /* if the flag has been set on the command line, then don't allow override,
2315 but don't report an error */
2316 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2320 def_ptr = parm_table[parmnum].ptr;
2322 /* we might point at a service, the default service or a global */
2326 if (parm_table[parmnum].class == P_GLOBAL) {
2328 ("Global parameter %s found in service section!\n",
2333 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2338 if (!ServicePtrs[snum]->copymap)
2339 init_copymap(ServicePtrs[snum]);
2341 /* this handles the aliases - set the copymap for other entries with
2342 the same data pointer */
2343 for (i = 0; parm_table[i].label; i++)
2344 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2345 ServicePtrs[snum]->copymap[i] = False;
2348 /* if it is a special case then go ahead */
2349 if (parm_table[parmnum].special) {
2350 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2354 /* now switch on the type of variable it is */
2355 switch (parm_table[parmnum].type)
2358 set_boolean(parm_ptr, pszParmValue);
2362 set_boolean(parm_ptr, pszParmValue);
2363 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2367 *(int *)parm_ptr = atoi(pszParmValue);
2371 *(char *)parm_ptr = *pszParmValue;
2375 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2379 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
2380 pszParmValue, NULL);
2384 string_set(parm_ptr, pszParmValue);
2388 string_set(parm_ptr, pszParmValue);
2389 strupper(*(char **)parm_ptr);
2393 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2396 parm_table[parmnum].enum_list[i].name)) {
2398 parm_table[parmnum].
2403 if (!parm_table[parmnum].enum_list[i].name) {
2404 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2405 pszParmValue, pszParmName));
2416 /***************************************************************************
2417 Process a parameter.
2418 ***************************************************************************/
2420 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2422 if (!bInGlobalSection && bGlobalOnly)
2425 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2426 pszParmName, pszParmValue));
2430 variable argument do parameter
2432 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2434 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2441 s = talloc_vasprintf(NULL, fmt, ap);
2443 ret = do_parameter(pszParmName, s);
2450 set a parameter from the commandline - this is called from command line parameter
2451 parsing code. It sets the parameter then marks the parameter as unable to be modified
2452 by smb.conf processing
2454 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2456 int parmnum = map_parameter(pszParmName);
2459 while (isspace(*pszParmValue)) pszParmValue++;
2462 if (parmnum < 0 && strchr(pszParmName, ':')) {
2463 /* set a parametric option */
2464 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2468 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2472 /* reset the CMDLINE flag in case this has been called before */
2473 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2475 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2479 parm_table[parmnum].flags |= FLAG_CMDLINE;
2481 /* we have to also set FLAG_CMDLINE on aliases */
2482 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2483 parm_table[i].flags |= FLAG_CMDLINE;
2485 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2486 parm_table[i].flags |= FLAG_CMDLINE;
2493 set a option from the commandline in 'a=b' format. Use to support --option
2495 BOOL lp_set_option(const char *option)
2513 ret = lp_set_cmdline(s, p+1);
2519 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2521 /***************************************************************************
2522 Print a parameter of the specified type.
2523 ***************************************************************************/
2525 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2531 for (i = 0; p->enum_list[i].name; i++) {
2532 if (*(int *)ptr == p->enum_list[i].value) {
2534 p->enum_list[i].name);
2541 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2545 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2549 fprintf(f, "%d", *(int *)ptr);
2553 fprintf(f, "%c", *(char *)ptr);
2557 if (*(int *)ptr == -1) {
2560 fprintf(f, "0%o", *(int *)ptr);
2565 if ((char ***)ptr && *(char ***)ptr) {
2566 char **list = *(char ***)ptr;
2568 for (; *list; list++)
2569 fprintf(f, "%s%s", *list,
2570 ((*(list+1))?", ":""));
2576 if (*(char **)ptr) {
2577 fprintf(f, "%s", *(char **)ptr);
2585 /***************************************************************************
2586 Check if two parameters are equal.
2587 ***************************************************************************/
2589 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2594 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2599 return (*((int *)ptr1) == *((int *)ptr2));
2602 return (*((char *)ptr1) == *((char *)ptr2));
2605 return str_list_equal((const char **)(*(char ***)ptr1),
2606 (const char **)(*(char ***)ptr2));
2611 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2616 return (p1 == p2 || strequal(p1, p2));
2624 /***************************************************************************
2625 Process a new section (service). At this stage all sections are services.
2626 Later we'll have special sections that permit server parameters to be set.
2627 Returns True on success, False on failure.
2628 ***************************************************************************/
2630 static BOOL do_section(const char *pszSectionName)
2633 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2634 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2637 /* if we've just struck a global section, note the fact. */
2638 bInGlobalSection = isglobal;
2640 /* check for multiple global sections */
2641 if (bInGlobalSection) {
2642 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2646 if (!bInGlobalSection && bGlobalOnly)
2649 /* if we have a current service, tidy it up before moving on */
2652 if (iServiceIndex >= 0)
2653 bRetval = service_ok(iServiceIndex);
2655 /* if all is still well, move to the next record in the services array */
2657 /* We put this here to avoid an odd message order if messages are */
2658 /* issued by the post-processing of a previous section. */
2659 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2661 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2663 DEBUG(0, ("Failed to add a new service\n"));
2672 /***************************************************************************
2673 Determine if a partcular base parameter is currentl set to the default value.
2674 ***************************************************************************/
2676 static BOOL is_default(int i)
2678 if (!defaults_saved)
2680 switch (parm_table[i].type) {
2682 return str_list_equal((const char **)parm_table[i].def.lvalue,
2683 (const char **)(*(char ***)parm_table[i].ptr));
2686 return strequal(parm_table[i].def.svalue,
2687 *(char **)parm_table[i].ptr);
2690 return parm_table[i].def.bvalue ==
2691 *(BOOL *)parm_table[i].ptr;
2693 return parm_table[i].def.cvalue ==
2694 *(char *)parm_table[i].ptr;
2698 return parm_table[i].def.ivalue ==
2699 *(int *)parm_table[i].ptr;
2706 /***************************************************************************
2707 Display the contents of the global structure.
2708 ***************************************************************************/
2710 static void dump_globals(FILE *f)
2713 struct param_opt *data;
2715 fprintf(f, "# Global parameters\n[global]\n");
2717 for (i = 0; parm_table[i].label; i++)
2718 if (parm_table[i].class == P_GLOBAL &&
2719 parm_table[i].ptr &&
2720 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2721 if (defaults_saved && is_default(i))
2723 fprintf(f, "\t%s = ", parm_table[i].label);
2724 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2727 if (Globals.param_opt != NULL) {
2728 data = Globals.param_opt;
2730 fprintf(f, "\t%s = %s\n", data->key, data->value);
2737 /***************************************************************************
2738 Display the contents of a single services record.
2739 ***************************************************************************/
2741 static void dump_a_service(service * pService, FILE * f)
2744 struct param_opt *data;
2746 if (pService != &sDefault)
2747 fprintf(f, "\n[%s]\n", pService->szService);
2749 for (i = 0; parm_table[i].label; i++)
2750 if (parm_table[i].class == P_LOCAL &&
2751 parm_table[i].ptr &&
2752 (*parm_table[i].label != '-') &&
2753 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2754 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2756 if (pService == &sDefault) {
2757 if (defaults_saved && is_default(i))
2760 if (equal_parameter(parm_table[i].type,
2761 ((char *)pService) +
2763 ((char *)&sDefault) +
2768 fprintf(f, "\t%s = ", parm_table[i].label);
2769 print_parameter(&parm_table[i],
2770 ((char *)pService) + pdiff, f);
2773 if (pService->param_opt != NULL) {
2774 data = pService->param_opt;
2776 fprintf(f, "\t%s = %s\n", data->key, data->value);
2783 /***************************************************************************
2784 Return info about the next service in a service. snum==-1 gives the globals.
2785 Return NULL when out of parameters.
2786 ***************************************************************************/
2788 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2791 /* do the globals */
2792 for (; parm_table[*i].label; (*i)++) {
2793 if (parm_table[*i].class == P_SEPARATOR)
2794 return &parm_table[(*i)++];
2796 if (!parm_table[*i].ptr
2797 || (*parm_table[*i].label == '-'))
2801 && (parm_table[*i].ptr ==
2802 parm_table[(*i) - 1].ptr))
2805 return &parm_table[(*i)++];
2808 service *pService = ServicePtrs[snum];
2810 for (; parm_table[*i].label; (*i)++) {
2811 if (parm_table[*i].class == P_SEPARATOR)
2812 return &parm_table[(*i)++];
2814 if (parm_table[*i].class == P_LOCAL &&
2815 parm_table[*i].ptr &&
2816 (*parm_table[*i].label != '-') &&
2818 (parm_table[*i].ptr !=
2819 parm_table[(*i) - 1].ptr)))
2822 PTR_DIFF(parm_table[*i].ptr,
2825 if (allparameters ||
2826 !equal_parameter(parm_table[*i].type,
2827 ((char *)pService) +
2829 ((char *)&sDefault) +
2832 return &parm_table[(*i)++];
2842 /***************************************************************************
2843 Return TRUE if the passed service number is within range.
2844 ***************************************************************************/
2846 BOOL lp_snum_ok(int iService)
2848 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2851 /***************************************************************************
2852 Auto-load some home services.
2853 ***************************************************************************/
2855 static void lp_add_auto_services(const char *str)
2860 /***************************************************************************
2861 Auto-load one printer.
2862 ***************************************************************************/
2864 void lp_add_one_printer(char *name, char *comment)
2866 int printers = lp_servicenumber(PRINTERS_NAME);
2869 if (lp_servicenumber(name) < 0) {
2870 lp_add_printer(name, printers);
2871 if ((i = lp_servicenumber(name)) >= 0) {
2872 string_set(&ServicePtrs[i]->comment, comment);
2873 ServicePtrs[i]->autoloaded = True;
2878 /***************************************************************************
2879 Announce ourselves as a print server.
2880 ***************************************************************************/
2882 void update_server_announce_as_printserver(void)
2884 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2887 /***************************************************************************
2888 Have we loaded a services file yet?
2889 ***************************************************************************/
2891 BOOL lp_loaded(void)
2896 /***************************************************************************
2897 Unload unused services.
2898 ***************************************************************************/
2900 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2903 for (i = 0; i < iNumServices; i++) {
2907 if (!snumused || !snumused(smb, i)) {
2908 ServicePtrs[i]->valid = False;
2909 free_service(ServicePtrs[i]);
2914 /***************************************************************************
2916 ***************************************************************************/
2918 void lp_killservice(int iServiceIn)
2920 if (VALID(iServiceIn)) {
2921 ServicePtrs[iServiceIn]->valid = False;
2922 free_service(ServicePtrs[iServiceIn]);
2926 /***************************************************************************
2927 Save the curent values of all global and sDefault parameters into the
2928 defaults union. This allows swat and testparm to show only the
2929 changed (ie. non-default) parameters.
2930 ***************************************************************************/
2932 static void lp_save_defaults(void)
2935 for (i = 0; parm_table[i].label; i++) {
2936 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2938 switch (parm_table[i].type) {
2940 parm_table[i].def.lvalue = str_list_copy(talloc_autofree_context(),
2941 *(const char ***)parm_table[i].ptr);
2945 if (parm_table[i].ptr) {
2946 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2948 parm_table[i].def.svalue = NULL;
2953 parm_table[i].def.bvalue =
2954 *(BOOL *)parm_table[i].ptr;
2957 parm_table[i].def.cvalue =
2958 *(char *)parm_table[i].ptr;
2963 parm_table[i].def.ivalue =
2964 *(int *)parm_table[i].ptr;
2970 defaults_saved = True;
2973 /*******************************************************************
2974 Set the server type we will announce as via nmbd.
2975 ********************************************************************/
2977 static void set_server_role(void)
2979 server_role = ROLE_STANDALONE;
2981 switch (lp_security()) {
2983 if (lp_domain_logons())
2984 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2989 if (lp_domain_logons()) {
2990 if (Globals.bDomainMaster) /* auto or yes */
2991 server_role = ROLE_DOMAIN_PDC;
2993 server_role = ROLE_DOMAIN_BDC;
2996 server_role = ROLE_DOMAIN_MEMBER;
2999 if (lp_domain_logons()) {
3001 if (Globals.bDomainMaster) /* auto or yes */
3002 server_role = ROLE_DOMAIN_PDC;
3004 server_role = ROLE_DOMAIN_BDC;
3008 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3012 DEBUG(10, ("set_server_role: role = "));
3014 switch(server_role) {
3015 case ROLE_STANDALONE:
3016 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3018 case ROLE_DOMAIN_MEMBER:
3019 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3021 case ROLE_DOMAIN_BDC:
3022 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3024 case ROLE_DOMAIN_PDC:
3025 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3030 /***************************************************************************
3031 Load the services array from the services file. Return True on success,
3033 ***************************************************************************/
3035 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3040 struct param_opt *data;
3042 pstrcpy(n2, pszFname);
3043 standard_sub_basic(n2,sizeof(n2));
3045 add_to_file_list(pszFname, n2);
3049 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3051 bInGlobalSection = True;
3052 bGlobalOnly = global_only;
3054 if (Globals.param_opt != NULL) {
3055 struct param_opt *next;
3056 for (data=Globals.param_opt; data; data=next) {
3058 if (data->flags & FLAG_CMDLINE) continue;
3061 DLIST_REMOVE(Globals.param_opt, data);
3073 /* We get sections first, so have to start 'behind' to make up */
3075 bRetval = pm_process(n2, do_section, do_parameter);
3077 /* finish up the last section */
3078 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3080 if (iServiceIndex >= 0)
3081 bRetval = service_ok(iServiceIndex);
3083 lp_add_auto_services(lp_auto_services());
3086 /* When 'restrict anonymous = 2' guest connections to ipc$
3088 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3089 lp_add_hidden("ADMIN$", "DISK", False);
3093 set_default_server_announce_type();
3097 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3098 /* if bWINSsupport is true and we are in the client */
3099 if (in_client && Globals.bWINSsupport) {
3100 lp_do_parameter(-1, "wins server", "127.0.0.1");
3108 /***************************************************************************
3109 Reset the max number of services.
3110 ***************************************************************************/
3112 void lp_resetnumservices(void)
3117 /***************************************************************************
3118 Return the max number of services.
3119 ***************************************************************************/
3121 int lp_numservices(void)
3123 return (iNumServices);
3126 /***************************************************************************
3127 Display the contents of the services array in human-readable form.
3128 ***************************************************************************/
3130 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3135 defaults_saved = False;
3139 dump_a_service(&sDefault, f);
3141 for (iService = 0; iService < maxtoprint; iService++)
3142 lp_dump_one(f, show_defaults, iService);
3145 /***************************************************************************
3146 Display the contents of one service in human-readable form.
3147 ***************************************************************************/
3149 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3152 if (ServicePtrs[snum]->szService[0] == '\0')
3154 dump_a_service(ServicePtrs[snum], f);
3158 /***************************************************************************
3159 Return the number of the service with the given name, or -1 if it doesn't
3160 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3161 getservicebyname()! This works ONLY if all services have been loaded, and
3162 does not copy the found service.
3163 ***************************************************************************/
3165 int lp_servicenumber(const char *pszServiceName)
3168 fstring serviceName;
3171 for (iService = iNumServices - 1; iService >= 0; iService--) {
3172 if (VALID(iService) && ServicePtrs[iService]->szService) {
3174 * The substitution here is used to support %U is
3177 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3178 standard_sub_basic(serviceName,sizeof(serviceName));
3179 if (strequal(serviceName, pszServiceName))
3185 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3190 /*******************************************************************
3191 A useful volume label function.
3192 ********************************************************************/
3193 const char *volume_label(int snum)
3195 const char *ret = lp_volume(snum);
3197 return lp_servicename(snum);
3202 /*******************************************************************
3203 Set the server type we will announce as via nmbd.
3204 ********************************************************************/
3206 static void set_default_server_announce_type(void)
3208 default_server_announce = 0;
3209 default_server_announce |= SV_TYPE_WORKSTATION;
3210 default_server_announce |= SV_TYPE_SERVER;
3211 default_server_announce |= SV_TYPE_SERVER_UNIX;
3213 switch (lp_announce_as()) {
3214 case ANNOUNCE_AS_NT_SERVER:
3215 default_server_announce |= SV_TYPE_SERVER_NT;
3216 /* fall through... */
3217 case ANNOUNCE_AS_NT_WORKSTATION:
3218 default_server_announce |= SV_TYPE_NT;
3220 case ANNOUNCE_AS_WIN95:
3221 default_server_announce |= SV_TYPE_WIN95_PLUS;
3223 case ANNOUNCE_AS_WFW:
3224 default_server_announce |= SV_TYPE_WFW;
3230 switch (lp_server_role()) {
3231 case ROLE_DOMAIN_MEMBER:
3232 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3234 case ROLE_DOMAIN_PDC:
3235 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3237 case ROLE_DOMAIN_BDC:
3238 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3240 case ROLE_STANDALONE:
3244 if (lp_time_server())
3245 default_server_announce |= SV_TYPE_TIME_SOURCE;
3247 if (lp_host_msdfs())
3248 default_server_announce |= SV_TYPE_DFS_SERVER;
3250 /* TODO: only announce us as print server when we are a print server */
3251 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3254 /***********************************************************
3255 returns role of Samba server
3256 ************************************************************/
3258 int lp_server_role(void)
3263 /***********************************************************
3264 If we are PDC then prefer us as DMB
3265 ************************************************************/
3267 BOOL lp_domain_master(void)
3269 if (Globals.bDomainMaster == Auto)
3270 return (lp_server_role() == ROLE_DOMAIN_PDC);
3272 return Globals.bDomainMaster;
3275 /***********************************************************
3276 If we are DMB then prefer us as LMB
3277 ************************************************************/
3279 BOOL lp_preferred_master(void)
3281 if (Globals.bPreferredMaster == Auto)
3282 return (lp_local_master() && lp_domain_master());
3284 return Globals.bPreferredMaster;
3287 /*******************************************************************
3289 ********************************************************************/
3291 void lp_remove_service(int snum)
3293 ServicePtrs[snum]->valid = False;
3296 /*******************************************************************
3298 ********************************************************************/
3300 void lp_copy_service(int snum, const char *new_name)
3302 const char *oldname = lp_servicename(snum);
3303 do_section(new_name);
3305 snum = lp_servicenumber(new_name);
3307 lp_do_parameter(snum, "copy", oldname);
3312 /*******************************************************************
3313 Get the default server type we will announce as via nmbd.
3314 ********************************************************************/
3315 int lp_default_server_announce(void)
3317 return default_server_announce;
3320 const char *lp_printername(int snum)
3322 const char *ret = _lp_printername(snum);
3323 if (ret == NULL || (ret != NULL && *ret == '\0'))
3324 ret = lp_const_servicename(snum);
3330 /*******************************************************************
3331 Return the max print jobs per queue.
3332 ********************************************************************/
3334 int lp_maxprintjobs(int snum)
3336 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3337 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3338 maxjobs = PRINT_MAX_JOBID - 1;