2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/iconv.h"
60 #include "system/network.h"
61 #include "system/printing.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "librpc/gen_ndr/ndr_nbt.h"
65 #include "dlinklist.h"
67 BOOL in_client = False; /* Not in the client by default */
68 static BOOL bLoaded = False;
71 #define GLOBAL_NAME "global"
75 #define PRINTERS_NAME "printers"
79 #define HOMES_NAME "homes"
82 /* some helpful bits */
83 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
84 #define VALID(i) ServicePtrs[i]->valid
86 static BOOL do_parameter(const char *, const char *);
87 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
89 static BOOL defaults_saved = False;
92 #define FLAG_BASIC 0x0001 /* fundamental options */
93 #define FLAG_SHARE 0x0002 /* file sharing options */
94 #define FLAG_PRINT 0x0004 /* printing options */
95 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
96 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
97 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
98 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
99 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
100 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
101 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
102 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
105 /* the following are used by loadparm for option lists */
108 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
109 P_STRING,P_USTRING,P_ENUM,P_SEP
114 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
128 BOOL (*special)(const char *, char **);
129 const struct enum_list *enum_list;
142 struct param_opt *prev, *next;
149 * This structure describes global (ie., server-wide) parameters.
157 char *display_charset;
158 char *szPrintcapname;
162 char *szDefaultService;
164 char *szServerString;
165 char *szAutoServices;
166 char *szPasswdProgram;
170 char *szSMBPasswdFile;
175 char **szPreloadModules;
176 char **szPasswordServers;
177 char *szSocketOptions;
184 char **szWINSservers;
186 char *szRemoteAnnounce;
187 char *szRemoteBrowseSync;
188 char *szSocketAddress;
189 char *szAnnounceVersion; /* This is initialised in init_globals */
192 char **szNetbiosAliases;
193 char *szNetbiosScope;
194 char *szDomainOtherSIDs;
195 char **szNameResolveOrder;
197 char *szAddUserScript;
198 char *szAddMachineScript;
200 char *szWINSPartners;
201 char **dcerpc_ep_servers;
202 char **server_services;
205 char *szNonUnixAccountRange;
206 char *szTemplateHomedir;
207 char *szTemplateShell;
208 char *szWinbindSeparator;
209 BOOL bWinbindEnumUsers;
210 BOOL bWinbindEnumGroups;
211 BOOL bWinbindUseDefaultDomain;
212 char *szIDMapBackend;
213 char *szGuestaccount;
222 BOOL paranoid_server_security;
224 BOOL bDisableSpoolss;
226 int enhanced_browsing;
233 int announce_as; /* This is initialised in init_globals */
234 int machine_password_timeout;
235 int winbind_cache_time;
240 char *socket_options;
245 BOOL bPreferredMaster;
248 BOOL bEncryptPasswords;
250 BOOL bObeyPamRestrictions;
252 BOOL bLargeReadwrite;
256 BOOL bBindInterfacesOnly;
257 BOOL bPamPasswordChange;
259 BOOL bNTStatusSupport;
260 BOOL bAllowTrustedDomains;
266 BOOL bClientLanManAuth;
267 BOOL bClientNTLMv2Auth;
269 BOOL bHideLocalUsers;
272 BOOL bHostnameLookups;
273 BOOL bUnixExtensions;
274 BOOL bDisableNetbios;
276 int restrict_anonymous;
277 int name_cache_timeout;
278 struct param_opt *param_opt;
282 static global Globals;
285 * This structure describes a single service.
294 char **szInvalidUsers;
299 char *szPrintcommand;
302 char *szLppausecommand;
303 char *szLpresumecommand;
304 char *szQueuepausecommand;
305 char *szQueueresumecommand;
313 char **ntvfs_handler;
339 struct param_opt *param_opt;
341 char dummy[3]; /* for alignment */
346 /* This is a default service used to prime a services structure */
347 static service sDefault = {
349 False, /* not autoloaded */
350 NULL, /* szService */
352 NULL, /* szUsername */
353 NULL, /* szInvalidUsers */
354 NULL, /* szValidUsers */
355 NULL, /* szAdminUsers */
357 NULL, /* szInclude */
358 NULL, /* szPrintcommand */
359 NULL, /* szLpqcommand */
360 NULL, /* szLprmcommand */
361 NULL, /* szLppausecommand */
362 NULL, /* szLpresumecommand */
363 NULL, /* szQueuepausecommand */
364 NULL, /* szQueueresumecommand */
365 NULL, /* szPrintername */
366 NULL, /* szHostsallow */
367 NULL, /* szHostsdeny */
371 NULL, /* szMSDfsProxy */
372 NULL, /* ntvfs_handler */
373 0, /* iMinPrintSpace */
374 1000, /* iMaxPrintJobs */
375 0, /* iMaxConnections */
376 DEFAULT_PRINTING, /* iPrinting */
378 True, /* bAvailable */
379 True, /* bBrowseable */
380 True, /* bRead_only */
381 False, /* bPrint_ok */
382 False, /* bMap_system */
383 False, /* bMap_hidden */
384 True, /* bMap_archive */
386 True, /* bStrictLocking */
387 True, /* bPosixLocking */
389 True, /* bLevel2OpLocks */
390 False, /* bOnlyUser */
391 False, /* bGuest_only */
392 False, /* bGuest_ok */
394 False, /* bMSDfsRoot */
395 True, /* bShareModes */
396 False, /* bStrictSync */
397 False, /* bCIFileSystem */
398 NULL, /* Parametric options */
403 /* local variables */
404 static service **ServicePtrs = NULL;
405 static int iNumServices = 0;
406 static int iServiceIndex = 0;
407 static BOOL bInGlobalSection = True;
408 static BOOL bGlobalOnly = False;
409 static int server_role;
410 static int default_server_announce;
412 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
414 /* prototypes for the special type handlers */
415 static BOOL handle_include(const char *pszParmValue, char **ptr);
416 static BOOL handle_copy(const char *pszParmValue, char **ptr);
417 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
418 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
419 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
421 static void set_server_role(void);
422 static void set_default_server_announce_type(void);
424 static const struct enum_list enum_protocol[] = {
425 {PROTOCOL_NT1, "NT1"},
426 {PROTOCOL_LANMAN2, "LANMAN2"},
427 {PROTOCOL_LANMAN1, "LANMAN1"},
428 {PROTOCOL_CORE, "CORE"},
429 {PROTOCOL_COREPLUS, "COREPLUS"},
430 {PROTOCOL_COREPLUS, "CORE+"},
434 static const struct enum_list enum_security[] = {
435 {SEC_SHARE, "SHARE"},
437 {SEC_SERVER, "SERVER"},
438 {SEC_DOMAIN, "DOMAIN"},
445 static const struct enum_list enum_printing[] = {
446 {PRINT_SYSV, "sysv"},
448 {PRINT_HPUX, "hpux"},
452 {PRINT_LPRNG, "lprng"},
453 {PRINT_SOFTQ, "softq"},
454 {PRINT_CUPS, "cups"},
456 {PRINT_LPROS2, "os2"},
458 {PRINT_TEST, "test"},
460 #endif /* DEVELOPER */
464 /* Types of machine we can announce as. */
465 #define ANNOUNCE_AS_NT_SERVER 1
466 #define ANNOUNCE_AS_WIN95 2
467 #define ANNOUNCE_AS_WFW 3
468 #define ANNOUNCE_AS_NT_WORKSTATION 4
470 static const struct enum_list enum_announce_as[] = {
471 {ANNOUNCE_AS_NT_SERVER, "NT"},
472 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
473 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
474 {ANNOUNCE_AS_WIN95, "win95"},
475 {ANNOUNCE_AS_WFW, "WfW"},
479 static const struct enum_list enum_bool_auto[] = {
490 /* Client-side offline caching policy types */
491 #define CSC_POLICY_MANUAL 0
492 #define CSC_POLICY_DOCUMENTS 1
493 #define CSC_POLICY_PROGRAMS 2
494 #define CSC_POLICY_DISABLE 3
496 static const struct enum_list enum_csc_policy[] = {
497 {CSC_POLICY_MANUAL, "manual"},
498 {CSC_POLICY_DOCUMENTS, "documents"},
499 {CSC_POLICY_PROGRAMS, "programs"},
500 {CSC_POLICY_DISABLE, "disable"},
504 /* SMB signing types. */
505 static const struct enum_list enum_smb_signing_vals[] = {
506 {SMB_SIGNING_OFF, "No"},
507 {SMB_SIGNING_OFF, "False"},
508 {SMB_SIGNING_OFF, "0"},
509 {SMB_SIGNING_OFF, "Off"},
510 {SMB_SIGNING_OFF, "disabled"},
511 {SMB_SIGNING_SUPPORTED, "Yes"},
512 {SMB_SIGNING_SUPPORTED, "True"},
513 {SMB_SIGNING_SUPPORTED, "1"},
514 {SMB_SIGNING_SUPPORTED, "On"},
515 {SMB_SIGNING_SUPPORTED, "enabled"},
516 {SMB_SIGNING_REQUIRED, "required"},
517 {SMB_SIGNING_REQUIRED, "mandatory"},
518 {SMB_SIGNING_REQUIRED, "force"},
519 {SMB_SIGNING_REQUIRED, "forced"},
520 {SMB_SIGNING_REQUIRED, "enforced"},
521 {SMB_SIGNING_AUTO, "auto"},
526 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
528 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
529 * is implied in current control logic. This may change at some later time. A
530 * flag value of 0 means - show as development option only.
532 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
533 * screen in SWAT. This is used to exclude parameters as well as to squash all
534 * parameters that have been duplicated by pseudonyms.
536 static struct parm_struct parm_table[] = {
537 {"Base Options", P_SEP, P_SEPARATOR},
539 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
544 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
545 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
546 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
547 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
550 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
551 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
554 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
555 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
556 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
557 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
559 {"Security Options", P_SEP, P_SEPARATOR},
561 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
562 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
563 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
570 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
579 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
588 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
590 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
592 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
593 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
594 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
596 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
597 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
598 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
600 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
602 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
604 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
606 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
607 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
608 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
609 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
611 {"Logging Options", P_SEP, P_SEPARATOR},
613 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
614 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
615 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
617 {"Protocol Options", P_SEP, P_SEPARATOR},
619 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
620 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
621 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
622 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
623 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
624 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
625 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
626 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
627 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
628 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
633 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
634 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
635 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
637 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
638 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
639 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
640 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
641 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
642 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
643 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
644 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
645 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
646 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
648 {"Tuning Options", P_SEP, P_SEPARATOR},
650 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
651 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
652 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
653 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
655 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
656 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
657 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
659 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
660 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
661 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
663 {"Printing Options", P_SEP, P_SEPARATOR},
665 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
666 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
667 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
668 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
669 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
670 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
671 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
672 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
673 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
674 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
675 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
676 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
677 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
678 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
679 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
681 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
682 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
684 {"Filename Handling", P_SEP, P_SEPARATOR},
686 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
687 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
688 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
690 {"Domain Options", P_SEP, P_SEPARATOR},
692 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
694 {"Logon Options", P_SEP, P_SEPARATOR},
696 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
697 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
703 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"Browse Options", P_SEP, P_SEPARATOR},
707 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
708 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
709 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
712 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
714 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
715 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
716 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
718 {"WINS Options", P_SEP, P_SEPARATOR},
719 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
720 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
722 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
723 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
724 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
725 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
727 {"Locking Options", P_SEP, P_SEPARATOR},
729 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
730 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
731 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
732 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
734 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
735 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
736 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
737 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
738 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
740 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
742 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
743 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
746 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
750 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
751 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
752 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
753 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
754 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
757 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
758 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
760 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
761 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
762 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
764 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
768 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
769 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"Winbind options", P_SEP, P_SEPARATOR},
772 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
782 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
785 /***************************************************************************
786 Initialise the sDefault parameter structure for the printer values.
787 ***************************************************************************/
789 static void init_printer_values(void)
791 /* choose defaults depending on the type of printing */
792 switch (sDefault.iPrinting) {
797 do_parameter("Lpqcommand", "lpq -P'%p'");
798 do_parameter("Lprmcommand", "lprm -P'%p' %j");
799 do_parameter("Printcommand",
805 do_parameter("Lpqcommand", "lpq -P'%p'");
806 do_parameter("Lprmcommand", "lprm -P'%p' %j");
807 do_parameter("Printcommand",
809 do_parameter("Queuepausecommand",
811 do_parameter("Queueresumecommand",
813 do_parameter("Lppausecommand",
815 do_parameter("Lpresumecommand",
816 "lpc release '%p' %j");
821 do_parameter("Lpqcommand", "");
822 do_parameter("Lprmcommand", "");
823 do_parameter("Printcommand", "");
824 do_parameter("Lppausecommand", "");
825 do_parameter("Lpresumecommand", "");
826 do_parameter("Queuepausecommand", "");
827 do_parameter("Queueresumecommand", "");
829 do_parameter("Printcapname", "cups");
831 do_parameter("Lpqcommand",
832 "/usr/bin/lpstat -o '%p'");
833 do_parameter("Lprmcommand",
834 "/usr/bin/cancel '%p-%j'");
835 do_parameter("Printcommand",
836 "/usr/bin/lp -d '%p' %s; rm %s");
837 do_parameter("Lppausecommand",
838 "lp -i '%p-%j' -H hold");
839 do_parameter("Lpresumecommand",
840 "lp -i '%p-%j' -H resume");
841 do_parameter("Queuepausecommand",
842 "/usr/bin/disable '%p'");
843 do_parameter("Queueresumecommand",
844 "/usr/bin/enable '%p'");
845 do_parameter("Printcapname", "lpstat");
846 #endif /* HAVE_CUPS */
851 do_parameter("Lpqcommand", "lpstat -o%p");
852 do_parameter("Lprmcommand", "cancel %p-%j");
853 do_parameter("Printcommand",
854 "lp -c -d%p %s; rm %s");
855 do_parameter("Queuepausecommand",
857 do_parameter("Queueresumecommand",
860 do_parameter("Lppausecommand",
861 "lp -i %p-%j -H hold");
862 do_parameter("Lpresumecommand",
863 "lp -i %p-%j -H resume");
868 do_parameter("Lpqcommand", "lpq -P%p");
869 do_parameter("Lprmcommand", "lprm -P%p %j");
870 do_parameter("Printcommand", "lp -r -P%p %s");
874 do_parameter("Lpqcommand", "qstat -l -d%p");
875 do_parameter("Lprmcommand",
877 do_parameter("Printcommand",
878 "lp -d%p -s %s; rm %s");
879 do_parameter("Lppausecommand",
881 do_parameter("Lpresumecommand",
887 do_parameter("Printcommand", "vlp print %p %s");
888 do_parameter("Lpqcommand", "vlp lpq %p");
889 do_parameter("Lprmcommand", "vlp lprm %p %j");
890 do_parameter("Lppausecommand", "vlp lppause %p %j");
891 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
892 do_parameter("Queuepausecommand", "vlp queuepause %p");
893 do_parameter("Queueresumecommand", "vlp queueresume %p");
895 #endif /* DEVELOPER */
901 /***************************************************************************
902 Initialise the global parameter structure.
903 ***************************************************************************/
904 static void init_globals(void)
909 DEBUG(3, ("Initialising global parameters\n"));
911 for (i = 0; parm_table[i].label; i++) {
912 if ((parm_table[i].type == P_STRING ||
913 parm_table[i].type == P_USTRING) &&
915 !(parm_table[i].flags & FLAG_CMDLINE)) {
916 string_set(parm_table[i].ptr, "");
920 /* options that can be set on the command line must be initialised via
921 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
923 do_parameter("socket options", "TCP_NODELAY");
925 do_parameter("workgroup", DEFAULT_WORKGROUP);
926 myname = get_myname();
927 do_parameter("netbios name", myname);
929 do_parameter("max protocol", "NT1");
930 do_parameter("name resolve order", "lmhosts wins host bcast");
932 init_printer_values();
934 do_parameter("fstype", FSTYPE_STRING);
935 do_parameter("ntvfs handler", "unixuid default");
936 do_parameter("max connections", "-1");
938 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
939 do_parameter("server services", "smb rpc nbt");
940 do_parameter("auth methods", "anonymous sam_ignoredomain");
941 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
942 do_parameter("private dir", dyn_PRIVATE_DIR);
943 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
944 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
945 do_parameter_var("wins database", "tdb://%s/wins.ldb", dyn_PRIVATE_DIR);
946 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
947 do_parameter("guest account", GUEST_ACCOUNT);
949 /* using UTF8 by default allows us to support all chars */
950 do_parameter("unix charset", "UTF8");
952 /* Use codepage 850 as a default for the dos character set */
953 do_parameter("dos charset", "CP850");
956 * Allow the default PASSWD_CHAT to be overridden in local.h.
958 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
960 do_parameter("passwd program", "");
961 do_parameter("printcap name", PRINTCAP_NAME);
963 do_parameter("pid directory", dyn_PIDDIR);
964 do_parameter("lock dir", dyn_LOCKDIR);
965 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
967 do_parameter("socket address", "0.0.0.0");
968 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
970 do_parameter_var("announce version", "%d.%d",
971 DEFAULT_MAJOR_VERSION,
972 DEFAULT_MINOR_VERSION);
974 do_parameter("logon drive", "");
976 do_parameter("logon home", "\\\\%N\\%U");
977 do_parameter("logon path", "\\\\%N\\%U\\profile");
978 do_parameter("password server", "*");
980 do_parameter("load printers", "True");
982 do_parameter("max mux", "50");
983 do_parameter("max xmit", "12288");
984 do_parameter("lpqcachetime", "10");
985 do_parameter("DisableSpoolss", "False");
986 do_parameter("password level", "0");
987 do_parameter("username level", "0");
988 do_parameter("LargeReadwrite", "True");
989 do_parameter("minprotocol", "CORE");
990 do_parameter("security", "USER");
991 do_parameter("paranoid server security", "True");
992 do_parameter("EncryptPasswords", "True");
993 do_parameter("ReadRaw", "True");
994 do_parameter("WriteRaw", "True");
995 do_parameter("NullPasswords", "False");
996 do_parameter("ObeyPamRestrictions", "False");
997 do_parameter("lm announce", "Auto");
998 do_parameter("lm interval", "60");
999 do_parameter("announce as", "NT SERVER");
1001 do_parameter("TimeServer", "False");
1002 do_parameter("BindInterfacesOnly", "False");
1003 do_parameter("PamPasswordChange", "False");
1004 do_parameter("Unicode", "True");
1005 do_parameter("restrict anonymous", "0");
1006 do_parameter("ClientLanManAuth", "True");
1007 do_parameter("LanmanAuth", "True");
1008 do_parameter("NTLMAuth", "True");
1010 do_parameter("enhanced browsing", "True");
1011 do_parameter("LockSpinCount", "3");
1012 do_parameter("LockSpinTime", "10");
1013 #ifdef MMAP_BLACKLIST
1014 do_parameter("UseMmap", "False");
1016 do_parameter("UseMmap", "True");
1018 do_parameter("UnixExtensions", "False");
1020 /* hostname lookups can be very expensive and are broken on
1021 a large number of sites (tridge) */
1022 do_parameter("HostnameLookups", "False");
1024 do_parameter("PreferredMaster", "Auto");
1025 do_parameter("os level", "20");
1026 do_parameter("LocalMaster", "True");
1027 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1028 do_parameter("DomainLogons", "False");
1029 do_parameter("WINSsupport", "False");
1030 do_parameter("WINSproxy", "False");
1032 do_parameter("DNSproxy", "True");
1034 do_parameter("AllowTrustedDomains", "True");
1036 do_parameter("TemplateShell", "/bin/false");
1037 do_parameter("TemplateHomedir", "/home/%D/%U");
1038 do_parameter("WinbindSeparator", "\\");
1040 do_parameter("winbind cache time", "15");
1041 do_parameter("WinbindEnumUsers", "True");
1042 do_parameter("WinbindEnumGroups", "True");
1043 do_parameter("WinbindUseDefaultDomain", "False");
1045 do_parameter("IDMapBackend", "tdb");
1047 do_parameter("name cache timeout", "660"); /* In seconds */
1049 do_parameter("client signing", "Yes");
1050 do_parameter("server signing", "auto");
1052 do_parameter("use spnego", "True");
1054 do_parameter("smb ports", SMB_PORTS);
1055 do_parameter("nbt port", "137");
1056 do_parameter("dgram port", "138");
1058 do_parameter("nt status support", "True");
1060 do_parameter("max wins ttl", "432000");
1061 do_parameter("min wins ttl", "10");
1064 static TALLOC_CTX *lp_talloc;
1066 /******************************************************************* a
1067 Free up temporary memory - called from the main loop.
1068 ********************************************************************/
1070 void lp_talloc_free(void)
1074 talloc_free(lp_talloc);
1078 /*******************************************************************
1079 Convenience routine to grab string parameters into temporary memory
1080 and run standard_sub_basic on them. The buffers can be written to by
1081 callers without affecting the source string.
1082 ********************************************************************/
1084 static const char *lp_string(const char *s)
1086 #if 0 /* until REWRITE done to make thread-safe */
1087 size_t len = s ? strlen(s) : 0;
1091 /* The follow debug is useful for tracking down memory problems
1092 especially if you have an inner loop that is calling a lp_*()
1093 function that returns a string. Perhaps this debug should be
1094 present all the time? */
1097 DEBUG(10, ("lp_string(%s)\n", s));
1100 #if 0 /* until REWRITE done to make thread-safe */
1102 lp_talloc = talloc_init("lp_talloc");
1104 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1112 StrnCpy(ret, s, len);
1114 if (trim_string(ret, "\"", "\"")) {
1115 if (strchr(ret,'"') != NULL)
1116 StrnCpy(ret, s, len);
1119 standard_sub_basic(ret,len+100);
1126 In this section all the functions that are used to access the
1127 parameters from the rest of the program are defined
1130 #define FN_GLOBAL_STRING(fn_name,ptr) \
1131 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1132 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1133 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1134 #define FN_GLOBAL_LIST(fn_name,ptr) \
1135 const char **fn_name(void) {return(*(const char ***)(ptr));}
1136 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1137 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1138 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1139 char fn_name(void) {return(*(char *)(ptr));}
1140 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1141 int fn_name(void) {return(*(int *)(ptr));}
1143 #define FN_LOCAL_STRING(fn_name,val) \
1144 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1145 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1146 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1147 #define FN_LOCAL_LIST(fn_name,val) \
1148 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1149 #define FN_LOCAL_BOOL(fn_name,val) \
1150 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1151 #define FN_LOCAL_CHAR(fn_name,val) \
1152 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1153 #define FN_LOCAL_INTEGER(fn_name,val) \
1154 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1156 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1157 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1158 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
1159 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1160 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1161 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1162 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1163 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1164 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1165 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1166 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1167 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
1168 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1169 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1170 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1171 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1172 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1173 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1174 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1175 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1176 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1177 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1178 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1179 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1180 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1181 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1182 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1183 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1184 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1185 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1186 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1187 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1188 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1189 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1190 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1191 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1192 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1193 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1194 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1195 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1196 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1197 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1198 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1199 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1200 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1201 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1202 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1204 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1206 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1208 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1209 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1210 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1211 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1212 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1213 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1214 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1215 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1216 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1218 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1219 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1220 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1221 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1222 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1223 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1224 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1225 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1226 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1227 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1228 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1229 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1230 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1231 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1232 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1233 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1234 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1235 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1236 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1237 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1238 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1239 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1240 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1241 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1242 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1243 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1244 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1245 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1246 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1247 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1248 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1249 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1250 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1251 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1252 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1253 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1254 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1255 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1256 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1257 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1258 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1259 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1260 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1261 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1262 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1263 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1264 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1265 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1266 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1267 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1268 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1269 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1270 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1271 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1272 FN_LOCAL_STRING(lp_servicename, szService)
1273 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1274 FN_LOCAL_STRING(lp_pathname, szPath)
1275 FN_LOCAL_STRING(lp_username, szUsername)
1276 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1277 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1278 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1279 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1280 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1281 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1282 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1283 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1284 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1285 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1286 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1287 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1288 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1289 FN_LOCAL_STRING(lp_comment, comment)
1290 FN_LOCAL_STRING(lp_fstype, fstype)
1291 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1292 static FN_LOCAL_STRING(lp_volume, volume)
1293 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1294 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1295 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1296 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1297 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1298 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1299 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1300 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1301 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1302 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1303 FN_LOCAL_BOOL(lp_locking, bLocking)
1304 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1305 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1306 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1307 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1308 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1309 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1310 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1311 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1312 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1313 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1314 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1315 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1316 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1317 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1318 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1319 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1320 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1321 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1323 /* local prototypes */
1325 static int map_parameter(const char *pszParmName);
1326 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1327 static int getservicebyname(const char *pszServiceName,
1328 service * pserviceDest);
1329 static void copy_service(service * pserviceDest,
1330 service * pserviceSource, BOOL *pcopymapDest);
1331 static BOOL service_ok(int iService);
1332 static BOOL do_section(const char *pszSectionName);
1333 static void init_copymap(service * pservice);
1335 /* This is a helper function for parametrical options support. */
1336 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1337 /* Actual parametrical functions are quite simple */
1338 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1341 struct param_opt *data;
1343 if (lookup_service >= iNumServices) return NULL;
1345 data = (lookup_service < 0) ?
1346 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1348 asprintf(&vfskey, "%s:%s", type, option);
1352 if (strcmp(data->key, vfskey) == 0) {
1359 if (lookup_service >= 0) {
1360 /* Try to fetch the same option but from globals */
1361 /* but only if we are not already working with Globals */
1362 data = Globals.param_opt;
1364 if (strcmp(data->key, vfskey) == 0) {
1378 /*******************************************************************
1379 convenience routine to return int parameters.
1380 ********************************************************************/
1381 static int lp_int(const char *s)
1385 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1392 /*******************************************************************
1393 convenience routine to return unsigned long parameters.
1394 ********************************************************************/
1395 static int lp_ulong(const char *s)
1399 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1403 return strtoul(s, NULL, 10);
1406 /*******************************************************************
1407 convenience routine to return boolean parameters.
1408 ********************************************************************/
1409 static BOOL lp_bool(const char *s)
1414 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1418 if (!set_boolean(&ret,s)) {
1419 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1427 /* Return parametric option from a given service. Type is a part of option before ':' */
1428 /* Parametric option has following syntax: 'Type: option = value' */
1429 /* Returned value is allocated in 'lp_talloc' context */
1431 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1433 const char *value = get_parametrics(lookup_service, type, option);
1436 return lp_string(value);
1441 /* Return parametric option from a given service. Type is a part of option before ':' */
1442 /* Parametric option has following syntax: 'Type: option = value' */
1443 /* Returned value is allocated in 'lp_talloc' context */
1445 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1446 const char *separator)
1448 const char *value = get_parametrics(lookup_service, type, option);
1451 return str_list_make(talloc_autofree_context(), value, separator);
1456 /* Return parametric option from a given service. Type is a part of option before ':' */
1457 /* Parametric option has following syntax: 'Type: option = value' */
1459 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1461 const char *value = get_parametrics(lookup_service, type, option);
1464 return lp_int(value);
1469 /* Return parametric option from a given service. Type is a part of option before ':' */
1470 /* Parametric option has following syntax: 'Type: option = value' */
1472 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1474 const char *value = get_parametrics(lookup_service, type, option);
1477 return lp_ulong(value);
1482 /* Return parametric option from a given service. Type is a part of option before ':' */
1483 /* Parametric option has following syntax: 'Type: option = value' */
1485 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1487 const char *value = get_parametrics(lookup_service, type, option);
1490 return lp_bool(value);
1496 /***************************************************************************
1497 Initialise a service to the defaults.
1498 ***************************************************************************/
1500 static void init_service(service * pservice)
1502 memset((char *)pservice, '\0', sizeof(service));
1503 copy_service(pservice, &sDefault, NULL);
1506 /***************************************************************************
1507 Free the dynamically allocated parts of a service struct.
1508 ***************************************************************************/
1510 static void free_service(service *pservice)
1513 struct param_opt *data, *pdata;
1517 if (pservice->szService)
1518 DEBUG(5, ("free_service: Freeing service %s\n",
1519 pservice->szService));
1521 string_free(&pservice->szService);
1522 SAFE_FREE(pservice->copymap);
1524 for (i = 0; parm_table[i].label; i++) {
1525 if ((parm_table[i].type == P_STRING ||
1526 parm_table[i].type == P_USTRING) &&
1527 parm_table[i].class == P_LOCAL) {
1528 string_free((char **)
1529 (((char *)pservice) +
1530 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1531 } else if (parm_table[i].type == P_LIST &&
1532 parm_table[i].class == P_LOCAL) {
1533 char ***listp = (char ***)(((char *)pservice) +
1534 PTR_DIFF(parm_table[i].ptr, &sDefault));
1535 talloc_free(*listp);
1540 DEBUG(5,("Freeing parametrics:\n"));
1541 data = pservice->param_opt;
1543 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1544 string_free(&data->key);
1545 string_free(&data->value);
1551 ZERO_STRUCTP(pservice);
1554 /***************************************************************************
1555 Add a new service to the services array initialising it with the given
1557 ***************************************************************************/
1559 static int add_a_service(const service *pservice, const char *name)
1563 int num_to_alloc = iNumServices + 1;
1564 struct param_opt *data, *pdata;
1566 tservice = *pservice;
1568 /* it might already exist */
1570 i = getservicebyname(name, NULL);
1572 /* Clean all parametric options for service */
1573 /* They will be added during parsing again */
1574 data = ServicePtrs[i]->param_opt;
1576 string_free(&data->key);
1577 string_free(&data->value);
1582 ServicePtrs[i]->param_opt = NULL;
1587 /* find an invalid one */
1588 for (i = 0; i < iNumServices; i++)
1589 if (!ServicePtrs[i]->valid)
1592 /* if not, then create one */
1593 if (i == iNumServices) {
1596 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1599 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1604 ServicePtrs[iNumServices] = malloc_p(service);
1606 if (!ServicePtrs[iNumServices]) {
1607 DEBUG(0,("add_a_service: out of memory!\n"));
1613 free_service(ServicePtrs[i]);
1615 ServicePtrs[i]->valid = True;
1617 init_service(ServicePtrs[i]);
1618 copy_service(ServicePtrs[i], &tservice, NULL);
1620 string_set(&ServicePtrs[i]->szService, name);
1624 /***************************************************************************
1625 Add a new home service, with the specified home directory, defaults coming
1627 ***************************************************************************/
1629 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1630 const char *user, const char *pszHomedir)
1635 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1640 if (!(*(ServicePtrs[iDefaultService]->szPath))
1641 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1642 pstrcpy(newHomedir, pszHomedir);
1644 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1645 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1648 string_set(&ServicePtrs[i]->szPath, newHomedir);
1650 if (!(*(ServicePtrs[i]->comment))) {
1652 slprintf(comment, sizeof(comment) - 1,
1653 "Home directory of %s", user);
1654 string_set(&ServicePtrs[i]->comment, comment);
1656 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1657 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1659 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1665 /***************************************************************************
1666 Add a new service, based on an old one.
1667 ***************************************************************************/
1669 int lp_add_service(const char *pszService, int iDefaultService)
1671 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1674 /***************************************************************************
1675 Add the IPC service.
1676 ***************************************************************************/
1678 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1681 int i = add_a_service(&sDefault, name);
1686 slprintf(comment, sizeof(comment) - 1,
1687 "%s Service (%s)", fstype, Globals.szServerString);
1689 string_set(&ServicePtrs[i]->szPath, tmpdir());
1690 string_set(&ServicePtrs[i]->szUsername, "");
1691 string_set(&ServicePtrs[i]->comment, comment);
1692 string_set(&ServicePtrs[i]->fstype, fstype);
1693 ServicePtrs[i]->iMaxConnections = -1;
1694 ServicePtrs[i]->bAvailable = True;
1695 ServicePtrs[i]->bRead_only = True;
1696 ServicePtrs[i]->bGuest_only = False;
1697 ServicePtrs[i]->bGuest_ok = guest_ok;
1698 ServicePtrs[i]->bPrint_ok = False;
1699 ServicePtrs[i]->bBrowseable = False;
1701 if (strcasecmp(fstype, "IPC") == 0) {
1702 lp_do_parameter(i, "ntvfs handler", "default");
1705 DEBUG(3, ("adding hidden service %s\n", name));
1710 /***************************************************************************
1711 Add a new printer service, with defaults coming from service iFrom.
1712 ***************************************************************************/
1714 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1716 const char *comment = "From Printcap";
1717 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1722 /* note that we do NOT default the availability flag to True - */
1723 /* we take it from the default service passed. This allows all */
1724 /* dynamic printers to be disabled by disabling the [printers] */
1725 /* entry (if/when the 'available' keyword is implemented!). */
1727 /* the printer name is set to the service name. */
1728 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1729 string_set(&ServicePtrs[i]->comment, comment);
1730 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1731 /* Printers cannot be read_only. */
1732 ServicePtrs[i]->bRead_only = False;
1733 /* No share modes on printer services. */
1734 ServicePtrs[i]->bShareModes = False;
1735 /* No oplocks on printer services. */
1736 ServicePtrs[i]->bOpLocks = False;
1737 /* Printer services must be printable. */
1738 ServicePtrs[i]->bPrint_ok = True;
1740 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1742 update_server_announce_as_printserver();
1747 /***************************************************************************
1748 Map a parameter's string representation to something we can use.
1749 Returns False if the parameter string is not recognised, else TRUE.
1750 ***************************************************************************/
1752 static int map_parameter(const char *pszParmName)
1756 if (*pszParmName == '-')
1759 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1760 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1763 /* Warn only if it isn't parametric option */
1764 if (strchr(pszParmName, ':') == NULL)
1765 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1766 /* We do return 'fail' for parametric options as well because they are
1767 stored in different storage
1772 /***************************************************************************
1773 Set a boolean variable from the text value stored in the passed string.
1774 Returns True in success, False if the passed string does not correctly
1775 represent a boolean.
1776 ***************************************************************************/
1778 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1783 if (strwicmp(pszParmValue, "yes") == 0 ||
1784 strwicmp(pszParmValue, "true") == 0 ||
1785 strwicmp(pszParmValue, "1") == 0)
1787 else if (strwicmp(pszParmValue, "no") == 0 ||
1788 strwicmp(pszParmValue, "False") == 0 ||
1789 strwicmp(pszParmValue, "0") == 0)
1793 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1800 /***************************************************************************
1801 Find a service by name. Otherwise works like get_service.
1802 ***************************************************************************/
1804 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1808 for (iService = iNumServices - 1; iService >= 0; iService--)
1809 if (VALID(iService) &&
1810 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1811 if (pserviceDest != NULL)
1812 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1819 /***************************************************************************
1820 Copy a service structure to another.
1821 If pcopymapDest is NULL then copy all fields
1822 ***************************************************************************/
1824 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1827 BOOL bcopyall = (pcopymapDest == NULL);
1828 struct param_opt *data, *pdata, *paramo;
1831 for (i = 0; parm_table[i].label; i++)
1832 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1833 (bcopyall || pcopymapDest[i])) {
1834 void *def_ptr = parm_table[i].ptr;
1836 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1839 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1842 switch (parm_table[i].type) {
1845 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1851 *(int *)dest_ptr = *(int *)src_ptr;
1855 *(char *)dest_ptr = *(char *)src_ptr;
1859 string_set(dest_ptr,
1864 string_set(dest_ptr,
1866 strupper(*(char **)dest_ptr);
1869 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1870 *(const char ***)src_ptr);
1878 init_copymap(pserviceDest);
1879 if (pserviceSource->copymap)
1880 memcpy((void *)pserviceDest->copymap,
1881 (void *)pserviceSource->copymap,
1882 sizeof(BOOL) * NUMPARAMETERS);
1885 data = pserviceSource->param_opt;
1888 pdata = pserviceDest->param_opt;
1889 /* Traverse destination */
1891 /* If we already have same option, override it */
1892 if (strcmp(pdata->key, data->key) == 0) {
1893 string_free(&pdata->value);
1894 pdata->value = strdup(data->value);
1898 pdata = pdata->next;
1901 paramo = smb_xmalloc_p(struct param_opt);
1902 paramo->key = strdup(data->key);
1903 paramo->value = strdup(data->value);
1904 DLIST_ADD(pserviceDest->param_opt, paramo);
1910 /***************************************************************************
1911 Check a service for consistency. Return False if the service is in any way
1912 incomplete or faulty, else True.
1913 ***************************************************************************/
1915 static BOOL service_ok(int iService)
1920 if (ServicePtrs[iService]->szService[0] == '\0') {
1921 DEBUG(0, ("The following message indicates an internal error:\n"));
1922 DEBUG(0, ("No service name in service entry.\n"));
1926 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1927 /* I can't see why you'd want a non-printable printer service... */
1928 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1929 if (!ServicePtrs[iService]->bPrint_ok) {
1930 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1931 ServicePtrs[iService]->szService));
1932 ServicePtrs[iService]->bPrint_ok = True;
1933 update_server_announce_as_printserver();
1935 /* [printers] service must also be non-browsable. */
1936 if (ServicePtrs[iService]->bBrowseable)
1937 ServicePtrs[iService]->bBrowseable = False;
1940 /* If a service is flagged unavailable, log the fact at level 0. */
1941 if (!ServicePtrs[iService]->bAvailable)
1942 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1943 ServicePtrs[iService]->szService));
1948 static struct file_lists {
1949 struct file_lists *next;
1953 } *file_lists = NULL;
1955 /*******************************************************************
1956 Keep a linked list of all config files so we know when one has changed
1957 it's date and needs to be reloaded.
1958 ********************************************************************/
1960 static void add_to_file_list(const char *fname, const char *subfname)
1962 struct file_lists *f = file_lists;
1965 if (f->name && !strcmp(f->name, fname))
1971 f = malloc_p(struct file_lists);
1974 f->next = file_lists;
1975 f->name = strdup(fname);
1980 f->subfname = strdup(subfname);
1986 f->modtime = file_modtime(subfname);
1988 time_t t = file_modtime(subfname);
1994 /*******************************************************************
1995 Check if a config file has changed date.
1996 ********************************************************************/
1998 BOOL lp_file_list_changed(void)
2000 struct file_lists *f = file_lists;
2001 DEBUG(6, ("lp_file_list_changed()\n"));
2007 pstrcpy(n2, f->name);
2008 standard_sub_basic(n2,sizeof(n2));
2010 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2011 f->name, n2, ctime(&f->modtime)));
2013 mod_time = file_modtime(n2);
2015 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2017 ("file %s modified: %s\n", n2,
2019 f->modtime = mod_time;
2020 SAFE_FREE(f->subfname);
2021 f->subfname = strdup(n2);
2029 /***************************************************************************
2030 Handle the include operation.
2031 ***************************************************************************/
2033 static BOOL handle_include(const char *pszParmValue, char **ptr)
2036 pstrcpy(fname, pszParmValue);
2038 standard_sub_basic(fname,sizeof(fname));
2040 add_to_file_list(pszParmValue, fname);
2042 string_set(ptr, fname);
2044 if (file_exist(fname))
2045 return (pm_process(fname, do_section, do_parameter));
2047 DEBUG(2, ("Can't find include file %s\n", fname));
2052 /***************************************************************************
2053 Handle the interpretation of the copy parameter.
2054 ***************************************************************************/
2056 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2060 service serviceTemp;
2062 string_set(ptr, pszParmValue);
2064 init_service(&serviceTemp);
2068 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2070 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2071 if (iTemp == iServiceIndex) {
2072 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2074 copy_service(ServicePtrs[iServiceIndex],
2076 ServicePtrs[iServiceIndex]->copymap);
2080 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2084 free_service(&serviceTemp);
2088 /***************************************************************************
2089 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2094 winbind uid = 1000-1999
2095 winbind gid = 700-899
2097 We only do simple parsing checks here. The strings are parsed into useful
2098 structures in the winbind daemon code.
2100 ***************************************************************************/
2102 /* Some lp_ routines to return winbind [ug]id information */
2104 static uid_t winbind_uid_low, winbind_uid_high;
2105 static gid_t winbind_gid_low, winbind_gid_high;
2106 static uint32_t non_unix_account_low, non_unix_account_high;
2108 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2110 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2114 *low = winbind_uid_low;
2117 *high = winbind_uid_high;
2122 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2124 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2128 *low = winbind_gid_low;
2131 *high = winbind_gid_high;
2136 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2138 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2142 *low = non_unix_account_low;
2145 *high = non_unix_account_high;
2150 /* Do some simple checks on "winbind [ug]id" parameter values */
2152 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2156 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2161 string_set(ptr, pszParmValue);
2163 winbind_uid_low = low;
2164 winbind_uid_high = high;
2169 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2173 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2178 string_set(ptr, pszParmValue);
2180 winbind_gid_low = low;
2181 winbind_gid_high = high;
2186 /***************************************************************************
2187 Do some simple checks on "non unix account range" parameter values.
2188 ***************************************************************************/
2190 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2194 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2199 string_set(ptr, pszParmValue);
2201 non_unix_account_low = low;
2202 non_unix_account_high = high;
2208 /***************************************************************************
2209 Initialise a copymap.
2210 ***************************************************************************/
2212 static void init_copymap(service * pservice)
2215 SAFE_FREE(pservice->copymap);
2216 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2217 if (!pservice->copymap)
2219 ("Couldn't allocate copymap!! (size %d)\n",
2220 (int)NUMPARAMETERS));
2222 for (i = 0; i < NUMPARAMETERS; i++)
2223 pservice->copymap[i] = True;
2226 /***************************************************************************
2227 Return the local pointer to a parameter given the service number and the
2228 pointer into the default structure.
2229 ***************************************************************************/
2231 void *lp_local_ptr(int snum, void *ptr)
2233 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2237 /***************************************************************************
2238 Process a parametric option
2239 ***************************************************************************/
2240 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2242 struct param_opt *paramo, *data;
2245 while (isspace(*pszParmName)) {
2249 name = strdup(pszParmName);
2250 if (!name) return False;
2255 data = Globals.param_opt;
2257 data = ServicePtrs[snum]->param_opt;
2260 /* Traverse destination */
2261 for (paramo=data; paramo; paramo=paramo->next) {
2262 /* If we already have the option set, override it unless
2263 it was a command line option and the new one isn't */
2264 if (strcmp(paramo->key, name) == 0) {
2265 if ((paramo->flags & FLAG_CMDLINE) &&
2266 !(flags & FLAG_CMDLINE)) {
2270 free(paramo->value);
2271 paramo->value = strdup(pszParmValue);
2272 paramo->flags = flags;
2278 paramo = smb_xmalloc_p(struct param_opt);
2279 paramo->key = strdup(name);
2280 paramo->value = strdup(pszParmValue);
2281 paramo->flags = flags;
2283 DLIST_ADD(Globals.param_opt, paramo);
2285 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2293 /***************************************************************************
2294 Process a parameter for a particular service number. If snum < 0
2295 then assume we are in the globals.
2296 ***************************************************************************/
2297 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2300 void *parm_ptr = NULL; /* where we are going to store the result */
2301 void *def_ptr = NULL;
2303 parmnum = map_parameter(pszParmName);
2306 if (strchr(pszParmName, ':')) {
2307 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2309 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2313 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2314 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2318 /* if the flag has been set on the command line, then don't allow override,
2319 but don't report an error */
2320 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2324 def_ptr = parm_table[parmnum].ptr;
2326 /* we might point at a service, the default service or a global */
2330 if (parm_table[parmnum].class == P_GLOBAL) {
2332 ("Global parameter %s found in service section!\n",
2337 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2342 if (!ServicePtrs[snum]->copymap)
2343 init_copymap(ServicePtrs[snum]);
2345 /* this handles the aliases - set the copymap for other entries with
2346 the same data pointer */
2347 for (i = 0; parm_table[i].label; i++)
2348 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2349 ServicePtrs[snum]->copymap[i] = False;
2352 /* if it is a special case then go ahead */
2353 if (parm_table[parmnum].special) {
2354 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2358 /* now switch on the type of variable it is */
2359 switch (parm_table[parmnum].type)
2362 set_boolean(parm_ptr, pszParmValue);
2366 set_boolean(parm_ptr, pszParmValue);
2367 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2371 *(int *)parm_ptr = atoi(pszParmValue);
2375 *(char *)parm_ptr = *pszParmValue;
2379 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2383 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
2384 pszParmValue, NULL);
2388 string_set(parm_ptr, pszParmValue);
2392 string_set(parm_ptr, pszParmValue);
2393 strupper(*(char **)parm_ptr);
2397 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2400 parm_table[parmnum].enum_list[i].name)) {
2402 parm_table[parmnum].
2407 if (!parm_table[parmnum].enum_list[i].name) {
2408 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2409 pszParmValue, pszParmName));
2420 /***************************************************************************
2421 Process a parameter.
2422 ***************************************************************************/
2424 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2426 if (!bInGlobalSection && bGlobalOnly)
2429 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2430 pszParmName, pszParmValue));
2434 variable argument do parameter
2436 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2438 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2445 s = talloc_vasprintf(NULL, fmt, ap);
2447 ret = do_parameter(pszParmName, s);
2454 set a parameter from the commandline - this is called from command line parameter
2455 parsing code. It sets the parameter then marks the parameter as unable to be modified
2456 by smb.conf processing
2458 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2460 int parmnum = map_parameter(pszParmName);
2463 while (isspace(*pszParmValue)) pszParmValue++;
2466 if (parmnum < 0 && strchr(pszParmName, ':')) {
2467 /* set a parametric option */
2468 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2472 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2476 /* reset the CMDLINE flag in case this has been called before */
2477 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2479 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2483 parm_table[parmnum].flags |= FLAG_CMDLINE;
2485 /* we have to also set FLAG_CMDLINE on aliases */
2486 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2487 parm_table[i].flags |= FLAG_CMDLINE;
2489 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2490 parm_table[i].flags |= FLAG_CMDLINE;
2497 set a option from the commandline in 'a=b' format. Use to support --option
2499 BOOL lp_set_option(const char *option)
2517 ret = lp_set_cmdline(s, p+1);
2523 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2525 /***************************************************************************
2526 Print a parameter of the specified type.
2527 ***************************************************************************/
2529 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2535 for (i = 0; p->enum_list[i].name; i++) {
2536 if (*(int *)ptr == p->enum_list[i].value) {
2538 p->enum_list[i].name);
2545 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2549 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2553 fprintf(f, "%d", *(int *)ptr);
2557 fprintf(f, "%c", *(char *)ptr);
2561 if (*(int *)ptr == -1) {
2564 fprintf(f, "0%o", *(int *)ptr);
2569 if ((char ***)ptr && *(char ***)ptr) {
2570 char **list = *(char ***)ptr;
2572 for (; *list; list++)
2573 fprintf(f, "%s%s", *list,
2574 ((*(list+1))?", ":""));
2580 if (*(char **)ptr) {
2581 fprintf(f, "%s", *(char **)ptr);
2589 /***************************************************************************
2590 Check if two parameters are equal.
2591 ***************************************************************************/
2593 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2598 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2603 return (*((int *)ptr1) == *((int *)ptr2));
2606 return (*((char *)ptr1) == *((char *)ptr2));
2609 return str_list_equal((const char **)(*(char ***)ptr1),
2610 (const char **)(*(char ***)ptr2));
2615 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2620 return (p1 == p2 || strequal(p1, p2));
2628 /***************************************************************************
2629 Process a new section (service). At this stage all sections are services.
2630 Later we'll have special sections that permit server parameters to be set.
2631 Returns True on success, False on failure.
2632 ***************************************************************************/
2634 static BOOL do_section(const char *pszSectionName)
2637 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2638 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2641 /* if we've just struck a global section, note the fact. */
2642 bInGlobalSection = isglobal;
2644 /* check for multiple global sections */
2645 if (bInGlobalSection) {
2646 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2650 if (!bInGlobalSection && bGlobalOnly)
2653 /* if we have a current service, tidy it up before moving on */
2656 if (iServiceIndex >= 0)
2657 bRetval = service_ok(iServiceIndex);
2659 /* if all is still well, move to the next record in the services array */
2661 /* We put this here to avoid an odd message order if messages are */
2662 /* issued by the post-processing of a previous section. */
2663 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2665 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2667 DEBUG(0, ("Failed to add a new service\n"));
2676 /***************************************************************************
2677 Determine if a partcular base parameter is currentl set to the default value.
2678 ***************************************************************************/
2680 static BOOL is_default(int i)
2682 if (!defaults_saved)
2684 switch (parm_table[i].type) {
2686 return str_list_equal((const char **)parm_table[i].def.lvalue,
2687 (const char **)(*(char ***)parm_table[i].ptr));
2690 return strequal(parm_table[i].def.svalue,
2691 *(char **)parm_table[i].ptr);
2694 return parm_table[i].def.bvalue ==
2695 *(BOOL *)parm_table[i].ptr;
2697 return parm_table[i].def.cvalue ==
2698 *(char *)parm_table[i].ptr;
2702 return parm_table[i].def.ivalue ==
2703 *(int *)parm_table[i].ptr;
2710 /***************************************************************************
2711 Display the contents of the global structure.
2712 ***************************************************************************/
2714 static void dump_globals(FILE *f)
2717 struct param_opt *data;
2719 fprintf(f, "# Global parameters\n[global]\n");
2721 for (i = 0; parm_table[i].label; i++)
2722 if (parm_table[i].class == P_GLOBAL &&
2723 parm_table[i].ptr &&
2724 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2725 if (defaults_saved && is_default(i))
2727 fprintf(f, "\t%s = ", parm_table[i].label);
2728 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2731 if (Globals.param_opt != NULL) {
2732 data = Globals.param_opt;
2734 fprintf(f, "\t%s = %s\n", data->key, data->value);
2741 /***************************************************************************
2742 Display the contents of a single services record.
2743 ***************************************************************************/
2745 static void dump_a_service(service * pService, FILE * f)
2748 struct param_opt *data;
2750 if (pService != &sDefault)
2751 fprintf(f, "\n[%s]\n", pService->szService);
2753 for (i = 0; parm_table[i].label; i++)
2754 if (parm_table[i].class == P_LOCAL &&
2755 parm_table[i].ptr &&
2756 (*parm_table[i].label != '-') &&
2757 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2758 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2760 if (pService == &sDefault) {
2761 if (defaults_saved && is_default(i))
2764 if (equal_parameter(parm_table[i].type,
2765 ((char *)pService) +
2767 ((char *)&sDefault) +
2772 fprintf(f, "\t%s = ", parm_table[i].label);
2773 print_parameter(&parm_table[i],
2774 ((char *)pService) + pdiff, f);
2777 if (pService->param_opt != NULL) {
2778 data = pService->param_opt;
2780 fprintf(f, "\t%s = %s\n", data->key, data->value);
2787 /***************************************************************************
2788 Return info about the next service in a service. snum==-1 gives the globals.
2789 Return NULL when out of parameters.
2790 ***************************************************************************/
2792 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2795 /* do the globals */
2796 for (; parm_table[*i].label; (*i)++) {
2797 if (parm_table[*i].class == P_SEPARATOR)
2798 return &parm_table[(*i)++];
2800 if (!parm_table[*i].ptr
2801 || (*parm_table[*i].label == '-'))
2805 && (parm_table[*i].ptr ==
2806 parm_table[(*i) - 1].ptr))
2809 return &parm_table[(*i)++];
2812 service *pService = ServicePtrs[snum];
2814 for (; parm_table[*i].label; (*i)++) {
2815 if (parm_table[*i].class == P_SEPARATOR)
2816 return &parm_table[(*i)++];
2818 if (parm_table[*i].class == P_LOCAL &&
2819 parm_table[*i].ptr &&
2820 (*parm_table[*i].label != '-') &&
2822 (parm_table[*i].ptr !=
2823 parm_table[(*i) - 1].ptr)))
2826 PTR_DIFF(parm_table[*i].ptr,
2829 if (allparameters ||
2830 !equal_parameter(parm_table[*i].type,
2831 ((char *)pService) +
2833 ((char *)&sDefault) +
2836 return &parm_table[(*i)++];
2846 /***************************************************************************
2847 Return TRUE if the passed service number is within range.
2848 ***************************************************************************/
2850 BOOL lp_snum_ok(int iService)
2852 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2855 /***************************************************************************
2856 Auto-load some home services.
2857 ***************************************************************************/
2859 static void lp_add_auto_services(const char *str)
2864 /***************************************************************************
2865 Auto-load one printer.
2866 ***************************************************************************/
2868 void lp_add_one_printer(char *name, char *comment)
2870 int printers = lp_servicenumber(PRINTERS_NAME);
2873 if (lp_servicenumber(name) < 0) {
2874 lp_add_printer(name, printers);
2875 if ((i = lp_servicenumber(name)) >= 0) {
2876 string_set(&ServicePtrs[i]->comment, comment);
2877 ServicePtrs[i]->autoloaded = True;
2882 /***************************************************************************
2883 Announce ourselves as a print server.
2884 ***************************************************************************/
2886 void update_server_announce_as_printserver(void)
2888 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2891 /***************************************************************************
2892 Have we loaded a services file yet?
2893 ***************************************************************************/
2895 BOOL lp_loaded(void)
2900 /***************************************************************************
2901 Unload unused services.
2902 ***************************************************************************/
2904 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2907 for (i = 0; i < iNumServices; i++) {
2911 if (!snumused || !snumused(smb, i)) {
2912 ServicePtrs[i]->valid = False;
2913 free_service(ServicePtrs[i]);
2918 /***************************************************************************
2920 ***************************************************************************/
2922 void lp_killservice(int iServiceIn)
2924 if (VALID(iServiceIn)) {
2925 ServicePtrs[iServiceIn]->valid = False;
2926 free_service(ServicePtrs[iServiceIn]);
2930 /***************************************************************************
2931 Save the curent values of all global and sDefault parameters into the
2932 defaults union. This allows swat and testparm to show only the
2933 changed (ie. non-default) parameters.
2934 ***************************************************************************/
2936 static void lp_save_defaults(void)
2939 for (i = 0; parm_table[i].label; i++) {
2940 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2942 switch (parm_table[i].type) {
2944 parm_table[i].def.lvalue = str_list_copy(talloc_autofree_context(),
2945 *(const char ***)parm_table[i].ptr);
2949 if (parm_table[i].ptr) {
2950 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2952 parm_table[i].def.svalue = NULL;
2957 parm_table[i].def.bvalue =
2958 *(BOOL *)parm_table[i].ptr;
2961 parm_table[i].def.cvalue =
2962 *(char *)parm_table[i].ptr;
2967 parm_table[i].def.ivalue =
2968 *(int *)parm_table[i].ptr;
2974 defaults_saved = True;
2977 /*******************************************************************
2978 Set the server type we will announce as via nmbd.
2979 ********************************************************************/
2981 static void set_server_role(void)
2983 server_role = ROLE_STANDALONE;
2985 switch (lp_security()) {
2987 if (lp_domain_logons())
2988 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2993 if (lp_domain_logons()) {
2994 if (Globals.bDomainMaster) /* auto or yes */
2995 server_role = ROLE_DOMAIN_PDC;
2997 server_role = ROLE_DOMAIN_BDC;
3000 server_role = ROLE_DOMAIN_MEMBER;
3003 if (lp_domain_logons()) {
3005 if (Globals.bDomainMaster) /* auto or yes */
3006 server_role = ROLE_DOMAIN_PDC;
3008 server_role = ROLE_DOMAIN_BDC;
3012 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3016 DEBUG(10, ("set_server_role: role = "));
3018 switch(server_role) {
3019 case ROLE_STANDALONE:
3020 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3022 case ROLE_DOMAIN_MEMBER:
3023 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3025 case ROLE_DOMAIN_BDC:
3026 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3028 case ROLE_DOMAIN_PDC:
3029 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3034 /***************************************************************************
3035 Load the services array from the services file. Return True on success,
3037 ***************************************************************************/
3039 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3044 struct param_opt *data;
3046 pstrcpy(n2, pszFname);
3047 standard_sub_basic(n2,sizeof(n2));
3049 add_to_file_list(pszFname, n2);
3053 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3055 bInGlobalSection = True;
3056 bGlobalOnly = global_only;
3058 if (Globals.param_opt != NULL) {
3059 struct param_opt *next;
3060 for (data=Globals.param_opt; data; data=next) {
3062 if (data->flags & FLAG_CMDLINE) continue;
3065 DLIST_REMOVE(Globals.param_opt, data);
3077 /* We get sections first, so have to start 'behind' to make up */
3079 bRetval = pm_process(n2, do_section, do_parameter);
3081 /* finish up the last section */
3082 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3084 if (iServiceIndex >= 0)
3085 bRetval = service_ok(iServiceIndex);
3087 lp_add_auto_services(lp_auto_services());
3090 /* When 'restrict anonymous = 2' guest connections to ipc$
3092 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3093 lp_add_hidden("ADMIN$", "DISK", False);
3097 set_default_server_announce_type();
3101 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3102 /* if bWINSsupport is true and we are in the client */
3103 if (in_client && Globals.bWINSsupport) {
3104 lp_do_parameter(-1, "wins server", "127.0.0.1");
3112 /***************************************************************************
3113 Reset the max number of services.
3114 ***************************************************************************/
3116 void lp_resetnumservices(void)
3121 /***************************************************************************
3122 Return the max number of services.
3123 ***************************************************************************/
3125 int lp_numservices(void)
3127 return (iNumServices);
3130 /***************************************************************************
3131 Display the contents of the services array in human-readable form.
3132 ***************************************************************************/
3134 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3139 defaults_saved = False;
3143 dump_a_service(&sDefault, f);
3145 for (iService = 0; iService < maxtoprint; iService++)
3146 lp_dump_one(f, show_defaults, iService);
3149 /***************************************************************************
3150 Display the contents of one service in human-readable form.
3151 ***************************************************************************/
3153 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3156 if (ServicePtrs[snum]->szService[0] == '\0')
3158 dump_a_service(ServicePtrs[snum], f);
3162 /***************************************************************************
3163 Return the number of the service with the given name, or -1 if it doesn't
3164 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3165 getservicebyname()! This works ONLY if all services have been loaded, and
3166 does not copy the found service.
3167 ***************************************************************************/
3169 int lp_servicenumber(const char *pszServiceName)
3172 fstring serviceName;
3175 for (iService = iNumServices - 1; iService >= 0; iService--) {
3176 if (VALID(iService) && ServicePtrs[iService]->szService) {
3178 * The substitution here is used to support %U is
3181 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3182 standard_sub_basic(serviceName,sizeof(serviceName));
3183 if (strequal(serviceName, pszServiceName))
3189 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3194 /*******************************************************************
3195 A useful volume label function.
3196 ********************************************************************/
3197 const char *volume_label(int snum)
3199 const char *ret = lp_volume(snum);
3201 return lp_servicename(snum);
3206 /*******************************************************************
3207 Set the server type we will announce as via nmbd.
3208 ********************************************************************/
3210 static void set_default_server_announce_type(void)
3212 default_server_announce = 0;
3213 default_server_announce |= SV_TYPE_WORKSTATION;
3214 default_server_announce |= SV_TYPE_SERVER;
3215 default_server_announce |= SV_TYPE_SERVER_UNIX;
3217 switch (lp_announce_as()) {
3218 case ANNOUNCE_AS_NT_SERVER:
3219 default_server_announce |= SV_TYPE_SERVER_NT;
3220 /* fall through... */
3221 case ANNOUNCE_AS_NT_WORKSTATION:
3222 default_server_announce |= SV_TYPE_NT;
3224 case ANNOUNCE_AS_WIN95:
3225 default_server_announce |= SV_TYPE_WIN95_PLUS;
3227 case ANNOUNCE_AS_WFW:
3228 default_server_announce |= SV_TYPE_WFW;
3234 switch (lp_server_role()) {
3235 case ROLE_DOMAIN_MEMBER:
3236 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3238 case ROLE_DOMAIN_PDC:
3239 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3241 case ROLE_DOMAIN_BDC:
3242 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3244 case ROLE_STANDALONE:
3248 if (lp_time_server())
3249 default_server_announce |= SV_TYPE_TIME_SOURCE;
3251 if (lp_host_msdfs())
3252 default_server_announce |= SV_TYPE_DFS_SERVER;
3254 /* TODO: only announce us as print server when we are a print server */
3255 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3258 /***********************************************************
3259 returns role of Samba server
3260 ************************************************************/
3262 int lp_server_role(void)
3267 /***********************************************************
3268 If we are PDC then prefer us as DMB
3269 ************************************************************/
3271 BOOL lp_domain_master(void)
3273 if (Globals.bDomainMaster == Auto)
3274 return (lp_server_role() == ROLE_DOMAIN_PDC);
3276 return Globals.bDomainMaster;
3279 /***********************************************************
3280 If we are DMB then prefer us as LMB
3281 ************************************************************/
3283 BOOL lp_preferred_master(void)
3285 if (Globals.bPreferredMaster == Auto)
3286 return (lp_local_master() && lp_domain_master());
3288 return Globals.bPreferredMaster;
3291 /*******************************************************************
3293 ********************************************************************/
3295 void lp_remove_service(int snum)
3297 ServicePtrs[snum]->valid = False;
3300 /*******************************************************************
3302 ********************************************************************/
3304 void lp_copy_service(int snum, const char *new_name)
3306 const char *oldname = lp_servicename(snum);
3307 do_section(new_name);
3309 snum = lp_servicenumber(new_name);
3311 lp_do_parameter(snum, "copy", oldname);
3316 /*******************************************************************
3317 Get the default server type we will announce as via nmbd.
3318 ********************************************************************/
3319 int lp_default_server_announce(void)
3321 return default_server_announce;
3324 const char *lp_printername(int snum)
3326 const char *ret = _lp_printername(snum);
3327 if (ret == NULL || (ret != NULL && *ret == '\0'))
3328 ret = lp_const_servicename(snum);
3334 /*******************************************************************
3335 Return the max print jobs per queue.
3336 ********************************************************************/
3338 int lp_maxprintjobs(int snum)
3340 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3341 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3342 maxjobs = PRINT_MAX_JOBID - 1;