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;
241 char *socket_options;
246 BOOL bPreferredMaster;
249 BOOL bEncryptPasswords;
251 BOOL bObeyPamRestrictions;
253 BOOL bLargeReadwrite;
257 BOOL bBindInterfacesOnly;
258 BOOL bPamPasswordChange;
260 BOOL bNTStatusSupport;
261 BOOL bAllowTrustedDomains;
267 BOOL bClientLanManAuth;
268 BOOL bClientNTLMv2Auth;
270 BOOL bHideLocalUsers;
273 BOOL bHostnameLookups;
274 BOOL bUnixExtensions;
275 BOOL bDisableNetbios;
277 int restrict_anonymous;
278 int name_cache_timeout;
279 struct param_opt *param_opt;
283 static global Globals;
286 * This structure describes a single service.
295 char **szInvalidUsers;
300 char *szPrintcommand;
303 char *szLppausecommand;
304 char *szLpresumecommand;
305 char *szQueuepausecommand;
306 char *szQueueresumecommand;
314 char **ntvfs_handler;
340 struct param_opt *param_opt;
342 char dummy[3]; /* for alignment */
347 /* This is a default service used to prime a services structure */
348 static service sDefault = {
350 False, /* not autoloaded */
351 NULL, /* szService */
353 NULL, /* szUsername */
354 NULL, /* szInvalidUsers */
355 NULL, /* szValidUsers */
356 NULL, /* szAdminUsers */
358 NULL, /* szInclude */
359 NULL, /* szPrintcommand */
360 NULL, /* szLpqcommand */
361 NULL, /* szLprmcommand */
362 NULL, /* szLppausecommand */
363 NULL, /* szLpresumecommand */
364 NULL, /* szQueuepausecommand */
365 NULL, /* szQueueresumecommand */
366 NULL, /* szPrintername */
367 NULL, /* szHostsallow */
368 NULL, /* szHostsdeny */
372 NULL, /* szMSDfsProxy */
373 NULL, /* ntvfs_handler */
374 0, /* iMinPrintSpace */
375 1000, /* iMaxPrintJobs */
376 0, /* iMaxConnections */
377 DEFAULT_PRINTING, /* iPrinting */
379 True, /* bAvailable */
380 True, /* bBrowseable */
381 True, /* bRead_only */
382 False, /* bPrint_ok */
383 False, /* bMap_system */
384 False, /* bMap_hidden */
385 True, /* bMap_archive */
387 True, /* bStrictLocking */
388 True, /* bPosixLocking */
390 True, /* bLevel2OpLocks */
391 False, /* bOnlyUser */
392 False, /* bGuest_only */
393 False, /* bGuest_ok */
395 False, /* bMSDfsRoot */
396 True, /* bShareModes */
397 False, /* bStrictSync */
398 False, /* bCIFileSystem */
399 NULL, /* Parametric options */
404 /* local variables */
405 static service **ServicePtrs = NULL;
406 static int iNumServices = 0;
407 static int iServiceIndex = 0;
408 static BOOL bInGlobalSection = True;
409 static BOOL bGlobalOnly = False;
410 static int server_role;
411 static int default_server_announce;
413 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
415 /* prototypes for the special type handlers */
416 static BOOL handle_include(const char *pszParmValue, char **ptr);
417 static BOOL handle_copy(const char *pszParmValue, char **ptr);
418 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
419 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
420 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
422 static void set_server_role(void);
423 static void set_default_server_announce_type(void);
425 static const struct enum_list enum_protocol[] = {
426 {PROTOCOL_NT1, "NT1"},
427 {PROTOCOL_LANMAN2, "LANMAN2"},
428 {PROTOCOL_LANMAN1, "LANMAN1"},
429 {PROTOCOL_CORE, "CORE"},
430 {PROTOCOL_COREPLUS, "COREPLUS"},
431 {PROTOCOL_COREPLUS, "CORE+"},
435 static const struct enum_list enum_security[] = {
436 {SEC_SHARE, "SHARE"},
438 {SEC_SERVER, "SERVER"},
439 {SEC_DOMAIN, "DOMAIN"},
446 static const struct enum_list enum_printing[] = {
447 {PRINT_SYSV, "sysv"},
449 {PRINT_HPUX, "hpux"},
453 {PRINT_LPRNG, "lprng"},
454 {PRINT_SOFTQ, "softq"},
455 {PRINT_CUPS, "cups"},
457 {PRINT_LPROS2, "os2"},
459 {PRINT_TEST, "test"},
461 #endif /* DEVELOPER */
465 /* Types of machine we can announce as. */
466 #define ANNOUNCE_AS_NT_SERVER 1
467 #define ANNOUNCE_AS_WIN95 2
468 #define ANNOUNCE_AS_WFW 3
469 #define ANNOUNCE_AS_NT_WORKSTATION 4
471 static const struct enum_list enum_announce_as[] = {
472 {ANNOUNCE_AS_NT_SERVER, "NT"},
473 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
474 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
475 {ANNOUNCE_AS_WIN95, "win95"},
476 {ANNOUNCE_AS_WFW, "WfW"},
480 static const struct enum_list enum_bool_auto[] = {
491 /* Client-side offline caching policy types */
492 #define CSC_POLICY_MANUAL 0
493 #define CSC_POLICY_DOCUMENTS 1
494 #define CSC_POLICY_PROGRAMS 2
495 #define CSC_POLICY_DISABLE 3
497 static const struct enum_list enum_csc_policy[] = {
498 {CSC_POLICY_MANUAL, "manual"},
499 {CSC_POLICY_DOCUMENTS, "documents"},
500 {CSC_POLICY_PROGRAMS, "programs"},
501 {CSC_POLICY_DISABLE, "disable"},
505 /* SMB signing types. */
506 static const struct enum_list enum_smb_signing_vals[] = {
507 {SMB_SIGNING_OFF, "No"},
508 {SMB_SIGNING_OFF, "False"},
509 {SMB_SIGNING_OFF, "0"},
510 {SMB_SIGNING_OFF, "Off"},
511 {SMB_SIGNING_OFF, "disabled"},
512 {SMB_SIGNING_SUPPORTED, "Yes"},
513 {SMB_SIGNING_SUPPORTED, "True"},
514 {SMB_SIGNING_SUPPORTED, "1"},
515 {SMB_SIGNING_SUPPORTED, "On"},
516 {SMB_SIGNING_SUPPORTED, "enabled"},
517 {SMB_SIGNING_REQUIRED, "required"},
518 {SMB_SIGNING_REQUIRED, "mandatory"},
519 {SMB_SIGNING_REQUIRED, "force"},
520 {SMB_SIGNING_REQUIRED, "forced"},
521 {SMB_SIGNING_REQUIRED, "enforced"},
522 {SMB_SIGNING_AUTO, "auto"},
527 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
529 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
530 * is implied in current control logic. This may change at some later time. A
531 * flag value of 0 means - show as development option only.
533 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
534 * screen in SWAT. This is used to exclude parameters as well as to squash all
535 * parameters that have been duplicated by pseudonyms.
537 static struct parm_struct parm_table[] = {
538 {"Base Options", P_SEP, P_SEPARATOR},
540 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
545 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
546 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
547 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
550 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
551 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
552 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
555 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
556 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
557 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
558 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
560 {"Security Options", P_SEP, P_SEPARATOR},
562 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
563 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
565 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
571 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
580 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
588 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
590 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
591 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
593 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
594 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
595 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
597 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
598 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
599 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
601 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
603 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
605 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
607 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
608 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
609 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
610 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
612 {"Logging Options", P_SEP, P_SEPARATOR},
614 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
615 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
616 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
618 {"Protocol Options", P_SEP, P_SEPARATOR},
620 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
621 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
622 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
624 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
625 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
626 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
627 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
628 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
629 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
630 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
635 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
636 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
637 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
639 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
640 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
641 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
642 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
643 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
644 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
645 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
646 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
647 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
648 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
650 {"Tuning Options", P_SEP, P_SEPARATOR},
652 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
653 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
654 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
655 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
657 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
658 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
659 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
661 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
662 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
663 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
665 {"Printing Options", P_SEP, P_SEPARATOR},
667 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
668 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
669 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
670 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
671 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
672 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
673 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
674 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
675 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
676 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
677 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
678 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
679 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
680 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
681 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
683 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
684 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
686 {"Filename Handling", P_SEP, P_SEPARATOR},
688 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
689 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
690 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
692 {"Domain Options", P_SEP, P_SEPARATOR},
694 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
696 {"Logon Options", P_SEP, P_SEPARATOR},
698 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
703 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"Browse Options", P_SEP, P_SEPARATOR},
709 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
712 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
714 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
715 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
717 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
718 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
720 {"WINS Options", P_SEP, P_SEPARATOR},
721 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
722 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
724 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
725 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
726 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
727 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
729 {"Locking Options", P_SEP, P_SEPARATOR},
731 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
732 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
733 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
734 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
736 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
737 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
738 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
739 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
740 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
742 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
744 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
745 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
748 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
751 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
752 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
753 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
754 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
756 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
759 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
760 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
762 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
763 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
764 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
766 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
770 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
771 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"Winbind options", P_SEP, P_SEPARATOR},
774 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
781 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
782 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
784 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
787 /***************************************************************************
788 Initialise the sDefault parameter structure for the printer values.
789 ***************************************************************************/
791 static void init_printer_values(void)
793 /* choose defaults depending on the type of printing */
794 switch (sDefault.iPrinting) {
799 do_parameter("Lpqcommand", "lpq -P'%p'");
800 do_parameter("Lprmcommand", "lprm -P'%p' %j");
801 do_parameter("Printcommand",
807 do_parameter("Lpqcommand", "lpq -P'%p'");
808 do_parameter("Lprmcommand", "lprm -P'%p' %j");
809 do_parameter("Printcommand",
811 do_parameter("Queuepausecommand",
813 do_parameter("Queueresumecommand",
815 do_parameter("Lppausecommand",
817 do_parameter("Lpresumecommand",
818 "lpc release '%p' %j");
823 do_parameter("Lpqcommand", "");
824 do_parameter("Lprmcommand", "");
825 do_parameter("Printcommand", "");
826 do_parameter("Lppausecommand", "");
827 do_parameter("Lpresumecommand", "");
828 do_parameter("Queuepausecommand", "");
829 do_parameter("Queueresumecommand", "");
831 do_parameter("Printcapname", "cups");
833 do_parameter("Lpqcommand",
834 "/usr/bin/lpstat -o '%p'");
835 do_parameter("Lprmcommand",
836 "/usr/bin/cancel '%p-%j'");
837 do_parameter("Printcommand",
838 "/usr/bin/lp -d '%p' %s; rm %s");
839 do_parameter("Lppausecommand",
840 "lp -i '%p-%j' -H hold");
841 do_parameter("Lpresumecommand",
842 "lp -i '%p-%j' -H resume");
843 do_parameter("Queuepausecommand",
844 "/usr/bin/disable '%p'");
845 do_parameter("Queueresumecommand",
846 "/usr/bin/enable '%p'");
847 do_parameter("Printcapname", "lpstat");
848 #endif /* HAVE_CUPS */
853 do_parameter("Lpqcommand", "lpstat -o%p");
854 do_parameter("Lprmcommand", "cancel %p-%j");
855 do_parameter("Printcommand",
856 "lp -c -d%p %s; rm %s");
857 do_parameter("Queuepausecommand",
859 do_parameter("Queueresumecommand",
862 do_parameter("Lppausecommand",
863 "lp -i %p-%j -H hold");
864 do_parameter("Lpresumecommand",
865 "lp -i %p-%j -H resume");
870 do_parameter("Lpqcommand", "lpq -P%p");
871 do_parameter("Lprmcommand", "lprm -P%p %j");
872 do_parameter("Printcommand", "lp -r -P%p %s");
876 do_parameter("Lpqcommand", "qstat -l -d%p");
877 do_parameter("Lprmcommand",
879 do_parameter("Printcommand",
880 "lp -d%p -s %s; rm %s");
881 do_parameter("Lppausecommand",
883 do_parameter("Lpresumecommand",
889 do_parameter("Printcommand", "vlp print %p %s");
890 do_parameter("Lpqcommand", "vlp lpq %p");
891 do_parameter("Lprmcommand", "vlp lprm %p %j");
892 do_parameter("Lppausecommand", "vlp lppause %p %j");
893 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
894 do_parameter("Queuepausecommand", "vlp queuepause %p");
895 do_parameter("Queueresumecommand", "vlp queueresume %p");
897 #endif /* DEVELOPER */
903 /***************************************************************************
904 Initialise the global parameter structure.
905 ***************************************************************************/
906 static void init_globals(void)
911 DEBUG(3, ("Initialising global parameters\n"));
913 for (i = 0; parm_table[i].label; i++) {
914 if ((parm_table[i].type == P_STRING ||
915 parm_table[i].type == P_USTRING) &&
917 !(parm_table[i].flags & FLAG_CMDLINE)) {
918 string_set(parm_table[i].ptr, "");
922 /* options that can be set on the command line must be initialised via
923 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
925 do_parameter("socket options", "TCP_NODELAY");
927 do_parameter("workgroup", DEFAULT_WORKGROUP);
928 myname = get_myname();
929 do_parameter("netbios name", myname);
931 do_parameter("max protocol", "NT1");
932 do_parameter("name resolve order", "lmhosts wins host bcast");
934 init_printer_values();
936 do_parameter("fstype", FSTYPE_STRING);
937 do_parameter("ntvfs handler", "unixuid default");
938 do_parameter("max connections", "-1");
940 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
941 do_parameter("server services", "smb rpc nbt ldap cldap");
942 do_parameter("auth methods", "anonymous sam_ignoredomain");
943 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
944 do_parameter("private dir", dyn_PRIVATE_DIR);
945 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
946 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
947 do_parameter_var("wins database", "tdb://%s/wins.ldb", dyn_PRIVATE_DIR);
948 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
949 do_parameter("guest account", GUEST_ACCOUNT);
951 /* using UTF8 by default allows us to support all chars */
952 do_parameter("unix charset", "UTF8");
954 /* Use codepage 850 as a default for the dos character set */
955 do_parameter("dos charset", "CP850");
958 * Allow the default PASSWD_CHAT to be overridden in local.h.
960 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
962 do_parameter("passwd program", "");
963 do_parameter("printcap name", PRINTCAP_NAME);
965 do_parameter("pid directory", dyn_PIDDIR);
966 do_parameter("lock dir", dyn_LOCKDIR);
967 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
969 do_parameter("socket address", "0.0.0.0");
970 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
972 do_parameter_var("announce version", "%d.%d",
973 DEFAULT_MAJOR_VERSION,
974 DEFAULT_MINOR_VERSION);
976 do_parameter("logon drive", "");
978 do_parameter("logon home", "\\\\%N\\%U");
979 do_parameter("logon path", "\\\\%N\\%U\\profile");
980 do_parameter("password server", "*");
982 do_parameter("load printers", "True");
984 do_parameter("max mux", "50");
985 do_parameter("max xmit", "12288");
986 do_parameter("lpqcachetime", "10");
987 do_parameter("DisableSpoolss", "False");
988 do_parameter("password level", "0");
989 do_parameter("username level", "0");
990 do_parameter("LargeReadwrite", "True");
991 do_parameter("minprotocol", "CORE");
992 do_parameter("security", "USER");
993 do_parameter("paranoid server security", "True");
994 do_parameter("EncryptPasswords", "True");
995 do_parameter("ReadRaw", "True");
996 do_parameter("WriteRaw", "True");
997 do_parameter("NullPasswords", "False");
998 do_parameter("ObeyPamRestrictions", "False");
999 do_parameter("lm announce", "Auto");
1000 do_parameter("lm interval", "60");
1001 do_parameter("announce as", "NT SERVER");
1003 do_parameter("TimeServer", "False");
1004 do_parameter("BindInterfacesOnly", "False");
1005 do_parameter("PamPasswordChange", "False");
1006 do_parameter("Unicode", "True");
1007 do_parameter("restrict anonymous", "0");
1008 do_parameter("ClientLanManAuth", "True");
1009 do_parameter("LanmanAuth", "True");
1010 do_parameter("NTLMAuth", "True");
1012 do_parameter("enhanced browsing", "True");
1013 do_parameter("LockSpinCount", "3");
1014 do_parameter("LockSpinTime", "10");
1015 #ifdef MMAP_BLACKLIST
1016 do_parameter("UseMmap", "False");
1018 do_parameter("UseMmap", "True");
1020 do_parameter("UnixExtensions", "False");
1022 /* hostname lookups can be very expensive and are broken on
1023 a large number of sites (tridge) */
1024 do_parameter("HostnameLookups", "False");
1026 do_parameter("PreferredMaster", "Auto");
1027 do_parameter("os level", "20");
1028 do_parameter("LocalMaster", "True");
1029 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1030 do_parameter("DomainLogons", "False");
1031 do_parameter("WINSsupport", "False");
1032 do_parameter("WINSproxy", "False");
1034 do_parameter("DNSproxy", "True");
1036 do_parameter("AllowTrustedDomains", "True");
1038 do_parameter("TemplateShell", "/bin/false");
1039 do_parameter("TemplateHomedir", "/home/%D/%U");
1040 do_parameter("WinbindSeparator", "\\");
1042 do_parameter("winbind cache time", "15");
1043 do_parameter("WinbindEnumUsers", "True");
1044 do_parameter("WinbindEnumGroups", "True");
1045 do_parameter("WinbindUseDefaultDomain", "False");
1047 do_parameter("IDMapBackend", "tdb");
1049 do_parameter("name cache timeout", "660"); /* In seconds */
1051 do_parameter("client signing", "Yes");
1052 do_parameter("server signing", "auto");
1054 do_parameter("use spnego", "True");
1056 do_parameter("smb ports", SMB_PORTS);
1057 do_parameter("nbt port", "137");
1058 do_parameter("dgram port", "138");
1059 do_parameter("cldap port", "389");
1061 do_parameter("nt status support", "True");
1063 do_parameter("max wins ttl", "432000");
1064 do_parameter("min wins ttl", "10");
1067 static TALLOC_CTX *lp_talloc;
1069 /******************************************************************* a
1070 Free up temporary memory - called from the main loop.
1071 ********************************************************************/
1073 void lp_talloc_free(void)
1077 talloc_free(lp_talloc);
1081 /*******************************************************************
1082 Convenience routine to grab string parameters into temporary memory
1083 and run standard_sub_basic on them. The buffers can be written to by
1084 callers without affecting the source string.
1085 ********************************************************************/
1087 static const char *lp_string(const char *s)
1089 #if 0 /* until REWRITE done to make thread-safe */
1090 size_t len = s ? strlen(s) : 0;
1094 /* The follow debug is useful for tracking down memory problems
1095 especially if you have an inner loop that is calling a lp_*()
1096 function that returns a string. Perhaps this debug should be
1097 present all the time? */
1100 DEBUG(10, ("lp_string(%s)\n", s));
1103 #if 0 /* until REWRITE done to make thread-safe */
1105 lp_talloc = talloc_init("lp_talloc");
1107 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1115 StrnCpy(ret, s, len);
1117 if (trim_string(ret, "\"", "\"")) {
1118 if (strchr(ret,'"') != NULL)
1119 StrnCpy(ret, s, len);
1122 standard_sub_basic(ret,len+100);
1129 In this section all the functions that are used to access the
1130 parameters from the rest of the program are defined
1133 #define FN_GLOBAL_STRING(fn_name,ptr) \
1134 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1135 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1136 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1137 #define FN_GLOBAL_LIST(fn_name,ptr) \
1138 const char **fn_name(void) {return(*(const char ***)(ptr));}
1139 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1140 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1141 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1142 char fn_name(void) {return(*(char *)(ptr));}
1143 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1144 int fn_name(void) {return(*(int *)(ptr));}
1146 #define FN_LOCAL_STRING(fn_name,val) \
1147 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1148 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1149 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1150 #define FN_LOCAL_LIST(fn_name,val) \
1151 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1152 #define FN_LOCAL_BOOL(fn_name,val) \
1153 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1154 #define FN_LOCAL_CHAR(fn_name,val) \
1155 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1156 #define FN_LOCAL_INTEGER(fn_name,val) \
1157 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1159 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1160 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1161 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
1162 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
1163 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1164 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1165 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1166 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1167 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1168 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1169 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1170 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1171 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
1172 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1173 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1174 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1175 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1176 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1177 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1178 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1179 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1180 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1181 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1182 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1183 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1184 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1185 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1186 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1187 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1188 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1189 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1190 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1191 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1192 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1193 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1194 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1195 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1196 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1197 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1198 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1199 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1200 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1201 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1202 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1203 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1204 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1205 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1206 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1208 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1210 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1212 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1213 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1214 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1215 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1216 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1217 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1218 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1219 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1220 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1222 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1223 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1224 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1225 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1226 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1227 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1228 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1229 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1230 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1231 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1232 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1233 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1234 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1235 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1236 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1237 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1238 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1239 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1240 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1241 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1242 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1243 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1244 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1245 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1246 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1247 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1248 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1249 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1250 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1251 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1252 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1253 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1254 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1255 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1256 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1257 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1258 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1259 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1260 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1261 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1262 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1263 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1264 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1265 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1266 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1267 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1268 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1269 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1270 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1271 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1272 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1273 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1274 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1275 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1276 FN_LOCAL_STRING(lp_servicename, szService)
1277 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1278 FN_LOCAL_STRING(lp_pathname, szPath)
1279 FN_LOCAL_STRING(lp_username, szUsername)
1280 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1281 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1282 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1283 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1284 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1285 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1286 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1287 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1288 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1289 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1290 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1291 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1292 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1293 FN_LOCAL_STRING(lp_comment, comment)
1294 FN_LOCAL_STRING(lp_fstype, fstype)
1295 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1296 static FN_LOCAL_STRING(lp_volume, volume)
1297 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1298 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1299 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1300 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1301 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1302 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1303 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1304 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1305 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1306 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1307 FN_LOCAL_BOOL(lp_locking, bLocking)
1308 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1309 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1310 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1311 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1312 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1313 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1314 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1315 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1316 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1317 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1318 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1319 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1320 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1321 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1322 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1323 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1324 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1325 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1327 /* local prototypes */
1329 static int map_parameter(const char *pszParmName);
1330 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1331 static int getservicebyname(const char *pszServiceName,
1332 service * pserviceDest);
1333 static void copy_service(service * pserviceDest,
1334 service * pserviceSource, BOOL *pcopymapDest);
1335 static BOOL service_ok(int iService);
1336 static BOOL do_section(const char *pszSectionName);
1337 static void init_copymap(service * pservice);
1339 /* This is a helper function for parametrical options support. */
1340 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1341 /* Actual parametrical functions are quite simple */
1342 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1345 struct param_opt *data;
1347 if (lookup_service >= iNumServices) return NULL;
1349 data = (lookup_service < 0) ?
1350 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1352 asprintf(&vfskey, "%s:%s", type, option);
1356 if (strcmp(data->key, vfskey) == 0) {
1363 if (lookup_service >= 0) {
1364 /* Try to fetch the same option but from globals */
1365 /* but only if we are not already working with Globals */
1366 data = Globals.param_opt;
1368 if (strcmp(data->key, vfskey) == 0) {
1382 /*******************************************************************
1383 convenience routine to return int parameters.
1384 ********************************************************************/
1385 static int lp_int(const char *s)
1389 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1396 /*******************************************************************
1397 convenience routine to return unsigned long parameters.
1398 ********************************************************************/
1399 static int lp_ulong(const char *s)
1403 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1407 return strtoul(s, NULL, 10);
1410 /*******************************************************************
1411 convenience routine to return boolean parameters.
1412 ********************************************************************/
1413 static BOOL lp_bool(const char *s)
1418 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1422 if (!set_boolean(&ret,s)) {
1423 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1431 /* Return parametric option from a given service. Type is a part of option before ':' */
1432 /* Parametric option has following syntax: 'Type: option = value' */
1433 /* Returned value is allocated in 'lp_talloc' context */
1435 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1437 const char *value = get_parametrics(lookup_service, type, option);
1440 return lp_string(value);
1445 /* Return parametric option from a given service. Type is a part of option before ':' */
1446 /* Parametric option has following syntax: 'Type: option = value' */
1447 /* Returned value is allocated in 'lp_talloc' context */
1449 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1450 const char *separator)
1452 const char *value = get_parametrics(lookup_service, type, option);
1455 return str_list_make(talloc_autofree_context(), value, separator);
1460 /* Return parametric option from a given service. Type is a part of option before ':' */
1461 /* Parametric option has following syntax: 'Type: option = value' */
1463 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1465 const char *value = get_parametrics(lookup_service, type, option);
1468 return lp_int(value);
1473 /* Return parametric option from a given service. Type is a part of option before ':' */
1474 /* Parametric option has following syntax: 'Type: option = value' */
1476 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1478 const char *value = get_parametrics(lookup_service, type, option);
1481 return lp_ulong(value);
1486 /* Return parametric option from a given service. Type is a part of option before ':' */
1487 /* Parametric option has following syntax: 'Type: option = value' */
1489 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1491 const char *value = get_parametrics(lookup_service, type, option);
1494 return lp_bool(value);
1500 /***************************************************************************
1501 Initialise a service to the defaults.
1502 ***************************************************************************/
1504 static void init_service(service * pservice)
1506 memset((char *)pservice, '\0', sizeof(service));
1507 copy_service(pservice, &sDefault, NULL);
1510 /***************************************************************************
1511 Free the dynamically allocated parts of a service struct.
1512 ***************************************************************************/
1514 static void free_service(service *pservice)
1517 struct param_opt *data, *pdata;
1521 if (pservice->szService)
1522 DEBUG(5, ("free_service: Freeing service %s\n",
1523 pservice->szService));
1525 string_free(&pservice->szService);
1526 SAFE_FREE(pservice->copymap);
1528 for (i = 0; parm_table[i].label; i++) {
1529 if ((parm_table[i].type == P_STRING ||
1530 parm_table[i].type == P_USTRING) &&
1531 parm_table[i].class == P_LOCAL) {
1532 string_free((char **)
1533 (((char *)pservice) +
1534 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1535 } else if (parm_table[i].type == P_LIST &&
1536 parm_table[i].class == P_LOCAL) {
1537 char ***listp = (char ***)(((char *)pservice) +
1538 PTR_DIFF(parm_table[i].ptr, &sDefault));
1539 talloc_free(*listp);
1544 DEBUG(5,("Freeing parametrics:\n"));
1545 data = pservice->param_opt;
1547 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1548 string_free(&data->key);
1549 string_free(&data->value);
1555 ZERO_STRUCTP(pservice);
1558 /***************************************************************************
1559 Add a new service to the services array initialising it with the given
1561 ***************************************************************************/
1563 static int add_a_service(const service *pservice, const char *name)
1567 int num_to_alloc = iNumServices + 1;
1568 struct param_opt *data, *pdata;
1570 tservice = *pservice;
1572 /* it might already exist */
1574 i = getservicebyname(name, NULL);
1576 /* Clean all parametric options for service */
1577 /* They will be added during parsing again */
1578 data = ServicePtrs[i]->param_opt;
1580 string_free(&data->key);
1581 string_free(&data->value);
1586 ServicePtrs[i]->param_opt = NULL;
1591 /* find an invalid one */
1592 for (i = 0; i < iNumServices; i++)
1593 if (!ServicePtrs[i]->valid)
1596 /* if not, then create one */
1597 if (i == iNumServices) {
1600 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1603 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1608 ServicePtrs[iNumServices] = malloc_p(service);
1610 if (!ServicePtrs[iNumServices]) {
1611 DEBUG(0,("add_a_service: out of memory!\n"));
1617 free_service(ServicePtrs[i]);
1619 ServicePtrs[i]->valid = True;
1621 init_service(ServicePtrs[i]);
1622 copy_service(ServicePtrs[i], &tservice, NULL);
1624 string_set(&ServicePtrs[i]->szService, name);
1628 /***************************************************************************
1629 Add a new home service, with the specified home directory, defaults coming
1631 ***************************************************************************/
1633 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1634 const char *user, const char *pszHomedir)
1639 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1644 if (!(*(ServicePtrs[iDefaultService]->szPath))
1645 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1646 pstrcpy(newHomedir, pszHomedir);
1648 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1649 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1652 string_set(&ServicePtrs[i]->szPath, newHomedir);
1654 if (!(*(ServicePtrs[i]->comment))) {
1656 slprintf(comment, sizeof(comment) - 1,
1657 "Home directory of %s", user);
1658 string_set(&ServicePtrs[i]->comment, comment);
1660 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1661 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1663 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1669 /***************************************************************************
1670 Add a new service, based on an old one.
1671 ***************************************************************************/
1673 int lp_add_service(const char *pszService, int iDefaultService)
1675 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1678 /***************************************************************************
1679 Add the IPC service.
1680 ***************************************************************************/
1682 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1685 int i = add_a_service(&sDefault, name);
1690 slprintf(comment, sizeof(comment) - 1,
1691 "%s Service (%s)", fstype, Globals.szServerString);
1693 string_set(&ServicePtrs[i]->szPath, tmpdir());
1694 string_set(&ServicePtrs[i]->szUsername, "");
1695 string_set(&ServicePtrs[i]->comment, comment);
1696 string_set(&ServicePtrs[i]->fstype, fstype);
1697 ServicePtrs[i]->iMaxConnections = -1;
1698 ServicePtrs[i]->bAvailable = True;
1699 ServicePtrs[i]->bRead_only = True;
1700 ServicePtrs[i]->bGuest_only = False;
1701 ServicePtrs[i]->bGuest_ok = guest_ok;
1702 ServicePtrs[i]->bPrint_ok = False;
1703 ServicePtrs[i]->bBrowseable = False;
1705 if (strcasecmp(fstype, "IPC") == 0) {
1706 lp_do_parameter(i, "ntvfs handler", "default");
1709 DEBUG(3, ("adding hidden service %s\n", name));
1714 /***************************************************************************
1715 Add a new printer service, with defaults coming from service iFrom.
1716 ***************************************************************************/
1718 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1720 const char *comment = "From Printcap";
1721 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1726 /* note that we do NOT default the availability flag to True - */
1727 /* we take it from the default service passed. This allows all */
1728 /* dynamic printers to be disabled by disabling the [printers] */
1729 /* entry (if/when the 'available' keyword is implemented!). */
1731 /* the printer name is set to the service name. */
1732 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1733 string_set(&ServicePtrs[i]->comment, comment);
1734 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1735 /* Printers cannot be read_only. */
1736 ServicePtrs[i]->bRead_only = False;
1737 /* No share modes on printer services. */
1738 ServicePtrs[i]->bShareModes = False;
1739 /* No oplocks on printer services. */
1740 ServicePtrs[i]->bOpLocks = False;
1741 /* Printer services must be printable. */
1742 ServicePtrs[i]->bPrint_ok = True;
1744 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1746 update_server_announce_as_printserver();
1751 /***************************************************************************
1752 Map a parameter's string representation to something we can use.
1753 Returns False if the parameter string is not recognised, else TRUE.
1754 ***************************************************************************/
1756 static int map_parameter(const char *pszParmName)
1760 if (*pszParmName == '-')
1763 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1764 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1767 /* Warn only if it isn't parametric option */
1768 if (strchr(pszParmName, ':') == NULL)
1769 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1770 /* We do return 'fail' for parametric options as well because they are
1771 stored in different storage
1776 /***************************************************************************
1777 Set a boolean variable from the text value stored in the passed string.
1778 Returns True in success, False if the passed string does not correctly
1779 represent a boolean.
1780 ***************************************************************************/
1782 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1787 if (strwicmp(pszParmValue, "yes") == 0 ||
1788 strwicmp(pszParmValue, "true") == 0 ||
1789 strwicmp(pszParmValue, "1") == 0)
1791 else if (strwicmp(pszParmValue, "no") == 0 ||
1792 strwicmp(pszParmValue, "False") == 0 ||
1793 strwicmp(pszParmValue, "0") == 0)
1797 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1804 /***************************************************************************
1805 Find a service by name. Otherwise works like get_service.
1806 ***************************************************************************/
1808 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1812 for (iService = iNumServices - 1; iService >= 0; iService--)
1813 if (VALID(iService) &&
1814 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1815 if (pserviceDest != NULL)
1816 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1823 /***************************************************************************
1824 Copy a service structure to another.
1825 If pcopymapDest is NULL then copy all fields
1826 ***************************************************************************/
1828 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1831 BOOL bcopyall = (pcopymapDest == NULL);
1832 struct param_opt *data, *pdata, *paramo;
1835 for (i = 0; parm_table[i].label; i++)
1836 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1837 (bcopyall || pcopymapDest[i])) {
1838 void *def_ptr = parm_table[i].ptr;
1840 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1843 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1846 switch (parm_table[i].type) {
1849 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1855 *(int *)dest_ptr = *(int *)src_ptr;
1859 *(char *)dest_ptr = *(char *)src_ptr;
1863 string_set(dest_ptr,
1868 string_set(dest_ptr,
1870 strupper(*(char **)dest_ptr);
1873 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1874 *(const char ***)src_ptr);
1882 init_copymap(pserviceDest);
1883 if (pserviceSource->copymap)
1884 memcpy((void *)pserviceDest->copymap,
1885 (void *)pserviceSource->copymap,
1886 sizeof(BOOL) * NUMPARAMETERS);
1889 data = pserviceSource->param_opt;
1892 pdata = pserviceDest->param_opt;
1893 /* Traverse destination */
1895 /* If we already have same option, override it */
1896 if (strcmp(pdata->key, data->key) == 0) {
1897 string_free(&pdata->value);
1898 pdata->value = strdup(data->value);
1902 pdata = pdata->next;
1905 paramo = smb_xmalloc_p(struct param_opt);
1906 paramo->key = strdup(data->key);
1907 paramo->value = strdup(data->value);
1908 DLIST_ADD(pserviceDest->param_opt, paramo);
1914 /***************************************************************************
1915 Check a service for consistency. Return False if the service is in any way
1916 incomplete or faulty, else True.
1917 ***************************************************************************/
1919 static BOOL service_ok(int iService)
1924 if (ServicePtrs[iService]->szService[0] == '\0') {
1925 DEBUG(0, ("The following message indicates an internal error:\n"));
1926 DEBUG(0, ("No service name in service entry.\n"));
1930 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1931 /* I can't see why you'd want a non-printable printer service... */
1932 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1933 if (!ServicePtrs[iService]->bPrint_ok) {
1934 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1935 ServicePtrs[iService]->szService));
1936 ServicePtrs[iService]->bPrint_ok = True;
1937 update_server_announce_as_printserver();
1939 /* [printers] service must also be non-browsable. */
1940 if (ServicePtrs[iService]->bBrowseable)
1941 ServicePtrs[iService]->bBrowseable = False;
1944 /* If a service is flagged unavailable, log the fact at level 0. */
1945 if (!ServicePtrs[iService]->bAvailable)
1946 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1947 ServicePtrs[iService]->szService));
1952 static struct file_lists {
1953 struct file_lists *next;
1957 } *file_lists = NULL;
1959 /*******************************************************************
1960 Keep a linked list of all config files so we know when one has changed
1961 it's date and needs to be reloaded.
1962 ********************************************************************/
1964 static void add_to_file_list(const char *fname, const char *subfname)
1966 struct file_lists *f = file_lists;
1969 if (f->name && !strcmp(f->name, fname))
1975 f = malloc_p(struct file_lists);
1978 f->next = file_lists;
1979 f->name = strdup(fname);
1984 f->subfname = strdup(subfname);
1990 f->modtime = file_modtime(subfname);
1992 time_t t = file_modtime(subfname);
1998 /*******************************************************************
1999 Check if a config file has changed date.
2000 ********************************************************************/
2002 BOOL lp_file_list_changed(void)
2004 struct file_lists *f = file_lists;
2005 DEBUG(6, ("lp_file_list_changed()\n"));
2011 pstrcpy(n2, f->name);
2012 standard_sub_basic(n2,sizeof(n2));
2014 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2015 f->name, n2, ctime(&f->modtime)));
2017 mod_time = file_modtime(n2);
2019 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2021 ("file %s modified: %s\n", n2,
2023 f->modtime = mod_time;
2024 SAFE_FREE(f->subfname);
2025 f->subfname = strdup(n2);
2033 /***************************************************************************
2034 Handle the include operation.
2035 ***************************************************************************/
2037 static BOOL handle_include(const char *pszParmValue, char **ptr)
2040 pstrcpy(fname, pszParmValue);
2042 standard_sub_basic(fname,sizeof(fname));
2044 add_to_file_list(pszParmValue, fname);
2046 string_set(ptr, fname);
2048 if (file_exist(fname))
2049 return (pm_process(fname, do_section, do_parameter));
2051 DEBUG(2, ("Can't find include file %s\n", fname));
2056 /***************************************************************************
2057 Handle the interpretation of the copy parameter.
2058 ***************************************************************************/
2060 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2064 service serviceTemp;
2066 string_set(ptr, pszParmValue);
2068 init_service(&serviceTemp);
2072 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2074 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2075 if (iTemp == iServiceIndex) {
2076 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2078 copy_service(ServicePtrs[iServiceIndex],
2080 ServicePtrs[iServiceIndex]->copymap);
2084 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2088 free_service(&serviceTemp);
2092 /***************************************************************************
2093 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2098 winbind uid = 1000-1999
2099 winbind gid = 700-899
2101 We only do simple parsing checks here. The strings are parsed into useful
2102 structures in the winbind daemon code.
2104 ***************************************************************************/
2106 /* Some lp_ routines to return winbind [ug]id information */
2108 static uid_t winbind_uid_low, winbind_uid_high;
2109 static gid_t winbind_gid_low, winbind_gid_high;
2110 static uint32_t non_unix_account_low, non_unix_account_high;
2112 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2114 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2118 *low = winbind_uid_low;
2121 *high = winbind_uid_high;
2126 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2128 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2132 *low = winbind_gid_low;
2135 *high = winbind_gid_high;
2140 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2142 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2146 *low = non_unix_account_low;
2149 *high = non_unix_account_high;
2154 /* Do some simple checks on "winbind [ug]id" parameter values */
2156 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2160 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2165 string_set(ptr, pszParmValue);
2167 winbind_uid_low = low;
2168 winbind_uid_high = high;
2173 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2177 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2182 string_set(ptr, pszParmValue);
2184 winbind_gid_low = low;
2185 winbind_gid_high = high;
2190 /***************************************************************************
2191 Do some simple checks on "non unix account range" parameter values.
2192 ***************************************************************************/
2194 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2198 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2203 string_set(ptr, pszParmValue);
2205 non_unix_account_low = low;
2206 non_unix_account_high = high;
2212 /***************************************************************************
2213 Initialise a copymap.
2214 ***************************************************************************/
2216 static void init_copymap(service * pservice)
2219 SAFE_FREE(pservice->copymap);
2220 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2221 if (!pservice->copymap)
2223 ("Couldn't allocate copymap!! (size %d)\n",
2224 (int)NUMPARAMETERS));
2226 for (i = 0; i < NUMPARAMETERS; i++)
2227 pservice->copymap[i] = True;
2230 /***************************************************************************
2231 Return the local pointer to a parameter given the service number and the
2232 pointer into the default structure.
2233 ***************************************************************************/
2235 void *lp_local_ptr(int snum, void *ptr)
2237 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2241 /***************************************************************************
2242 Process a parametric option
2243 ***************************************************************************/
2244 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2246 struct param_opt *paramo, *data;
2249 while (isspace(*pszParmName)) {
2253 name = strdup(pszParmName);
2254 if (!name) return False;
2259 data = Globals.param_opt;
2261 data = ServicePtrs[snum]->param_opt;
2264 /* Traverse destination */
2265 for (paramo=data; paramo; paramo=paramo->next) {
2266 /* If we already have the option set, override it unless
2267 it was a command line option and the new one isn't */
2268 if (strcmp(paramo->key, name) == 0) {
2269 if ((paramo->flags & FLAG_CMDLINE) &&
2270 !(flags & FLAG_CMDLINE)) {
2274 free(paramo->value);
2275 paramo->value = strdup(pszParmValue);
2276 paramo->flags = flags;
2282 paramo = smb_xmalloc_p(struct param_opt);
2283 paramo->key = strdup(name);
2284 paramo->value = strdup(pszParmValue);
2285 paramo->flags = flags;
2287 DLIST_ADD(Globals.param_opt, paramo);
2289 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2297 /***************************************************************************
2298 Process a parameter for a particular service number. If snum < 0
2299 then assume we are in the globals.
2300 ***************************************************************************/
2301 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2304 void *parm_ptr = NULL; /* where we are going to store the result */
2305 void *def_ptr = NULL;
2307 parmnum = map_parameter(pszParmName);
2310 if (strchr(pszParmName, ':')) {
2311 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2313 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2317 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2318 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2322 /* if the flag has been set on the command line, then don't allow override,
2323 but don't report an error */
2324 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2328 def_ptr = parm_table[parmnum].ptr;
2330 /* we might point at a service, the default service or a global */
2334 if (parm_table[parmnum].class == P_GLOBAL) {
2336 ("Global parameter %s found in service section!\n",
2341 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2346 if (!ServicePtrs[snum]->copymap)
2347 init_copymap(ServicePtrs[snum]);
2349 /* this handles the aliases - set the copymap for other entries with
2350 the same data pointer */
2351 for (i = 0; parm_table[i].label; i++)
2352 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2353 ServicePtrs[snum]->copymap[i] = False;
2356 /* if it is a special case then go ahead */
2357 if (parm_table[parmnum].special) {
2358 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2362 /* now switch on the type of variable it is */
2363 switch (parm_table[parmnum].type)
2366 set_boolean(parm_ptr, pszParmValue);
2370 set_boolean(parm_ptr, pszParmValue);
2371 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2375 *(int *)parm_ptr = atoi(pszParmValue);
2379 *(char *)parm_ptr = *pszParmValue;
2383 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2387 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
2388 pszParmValue, NULL);
2392 string_set(parm_ptr, pszParmValue);
2396 string_set(parm_ptr, pszParmValue);
2397 strupper(*(char **)parm_ptr);
2401 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2404 parm_table[parmnum].enum_list[i].name)) {
2406 parm_table[parmnum].
2411 if (!parm_table[parmnum].enum_list[i].name) {
2412 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2413 pszParmValue, pszParmName));
2424 /***************************************************************************
2425 Process a parameter.
2426 ***************************************************************************/
2428 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2430 if (!bInGlobalSection && bGlobalOnly)
2433 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2434 pszParmName, pszParmValue));
2438 variable argument do parameter
2440 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2442 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2449 s = talloc_vasprintf(NULL, fmt, ap);
2451 ret = do_parameter(pszParmName, s);
2458 set a parameter from the commandline - this is called from command line parameter
2459 parsing code. It sets the parameter then marks the parameter as unable to be modified
2460 by smb.conf processing
2462 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2464 int parmnum = map_parameter(pszParmName);
2467 while (isspace(*pszParmValue)) pszParmValue++;
2470 if (parmnum < 0 && strchr(pszParmName, ':')) {
2471 /* set a parametric option */
2472 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2476 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2480 /* reset the CMDLINE flag in case this has been called before */
2481 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2483 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2487 parm_table[parmnum].flags |= FLAG_CMDLINE;
2489 /* we have to also set FLAG_CMDLINE on aliases */
2490 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2491 parm_table[i].flags |= FLAG_CMDLINE;
2493 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2494 parm_table[i].flags |= FLAG_CMDLINE;
2501 set a option from the commandline in 'a=b' format. Use to support --option
2503 BOOL lp_set_option(const char *option)
2521 ret = lp_set_cmdline(s, p+1);
2527 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2529 /***************************************************************************
2530 Print a parameter of the specified type.
2531 ***************************************************************************/
2533 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2539 for (i = 0; p->enum_list[i].name; i++) {
2540 if (*(int *)ptr == p->enum_list[i].value) {
2542 p->enum_list[i].name);
2549 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2553 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2557 fprintf(f, "%d", *(int *)ptr);
2561 fprintf(f, "%c", *(char *)ptr);
2565 if (*(int *)ptr == -1) {
2568 fprintf(f, "0%o", *(int *)ptr);
2573 if ((char ***)ptr && *(char ***)ptr) {
2574 char **list = *(char ***)ptr;
2576 for (; *list; list++)
2577 fprintf(f, "%s%s", *list,
2578 ((*(list+1))?", ":""));
2584 if (*(char **)ptr) {
2585 fprintf(f, "%s", *(char **)ptr);
2593 /***************************************************************************
2594 Check if two parameters are equal.
2595 ***************************************************************************/
2597 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2602 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2607 return (*((int *)ptr1) == *((int *)ptr2));
2610 return (*((char *)ptr1) == *((char *)ptr2));
2613 return str_list_equal((const char **)(*(char ***)ptr1),
2614 (const char **)(*(char ***)ptr2));
2619 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2624 return (p1 == p2 || strequal(p1, p2));
2632 /***************************************************************************
2633 Process a new section (service). At this stage all sections are services.
2634 Later we'll have special sections that permit server parameters to be set.
2635 Returns True on success, False on failure.
2636 ***************************************************************************/
2638 static BOOL do_section(const char *pszSectionName)
2641 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2642 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2645 /* if we've just struck a global section, note the fact. */
2646 bInGlobalSection = isglobal;
2648 /* check for multiple global sections */
2649 if (bInGlobalSection) {
2650 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2654 if (!bInGlobalSection && bGlobalOnly)
2657 /* if we have a current service, tidy it up before moving on */
2660 if (iServiceIndex >= 0)
2661 bRetval = service_ok(iServiceIndex);
2663 /* if all is still well, move to the next record in the services array */
2665 /* We put this here to avoid an odd message order if messages are */
2666 /* issued by the post-processing of a previous section. */
2667 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2669 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2671 DEBUG(0, ("Failed to add a new service\n"));
2680 /***************************************************************************
2681 Determine if a partcular base parameter is currentl set to the default value.
2682 ***************************************************************************/
2684 static BOOL is_default(int i)
2686 if (!defaults_saved)
2688 switch (parm_table[i].type) {
2690 return str_list_equal((const char **)parm_table[i].def.lvalue,
2691 (const char **)(*(char ***)parm_table[i].ptr));
2694 return strequal(parm_table[i].def.svalue,
2695 *(char **)parm_table[i].ptr);
2698 return parm_table[i].def.bvalue ==
2699 *(BOOL *)parm_table[i].ptr;
2701 return parm_table[i].def.cvalue ==
2702 *(char *)parm_table[i].ptr;
2706 return parm_table[i].def.ivalue ==
2707 *(int *)parm_table[i].ptr;
2714 /***************************************************************************
2715 Display the contents of the global structure.
2716 ***************************************************************************/
2718 static void dump_globals(FILE *f)
2721 struct param_opt *data;
2723 fprintf(f, "# Global parameters\n[global]\n");
2725 for (i = 0; parm_table[i].label; i++)
2726 if (parm_table[i].class == P_GLOBAL &&
2727 parm_table[i].ptr &&
2728 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2729 if (defaults_saved && is_default(i))
2731 fprintf(f, "\t%s = ", parm_table[i].label);
2732 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2735 if (Globals.param_opt != NULL) {
2736 data = Globals.param_opt;
2738 fprintf(f, "\t%s = %s\n", data->key, data->value);
2745 /***************************************************************************
2746 Display the contents of a single services record.
2747 ***************************************************************************/
2749 static void dump_a_service(service * pService, FILE * f)
2752 struct param_opt *data;
2754 if (pService != &sDefault)
2755 fprintf(f, "\n[%s]\n", pService->szService);
2757 for (i = 0; parm_table[i].label; i++)
2758 if (parm_table[i].class == P_LOCAL &&
2759 parm_table[i].ptr &&
2760 (*parm_table[i].label != '-') &&
2761 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2762 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2764 if (pService == &sDefault) {
2765 if (defaults_saved && is_default(i))
2768 if (equal_parameter(parm_table[i].type,
2769 ((char *)pService) +
2771 ((char *)&sDefault) +
2776 fprintf(f, "\t%s = ", parm_table[i].label);
2777 print_parameter(&parm_table[i],
2778 ((char *)pService) + pdiff, f);
2781 if (pService->param_opt != NULL) {
2782 data = pService->param_opt;
2784 fprintf(f, "\t%s = %s\n", data->key, data->value);
2791 /***************************************************************************
2792 Return info about the next service in a service. snum==-1 gives the globals.
2793 Return NULL when out of parameters.
2794 ***************************************************************************/
2796 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2799 /* do the globals */
2800 for (; parm_table[*i].label; (*i)++) {
2801 if (parm_table[*i].class == P_SEPARATOR)
2802 return &parm_table[(*i)++];
2804 if (!parm_table[*i].ptr
2805 || (*parm_table[*i].label == '-'))
2809 && (parm_table[*i].ptr ==
2810 parm_table[(*i) - 1].ptr))
2813 return &parm_table[(*i)++];
2816 service *pService = ServicePtrs[snum];
2818 for (; parm_table[*i].label; (*i)++) {
2819 if (parm_table[*i].class == P_SEPARATOR)
2820 return &parm_table[(*i)++];
2822 if (parm_table[*i].class == P_LOCAL &&
2823 parm_table[*i].ptr &&
2824 (*parm_table[*i].label != '-') &&
2826 (parm_table[*i].ptr !=
2827 parm_table[(*i) - 1].ptr)))
2830 PTR_DIFF(parm_table[*i].ptr,
2833 if (allparameters ||
2834 !equal_parameter(parm_table[*i].type,
2835 ((char *)pService) +
2837 ((char *)&sDefault) +
2840 return &parm_table[(*i)++];
2850 /***************************************************************************
2851 Return TRUE if the passed service number is within range.
2852 ***************************************************************************/
2854 BOOL lp_snum_ok(int iService)
2856 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2859 /***************************************************************************
2860 Auto-load some home services.
2861 ***************************************************************************/
2863 static void lp_add_auto_services(const char *str)
2868 /***************************************************************************
2869 Auto-load one printer.
2870 ***************************************************************************/
2872 void lp_add_one_printer(char *name, char *comment)
2874 int printers = lp_servicenumber(PRINTERS_NAME);
2877 if (lp_servicenumber(name) < 0) {
2878 lp_add_printer(name, printers);
2879 if ((i = lp_servicenumber(name)) >= 0) {
2880 string_set(&ServicePtrs[i]->comment, comment);
2881 ServicePtrs[i]->autoloaded = True;
2886 /***************************************************************************
2887 Announce ourselves as a print server.
2888 ***************************************************************************/
2890 void update_server_announce_as_printserver(void)
2892 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2895 /***************************************************************************
2896 Have we loaded a services file yet?
2897 ***************************************************************************/
2899 BOOL lp_loaded(void)
2904 /***************************************************************************
2905 Unload unused services.
2906 ***************************************************************************/
2908 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2911 for (i = 0; i < iNumServices; i++) {
2915 if (!snumused || !snumused(smb, i)) {
2916 ServicePtrs[i]->valid = False;
2917 free_service(ServicePtrs[i]);
2922 /***************************************************************************
2924 ***************************************************************************/
2926 void lp_killservice(int iServiceIn)
2928 if (VALID(iServiceIn)) {
2929 ServicePtrs[iServiceIn]->valid = False;
2930 free_service(ServicePtrs[iServiceIn]);
2934 /***************************************************************************
2935 Save the curent values of all global and sDefault parameters into the
2936 defaults union. This allows swat and testparm to show only the
2937 changed (ie. non-default) parameters.
2938 ***************************************************************************/
2940 static void lp_save_defaults(void)
2943 for (i = 0; parm_table[i].label; i++) {
2944 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2946 switch (parm_table[i].type) {
2948 parm_table[i].def.lvalue = str_list_copy(talloc_autofree_context(),
2949 *(const char ***)parm_table[i].ptr);
2953 if (parm_table[i].ptr) {
2954 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2956 parm_table[i].def.svalue = NULL;
2961 parm_table[i].def.bvalue =
2962 *(BOOL *)parm_table[i].ptr;
2965 parm_table[i].def.cvalue =
2966 *(char *)parm_table[i].ptr;
2971 parm_table[i].def.ivalue =
2972 *(int *)parm_table[i].ptr;
2978 defaults_saved = True;
2981 /*******************************************************************
2982 Set the server type we will announce as via nmbd.
2983 ********************************************************************/
2985 static void set_server_role(void)
2987 server_role = ROLE_STANDALONE;
2989 switch (lp_security()) {
2991 if (lp_domain_logons())
2992 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2997 if (lp_domain_logons()) {
2998 if (Globals.bDomainMaster) /* auto or yes */
2999 server_role = ROLE_DOMAIN_PDC;
3001 server_role = ROLE_DOMAIN_BDC;
3004 server_role = ROLE_DOMAIN_MEMBER;
3007 if (lp_domain_logons()) {
3009 if (Globals.bDomainMaster) /* auto or yes */
3010 server_role = ROLE_DOMAIN_PDC;
3012 server_role = ROLE_DOMAIN_BDC;
3016 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3020 DEBUG(10, ("set_server_role: role = "));
3022 switch(server_role) {
3023 case ROLE_STANDALONE:
3024 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3026 case ROLE_DOMAIN_MEMBER:
3027 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3029 case ROLE_DOMAIN_BDC:
3030 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3032 case ROLE_DOMAIN_PDC:
3033 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3038 /***************************************************************************
3039 Load the services array from the services file. Return True on success,
3041 ***************************************************************************/
3043 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3048 struct param_opt *data;
3050 pstrcpy(n2, pszFname);
3051 standard_sub_basic(n2,sizeof(n2));
3053 add_to_file_list(pszFname, n2);
3057 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3059 bInGlobalSection = True;
3060 bGlobalOnly = global_only;
3062 if (Globals.param_opt != NULL) {
3063 struct param_opt *next;
3064 for (data=Globals.param_opt; data; data=next) {
3066 if (data->flags & FLAG_CMDLINE) continue;
3069 DLIST_REMOVE(Globals.param_opt, data);
3081 /* We get sections first, so have to start 'behind' to make up */
3083 bRetval = pm_process(n2, do_section, do_parameter);
3085 /* finish up the last section */
3086 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3088 if (iServiceIndex >= 0)
3089 bRetval = service_ok(iServiceIndex);
3091 lp_add_auto_services(lp_auto_services());
3094 /* When 'restrict anonymous = 2' guest connections to ipc$
3096 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3097 lp_add_hidden("ADMIN$", "DISK", False);
3101 set_default_server_announce_type();
3105 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3106 /* if bWINSsupport is true and we are in the client */
3107 if (in_client && Globals.bWINSsupport) {
3108 lp_do_parameter(-1, "wins server", "127.0.0.1");
3116 /***************************************************************************
3117 Reset the max number of services.
3118 ***************************************************************************/
3120 void lp_resetnumservices(void)
3125 /***************************************************************************
3126 Return the max number of services.
3127 ***************************************************************************/
3129 int lp_numservices(void)
3131 return (iNumServices);
3134 /***************************************************************************
3135 Display the contents of the services array in human-readable form.
3136 ***************************************************************************/
3138 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3143 defaults_saved = False;
3147 dump_a_service(&sDefault, f);
3149 for (iService = 0; iService < maxtoprint; iService++)
3150 lp_dump_one(f, show_defaults, iService);
3153 /***************************************************************************
3154 Display the contents of one service in human-readable form.
3155 ***************************************************************************/
3157 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3160 if (ServicePtrs[snum]->szService[0] == '\0')
3162 dump_a_service(ServicePtrs[snum], f);
3166 /***************************************************************************
3167 Return the number of the service with the given name, or -1 if it doesn't
3168 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3169 getservicebyname()! This works ONLY if all services have been loaded, and
3170 does not copy the found service.
3171 ***************************************************************************/
3173 int lp_servicenumber(const char *pszServiceName)
3176 fstring serviceName;
3179 for (iService = iNumServices - 1; iService >= 0; iService--) {
3180 if (VALID(iService) && ServicePtrs[iService]->szService) {
3182 * The substitution here is used to support %U is
3185 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3186 standard_sub_basic(serviceName,sizeof(serviceName));
3187 if (strequal(serviceName, pszServiceName))
3193 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3198 /*******************************************************************
3199 A useful volume label function.
3200 ********************************************************************/
3201 const char *volume_label(int snum)
3203 const char *ret = lp_volume(snum);
3205 return lp_servicename(snum);
3210 /*******************************************************************
3211 Set the server type we will announce as via nmbd.
3212 ********************************************************************/
3214 static void set_default_server_announce_type(void)
3216 default_server_announce = 0;
3217 default_server_announce |= SV_TYPE_WORKSTATION;
3218 default_server_announce |= SV_TYPE_SERVER;
3219 default_server_announce |= SV_TYPE_SERVER_UNIX;
3221 switch (lp_announce_as()) {
3222 case ANNOUNCE_AS_NT_SERVER:
3223 default_server_announce |= SV_TYPE_SERVER_NT;
3224 /* fall through... */
3225 case ANNOUNCE_AS_NT_WORKSTATION:
3226 default_server_announce |= SV_TYPE_NT;
3228 case ANNOUNCE_AS_WIN95:
3229 default_server_announce |= SV_TYPE_WIN95_PLUS;
3231 case ANNOUNCE_AS_WFW:
3232 default_server_announce |= SV_TYPE_WFW;
3238 switch (lp_server_role()) {
3239 case ROLE_DOMAIN_MEMBER:
3240 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3242 case ROLE_DOMAIN_PDC:
3243 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3245 case ROLE_DOMAIN_BDC:
3246 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3248 case ROLE_STANDALONE:
3252 if (lp_time_server())
3253 default_server_announce |= SV_TYPE_TIME_SOURCE;
3255 if (lp_host_msdfs())
3256 default_server_announce |= SV_TYPE_DFS_SERVER;
3258 /* TODO: only announce us as print server when we are a print server */
3259 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3262 /***********************************************************
3263 returns role of Samba server
3264 ************************************************************/
3266 int lp_server_role(void)
3271 /***********************************************************
3272 If we are PDC then prefer us as DMB
3273 ************************************************************/
3275 BOOL lp_domain_master(void)
3277 if (Globals.bDomainMaster == Auto)
3278 return (lp_server_role() == ROLE_DOMAIN_PDC);
3280 return Globals.bDomainMaster;
3283 /***********************************************************
3284 If we are DMB then prefer us as LMB
3285 ************************************************************/
3287 BOOL lp_preferred_master(void)
3289 if (Globals.bPreferredMaster == Auto)
3290 return (lp_local_master() && lp_domain_master());
3292 return Globals.bPreferredMaster;
3295 /*******************************************************************
3297 ********************************************************************/
3299 void lp_remove_service(int snum)
3301 ServicePtrs[snum]->valid = False;
3304 /*******************************************************************
3306 ********************************************************************/
3308 void lp_copy_service(int snum, const char *new_name)
3310 const char *oldname = lp_servicename(snum);
3311 do_section(new_name);
3313 snum = lp_servicenumber(new_name);
3315 lp_do_parameter(snum, "copy", oldname);
3320 /*******************************************************************
3321 Get the default server type we will announce as via nmbd.
3322 ********************************************************************/
3323 int lp_default_server_announce(void)
3325 return default_server_announce;
3328 const char *lp_printername(int snum)
3330 const char *ret = _lp_printername(snum);
3331 if (ret == NULL || (ret != NULL && *ret == '\0'))
3332 ret = lp_const_servicename(snum);
3338 /*******************************************************************
3339 Return the max print jobs per queue.
3340 ********************************************************************/
3342 int lp_maxprintjobs(int snum)
3344 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3345 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3346 maxjobs = PRINT_MAX_JOBID - 1;