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;
174 char **szPreloadModules;
175 char **szPasswordServers;
176 char *szSocketOptions;
183 char **szWINSservers;
185 char *szRemoteAnnounce;
186 char *szRemoteBrowseSync;
187 char *szSocketAddress;
188 char *szAnnounceVersion; /* This is initialised in init_globals */
191 char **szNetbiosAliases;
192 char *szNetbiosScope;
193 char *szDomainOtherSIDs;
194 char **szNameResolveOrder;
196 char *szAddUserScript;
197 char *szAddMachineScript;
199 char *szWINSPartners;
200 char **dcerpc_ep_servers;
201 char **server_services;
204 char *szNonUnixAccountRange;
205 char *szTemplateHomedir;
206 char *szTemplateShell;
207 char *szWinbindSeparator;
208 BOOL bWinbindEnumUsers;
209 BOOL bWinbindEnumGroups;
210 BOOL bWinbindUseDefaultDomain;
211 char *szIDMapBackend;
212 char *szGuestaccount;
221 BOOL paranoid_server_security;
223 BOOL bDisableSpoolss;
225 int enhanced_browsing;
232 int announce_as; /* This is initialised in init_globals */
233 int machine_password_timeout;
234 int winbind_cache_time;
238 char *socket_options;
243 BOOL bPreferredMaster;
246 BOOL bEncryptPasswords;
248 BOOL bObeyPamRestrictions;
250 BOOL bLargeReadwrite;
254 BOOL bBindInterfacesOnly;
255 BOOL bPamPasswordChange;
257 BOOL bNTStatusSupport;
258 BOOL bAllowTrustedDomains;
264 BOOL bClientLanManAuth;
265 BOOL bClientNTLMv2Auth;
267 BOOL bHideLocalUsers;
270 BOOL bHostnameLookups;
271 BOOL bUnixExtensions;
272 BOOL bDisableNetbios;
274 int restrict_anonymous;
275 int name_cache_timeout;
276 struct param_opt *param_opt;
280 static global Globals;
283 * This structure describes a single service.
292 char **szInvalidUsers;
297 char *szPrintcommand;
300 char *szLppausecommand;
301 char *szLpresumecommand;
302 char *szQueuepausecommand;
303 char *szQueueresumecommand;
311 char **ntvfs_handler;
337 struct param_opt *param_opt;
339 char dummy[3]; /* for alignment */
344 /* This is a default service used to prime a services structure */
345 static service sDefault = {
347 False, /* not autoloaded */
348 NULL, /* szService */
350 NULL, /* szUsername */
351 NULL, /* szInvalidUsers */
352 NULL, /* szValidUsers */
353 NULL, /* szAdminUsers */
355 NULL, /* szInclude */
356 NULL, /* szPrintcommand */
357 NULL, /* szLpqcommand */
358 NULL, /* szLprmcommand */
359 NULL, /* szLppausecommand */
360 NULL, /* szLpresumecommand */
361 NULL, /* szQueuepausecommand */
362 NULL, /* szQueueresumecommand */
363 NULL, /* szPrintername */
364 NULL, /* szHostsallow */
365 NULL, /* szHostsdeny */
369 NULL, /* szMSDfsProxy */
370 NULL, /* ntvfs_handler */
371 0, /* iMinPrintSpace */
372 1000, /* iMaxPrintJobs */
373 0, /* iMaxConnections */
374 DEFAULT_PRINTING, /* iPrinting */
376 True, /* bAvailable */
377 True, /* bBrowseable */
378 True, /* bRead_only */
379 False, /* bPrint_ok */
380 False, /* bMap_system */
381 False, /* bMap_hidden */
382 True, /* bMap_archive */
384 True, /* bStrictLocking */
385 True, /* bPosixLocking */
387 True, /* bLevel2OpLocks */
388 False, /* bOnlyUser */
389 False, /* bGuest_only */
390 False, /* bGuest_ok */
392 False, /* bMSDfsRoot */
393 True, /* bShareModes */
394 False, /* bStrictSync */
395 False, /* bCIFileSystem */
396 NULL, /* Parametric options */
401 /* local variables */
402 static service **ServicePtrs = NULL;
403 static int iNumServices = 0;
404 static int iServiceIndex = 0;
405 static BOOL bInGlobalSection = True;
406 static BOOL bGlobalOnly = False;
407 static int server_role;
408 static int default_server_announce;
410 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
412 /* prototypes for the special type handlers */
413 static BOOL handle_include(const char *pszParmValue, char **ptr);
414 static BOOL handle_copy(const char *pszParmValue, char **ptr);
415 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
416 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
417 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
419 static void set_server_role(void);
420 static void set_default_server_announce_type(void);
422 static const struct enum_list enum_protocol[] = {
423 {PROTOCOL_NT1, "NT1"},
424 {PROTOCOL_LANMAN2, "LANMAN2"},
425 {PROTOCOL_LANMAN1, "LANMAN1"},
426 {PROTOCOL_CORE, "CORE"},
427 {PROTOCOL_COREPLUS, "COREPLUS"},
428 {PROTOCOL_COREPLUS, "CORE+"},
432 static const struct enum_list enum_security[] = {
433 {SEC_SHARE, "SHARE"},
435 {SEC_SERVER, "SERVER"},
436 {SEC_DOMAIN, "DOMAIN"},
443 static const struct enum_list enum_printing[] = {
444 {PRINT_SYSV, "sysv"},
446 {PRINT_HPUX, "hpux"},
450 {PRINT_LPRNG, "lprng"},
451 {PRINT_SOFTQ, "softq"},
452 {PRINT_CUPS, "cups"},
454 {PRINT_LPROS2, "os2"},
456 {PRINT_TEST, "test"},
458 #endif /* DEVELOPER */
462 /* Types of machine we can announce as. */
463 #define ANNOUNCE_AS_NT_SERVER 1
464 #define ANNOUNCE_AS_WIN95 2
465 #define ANNOUNCE_AS_WFW 3
466 #define ANNOUNCE_AS_NT_WORKSTATION 4
468 static const struct enum_list enum_announce_as[] = {
469 {ANNOUNCE_AS_NT_SERVER, "NT"},
470 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
471 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
472 {ANNOUNCE_AS_WIN95, "win95"},
473 {ANNOUNCE_AS_WFW, "WfW"},
477 static const struct enum_list enum_bool_auto[] = {
488 /* Client-side offline caching policy types */
489 #define CSC_POLICY_MANUAL 0
490 #define CSC_POLICY_DOCUMENTS 1
491 #define CSC_POLICY_PROGRAMS 2
492 #define CSC_POLICY_DISABLE 3
494 static const struct enum_list enum_csc_policy[] = {
495 {CSC_POLICY_MANUAL, "manual"},
496 {CSC_POLICY_DOCUMENTS, "documents"},
497 {CSC_POLICY_PROGRAMS, "programs"},
498 {CSC_POLICY_DISABLE, "disable"},
502 /* SMB signing types. */
503 static const struct enum_list enum_smb_signing_vals[] = {
504 {SMB_SIGNING_OFF, "No"},
505 {SMB_SIGNING_OFF, "False"},
506 {SMB_SIGNING_OFF, "0"},
507 {SMB_SIGNING_OFF, "Off"},
508 {SMB_SIGNING_OFF, "disabled"},
509 {SMB_SIGNING_SUPPORTED, "Yes"},
510 {SMB_SIGNING_SUPPORTED, "True"},
511 {SMB_SIGNING_SUPPORTED, "1"},
512 {SMB_SIGNING_SUPPORTED, "On"},
513 {SMB_SIGNING_SUPPORTED, "enabled"},
514 {SMB_SIGNING_REQUIRED, "required"},
515 {SMB_SIGNING_REQUIRED, "mandatory"},
516 {SMB_SIGNING_REQUIRED, "force"},
517 {SMB_SIGNING_REQUIRED, "forced"},
518 {SMB_SIGNING_REQUIRED, "enforced"},
519 {SMB_SIGNING_AUTO, "auto"},
524 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
526 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
527 * is implied in current control logic. This may change at some later time. A
528 * flag value of 0 means - show as development option only.
530 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
531 * screen in SWAT. This is used to exclude parameters as well as to squash all
532 * parameters that have been duplicated by pseudonyms.
534 static struct parm_struct parm_table[] = {
535 {"Base Options", P_SEP, P_SEPARATOR},
537 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
542 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
543 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
544 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
546 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
547 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
552 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
553 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
554 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
555 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
557 {"Security Options", P_SEP, P_SEPARATOR},
559 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
560 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
561 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
562 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
568 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
576 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
590 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
591 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
593 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
594 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
595 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
597 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
599 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
601 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
603 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
604 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
605 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
606 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
608 {"Logging Options", P_SEP, P_SEPARATOR},
610 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
611 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
612 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
614 {"Protocol Options", P_SEP, P_SEPARATOR},
616 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
617 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
618 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
619 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
620 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
621 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
622 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
623 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
624 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
629 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
630 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
634 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
635 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
636 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
637 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
638 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
639 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
640 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
641 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
642 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
644 {"Tuning Options", P_SEP, P_SEPARATOR},
646 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
647 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
648 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
649 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
651 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
652 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
653 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
655 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
656 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
657 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
659 {"Printing Options", P_SEP, P_SEPARATOR},
661 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
662 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
663 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
664 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
665 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
666 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
667 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
668 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
671 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
673 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
674 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
675 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
677 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
678 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
680 {"Filename Handling", P_SEP, P_SEPARATOR},
682 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
683 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
684 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
686 {"Domain Options", P_SEP, P_SEPARATOR},
688 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
690 {"Logon Options", P_SEP, P_SEPARATOR},
692 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
697 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"Browse Options", P_SEP, P_SEPARATOR},
703 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
706 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
708 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
709 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
711 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
712 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
714 {"WINS Options", P_SEP, P_SEPARATOR},
715 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
718 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
719 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
720 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
721 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
723 {"Locking Options", P_SEP, P_SEPARATOR},
725 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
726 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
727 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
728 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
730 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
731 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
732 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
733 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
734 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
736 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
738 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
739 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
742 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
747 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
748 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
750 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
751 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
753 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
754 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
756 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
757 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
758 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
760 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
764 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
765 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"Winbind options", P_SEP, P_SEPARATOR},
768 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
781 /***************************************************************************
782 Initialise the sDefault parameter structure for the printer values.
783 ***************************************************************************/
785 static void init_printer_values(void)
787 /* choose defaults depending on the type of printing */
788 switch (sDefault.iPrinting) {
793 do_parameter("Lpqcommand", "lpq -P'%p'");
794 do_parameter("Lprmcommand", "lprm -P'%p' %j");
795 do_parameter("Printcommand",
801 do_parameter("Lpqcommand", "lpq -P'%p'");
802 do_parameter("Lprmcommand", "lprm -P'%p' %j");
803 do_parameter("Printcommand",
805 do_parameter("Queuepausecommand",
807 do_parameter("Queueresumecommand",
809 do_parameter("Lppausecommand",
811 do_parameter("Lpresumecommand",
812 "lpc release '%p' %j");
817 do_parameter("Lpqcommand", "");
818 do_parameter("Lprmcommand", "");
819 do_parameter("Printcommand", "");
820 do_parameter("Lppausecommand", "");
821 do_parameter("Lpresumecommand", "");
822 do_parameter("Queuepausecommand", "");
823 do_parameter("Queueresumecommand", "");
825 do_parameter("Printcapname", "cups");
827 do_parameter("Lpqcommand",
828 "/usr/bin/lpstat -o '%p'");
829 do_parameter("Lprmcommand",
830 "/usr/bin/cancel '%p-%j'");
831 do_parameter("Printcommand",
832 "/usr/bin/lp -d '%p' %s; rm %s");
833 do_parameter("Lppausecommand",
834 "lp -i '%p-%j' -H hold");
835 do_parameter("Lpresumecommand",
836 "lp -i '%p-%j' -H resume");
837 do_parameter("Queuepausecommand",
838 "/usr/bin/disable '%p'");
839 do_parameter("Queueresumecommand",
840 "/usr/bin/enable '%p'");
841 do_parameter("Printcapname", "lpstat");
842 #endif /* HAVE_CUPS */
847 do_parameter("Lpqcommand", "lpstat -o%p");
848 do_parameter("Lprmcommand", "cancel %p-%j");
849 do_parameter("Printcommand",
850 "lp -c -d%p %s; rm %s");
851 do_parameter("Queuepausecommand",
853 do_parameter("Queueresumecommand",
856 do_parameter("Lppausecommand",
857 "lp -i %p-%j -H hold");
858 do_parameter("Lpresumecommand",
859 "lp -i %p-%j -H resume");
864 do_parameter("Lpqcommand", "lpq -P%p");
865 do_parameter("Lprmcommand", "lprm -P%p %j");
866 do_parameter("Printcommand", "lp -r -P%p %s");
870 do_parameter("Lpqcommand", "qstat -l -d%p");
871 do_parameter("Lprmcommand",
873 do_parameter("Printcommand",
874 "lp -d%p -s %s; rm %s");
875 do_parameter("Lppausecommand",
877 do_parameter("Lpresumecommand",
883 do_parameter("Printcommand", "vlp print %p %s");
884 do_parameter("Lpqcommand", "vlp lpq %p");
885 do_parameter("Lprmcommand", "vlp lprm %p %j");
886 do_parameter("Lppausecommand", "vlp lppause %p %j");
887 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
888 do_parameter("Queuepausecommand", "vlp queuepause %p");
889 do_parameter("Queueresumecommand", "vlp queueresume %p");
891 #endif /* DEVELOPER */
897 /***************************************************************************
898 Initialise the global parameter structure.
899 ***************************************************************************/
900 static void init_globals(void)
905 DEBUG(3, ("Initialising global parameters\n"));
907 for (i = 0; parm_table[i].label; i++) {
908 if ((parm_table[i].type == P_STRING ||
909 parm_table[i].type == P_USTRING) &&
911 !(parm_table[i].flags & FLAG_CMDLINE)) {
912 string_set(parm_table[i].ptr, "");
916 /* options that can be set on the command line must be initialised via
917 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
919 do_parameter("socket options", "TCP_NODELAY");
921 do_parameter("workgroup", DEFAULT_WORKGROUP);
922 myname = get_myname();
923 do_parameter("netbios name", myname);
925 do_parameter("max protocol", "NT1");
926 do_parameter("name resolve order", "lmhosts wins host bcast");
928 init_printer_values();
930 do_parameter("fstype", FSTYPE_STRING);
931 do_parameter("ntvfs handler", "unixuid default");
932 do_parameter("max connections", "-1");
934 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg IOXIDResolver IRemoteActivation dssetup");
935 do_parameter("server services", "smb rpc nbt");
936 do_parameter("auth methods", "anonymous sam_ignoredomain");
937 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
938 do_parameter("private dir", dyn_PRIVATE_DIR);
939 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
940 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
941 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
942 do_parameter("guest account", GUEST_ACCOUNT);
944 /* using UTF8 by default allows us to support all chars */
945 do_parameter("unix charset", "UTF8");
947 /* Use codepage 850 as a default for the dos character set */
948 do_parameter("dos charset", "CP850");
951 * Allow the default PASSWD_CHAT to be overridden in local.h.
953 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
955 do_parameter("passwd program", "");
956 do_parameter("printcap name", PRINTCAP_NAME);
958 do_parameter("pid directory", dyn_PIDDIR);
959 do_parameter("lock dir", dyn_LOCKDIR);
960 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
962 do_parameter("socket address", "0.0.0.0");
963 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
965 do_parameter_var("announce version", "%d.%d",
966 DEFAULT_MAJOR_VERSION,
967 DEFAULT_MINOR_VERSION);
969 do_parameter("logon drive", "");
971 do_parameter("logon home", "\\\\%N\\%U");
972 do_parameter("logon path", "\\\\%N\\%U\\profile");
973 do_parameter("password server", "*");
975 do_parameter("load printers", "True");
977 do_parameter("max mux", "50");
978 do_parameter("max xmit", "12288");
979 do_parameter("lpqcachetime", "10");
980 do_parameter("DisableSpoolss", "False");
981 do_parameter("password level", "0");
982 do_parameter("username level", "0");
983 do_parameter("LargeReadwrite", "True");
984 do_parameter("minprotocol", "CORE");
985 do_parameter("security", "USER");
986 do_parameter("paranoid server security", "True");
987 do_parameter("EncryptPasswords", "True");
988 do_parameter("ReadRaw", "True");
989 do_parameter("WriteRaw", "True");
990 do_parameter("NullPasswords", "False");
991 do_parameter("ObeyPamRestrictions", "False");
992 do_parameter("lm announce", "Auto");
993 do_parameter("lm interval", "60");
994 do_parameter("announce as", "NT SERVER");
996 do_parameter("TimeServer", "False");
997 do_parameter("BindInterfacesOnly", "False");
998 do_parameter("PamPasswordChange", "False");
999 do_parameter("Unicode", "True");
1000 do_parameter("restrict anonymous", "0");
1001 do_parameter("ClientLanManAuth", "True");
1002 do_parameter("LanmanAuth", "True");
1003 do_parameter("NTLMAuth", "True");
1005 do_parameter("enhanced browsing", "True");
1006 do_parameter("LockSpinCount", "3");
1007 do_parameter("LockSpinTime", "10");
1008 #ifdef MMAP_BLACKLIST
1009 do_parameter("UseMmap", "False");
1011 do_parameter("UseMmap", "True");
1013 do_parameter("UnixExtensions", "False");
1015 /* hostname lookups can be very expensive and are broken on
1016 a large number of sites (tridge) */
1017 do_parameter("HostnameLookups", "False");
1019 do_parameter("PreferredMaster", "Auto");
1020 do_parameter("os level", "20");
1021 do_parameter("LocalMaster", "True");
1022 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1023 do_parameter("DomainLogons", "False");
1024 do_parameter("WINSsupport", "False");
1025 do_parameter("WINSproxy", "False");
1027 do_parameter("DNSproxy", "True");
1029 do_parameter("AllowTrustedDomains", "True");
1031 do_parameter("TemplateShell", "/bin/false");
1032 do_parameter("TemplateHomedir", "/home/%D/%U");
1033 do_parameter("WinbindSeparator", "\\");
1035 do_parameter("winbind cache time", "15");
1036 do_parameter("WinbindEnumUsers", "True");
1037 do_parameter("WinbindEnumGroups", "True");
1038 do_parameter("WinbindUseDefaultDomain", "False");
1040 do_parameter("IDMapBackend", "tdb");
1042 do_parameter("name cache timeout", "660"); /* In seconds */
1044 do_parameter("client signing", "Yes");
1045 do_parameter("server signing", "auto");
1047 do_parameter("use spnego", "True");
1049 do_parameter("smb ports", SMB_PORTS);
1050 do_parameter("nbt port", "137");
1052 do_parameter("nt status support", "True");
1055 static TALLOC_CTX *lp_talloc;
1057 /******************************************************************* a
1058 Free up temporary memory - called from the main loop.
1059 ********************************************************************/
1061 void lp_talloc_free(void)
1065 talloc_free(lp_talloc);
1069 /*******************************************************************
1070 Convenience routine to grab string parameters into temporary memory
1071 and run standard_sub_basic on them. The buffers can be written to by
1072 callers without affecting the source string.
1073 ********************************************************************/
1075 static const char *lp_string(const char *s)
1077 #if 0 /* until REWRITE done to make thread-safe */
1078 size_t len = s ? strlen(s) : 0;
1082 /* The follow debug is useful for tracking down memory problems
1083 especially if you have an inner loop that is calling a lp_*()
1084 function that returns a string. Perhaps this debug should be
1085 present all the time? */
1088 DEBUG(10, ("lp_string(%s)\n", s));
1091 #if 0 /* until REWRITE done to make thread-safe */
1093 lp_talloc = talloc_init("lp_talloc");
1095 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1103 StrnCpy(ret, s, len);
1105 if (trim_string(ret, "\"", "\"")) {
1106 if (strchr(ret,'"') != NULL)
1107 StrnCpy(ret, s, len);
1110 standard_sub_basic(ret,len+100);
1117 In this section all the functions that are used to access the
1118 parameters from the rest of the program are defined
1121 #define FN_GLOBAL_STRING(fn_name,ptr) \
1122 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1123 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1124 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1125 #define FN_GLOBAL_LIST(fn_name,ptr) \
1126 const char **fn_name(void) {return(*(const char ***)(ptr));}
1127 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1128 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1129 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1130 char fn_name(void) {return(*(char *)(ptr));}
1131 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1132 int fn_name(void) {return(*(int *)(ptr));}
1134 #define FN_LOCAL_STRING(fn_name,val) \
1135 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1136 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1137 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1138 #define FN_LOCAL_LIST(fn_name,val) \
1139 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1140 #define FN_LOCAL_BOOL(fn_name,val) \
1141 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1142 #define FN_LOCAL_CHAR(fn_name,val) \
1143 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1144 #define FN_LOCAL_INTEGER(fn_name,val) \
1145 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1147 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1148 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1149 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1150 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1151 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1152 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1153 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1154 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1155 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1156 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1157 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1158 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1159 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1160 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1161 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1162 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1163 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1164 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1165 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1166 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1167 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1168 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1169 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1170 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1171 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1172 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1173 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1174 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1175 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1176 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1177 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1178 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1179 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1180 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1181 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1182 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1183 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1184 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1185 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1186 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1187 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1188 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1189 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1190 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1191 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1193 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1195 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1197 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1198 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1199 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1200 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1201 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1202 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1203 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1204 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1205 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1207 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1208 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1209 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1210 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1211 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1212 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1213 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1214 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1215 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1216 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1217 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1218 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1219 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1220 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1221 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1222 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1223 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1224 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1225 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1226 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1227 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1228 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1229 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1230 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1231 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1232 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1233 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1234 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1235 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1236 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1237 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1238 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1239 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1240 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1241 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1242 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1243 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1244 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1245 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1246 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1247 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1248 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1249 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1250 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1251 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1252 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1253 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1254 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1255 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1256 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1257 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1258 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1259 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1260 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1261 FN_LOCAL_STRING(lp_servicename, szService)
1262 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1263 FN_LOCAL_STRING(lp_pathname, szPath)
1264 FN_LOCAL_STRING(lp_username, szUsername)
1265 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1266 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1267 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1268 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1269 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1270 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1271 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1272 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1273 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1274 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1275 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1276 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1277 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1278 FN_LOCAL_STRING(lp_comment, comment)
1279 FN_LOCAL_STRING(lp_fstype, fstype)
1280 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1281 static FN_LOCAL_STRING(lp_volume, volume)
1282 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1283 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1284 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1285 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1286 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1287 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1288 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1289 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1290 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1291 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1292 FN_LOCAL_BOOL(lp_locking, bLocking)
1293 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1294 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1295 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1296 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1297 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1298 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1299 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1300 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1301 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1302 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1303 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1304 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1305 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1306 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1307 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1308 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1309 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1310 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1312 /* local prototypes */
1314 static int map_parameter(const char *pszParmName);
1315 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1316 static int getservicebyname(const char *pszServiceName,
1317 service * pserviceDest);
1318 static void copy_service(service * pserviceDest,
1319 service * pserviceSource, BOOL *pcopymapDest);
1320 static BOOL service_ok(int iService);
1321 static BOOL do_section(const char *pszSectionName);
1322 static void init_copymap(service * pservice);
1324 /* This is a helper function for parametrical options support. */
1325 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1326 /* Actual parametrical functions are quite simple */
1327 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1330 struct param_opt *data;
1332 if (lookup_service >= iNumServices) return NULL;
1334 data = (lookup_service < 0) ?
1335 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1337 asprintf(&vfskey, "%s:%s", type, option);
1341 if (strcmp(data->key, vfskey) == 0) {
1348 if (lookup_service >= 0) {
1349 /* Try to fetch the same option but from globals */
1350 /* but only if we are not already working with Globals */
1351 data = Globals.param_opt;
1353 if (strcmp(data->key, vfskey) == 0) {
1367 /*******************************************************************
1368 convenience routine to return int parameters.
1369 ********************************************************************/
1370 static int lp_int(const char *s)
1374 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1381 /*******************************************************************
1382 convenience routine to return unsigned long parameters.
1383 ********************************************************************/
1384 static int lp_ulong(const char *s)
1388 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1392 return strtoul(s, NULL, 10);
1395 /*******************************************************************
1396 convenience routine to return boolean parameters.
1397 ********************************************************************/
1398 static BOOL lp_bool(const char *s)
1403 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1407 if (!set_boolean(&ret,s)) {
1408 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1416 /* Return parametric option from a given service. Type is a part of option before ':' */
1417 /* Parametric option has following syntax: 'Type: option = value' */
1418 /* Returned value is allocated in 'lp_talloc' context */
1420 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1422 const char *value = get_parametrics(lookup_service, type, option);
1425 return lp_string(value);
1430 /* Return parametric option from a given service. Type is a part of option before ':' */
1431 /* Parametric option has following syntax: 'Type: option = value' */
1432 /* Returned value is allocated in 'lp_talloc' context */
1434 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1435 const char *separator)
1437 const char *value = get_parametrics(lookup_service, type, option);
1440 return str_list_make(NULL, value, separator);
1445 /* Return parametric option from a given service. Type is a part of option before ':' */
1446 /* Parametric option has following syntax: 'Type: option = value' */
1448 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1450 const char *value = get_parametrics(lookup_service, type, option);
1453 return lp_int(value);
1458 /* Return parametric option from a given service. Type is a part of option before ':' */
1459 /* Parametric option has following syntax: 'Type: option = value' */
1461 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1463 const char *value = get_parametrics(lookup_service, type, option);
1466 return lp_ulong(value);
1471 /* Return parametric option from a given service. Type is a part of option before ':' */
1472 /* Parametric option has following syntax: 'Type: option = value' */
1474 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1476 const char *value = get_parametrics(lookup_service, type, option);
1479 return lp_bool(value);
1485 /***************************************************************************
1486 Initialise a service to the defaults.
1487 ***************************************************************************/
1489 static void init_service(service * pservice)
1491 memset((char *)pservice, '\0', sizeof(service));
1492 copy_service(pservice, &sDefault, NULL);
1495 /***************************************************************************
1496 Free the dynamically allocated parts of a service struct.
1497 ***************************************************************************/
1499 static void free_service(service *pservice)
1502 struct param_opt *data, *pdata;
1506 if (pservice->szService)
1507 DEBUG(5, ("free_service: Freeing service %s\n",
1508 pservice->szService));
1510 string_free(&pservice->szService);
1511 SAFE_FREE(pservice->copymap);
1513 for (i = 0; parm_table[i].label; i++) {
1514 if ((parm_table[i].type == P_STRING ||
1515 parm_table[i].type == P_USTRING) &&
1516 parm_table[i].class == P_LOCAL) {
1517 string_free((char **)
1518 (((char *)pservice) +
1519 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1520 } else if (parm_table[i].type == P_LIST &&
1521 parm_table[i].class == P_LOCAL) {
1522 char ***listp = (char ***)(((char *)pservice) +
1523 PTR_DIFF(parm_table[i].ptr, &sDefault));
1524 talloc_free(*listp);
1529 DEBUG(5,("Freeing parametrics:\n"));
1530 data = pservice->param_opt;
1532 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1533 string_free(&data->key);
1534 string_free(&data->value);
1540 ZERO_STRUCTP(pservice);
1543 /***************************************************************************
1544 Add a new service to the services array initialising it with the given
1546 ***************************************************************************/
1548 static int add_a_service(const service *pservice, const char *name)
1552 int num_to_alloc = iNumServices + 1;
1553 struct param_opt *data, *pdata;
1555 tservice = *pservice;
1557 /* it might already exist */
1559 i = getservicebyname(name, NULL);
1561 /* Clean all parametric options for service */
1562 /* They will be added during parsing again */
1563 data = ServicePtrs[i]->param_opt;
1565 string_free(&data->key);
1566 string_free(&data->value);
1571 ServicePtrs[i]->param_opt = NULL;
1576 /* find an invalid one */
1577 for (i = 0; i < iNumServices; i++)
1578 if (!ServicePtrs[i]->valid)
1581 /* if not, then create one */
1582 if (i == iNumServices) {
1585 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1588 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1593 ServicePtrs[iNumServices] = malloc_p(service);
1595 if (!ServicePtrs[iNumServices]) {
1596 DEBUG(0,("add_a_service: out of memory!\n"));
1602 free_service(ServicePtrs[i]);
1604 ServicePtrs[i]->valid = True;
1606 init_service(ServicePtrs[i]);
1607 copy_service(ServicePtrs[i], &tservice, NULL);
1609 string_set(&ServicePtrs[i]->szService, name);
1613 /***************************************************************************
1614 Add a new home service, with the specified home directory, defaults coming
1616 ***************************************************************************/
1618 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1619 const char *user, const char *pszHomedir)
1624 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1629 if (!(*(ServicePtrs[iDefaultService]->szPath))
1630 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1631 pstrcpy(newHomedir, pszHomedir);
1633 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1634 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1637 string_set(&ServicePtrs[i]->szPath, newHomedir);
1639 if (!(*(ServicePtrs[i]->comment))) {
1641 slprintf(comment, sizeof(comment) - 1,
1642 "Home directory of %s", user);
1643 string_set(&ServicePtrs[i]->comment, comment);
1645 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1646 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1648 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1654 /***************************************************************************
1655 Add a new service, based on an old one.
1656 ***************************************************************************/
1658 int lp_add_service(const char *pszService, int iDefaultService)
1660 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1663 /***************************************************************************
1664 Add the IPC service.
1665 ***************************************************************************/
1667 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1670 int i = add_a_service(&sDefault, name);
1675 slprintf(comment, sizeof(comment) - 1,
1676 "%s Service (%s)", fstype, Globals.szServerString);
1678 string_set(&ServicePtrs[i]->szPath, tmpdir());
1679 string_set(&ServicePtrs[i]->szUsername, "");
1680 string_set(&ServicePtrs[i]->comment, comment);
1681 string_set(&ServicePtrs[i]->fstype, fstype);
1682 ServicePtrs[i]->iMaxConnections = -1;
1683 ServicePtrs[i]->bAvailable = True;
1684 ServicePtrs[i]->bRead_only = True;
1685 ServicePtrs[i]->bGuest_only = False;
1686 ServicePtrs[i]->bGuest_ok = guest_ok;
1687 ServicePtrs[i]->bPrint_ok = False;
1688 ServicePtrs[i]->bBrowseable = False;
1690 if (strcasecmp(fstype, "IPC") == 0) {
1691 lp_do_parameter(i, "ntvfs handler", "default");
1694 DEBUG(3, ("adding hidden service %s\n", name));
1699 /***************************************************************************
1700 Add a new printer service, with defaults coming from service iFrom.
1701 ***************************************************************************/
1703 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1705 const char *comment = "From Printcap";
1706 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1711 /* note that we do NOT default the availability flag to True - */
1712 /* we take it from the default service passed. This allows all */
1713 /* dynamic printers to be disabled by disabling the [printers] */
1714 /* entry (if/when the 'available' keyword is implemented!). */
1716 /* the printer name is set to the service name. */
1717 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1718 string_set(&ServicePtrs[i]->comment, comment);
1719 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1720 /* Printers cannot be read_only. */
1721 ServicePtrs[i]->bRead_only = False;
1722 /* No share modes on printer services. */
1723 ServicePtrs[i]->bShareModes = False;
1724 /* No oplocks on printer services. */
1725 ServicePtrs[i]->bOpLocks = False;
1726 /* Printer services must be printable. */
1727 ServicePtrs[i]->bPrint_ok = True;
1729 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1731 update_server_announce_as_printserver();
1736 /***************************************************************************
1737 Map a parameter's string representation to something we can use.
1738 Returns False if the parameter string is not recognised, else TRUE.
1739 ***************************************************************************/
1741 static int map_parameter(const char *pszParmName)
1745 if (*pszParmName == '-')
1748 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1749 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1752 /* Warn only if it isn't parametric option */
1753 if (strchr(pszParmName, ':') == NULL)
1754 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1755 /* We do return 'fail' for parametric options as well because they are
1756 stored in different storage
1761 /***************************************************************************
1762 Set a boolean variable from the text value stored in the passed string.
1763 Returns True in success, False if the passed string does not correctly
1764 represent a boolean.
1765 ***************************************************************************/
1767 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1772 if (strwicmp(pszParmValue, "yes") == 0 ||
1773 strwicmp(pszParmValue, "true") == 0 ||
1774 strwicmp(pszParmValue, "1") == 0)
1776 else if (strwicmp(pszParmValue, "no") == 0 ||
1777 strwicmp(pszParmValue, "False") == 0 ||
1778 strwicmp(pszParmValue, "0") == 0)
1782 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1789 /***************************************************************************
1790 Find a service by name. Otherwise works like get_service.
1791 ***************************************************************************/
1793 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1797 for (iService = iNumServices - 1; iService >= 0; iService--)
1798 if (VALID(iService) &&
1799 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1800 if (pserviceDest != NULL)
1801 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1808 /***************************************************************************
1809 Copy a service structure to another.
1810 If pcopymapDest is NULL then copy all fields
1811 ***************************************************************************/
1813 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1816 BOOL bcopyall = (pcopymapDest == NULL);
1817 struct param_opt *data, *pdata, *paramo;
1820 for (i = 0; parm_table[i].label; i++)
1821 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1822 (bcopyall || pcopymapDest[i])) {
1823 void *def_ptr = parm_table[i].ptr;
1825 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1828 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1831 switch (parm_table[i].type) {
1834 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1840 *(int *)dest_ptr = *(int *)src_ptr;
1844 *(char *)dest_ptr = *(char *)src_ptr;
1848 string_set(dest_ptr,
1853 string_set(dest_ptr,
1855 strupper(*(char **)dest_ptr);
1858 *(char ***)dest_ptr = str_list_copy(NULL, *(const char ***)src_ptr);
1866 init_copymap(pserviceDest);
1867 if (pserviceSource->copymap)
1868 memcpy((void *)pserviceDest->copymap,
1869 (void *)pserviceSource->copymap,
1870 sizeof(BOOL) * NUMPARAMETERS);
1873 data = pserviceSource->param_opt;
1876 pdata = pserviceDest->param_opt;
1877 /* Traverse destination */
1879 /* If we already have same option, override it */
1880 if (strcmp(pdata->key, data->key) == 0) {
1881 string_free(&pdata->value);
1882 pdata->value = strdup(data->value);
1886 pdata = pdata->next;
1889 paramo = smb_xmalloc_p(struct param_opt);
1890 paramo->key = strdup(data->key);
1891 paramo->value = strdup(data->value);
1892 DLIST_ADD(pserviceDest->param_opt, paramo);
1898 /***************************************************************************
1899 Check a service for consistency. Return False if the service is in any way
1900 incomplete or faulty, else True.
1901 ***************************************************************************/
1903 static BOOL service_ok(int iService)
1908 if (ServicePtrs[iService]->szService[0] == '\0') {
1909 DEBUG(0, ("The following message indicates an internal error:\n"));
1910 DEBUG(0, ("No service name in service entry.\n"));
1914 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1915 /* I can't see why you'd want a non-printable printer service... */
1916 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1917 if (!ServicePtrs[iService]->bPrint_ok) {
1918 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1919 ServicePtrs[iService]->szService));
1920 ServicePtrs[iService]->bPrint_ok = True;
1922 /* [printers] service must also be non-browsable. */
1923 if (ServicePtrs[iService]->bBrowseable)
1924 ServicePtrs[iService]->bBrowseable = False;
1927 /* If a service is flagged unavailable, log the fact at level 0. */
1928 if (!ServicePtrs[iService]->bAvailable)
1929 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1930 ServicePtrs[iService]->szService));
1935 static struct file_lists {
1936 struct file_lists *next;
1940 } *file_lists = NULL;
1942 /*******************************************************************
1943 Keep a linked list of all config files so we know when one has changed
1944 it's date and needs to be reloaded.
1945 ********************************************************************/
1947 static void add_to_file_list(const char *fname, const char *subfname)
1949 struct file_lists *f = file_lists;
1952 if (f->name && !strcmp(f->name, fname))
1958 f = malloc_p(struct file_lists);
1961 f->next = file_lists;
1962 f->name = strdup(fname);
1967 f->subfname = strdup(subfname);
1973 f->modtime = file_modtime(subfname);
1975 time_t t = file_modtime(subfname);
1981 /*******************************************************************
1982 Check if a config file has changed date.
1983 ********************************************************************/
1985 BOOL lp_file_list_changed(void)
1987 struct file_lists *f = file_lists;
1988 DEBUG(6, ("lp_file_list_changed()\n"));
1994 pstrcpy(n2, f->name);
1995 standard_sub_basic(n2,sizeof(n2));
1997 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1998 f->name, n2, ctime(&f->modtime)));
2000 mod_time = file_modtime(n2);
2002 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2004 ("file %s modified: %s\n", n2,
2006 f->modtime = mod_time;
2007 SAFE_FREE(f->subfname);
2008 f->subfname = strdup(n2);
2016 /***************************************************************************
2017 Handle the include operation.
2018 ***************************************************************************/
2020 static BOOL handle_include(const char *pszParmValue, char **ptr)
2023 pstrcpy(fname, pszParmValue);
2025 standard_sub_basic(fname,sizeof(fname));
2027 add_to_file_list(pszParmValue, fname);
2029 string_set(ptr, fname);
2031 if (file_exist(fname, NULL))
2032 return (pm_process(fname, do_section, do_parameter));
2034 DEBUG(2, ("Can't find include file %s\n", fname));
2039 /***************************************************************************
2040 Handle the interpretation of the copy parameter.
2041 ***************************************************************************/
2043 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2047 service serviceTemp;
2049 string_set(ptr, pszParmValue);
2051 init_service(&serviceTemp);
2055 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2057 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2058 if (iTemp == iServiceIndex) {
2059 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2061 copy_service(ServicePtrs[iServiceIndex],
2063 ServicePtrs[iServiceIndex]->copymap);
2067 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2071 free_service(&serviceTemp);
2075 /***************************************************************************
2076 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2081 winbind uid = 1000-1999
2082 winbind gid = 700-899
2084 We only do simple parsing checks here. The strings are parsed into useful
2085 structures in the winbind daemon code.
2087 ***************************************************************************/
2089 /* Some lp_ routines to return winbind [ug]id information */
2091 static uid_t winbind_uid_low, winbind_uid_high;
2092 static gid_t winbind_gid_low, winbind_gid_high;
2093 static uint32_t non_unix_account_low, non_unix_account_high;
2095 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2097 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2101 *low = winbind_uid_low;
2104 *high = winbind_uid_high;
2109 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2111 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2115 *low = winbind_gid_low;
2118 *high = winbind_gid_high;
2123 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2125 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2129 *low = non_unix_account_low;
2132 *high = non_unix_account_high;
2137 /* Do some simple checks on "winbind [ug]id" parameter values */
2139 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2143 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2148 string_set(ptr, pszParmValue);
2150 winbind_uid_low = low;
2151 winbind_uid_high = high;
2156 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2160 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2165 string_set(ptr, pszParmValue);
2167 winbind_gid_low = low;
2168 winbind_gid_high = high;
2173 /***************************************************************************
2174 Do some simple checks on "non unix account range" parameter values.
2175 ***************************************************************************/
2177 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2181 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2186 string_set(ptr, pszParmValue);
2188 non_unix_account_low = low;
2189 non_unix_account_high = high;
2195 /***************************************************************************
2196 Initialise a copymap.
2197 ***************************************************************************/
2199 static void init_copymap(service * pservice)
2202 SAFE_FREE(pservice->copymap);
2203 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2204 if (!pservice->copymap)
2206 ("Couldn't allocate copymap!! (size %d)\n",
2207 (int)NUMPARAMETERS));
2209 for (i = 0; i < NUMPARAMETERS; i++)
2210 pservice->copymap[i] = True;
2213 /***************************************************************************
2214 Return the local pointer to a parameter given the service number and the
2215 pointer into the default structure.
2216 ***************************************************************************/
2218 void *lp_local_ptr(int snum, void *ptr)
2220 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2224 /***************************************************************************
2225 Process a parametric option
2226 ***************************************************************************/
2227 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2229 struct param_opt *paramo, *data;
2232 while (isspace(*pszParmName)) {
2236 name = strdup(pszParmName);
2237 if (!name) return False;
2242 data = Globals.param_opt;
2244 data = ServicePtrs[snum]->param_opt;
2247 /* Traverse destination */
2248 for (paramo=data; paramo; paramo=paramo->next) {
2249 /* If we already have the option set, override it unless
2250 it was a command line option and the new one isn't */
2251 if (strcmp(paramo->key, name) == 0) {
2252 if ((paramo->flags & FLAG_CMDLINE) &&
2253 !(flags & FLAG_CMDLINE)) {
2257 free(paramo->value);
2258 paramo->value = strdup(pszParmValue);
2259 paramo->flags = flags;
2265 paramo = smb_xmalloc_p(struct param_opt);
2266 paramo->key = strdup(name);
2267 paramo->value = strdup(pszParmValue);
2268 paramo->flags = flags;
2270 DLIST_ADD(Globals.param_opt, paramo);
2272 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2280 /***************************************************************************
2281 Process a parameter for a particular service number. If snum < 0
2282 then assume we are in the globals.
2283 ***************************************************************************/
2284 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2287 void *parm_ptr = NULL; /* where we are going to store the result */
2288 void *def_ptr = NULL;
2290 parmnum = map_parameter(pszParmName);
2293 if (strchr(pszParmName, ':')) {
2294 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2296 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2300 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2301 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2305 /* if the flag has been set on the command line, then don't allow override,
2306 but don't report an error */
2307 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2311 def_ptr = parm_table[parmnum].ptr;
2313 /* we might point at a service, the default service or a global */
2317 if (parm_table[parmnum].class == P_GLOBAL) {
2319 ("Global parameter %s found in service section!\n",
2324 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2329 if (!ServicePtrs[snum]->copymap)
2330 init_copymap(ServicePtrs[snum]);
2332 /* this handles the aliases - set the copymap for other entries with
2333 the same data pointer */
2334 for (i = 0; parm_table[i].label; i++)
2335 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2336 ServicePtrs[snum]->copymap[i] = False;
2339 /* if it is a special case then go ahead */
2340 if (parm_table[parmnum].special) {
2341 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2345 /* now switch on the type of variable it is */
2346 switch (parm_table[parmnum].type)
2349 set_boolean(parm_ptr, pszParmValue);
2353 set_boolean(parm_ptr, pszParmValue);
2354 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2358 *(int *)parm_ptr = atoi(pszParmValue);
2362 *(char *)parm_ptr = *pszParmValue;
2366 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2370 *(char ***)parm_ptr = str_list_make(NULL, pszParmValue, NULL);
2374 string_set(parm_ptr, pszParmValue);
2378 string_set(parm_ptr, pszParmValue);
2379 strupper(*(char **)parm_ptr);
2383 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2386 parm_table[parmnum].enum_list[i].name)) {
2388 parm_table[parmnum].
2393 if (!parm_table[parmnum].enum_list[i].name) {
2394 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2395 pszParmValue, pszParmName));
2406 /***************************************************************************
2407 Process a parameter.
2408 ***************************************************************************/
2410 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2412 if (!bInGlobalSection && bGlobalOnly)
2415 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2416 pszParmName, pszParmValue));
2420 variable argument do parameter
2422 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2424 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2431 s = talloc_vasprintf(NULL, fmt, ap);
2433 ret = do_parameter(pszParmName, s);
2440 set a parameter from the commandline - this is called from command line parameter
2441 parsing code. It sets the parameter then marks the parameter as unable to be modified
2442 by smb.conf processing
2444 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2446 int parmnum = map_parameter(pszParmName);
2449 while (isspace(*pszParmValue)) pszParmValue++;
2452 if (parmnum < 0 && strchr(pszParmName, ':')) {
2453 /* set a parametric option */
2454 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2458 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2462 /* reset the CMDLINE flag in case this has been called before */
2463 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2465 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2469 parm_table[parmnum].flags |= FLAG_CMDLINE;
2471 /* we have to also set FLAG_CMDLINE on aliases */
2472 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2473 parm_table[i].flags |= FLAG_CMDLINE;
2475 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2476 parm_table[i].flags |= FLAG_CMDLINE;
2483 set a option from the commandline in 'a=b' format. Use to support --option
2485 BOOL lp_set_option(const char *option)
2503 ret = lp_set_cmdline(s, p+1);
2509 /***************************************************************************
2510 Print a parameter of the specified type.
2511 ***************************************************************************/
2513 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2519 for (i = 0; p->enum_list[i].name; i++) {
2520 if (*(int *)ptr == p->enum_list[i].value) {
2522 p->enum_list[i].name);
2529 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2533 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2537 fprintf(f, "%d", *(int *)ptr);
2541 fprintf(f, "%c", *(char *)ptr);
2545 if (*(int *)ptr == -1) {
2548 fprintf(f, "0%o", *(int *)ptr);
2553 if ((char ***)ptr && *(char ***)ptr) {
2554 char **list = *(char ***)ptr;
2556 for (; *list; list++)
2557 fprintf(f, "%s%s", *list,
2558 ((*(list+1))?", ":""));
2564 if (*(char **)ptr) {
2565 fprintf(f, "%s", *(char **)ptr);
2573 /***************************************************************************
2574 Check if two parameters are equal.
2575 ***************************************************************************/
2577 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2582 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2587 return (*((int *)ptr1) == *((int *)ptr2));
2590 return (*((char *)ptr1) == *((char *)ptr2));
2593 return str_list_equal((const char **)(*(char ***)ptr1),
2594 (const char **)(*(char ***)ptr2));
2599 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2604 return (p1 == p2 || strequal(p1, p2));
2612 /***************************************************************************
2613 Process a new section (service). At this stage all sections are services.
2614 Later we'll have special sections that permit server parameters to be set.
2615 Returns True on success, False on failure.
2616 ***************************************************************************/
2618 static BOOL do_section(const char *pszSectionName)
2621 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2622 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2625 /* if we've just struck a global section, note the fact. */
2626 bInGlobalSection = isglobal;
2628 /* check for multiple global sections */
2629 if (bInGlobalSection) {
2630 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2634 if (!bInGlobalSection && bGlobalOnly)
2637 /* if we have a current service, tidy it up before moving on */
2640 if (iServiceIndex >= 0)
2641 bRetval = service_ok(iServiceIndex);
2643 /* if all is still well, move to the next record in the services array */
2645 /* We put this here to avoid an odd message order if messages are */
2646 /* issued by the post-processing of a previous section. */
2647 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2649 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2651 DEBUG(0, ("Failed to add a new service\n"));
2660 /***************************************************************************
2661 Determine if a partcular base parameter is currentl set to the default value.
2662 ***************************************************************************/
2664 static BOOL is_default(int i)
2666 if (!defaults_saved)
2668 switch (parm_table[i].type) {
2670 return str_list_equal((const char **)parm_table[i].def.lvalue,
2671 (const char **)(*(char ***)parm_table[i].ptr));
2674 return strequal(parm_table[i].def.svalue,
2675 *(char **)parm_table[i].ptr);
2678 return parm_table[i].def.bvalue ==
2679 *(BOOL *)parm_table[i].ptr;
2681 return parm_table[i].def.cvalue ==
2682 *(char *)parm_table[i].ptr;
2686 return parm_table[i].def.ivalue ==
2687 *(int *)parm_table[i].ptr;
2694 /***************************************************************************
2695 Display the contents of the global structure.
2696 ***************************************************************************/
2698 static void dump_globals(FILE *f)
2701 struct param_opt *data;
2703 fprintf(f, "# Global parameters\n[global]\n");
2705 for (i = 0; parm_table[i].label; i++)
2706 if (parm_table[i].class == P_GLOBAL &&
2707 parm_table[i].ptr &&
2708 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2709 if (defaults_saved && is_default(i))
2711 fprintf(f, "\t%s = ", parm_table[i].label);
2712 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2715 if (Globals.param_opt != NULL) {
2716 data = Globals.param_opt;
2718 fprintf(f, "\t%s = %s\n", data->key, data->value);
2725 /***************************************************************************
2726 Display the contents of a single services record.
2727 ***************************************************************************/
2729 static void dump_a_service(service * pService, FILE * f)
2732 struct param_opt *data;
2734 if (pService != &sDefault)
2735 fprintf(f, "\n[%s]\n", pService->szService);
2737 for (i = 0; parm_table[i].label; i++)
2738 if (parm_table[i].class == P_LOCAL &&
2739 parm_table[i].ptr &&
2740 (*parm_table[i].label != '-') &&
2741 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2742 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2744 if (pService == &sDefault) {
2745 if (defaults_saved && is_default(i))
2748 if (equal_parameter(parm_table[i].type,
2749 ((char *)pService) +
2751 ((char *)&sDefault) +
2756 fprintf(f, "\t%s = ", parm_table[i].label);
2757 print_parameter(&parm_table[i],
2758 ((char *)pService) + pdiff, f);
2761 if (pService->param_opt != NULL) {
2762 data = pService->param_opt;
2764 fprintf(f, "\t%s = %s\n", data->key, data->value);
2771 /***************************************************************************
2772 Return info about the next service in a service. snum==-1 gives the globals.
2773 Return NULL when out of parameters.
2774 ***************************************************************************/
2776 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2779 /* do the globals */
2780 for (; parm_table[*i].label; (*i)++) {
2781 if (parm_table[*i].class == P_SEPARATOR)
2782 return &parm_table[(*i)++];
2784 if (!parm_table[*i].ptr
2785 || (*parm_table[*i].label == '-'))
2789 && (parm_table[*i].ptr ==
2790 parm_table[(*i) - 1].ptr))
2793 return &parm_table[(*i)++];
2796 service *pService = ServicePtrs[snum];
2798 for (; parm_table[*i].label; (*i)++) {
2799 if (parm_table[*i].class == P_SEPARATOR)
2800 return &parm_table[(*i)++];
2802 if (parm_table[*i].class == P_LOCAL &&
2803 parm_table[*i].ptr &&
2804 (*parm_table[*i].label != '-') &&
2806 (parm_table[*i].ptr !=
2807 parm_table[(*i) - 1].ptr)))
2810 PTR_DIFF(parm_table[*i].ptr,
2813 if (allparameters ||
2814 !equal_parameter(parm_table[*i].type,
2815 ((char *)pService) +
2817 ((char *)&sDefault) +
2820 return &parm_table[(*i)++];
2830 /***************************************************************************
2831 Return TRUE if the passed service number is within range.
2832 ***************************************************************************/
2834 BOOL lp_snum_ok(int iService)
2836 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2839 /***************************************************************************
2840 Auto-load some home services.
2841 ***************************************************************************/
2843 static void lp_add_auto_services(const char *str)
2848 /***************************************************************************
2849 Auto-load one printer.
2850 ***************************************************************************/
2852 void lp_add_one_printer(char *name, char *comment)
2854 int printers = lp_servicenumber(PRINTERS_NAME);
2857 if (lp_servicenumber(name) < 0) {
2858 lp_add_printer(name, printers);
2859 if ((i = lp_servicenumber(name)) >= 0) {
2860 string_set(&ServicePtrs[i]->comment, comment);
2861 ServicePtrs[i]->autoloaded = True;
2866 /***************************************************************************
2867 Announce ourselves as a print server.
2868 ***************************************************************************/
2870 void update_server_announce_as_printserver(void)
2872 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2875 /***************************************************************************
2876 Have we loaded a services file yet?
2877 ***************************************************************************/
2879 BOOL lp_loaded(void)
2884 /***************************************************************************
2885 Unload unused services.
2886 ***************************************************************************/
2888 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2891 for (i = 0; i < iNumServices; i++) {
2895 if (!snumused || !snumused(smb, i)) {
2896 ServicePtrs[i]->valid = False;
2897 free_service(ServicePtrs[i]);
2902 /***************************************************************************
2904 ***************************************************************************/
2906 void lp_killservice(int iServiceIn)
2908 if (VALID(iServiceIn)) {
2909 ServicePtrs[iServiceIn]->valid = False;
2910 free_service(ServicePtrs[iServiceIn]);
2914 /***************************************************************************
2915 Save the curent values of all global and sDefault parameters into the
2916 defaults union. This allows swat and testparm to show only the
2917 changed (ie. non-default) parameters.
2918 ***************************************************************************/
2920 static void lp_save_defaults(void)
2923 for (i = 0; parm_table[i].label; i++) {
2924 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2926 switch (parm_table[i].type) {
2928 parm_table[i].def.lvalue = str_list_copy(NULL,
2929 *(const char ***)parm_table[i].ptr);
2933 if (parm_table[i].ptr) {
2934 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2936 parm_table[i].def.svalue = NULL;
2941 parm_table[i].def.bvalue =
2942 *(BOOL *)parm_table[i].ptr;
2945 parm_table[i].def.cvalue =
2946 *(char *)parm_table[i].ptr;
2951 parm_table[i].def.ivalue =
2952 *(int *)parm_table[i].ptr;
2958 defaults_saved = True;
2961 /*******************************************************************
2962 Set the server type we will announce as via nmbd.
2963 ********************************************************************/
2965 static void set_server_role(void)
2967 server_role = ROLE_STANDALONE;
2969 switch (lp_security()) {
2971 if (lp_domain_logons())
2972 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2977 if (lp_domain_logons()) {
2978 if (Globals.bDomainMaster) /* auto or yes */
2979 server_role = ROLE_DOMAIN_PDC;
2981 server_role = ROLE_DOMAIN_BDC;
2984 server_role = ROLE_DOMAIN_MEMBER;
2987 if (lp_domain_logons()) {
2989 if (Globals.bDomainMaster) /* auto or yes */
2990 server_role = ROLE_DOMAIN_PDC;
2992 server_role = ROLE_DOMAIN_BDC;
2996 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3000 DEBUG(10, ("set_server_role: role = "));
3002 switch(server_role) {
3003 case ROLE_STANDALONE:
3004 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3006 case ROLE_DOMAIN_MEMBER:
3007 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3009 case ROLE_DOMAIN_BDC:
3010 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3012 case ROLE_DOMAIN_PDC:
3013 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3018 /***************************************************************************
3019 Load the services array from the services file. Return True on success,
3021 ***************************************************************************/
3023 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3028 struct param_opt *data;
3030 pstrcpy(n2, pszFname);
3031 standard_sub_basic(n2,sizeof(n2));
3033 add_to_file_list(pszFname, n2);
3037 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3039 bInGlobalSection = True;
3040 bGlobalOnly = global_only;
3042 if (Globals.param_opt != NULL) {
3043 struct param_opt *next;
3044 for (data=Globals.param_opt; data; data=next) {
3046 if (data->flags & FLAG_CMDLINE) continue;
3049 DLIST_REMOVE(Globals.param_opt, data);
3061 /* We get sections first, so have to start 'behind' to make up */
3063 bRetval = pm_process(n2, do_section, do_parameter);
3065 /* finish up the last section */
3066 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3068 if (iServiceIndex >= 0)
3069 bRetval = service_ok(iServiceIndex);
3071 lp_add_auto_services(lp_auto_services());
3074 /* When 'restrict anonymous = 2' guest connections to ipc$
3076 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3077 lp_add_hidden("ADMIN$", "DISK", False);
3081 set_default_server_announce_type();
3085 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3086 /* if bWINSsupport is true and we are in the client */
3087 if (in_client && Globals.bWINSsupport) {
3088 lp_do_parameter(-1, "wins server", "127.0.0.1");
3096 /***************************************************************************
3097 Reset the max number of services.
3098 ***************************************************************************/
3100 void lp_resetnumservices(void)
3105 /***************************************************************************
3106 Return the max number of services.
3107 ***************************************************************************/
3109 int lp_numservices(void)
3111 return (iNumServices);
3114 /***************************************************************************
3115 Display the contents of the services array in human-readable form.
3116 ***************************************************************************/
3118 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3123 defaults_saved = False;
3127 dump_a_service(&sDefault, f);
3129 for (iService = 0; iService < maxtoprint; iService++)
3130 lp_dump_one(f, show_defaults, iService);
3133 /***************************************************************************
3134 Display the contents of one service in human-readable form.
3135 ***************************************************************************/
3137 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3140 if (ServicePtrs[snum]->szService[0] == '\0')
3142 dump_a_service(ServicePtrs[snum], f);
3146 /***************************************************************************
3147 Return the number of the service with the given name, or -1 if it doesn't
3148 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3149 getservicebyname()! This works ONLY if all services have been loaded, and
3150 does not copy the found service.
3151 ***************************************************************************/
3153 int lp_servicenumber(const char *pszServiceName)
3156 fstring serviceName;
3159 for (iService = iNumServices - 1; iService >= 0; iService--) {
3160 if (VALID(iService) && ServicePtrs[iService]->szService) {
3162 * The substitution here is used to support %U is
3165 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3166 standard_sub_basic(serviceName,sizeof(serviceName));
3167 if (strequal(serviceName, pszServiceName))
3173 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3178 /*******************************************************************
3179 A useful volume label function.
3180 ********************************************************************/
3181 const char *volume_label(int snum)
3183 const char *ret = lp_volume(snum);
3185 return lp_servicename(snum);
3190 /*******************************************************************
3191 Set the server type we will announce as via nmbd.
3192 ********************************************************************/
3194 static void set_default_server_announce_type(void)
3196 default_server_announce = 0;
3197 default_server_announce |= SV_TYPE_WORKSTATION;
3198 default_server_announce |= SV_TYPE_SERVER;
3199 default_server_announce |= SV_TYPE_SERVER_UNIX;
3201 switch (lp_announce_as()) {
3202 case ANNOUNCE_AS_NT_SERVER:
3203 default_server_announce |= SV_TYPE_SERVER_NT;
3204 /* fall through... */
3205 case ANNOUNCE_AS_NT_WORKSTATION:
3206 default_server_announce |= SV_TYPE_NT;
3208 case ANNOUNCE_AS_WIN95:
3209 default_server_announce |= SV_TYPE_WIN95_PLUS;
3211 case ANNOUNCE_AS_WFW:
3212 default_server_announce |= SV_TYPE_WFW;
3218 switch (lp_server_role()) {
3219 case ROLE_DOMAIN_MEMBER:
3220 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3222 case ROLE_DOMAIN_PDC:
3223 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3225 case ROLE_DOMAIN_BDC:
3226 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3228 case ROLE_STANDALONE:
3232 if (lp_time_server())
3233 default_server_announce |= SV_TYPE_TIME_SOURCE;
3235 if (lp_host_msdfs())
3236 default_server_announce |= SV_TYPE_DFS_SERVER;
3239 /***********************************************************
3240 returns role of Samba server
3241 ************************************************************/
3243 int lp_server_role(void)
3248 /***********************************************************
3249 If we are PDC then prefer us as DMB
3250 ************************************************************/
3252 BOOL lp_domain_master(void)
3254 if (Globals.bDomainMaster == Auto)
3255 return (lp_server_role() == ROLE_DOMAIN_PDC);
3257 return Globals.bDomainMaster;
3260 /***********************************************************
3261 If we are DMB then prefer us as LMB
3262 ************************************************************/
3264 BOOL lp_preferred_master(void)
3266 if (Globals.bPreferredMaster == Auto)
3267 return (lp_local_master() && lp_domain_master());
3269 return Globals.bPreferredMaster;
3272 /*******************************************************************
3274 ********************************************************************/
3276 void lp_remove_service(int snum)
3278 ServicePtrs[snum]->valid = False;
3281 /*******************************************************************
3283 ********************************************************************/
3285 void lp_copy_service(int snum, const char *new_name)
3287 const char *oldname = lp_servicename(snum);
3288 do_section(new_name);
3290 snum = lp_servicenumber(new_name);
3292 lp_do_parameter(snum, "copy", oldname);
3297 /*******************************************************************
3298 Get the default server type we will announce as via nmbd.
3299 ********************************************************************/
3300 int lp_default_server_announce(void)
3302 return default_server_announce;
3305 const char *lp_printername(int snum)
3307 const char *ret = _lp_printername(snum);
3308 if (ret == NULL || (ret != NULL && *ret == '\0'))
3309 ret = lp_const_servicename(snum);
3315 /*******************************************************************
3316 Return the max print jobs per queue.
3317 ********************************************************************/
3319 int lp_maxprintjobs(int snum)
3321 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3322 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3323 maxjobs = PRINT_MAX_JOBID - 1;