2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
56 #include "dynconfig.h"
57 #include "system/time.h"
58 #include "system/iconv.h"
59 #include "system/network.h"
60 #include "system/printing.h"
61 #include "librpc/gen_ndr/ndr_svcctl.h"
62 #include "dlinklist.h"
64 BOOL in_client = False; /* Not in the client by default */
65 static BOOL bLoaded = False;
68 #define GLOBAL_NAME "global"
72 #define PRINTERS_NAME "printers"
76 #define HOMES_NAME "homes"
79 /* some helpful bits */
80 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
81 #define VALID(i) ServicePtrs[i]->valid
83 static BOOL do_parameter(const char *, const char *);
84 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
86 static BOOL defaults_saved = False;
89 #define FLAG_BASIC 0x0001 /* fundamental options */
90 #define FLAG_SHARE 0x0002 /* file sharing options */
91 #define FLAG_PRINT 0x0004 /* printing options */
92 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
93 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
94 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
95 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
96 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
97 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
98 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
99 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
102 /* the following are used by loadparm for option lists */
105 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
106 P_STRING,P_USTRING,P_ENUM,P_SEP
111 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
125 BOOL (*special)(const char *, char **);
126 const struct enum_list *enum_list;
139 struct param_opt *prev, *next;
146 * This structure describes global (ie., server-wide) parameters.
154 char *display_charset;
155 char *szPrintcapname;
159 char *szDefaultService;
161 char *szServerString;
162 char *szAutoServices;
163 char *szPasswdProgram;
167 char *szSMBPasswdFile;
171 char **szPreloadModules;
172 char *szPasswordServer;
173 char *szSocketOptions;
180 char **szWINSservers;
182 char *szRemoteAnnounce;
183 char *szRemoteBrowseSync;
184 char *szSocketAddress;
185 char *szAnnounceVersion; /* This is initialised in init_globals */
188 char **szNetbiosAliases;
189 char *szNetbiosScope;
190 char *szDomainOtherSIDs;
191 char *szNameResolveOrder;
193 char *szAddUserScript;
194 char *szAddMachineScript;
196 char *szWINSPartners;
197 char **dcerpc_ep_servers;
198 char **server_services;
201 char *szNonUnixAccountRange;
202 char *szTemplateHomedir;
203 char *szTemplateShell;
204 char *szWinbindSeparator;
205 BOOL bWinbindEnumUsers;
206 BOOL bWinbindEnumGroups;
207 BOOL bWinbindUseDefaultDomain;
208 char *szIDMapBackend;
209 char *szGuestaccount;
218 BOOL paranoid_server_security;
220 BOOL bDisableSpoolss;
222 int enhanced_browsing;
229 int announce_as; /* This is initialised in init_globals */
230 int machine_password_timeout;
231 int winbind_cache_time;
234 char *socket_options;
239 BOOL bPreferredMaster;
242 BOOL bEncryptPasswords;
244 BOOL bObeyPamRestrictions;
246 BOOL bLargeReadwrite;
250 BOOL bBindInterfacesOnly;
251 BOOL bPamPasswordChange;
253 BOOL bNTStatusSupport;
254 BOOL bAllowTrustedDomains;
260 BOOL bClientLanManAuth;
261 BOOL bClientNTLMv2Auth;
263 BOOL bHideLocalUsers;
266 BOOL bHostnameLookups;
267 BOOL bUnixExtensions;
268 BOOL bDisableNetbios;
270 int restrict_anonymous;
271 int name_cache_timeout;
272 struct param_opt *param_opt;
276 static global Globals;
279 * This structure describes a single service.
288 char **szInvalidUsers;
293 char *szPrintcommand;
296 char *szLppausecommand;
297 char *szLpresumecommand;
298 char *szQueuepausecommand;
299 char *szQueueresumecommand;
307 char **ntvfs_handler;
333 struct param_opt *param_opt;
335 char dummy[3]; /* for alignment */
340 /* This is a default service used to prime a services structure */
341 static service sDefault = {
343 False, /* not autoloaded */
344 NULL, /* szService */
346 NULL, /* szUsername */
347 NULL, /* szInvalidUsers */
348 NULL, /* szValidUsers */
349 NULL, /* szAdminUsers */
351 NULL, /* szInclude */
352 NULL, /* szPrintcommand */
353 NULL, /* szLpqcommand */
354 NULL, /* szLprmcommand */
355 NULL, /* szLppausecommand */
356 NULL, /* szLpresumecommand */
357 NULL, /* szQueuepausecommand */
358 NULL, /* szQueueresumecommand */
359 NULL, /* szPrintername */
360 NULL, /* szHostsallow */
361 NULL, /* szHostsdeny */
365 NULL, /* szMSDfsProxy */
366 NULL, /* ntvfs_handler */
367 0, /* iMinPrintSpace */
368 1000, /* iMaxPrintJobs */
369 0, /* iMaxConnections */
370 DEFAULT_PRINTING, /* iPrinting */
372 True, /* bAvailable */
373 True, /* bBrowseable */
374 True, /* bRead_only */
375 False, /* bPrint_ok */
376 False, /* bMap_system */
377 False, /* bMap_hidden */
378 True, /* bMap_archive */
380 True, /* bStrictLocking */
381 True, /* bPosixLocking */
383 True, /* bLevel2OpLocks */
384 False, /* bOnlyUser */
385 False, /* bGuest_only */
386 False, /* bGuest_ok */
388 False, /* bMSDfsRoot */
389 True, /* bShareModes */
390 False, /* bStrictSync */
391 False, /* bCIFileSystem */
392 NULL, /* Parametric options */
397 /* local variables */
398 static service **ServicePtrs = NULL;
399 static int iNumServices = 0;
400 static int iServiceIndex = 0;
401 static BOOL bInGlobalSection = True;
402 static BOOL bGlobalOnly = False;
403 static int server_role;
404 static int default_server_announce;
406 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
408 /* prototypes for the special type handlers */
409 static BOOL handle_include(const char *pszParmValue, char **ptr);
410 static BOOL handle_copy(const char *pszParmValue, char **ptr);
411 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
412 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
413 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
415 static void set_server_role(void);
416 static void set_default_server_announce_type(void);
418 static const struct enum_list enum_protocol[] = {
419 {PROTOCOL_NT1, "NT1"},
420 {PROTOCOL_LANMAN2, "LANMAN2"},
421 {PROTOCOL_LANMAN1, "LANMAN1"},
422 {PROTOCOL_CORE, "CORE"},
423 {PROTOCOL_COREPLUS, "COREPLUS"},
424 {PROTOCOL_COREPLUS, "CORE+"},
428 static const struct enum_list enum_security[] = {
429 {SEC_SHARE, "SHARE"},
431 {SEC_SERVER, "SERVER"},
432 {SEC_DOMAIN, "DOMAIN"},
439 static const struct enum_list enum_printing[] = {
440 {PRINT_SYSV, "sysv"},
442 {PRINT_HPUX, "hpux"},
446 {PRINT_LPRNG, "lprng"},
447 {PRINT_SOFTQ, "softq"},
448 {PRINT_CUPS, "cups"},
450 {PRINT_LPROS2, "os2"},
452 {PRINT_TEST, "test"},
454 #endif /* DEVELOPER */
458 /* Types of machine we can announce as. */
459 #define ANNOUNCE_AS_NT_SERVER 1
460 #define ANNOUNCE_AS_WIN95 2
461 #define ANNOUNCE_AS_WFW 3
462 #define ANNOUNCE_AS_NT_WORKSTATION 4
464 static const struct enum_list enum_announce_as[] = {
465 {ANNOUNCE_AS_NT_SERVER, "NT"},
466 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
467 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
468 {ANNOUNCE_AS_WIN95, "win95"},
469 {ANNOUNCE_AS_WFW, "WfW"},
473 static const struct enum_list enum_bool_auto[] = {
484 /* Client-side offline caching policy types */
485 #define CSC_POLICY_MANUAL 0
486 #define CSC_POLICY_DOCUMENTS 1
487 #define CSC_POLICY_PROGRAMS 2
488 #define CSC_POLICY_DISABLE 3
490 static const struct enum_list enum_csc_policy[] = {
491 {CSC_POLICY_MANUAL, "manual"},
492 {CSC_POLICY_DOCUMENTS, "documents"},
493 {CSC_POLICY_PROGRAMS, "programs"},
494 {CSC_POLICY_DISABLE, "disable"},
498 /* SMB signing types. */
499 static const struct enum_list enum_smb_signing_vals[] = {
500 {SMB_SIGNING_OFF, "No"},
501 {SMB_SIGNING_OFF, "False"},
502 {SMB_SIGNING_OFF, "0"},
503 {SMB_SIGNING_OFF, "Off"},
504 {SMB_SIGNING_OFF, "disabled"},
505 {SMB_SIGNING_SUPPORTED, "Yes"},
506 {SMB_SIGNING_SUPPORTED, "True"},
507 {SMB_SIGNING_SUPPORTED, "1"},
508 {SMB_SIGNING_SUPPORTED, "On"},
509 {SMB_SIGNING_SUPPORTED, "enabled"},
510 {SMB_SIGNING_REQUIRED, "required"},
511 {SMB_SIGNING_REQUIRED, "mandatory"},
512 {SMB_SIGNING_REQUIRED, "force"},
513 {SMB_SIGNING_REQUIRED, "forced"},
514 {SMB_SIGNING_REQUIRED, "enforced"},
515 {SMB_SIGNING_AUTO, "auto"},
520 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
522 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
523 * is implied in current control logic. This may change at some later time. A
524 * flag value of 0 means - show as development option only.
526 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
527 * screen in SWAT. This is used to exclude parameters as well as to squash all
528 * parameters that have been duplicated by pseudonyms.
530 static struct parm_struct parm_table[] = {
531 {"Base Options", P_SEP, P_SEPARATOR},
533 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
538 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
539 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
540 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
541 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
542 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
543 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
544 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
550 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
551 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
553 {"Security Options", P_SEP, P_SEPARATOR},
555 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
556 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
557 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
558 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
572 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
586 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
587 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
589 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
590 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
591 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
593 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
595 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
597 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
599 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
600 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
601 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
602 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
604 {"Logging Options", P_SEP, P_SEPARATOR},
606 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
608 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"Protocol Options", P_SEP, P_SEPARATOR},
612 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
614 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
615 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
616 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
617 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
618 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
619 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
621 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
624 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
625 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
629 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
635 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
636 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
637 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
639 {"Tuning Options", P_SEP, P_SEPARATOR},
641 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
642 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
643 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
644 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
646 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
647 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
648 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
650 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
651 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
652 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
654 {"Printing Options", P_SEP, P_SEPARATOR},
656 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
657 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
658 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
659 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
660 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
661 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
662 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
663 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
664 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
666 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
667 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
668 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
673 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
675 {"Filename Handling", P_SEP, P_SEPARATOR},
677 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
678 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
679 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
681 {"Domain Options", P_SEP, P_SEPARATOR},
683 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
685 {"Logon Options", P_SEP, P_SEPARATOR},
687 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
688 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
690 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
691 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"Browse Options", P_SEP, P_SEPARATOR},
698 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
703 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
706 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
707 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
709 {"WINS Options", P_SEP, P_SEPARATOR},
710 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
714 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
715 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
718 {"Locking Options", P_SEP, P_SEPARATOR},
720 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
721 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
722 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
723 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
725 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
726 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
727 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
729 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
731 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
733 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
734 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
737 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
742 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
745 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
748 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
749 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
751 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
752 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
753 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
755 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
759 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
760 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"Winbind options", P_SEP, P_SEPARATOR},
763 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
776 /***************************************************************************
777 Initialise the sDefault parameter structure for the printer values.
778 ***************************************************************************/
780 static void init_printer_values(void)
782 /* choose defaults depending on the type of printing */
783 switch (sDefault.iPrinting) {
788 do_parameter("Lpqcommand", "lpq -P'%p'");
789 do_parameter("Lprmcommand", "lprm -P'%p' %j");
790 do_parameter("Printcommand",
796 do_parameter("Lpqcommand", "lpq -P'%p'");
797 do_parameter("Lprmcommand", "lprm -P'%p' %j");
798 do_parameter("Printcommand",
800 do_parameter("Queuepausecommand",
802 do_parameter("Queueresumecommand",
804 do_parameter("Lppausecommand",
806 do_parameter("Lpresumecommand",
807 "lpc release '%p' %j");
812 do_parameter("Lpqcommand", "");
813 do_parameter("Lprmcommand", "");
814 do_parameter("Printcommand", "");
815 do_parameter("Lppausecommand", "");
816 do_parameter("Lpresumecommand", "");
817 do_parameter("Queuepausecommand", "");
818 do_parameter("Queueresumecommand", "");
820 do_parameter("Printcapname", "cups");
822 do_parameter("Lpqcommand",
823 "/usr/bin/lpstat -o '%p'");
824 do_parameter("Lprmcommand",
825 "/usr/bin/cancel '%p-%j'");
826 do_parameter("Printcommand",
827 "/usr/bin/lp -d '%p' %s; rm %s");
828 do_parameter("Lppausecommand",
829 "lp -i '%p-%j' -H hold");
830 do_parameter("Lpresumecommand",
831 "lp -i '%p-%j' -H resume");
832 do_parameter("Queuepausecommand",
833 "/usr/bin/disable '%p'");
834 do_parameter("Queueresumecommand",
835 "/usr/bin/enable '%p'");
836 do_parameter("Printcapname", "lpstat");
837 #endif /* HAVE_CUPS */
842 do_parameter("Lpqcommand", "lpstat -o%p");
843 do_parameter("Lprmcommand", "cancel %p-%j");
844 do_parameter("Printcommand",
845 "lp -c -d%p %s; rm %s");
846 do_parameter("Queuepausecommand",
848 do_parameter("Queueresumecommand",
851 do_parameter("Lppausecommand",
852 "lp -i %p-%j -H hold");
853 do_parameter("Lpresumecommand",
854 "lp -i %p-%j -H resume");
859 do_parameter("Lpqcommand", "lpq -P%p");
860 do_parameter("Lprmcommand", "lprm -P%p %j");
861 do_parameter("Printcommand", "lp -r -P%p %s");
865 do_parameter("Lpqcommand", "qstat -l -d%p");
866 do_parameter("Lprmcommand",
868 do_parameter("Printcommand",
869 "lp -d%p -s %s; rm %s");
870 do_parameter("Lppausecommand",
872 do_parameter("Lpresumecommand",
878 do_parameter("Printcommand", "vlp print %p %s");
879 do_parameter("Lpqcommand", "vlp lpq %p");
880 do_parameter("Lprmcommand", "vlp lprm %p %j");
881 do_parameter("Lppausecommand", "vlp lppause %p %j");
882 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
883 do_parameter("Queuepausecommand", "vlp queuepause %p");
884 do_parameter("Queueresumecommand", "vlp queueresume %p");
886 #endif /* DEVELOPER */
892 /***************************************************************************
893 Initialise the global parameter structure.
894 ***************************************************************************/
895 static void init_globals(void)
900 DEBUG(3, ("Initialising global parameters\n"));
902 for (i = 0; parm_table[i].label; i++) {
903 if ((parm_table[i].type == P_STRING ||
904 parm_table[i].type == P_USTRING) &&
906 !(parm_table[i].flags & FLAG_CMDLINE)) {
907 string_set(parm_table[i].ptr, "");
911 /* options that can be set on the command line must be initialised via
912 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
914 do_parameter("socket options", "TCP_NODELAY");
916 do_parameter("workgroup", DEFAULT_WORKGROUP);
917 myname = get_myname();
918 do_parameter("netbios name", myname);
920 do_parameter("max protocol", "NT1");
921 do_parameter("name resolve order", "lmhosts wins host bcast");
923 init_printer_values();
925 do_parameter("fstype", FSTYPE_STRING);
926 do_parameter("ntvfs handler", "unixuid default");
927 do_parameter("max connections", "-1");
929 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg IOXIDResolver IRemoteActivation");
930 do_parameter("server services", "smb rpc");
931 do_parameter("auth methods", "anonymous sam_ignoredomain");
932 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
933 do_parameter("private dir", dyn_PRIVATE_DIR);
934 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
935 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
936 do_parameter("guest account", GUEST_ACCOUNT);
938 /* using UTF8 by default allows us to support all chars */
939 do_parameter("unix charset", "UTF8");
941 /* Use codepage 850 as a default for the dos character set */
942 do_parameter("dos charset", "CP850");
945 * Allow the default PASSWD_CHAT to be overridden in local.h.
947 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
949 do_parameter("passwd program", "");
950 do_parameter("printcap name", PRINTCAP_NAME);
952 do_parameter("pid directory", dyn_PIDDIR);
953 do_parameter("lock dir", dyn_LOCKDIR);
954 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
956 do_parameter("socket address", "0.0.0.0");
957 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
959 do_parameter_var("announce version", "%d.%d",
960 DEFAULT_MAJOR_VERSION,
961 DEFAULT_MINOR_VERSION);
963 do_parameter("logon drive", "");
965 do_parameter("logon home", "\\\\%N\\%U");
966 do_parameter("logon path", "\\\\%N\\%U\\profile");
967 do_parameter("password server", "*");
969 do_parameter("load printers", "True");
971 do_parameter("max mux", "50");
972 do_parameter("max xmit", "12288");
973 do_parameter("lpqcachetime", "10");
974 do_parameter("DisableSpoolss", "False");
975 do_parameter("password level", "0");
976 do_parameter("username level", "0");
977 do_parameter("LargeReadwrite", "True");
978 do_parameter("minprotocol", "CORE");
979 do_parameter("security", "USER");
980 do_parameter("paranoid server security", "True");
981 do_parameter("EncryptPasswords", "True");
982 do_parameter("ReadRaw", "True");
983 do_parameter("WriteRaw", "True");
984 do_parameter("NullPasswords", "False");
985 do_parameter("ObeyPamRestrictions", "False");
986 do_parameter("lm announce", "Auto");
987 do_parameter("lm interval", "60");
988 do_parameter("announce as", "NT SERVER");
990 do_parameter("TimeServer", "False");
991 do_parameter("BindInterfacesOnly", "False");
992 do_parameter("PamPasswordChange", "False");
993 do_parameter("Unicode", "True");
994 do_parameter("restrict anonymous", "0");
995 do_parameter("ClientLanManAuth", "True");
996 do_parameter("LanmanAuth", "True");
997 do_parameter("NTLMAuth", "True");
999 do_parameter("enhanced browsing", "True");
1000 do_parameter("LockSpinCount", "3");
1001 do_parameter("LockSpinTime", "10");
1002 #ifdef MMAP_BLACKLIST
1003 do_parameter("UseMmap", "False");
1005 do_parameter("UseMmap", "True");
1007 do_parameter("UnixExtensions", "False");
1009 /* hostname lookups can be very expensive and are broken on
1010 a large number of sites (tridge) */
1011 do_parameter("HostnameLookups", "False");
1013 do_parameter("PreferredMaster", "Auto");
1014 do_parameter("os level", "20");
1015 do_parameter("LocalMaster", "True");
1016 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1017 do_parameter("DomainLogons", "False");
1018 do_parameter("WINSsupport", "False");
1019 do_parameter("WINSproxy", "False");
1021 do_parameter("DNSproxy", "True");
1023 do_parameter("AllowTrustedDomains", "True");
1025 do_parameter("TemplateShell", "/bin/false");
1026 do_parameter("TemplateHomedir", "/home/%D/%U");
1027 do_parameter("WinbindSeparator", "\\");
1029 do_parameter("winbind cache time", "15");
1030 do_parameter("WinbindEnumUsers", "True");
1031 do_parameter("WinbindEnumGroups", "True");
1032 do_parameter("WinbindUseDefaultDomain", "False");
1034 do_parameter("IDMapBackend", "tdb");
1036 do_parameter("name cache timeout", "660"); /* In seconds */
1038 do_parameter("client signing", "Yes");
1039 do_parameter("server signing", "auto");
1041 do_parameter("use spnego", "True");
1043 do_parameter("smb ports", SMB_PORTS);
1045 do_parameter("nt status support", "True");
1048 static TALLOC_CTX *lp_talloc;
1050 /******************************************************************* a
1051 Free up temporary memory - called from the main loop.
1052 ********************************************************************/
1054 void lp_talloc_free(void)
1058 talloc_free(lp_talloc);
1062 /*******************************************************************
1063 Convenience routine to grab string parameters into temporary memory
1064 and run standard_sub_basic on them. The buffers can be written to by
1065 callers without affecting the source string.
1066 ********************************************************************/
1068 static const char *lp_string(const char *s)
1070 #if 0 /* until REWRITE done to make thread-safe */
1071 size_t len = s ? strlen(s) : 0;
1075 /* The follow debug is useful for tracking down memory problems
1076 especially if you have an inner loop that is calling a lp_*()
1077 function that returns a string. Perhaps this debug should be
1078 present all the time? */
1081 DEBUG(10, ("lp_string(%s)\n", s));
1084 #if 0 /* until REWRITE done to make thread-safe */
1086 lp_talloc = talloc_init("lp_talloc");
1088 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1096 StrnCpy(ret, s, len);
1098 if (trim_string(ret, "\"", "\"")) {
1099 if (strchr(ret,'"') != NULL)
1100 StrnCpy(ret, s, len);
1103 standard_sub_basic(ret,len+100);
1110 In this section all the functions that are used to access the
1111 parameters from the rest of the program are defined
1114 #define FN_GLOBAL_STRING(fn_name,ptr) \
1115 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1116 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1117 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1118 #define FN_GLOBAL_LIST(fn_name,ptr) \
1119 const char **fn_name(void) {return(*(const char ***)(ptr));}
1120 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1121 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1122 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1123 char fn_name(void) {return(*(char *)(ptr));}
1124 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1125 int fn_name(void) {return(*(int *)(ptr));}
1127 #define FN_LOCAL_STRING(fn_name,val) \
1128 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1129 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1130 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1131 #define FN_LOCAL_LIST(fn_name,val) \
1132 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1133 #define FN_LOCAL_BOOL(fn_name,val) \
1134 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1135 #define FN_LOCAL_CHAR(fn_name,val) \
1136 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1137 #define FN_LOCAL_INTEGER(fn_name,val) \
1138 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1140 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1141 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1142 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1143 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1144 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1145 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1146 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1147 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1148 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1149 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1150 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1151 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1152 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1153 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1154 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1155 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1156 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1157 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1158 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1159 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1160 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1161 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1162 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1163 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1164 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1165 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1166 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1167 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1168 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1169 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1170 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1171 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1172 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1173 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1174 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1175 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1176 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1177 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1178 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1179 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1180 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1181 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1182 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1183 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1185 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1187 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1189 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1190 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1191 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1192 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1193 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1194 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1195 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1196 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1197 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1199 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1200 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1201 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1202 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1203 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1204 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1205 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1206 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1207 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1208 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1209 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1210 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1211 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1212 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1213 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1214 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1215 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1216 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1217 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1218 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1219 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1220 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1221 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1222 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1223 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1224 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1225 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1226 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1227 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1228 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1229 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1230 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1231 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1232 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1233 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1234 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1235 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1236 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1237 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1238 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1239 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1240 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1241 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1242 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1243 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1244 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1245 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1246 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1247 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1248 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1249 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1250 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1251 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1252 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1253 FN_LOCAL_STRING(lp_servicename, szService)
1254 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1255 FN_LOCAL_STRING(lp_pathname, szPath)
1256 FN_LOCAL_STRING(lp_username, szUsername)
1257 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1258 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1259 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1260 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1261 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1262 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1263 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1264 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1265 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1266 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1267 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1268 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1269 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1270 FN_LOCAL_STRING(lp_comment, comment)
1271 FN_LOCAL_STRING(lp_fstype, fstype)
1272 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1273 static FN_LOCAL_STRING(lp_volume, volume)
1274 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1275 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1276 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1277 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1278 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1279 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1280 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1281 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1282 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1283 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1284 FN_LOCAL_BOOL(lp_locking, bLocking)
1285 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1286 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1287 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1288 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1289 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1290 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1291 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1292 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1293 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1294 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1295 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1296 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1297 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1298 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1299 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1300 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1301 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1302 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1304 /* local prototypes */
1306 static int map_parameter(const char *pszParmName);
1307 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1308 static int getservicebyname(const char *pszServiceName,
1309 service * pserviceDest);
1310 static void copy_service(service * pserviceDest,
1311 service * pserviceSource, BOOL *pcopymapDest);
1312 static BOOL service_ok(int iService);
1313 static BOOL do_section(const char *pszSectionName);
1314 static void init_copymap(service * pservice);
1316 /* This is a helper function for parametrical options support. */
1317 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1318 /* Actual parametrical functions are quite simple */
1319 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1322 struct param_opt *data;
1324 if (lookup_service >= iNumServices) return NULL;
1326 data = (lookup_service < 0) ?
1327 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1329 asprintf(&vfskey, "%s:%s", type, option);
1333 if (strcmp(data->key, vfskey) == 0) {
1340 if (lookup_service >= 0) {
1341 /* Try to fetch the same option but from globals */
1342 /* but only if we are not already working with Globals */
1343 data = Globals.param_opt;
1345 if (strcmp(data->key, vfskey) == 0) {
1359 /*******************************************************************
1360 convenience routine to return int parameters.
1361 ********************************************************************/
1362 static int lp_int(const char *s)
1366 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1373 /*******************************************************************
1374 convenience routine to return unsigned long parameters.
1375 ********************************************************************/
1376 static int lp_ulong(const char *s)
1380 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1384 return strtoul(s, NULL, 10);
1387 /*******************************************************************
1388 convenience routine to return boolean parameters.
1389 ********************************************************************/
1390 static BOOL lp_bool(const char *s)
1395 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1399 if (!set_boolean(&ret,s)) {
1400 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1408 /* Return parametric option from a given service. Type is a part of option before ':' */
1409 /* Parametric option has following syntax: 'Type: option = value' */
1410 /* Returned value is allocated in 'lp_talloc' context */
1412 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1414 const char *value = get_parametrics(lookup_service, type, option);
1417 return lp_string(value);
1422 /* Return parametric option from a given service. Type is a part of option before ':' */
1423 /* Parametric option has following syntax: 'Type: option = value' */
1424 /* Returned value is allocated in 'lp_talloc' context */
1426 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1427 const char *separator)
1429 const char *value = get_parametrics(lookup_service, type, option);
1432 return str_list_make(value, separator);
1437 /* Return parametric option from a given service. Type is a part of option before ':' */
1438 /* Parametric option has following syntax: 'Type: option = value' */
1440 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1442 const char *value = get_parametrics(lookup_service, type, option);
1445 return lp_int(value);
1450 /* Return parametric option from a given service. Type is a part of option before ':' */
1451 /* Parametric option has following syntax: 'Type: option = value' */
1453 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1455 const char *value = get_parametrics(lookup_service, type, option);
1458 return lp_ulong(value);
1463 /* Return parametric option from a given service. Type is a part of option before ':' */
1464 /* Parametric option has following syntax: 'Type: option = value' */
1466 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1468 const char *value = get_parametrics(lookup_service, type, option);
1471 return lp_bool(value);
1477 /***************************************************************************
1478 Initialise a service to the defaults.
1479 ***************************************************************************/
1481 static void init_service(service * pservice)
1483 memset((char *)pservice, '\0', sizeof(service));
1484 copy_service(pservice, &sDefault, NULL);
1487 /***************************************************************************
1488 Free the dynamically allocated parts of a service struct.
1489 ***************************************************************************/
1491 static void free_service(service *pservice)
1494 struct param_opt *data, *pdata;
1498 if (pservice->szService)
1499 DEBUG(5, ("free_service: Freeing service %s\n",
1500 pservice->szService));
1502 string_free(&pservice->szService);
1503 SAFE_FREE(pservice->copymap);
1505 for (i = 0; parm_table[i].label; i++) {
1506 if ((parm_table[i].type == P_STRING ||
1507 parm_table[i].type == P_USTRING) &&
1508 parm_table[i].class == P_LOCAL)
1509 string_free((char **)
1510 (((char *)pservice) +
1511 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1512 else if (parm_table[i].type == P_LIST &&
1513 parm_table[i].class == P_LOCAL)
1514 str_list_free((char ***)
1515 (((char *)pservice) +
1516 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1519 DEBUG(5,("Freeing parametrics:\n"));
1520 data = pservice->param_opt;
1522 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1523 string_free(&data->key);
1524 string_free(&data->value);
1530 ZERO_STRUCTP(pservice);
1533 /***************************************************************************
1534 Add a new service to the services array initialising it with the given
1536 ***************************************************************************/
1538 static int add_a_service(const service *pservice, const char *name)
1542 int num_to_alloc = iNumServices + 1;
1543 struct param_opt *data, *pdata;
1545 tservice = *pservice;
1547 /* it might already exist */
1549 i = getservicebyname(name, NULL);
1551 /* Clean all parametric options for service */
1552 /* They will be added during parsing again */
1553 data = ServicePtrs[i]->param_opt;
1555 string_free(&data->key);
1556 string_free(&data->value);
1561 ServicePtrs[i]->param_opt = NULL;
1566 /* find an invalid one */
1567 for (i = 0; i < iNumServices; i++)
1568 if (!ServicePtrs[i]->valid)
1571 /* if not, then create one */
1572 if (i == iNumServices) {
1575 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1578 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1583 ServicePtrs[iNumServices] = malloc_p(service);
1585 if (!ServicePtrs[iNumServices]) {
1586 DEBUG(0,("add_a_service: out of memory!\n"));
1592 free_service(ServicePtrs[i]);
1594 ServicePtrs[i]->valid = True;
1596 init_service(ServicePtrs[i]);
1597 copy_service(ServicePtrs[i], &tservice, NULL);
1599 string_set(&ServicePtrs[i]->szService, name);
1603 /***************************************************************************
1604 Add a new home service, with the specified home directory, defaults coming
1606 ***************************************************************************/
1608 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1609 const char *user, const char *pszHomedir)
1614 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1619 if (!(*(ServicePtrs[iDefaultService]->szPath))
1620 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1621 pstrcpy(newHomedir, pszHomedir);
1623 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1624 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1627 string_set(&ServicePtrs[i]->szPath, newHomedir);
1629 if (!(*(ServicePtrs[i]->comment))) {
1631 slprintf(comment, sizeof(comment) - 1,
1632 "Home directory of %s", user);
1633 string_set(&ServicePtrs[i]->comment, comment);
1635 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1636 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1638 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1644 /***************************************************************************
1645 Add a new service, based on an old one.
1646 ***************************************************************************/
1648 int lp_add_service(const char *pszService, int iDefaultService)
1650 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1653 /***************************************************************************
1654 Add the IPC service.
1655 ***************************************************************************/
1657 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1660 int i = add_a_service(&sDefault, name);
1665 slprintf(comment, sizeof(comment) - 1,
1666 "%s Service (%s)", fstype, Globals.szServerString);
1668 string_set(&ServicePtrs[i]->szPath, tmpdir());
1669 string_set(&ServicePtrs[i]->szUsername, "");
1670 string_set(&ServicePtrs[i]->comment, comment);
1671 string_set(&ServicePtrs[i]->fstype, fstype);
1672 ServicePtrs[i]->iMaxConnections = -1;
1673 ServicePtrs[i]->bAvailable = True;
1674 ServicePtrs[i]->bRead_only = True;
1675 ServicePtrs[i]->bGuest_only = False;
1676 ServicePtrs[i]->bGuest_ok = guest_ok;
1677 ServicePtrs[i]->bPrint_ok = False;
1678 ServicePtrs[i]->bBrowseable = False;
1680 if (strcasecmp(fstype, "IPC") == 0) {
1681 lp_do_parameter(i, "ntvfs handler", "default");
1684 DEBUG(3, ("adding hidden service %s\n", name));
1689 /***************************************************************************
1690 Add a new printer service, with defaults coming from service iFrom.
1691 ***************************************************************************/
1693 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1695 const char *comment = "From Printcap";
1696 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1701 /* note that we do NOT default the availability flag to True - */
1702 /* we take it from the default service passed. This allows all */
1703 /* dynamic printers to be disabled by disabling the [printers] */
1704 /* entry (if/when the 'available' keyword is implemented!). */
1706 /* the printer name is set to the service name. */
1707 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1708 string_set(&ServicePtrs[i]->comment, comment);
1709 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1710 /* Printers cannot be read_only. */
1711 ServicePtrs[i]->bRead_only = False;
1712 /* No share modes on printer services. */
1713 ServicePtrs[i]->bShareModes = False;
1714 /* No oplocks on printer services. */
1715 ServicePtrs[i]->bOpLocks = False;
1716 /* Printer services must be printable. */
1717 ServicePtrs[i]->bPrint_ok = True;
1719 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1721 update_server_announce_as_printserver();
1726 /***************************************************************************
1727 Map a parameter's string representation to something we can use.
1728 Returns False if the parameter string is not recognised, else TRUE.
1729 ***************************************************************************/
1731 static int map_parameter(const char *pszParmName)
1735 if (*pszParmName == '-')
1738 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1739 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1742 /* Warn only if it isn't parametric option */
1743 if (strchr(pszParmName, ':') == NULL)
1744 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1745 /* We do return 'fail' for parametric options as well because they are
1746 stored in different storage
1751 /***************************************************************************
1752 Set a boolean variable from the text value stored in the passed string.
1753 Returns True in success, False if the passed string does not correctly
1754 represent a boolean.
1755 ***************************************************************************/
1757 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1762 if (strwicmp(pszParmValue, "yes") == 0 ||
1763 strwicmp(pszParmValue, "true") == 0 ||
1764 strwicmp(pszParmValue, "1") == 0)
1766 else if (strwicmp(pszParmValue, "no") == 0 ||
1767 strwicmp(pszParmValue, "False") == 0 ||
1768 strwicmp(pszParmValue, "0") == 0)
1772 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1779 /***************************************************************************
1780 Find a service by name. Otherwise works like get_service.
1781 ***************************************************************************/
1783 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1787 for (iService = iNumServices - 1; iService >= 0; iService--)
1788 if (VALID(iService) &&
1789 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1790 if (pserviceDest != NULL)
1791 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1798 /***************************************************************************
1799 Copy a service structure to another.
1800 If pcopymapDest is NULL then copy all fields
1801 ***************************************************************************/
1803 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1806 BOOL bcopyall = (pcopymapDest == NULL);
1807 struct param_opt *data, *pdata, *paramo;
1810 for (i = 0; parm_table[i].label; i++)
1811 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1812 (bcopyall || pcopymapDest[i])) {
1813 void *def_ptr = parm_table[i].ptr;
1815 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1818 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1821 switch (parm_table[i].type) {
1824 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1830 *(int *)dest_ptr = *(int *)src_ptr;
1834 *(char *)dest_ptr = *(char *)src_ptr;
1838 string_set(dest_ptr,
1843 string_set(dest_ptr,
1845 strupper(*(char **)dest_ptr);
1848 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1856 init_copymap(pserviceDest);
1857 if (pserviceSource->copymap)
1858 memcpy((void *)pserviceDest->copymap,
1859 (void *)pserviceSource->copymap,
1860 sizeof(BOOL) * NUMPARAMETERS);
1863 data = pserviceSource->param_opt;
1866 pdata = pserviceDest->param_opt;
1867 /* Traverse destination */
1869 /* If we already have same option, override it */
1870 if (strcmp(pdata->key, data->key) == 0) {
1871 string_free(&pdata->value);
1872 pdata->value = strdup(data->value);
1876 pdata = pdata->next;
1879 paramo = smb_xmalloc_p(struct param_opt);
1880 paramo->key = strdup(data->key);
1881 paramo->value = strdup(data->value);
1882 DLIST_ADD(pserviceDest->param_opt, paramo);
1888 /***************************************************************************
1889 Check a service for consistency. Return False if the service is in any way
1890 incomplete or faulty, else True.
1891 ***************************************************************************/
1893 static BOOL service_ok(int iService)
1898 if (ServicePtrs[iService]->szService[0] == '\0') {
1899 DEBUG(0, ("The following message indicates an internal error:\n"));
1900 DEBUG(0, ("No service name in service entry.\n"));
1904 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1905 /* I can't see why you'd want a non-printable printer service... */
1906 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1907 if (!ServicePtrs[iService]->bPrint_ok) {
1908 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1909 ServicePtrs[iService]->szService));
1910 ServicePtrs[iService]->bPrint_ok = True;
1912 /* [printers] service must also be non-browsable. */
1913 if (ServicePtrs[iService]->bBrowseable)
1914 ServicePtrs[iService]->bBrowseable = False;
1917 /* If a service is flagged unavailable, log the fact at level 0. */
1918 if (!ServicePtrs[iService]->bAvailable)
1919 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1920 ServicePtrs[iService]->szService));
1925 static struct file_lists {
1926 struct file_lists *next;
1930 } *file_lists = NULL;
1932 /*******************************************************************
1933 Keep a linked list of all config files so we know when one has changed
1934 it's date and needs to be reloaded.
1935 ********************************************************************/
1937 static void add_to_file_list(const char *fname, const char *subfname)
1939 struct file_lists *f = file_lists;
1942 if (f->name && !strcmp(f->name, fname))
1948 f = malloc_p(struct file_lists);
1951 f->next = file_lists;
1952 f->name = strdup(fname);
1957 f->subfname = strdup(subfname);
1963 f->modtime = file_modtime(subfname);
1965 time_t t = file_modtime(subfname);
1971 /*******************************************************************
1972 Check if a config file has changed date.
1973 ********************************************************************/
1975 BOOL lp_file_list_changed(void)
1977 struct file_lists *f = file_lists;
1978 DEBUG(6, ("lp_file_list_changed()\n"));
1984 pstrcpy(n2, f->name);
1985 standard_sub_basic(n2,sizeof(n2));
1987 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1988 f->name, n2, ctime(&f->modtime)));
1990 mod_time = file_modtime(n2);
1992 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1994 ("file %s modified: %s\n", n2,
1996 f->modtime = mod_time;
1997 SAFE_FREE(f->subfname);
1998 f->subfname = strdup(n2);
2006 /***************************************************************************
2007 Handle the include operation.
2008 ***************************************************************************/
2010 static BOOL handle_include(const char *pszParmValue, char **ptr)
2013 pstrcpy(fname, pszParmValue);
2015 standard_sub_basic(fname,sizeof(fname));
2017 add_to_file_list(pszParmValue, fname);
2019 string_set(ptr, fname);
2021 if (file_exist(fname, NULL))
2022 return (pm_process(fname, do_section, do_parameter));
2024 DEBUG(2, ("Can't find include file %s\n", fname));
2029 /***************************************************************************
2030 Handle the interpretation of the copy parameter.
2031 ***************************************************************************/
2033 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2037 service serviceTemp;
2039 string_set(ptr, pszParmValue);
2041 init_service(&serviceTemp);
2045 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2047 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2048 if (iTemp == iServiceIndex) {
2049 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2051 copy_service(ServicePtrs[iServiceIndex],
2053 ServicePtrs[iServiceIndex]->copymap);
2057 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2061 free_service(&serviceTemp);
2065 /***************************************************************************
2066 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2071 winbind uid = 1000-1999
2072 winbind gid = 700-899
2074 We only do simple parsing checks here. The strings are parsed into useful
2075 structures in the winbind daemon code.
2077 ***************************************************************************/
2079 /* Some lp_ routines to return winbind [ug]id information */
2081 static uid_t winbind_uid_low, winbind_uid_high;
2082 static gid_t winbind_gid_low, winbind_gid_high;
2083 static uint32_t non_unix_account_low, non_unix_account_high;
2085 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2087 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2091 *low = winbind_uid_low;
2094 *high = winbind_uid_high;
2099 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2101 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2105 *low = winbind_gid_low;
2108 *high = winbind_gid_high;
2113 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2115 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2119 *low = non_unix_account_low;
2122 *high = non_unix_account_high;
2127 /* Do some simple checks on "winbind [ug]id" parameter values */
2129 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2133 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2138 string_set(ptr, pszParmValue);
2140 winbind_uid_low = low;
2141 winbind_uid_high = high;
2146 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2150 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2155 string_set(ptr, pszParmValue);
2157 winbind_gid_low = low;
2158 winbind_gid_high = high;
2163 /***************************************************************************
2164 Do some simple checks on "non unix account range" parameter values.
2165 ***************************************************************************/
2167 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2171 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2176 string_set(ptr, pszParmValue);
2178 non_unix_account_low = low;
2179 non_unix_account_high = high;
2185 /***************************************************************************
2186 Initialise a copymap.
2187 ***************************************************************************/
2189 static void init_copymap(service * pservice)
2192 SAFE_FREE(pservice->copymap);
2193 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2194 if (!pservice->copymap)
2196 ("Couldn't allocate copymap!! (size %d)\n",
2197 (int)NUMPARAMETERS));
2199 for (i = 0; i < NUMPARAMETERS; i++)
2200 pservice->copymap[i] = True;
2203 /***************************************************************************
2204 Return the local pointer to a parameter given the service number and the
2205 pointer into the default structure.
2206 ***************************************************************************/
2208 void *lp_local_ptr(int snum, void *ptr)
2210 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2214 /***************************************************************************
2215 Process a parametric option
2216 ***************************************************************************/
2217 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2219 struct param_opt *paramo, *data;
2222 while (isspace(*pszParmName)) {
2226 name = strdup(pszParmName);
2227 if (!name) return False;
2232 data = Globals.param_opt;
2234 data = ServicePtrs[snum]->param_opt;
2237 /* Traverse destination */
2238 for (paramo=data; paramo; paramo=paramo->next) {
2239 /* If we already have the option set, override it unless
2240 it was a command line option and the new one isn't */
2241 if (strcmp(paramo->key, name) == 0) {
2242 if ((paramo->flags & FLAG_CMDLINE) &&
2243 !(flags & FLAG_CMDLINE)) {
2247 free(paramo->value);
2248 paramo->value = strdup(pszParmValue);
2249 paramo->flags = flags;
2255 paramo = smb_xmalloc_p(struct param_opt);
2256 paramo->key = strdup(name);
2257 paramo->value = strdup(pszParmValue);
2258 paramo->flags = flags;
2260 DLIST_ADD(Globals.param_opt, paramo);
2262 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2270 /***************************************************************************
2271 Process a parameter for a particular service number. If snum < 0
2272 then assume we are in the globals.
2273 ***************************************************************************/
2274 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2277 void *parm_ptr = NULL; /* where we are going to store the result */
2278 void *def_ptr = NULL;
2280 parmnum = map_parameter(pszParmName);
2283 if (strchr(pszParmName, ':')) {
2284 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2286 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2290 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2291 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2295 /* if the flag has been set on the command line, then don't allow override,
2296 but don't report an error */
2297 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2301 def_ptr = parm_table[parmnum].ptr;
2303 /* we might point at a service, the default service or a global */
2307 if (parm_table[parmnum].class == P_GLOBAL) {
2309 ("Global parameter %s found in service section!\n",
2314 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2319 if (!ServicePtrs[snum]->copymap)
2320 init_copymap(ServicePtrs[snum]);
2322 /* this handles the aliases - set the copymap for other entries with
2323 the same data pointer */
2324 for (i = 0; parm_table[i].label; i++)
2325 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2326 ServicePtrs[snum]->copymap[i] = False;
2329 /* if it is a special case then go ahead */
2330 if (parm_table[parmnum].special) {
2331 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2335 /* now switch on the type of variable it is */
2336 switch (parm_table[parmnum].type)
2339 set_boolean(parm_ptr, pszParmValue);
2343 set_boolean(parm_ptr, pszParmValue);
2344 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2348 *(int *)parm_ptr = atoi(pszParmValue);
2352 *(char *)parm_ptr = *pszParmValue;
2356 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2360 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2364 string_set(parm_ptr, pszParmValue);
2368 string_set(parm_ptr, pszParmValue);
2369 strupper(*(char **)parm_ptr);
2373 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2376 parm_table[parmnum].enum_list[i].name)) {
2378 parm_table[parmnum].
2383 if (!parm_table[parmnum].enum_list[i].name) {
2384 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2385 pszParmValue, pszParmName));
2396 /***************************************************************************
2397 Process a parameter.
2398 ***************************************************************************/
2400 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2402 if (!bInGlobalSection && bGlobalOnly)
2405 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2406 pszParmName, pszParmValue));
2410 variable argument do parameter
2412 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2414 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2421 s = talloc_vasprintf(NULL, fmt, ap);
2423 ret = do_parameter(pszParmName, s);
2430 set a parameter from the commandline - this is called from command line parameter
2431 parsing code. It sets the parameter then marks the parameter as unable to be modified
2432 by smb.conf processing
2434 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2436 int parmnum = map_parameter(pszParmName);
2439 while (isspace(*pszParmValue)) pszParmValue++;
2442 if (parmnum < 0 && strchr(pszParmName, ':')) {
2443 /* set a parametric option */
2444 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2448 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2452 /* reset the CMDLINE flag in case this has been called before */
2453 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2455 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2459 parm_table[parmnum].flags |= FLAG_CMDLINE;
2461 /* we have to also set FLAG_CMDLINE on aliases */
2462 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2463 parm_table[i].flags |= FLAG_CMDLINE;
2465 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2466 parm_table[i].flags |= FLAG_CMDLINE;
2473 set a option from the commandline in 'a=b' format. Use to support --option
2475 BOOL lp_set_option(const char *option)
2493 ret = lp_set_cmdline(s, p+1);
2499 /***************************************************************************
2500 Print a parameter of the specified type.
2501 ***************************************************************************/
2503 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2509 for (i = 0; p->enum_list[i].name; i++) {
2510 if (*(int *)ptr == p->enum_list[i].value) {
2512 p->enum_list[i].name);
2519 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2523 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2527 fprintf(f, "%d", *(int *)ptr);
2531 fprintf(f, "%c", *(char *)ptr);
2535 if (*(int *)ptr == -1) {
2538 fprintf(f, "0%o", *(int *)ptr);
2543 if ((char ***)ptr && *(char ***)ptr) {
2544 char **list = *(char ***)ptr;
2546 for (; *list; list++)
2547 fprintf(f, "%s%s", *list,
2548 ((*(list+1))?", ":""));
2554 if (*(char **)ptr) {
2555 fprintf(f, "%s", *(char **)ptr);
2563 /***************************************************************************
2564 Check if two parameters are equal.
2565 ***************************************************************************/
2567 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2572 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2577 return (*((int *)ptr1) == *((int *)ptr2));
2580 return (*((char *)ptr1) == *((char *)ptr2));
2583 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2588 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2593 return (p1 == p2 || strequal(p1, p2));
2601 /***************************************************************************
2602 Process a new section (service). At this stage all sections are services.
2603 Later we'll have special sections that permit server parameters to be set.
2604 Returns True on success, False on failure.
2605 ***************************************************************************/
2607 static BOOL do_section(const char *pszSectionName)
2610 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2611 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2614 /* if we've just struck a global section, note the fact. */
2615 bInGlobalSection = isglobal;
2617 /* check for multiple global sections */
2618 if (bInGlobalSection) {
2619 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2623 if (!bInGlobalSection && bGlobalOnly)
2626 /* if we have a current service, tidy it up before moving on */
2629 if (iServiceIndex >= 0)
2630 bRetval = service_ok(iServiceIndex);
2632 /* if all is still well, move to the next record in the services array */
2634 /* We put this here to avoid an odd message order if messages are */
2635 /* issued by the post-processing of a previous section. */
2636 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2638 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2640 DEBUG(0, ("Failed to add a new service\n"));
2649 /***************************************************************************
2650 Determine if a partcular base parameter is currentl set to the default value.
2651 ***************************************************************************/
2653 static BOOL is_default(int i)
2655 if (!defaults_saved)
2657 switch (parm_table[i].type) {
2659 return str_list_compare (parm_table[i].def.lvalue,
2660 *(char ***)parm_table[i].ptr);
2663 return strequal(parm_table[i].def.svalue,
2664 *(char **)parm_table[i].ptr);
2667 return parm_table[i].def.bvalue ==
2668 *(BOOL *)parm_table[i].ptr;
2670 return parm_table[i].def.cvalue ==
2671 *(char *)parm_table[i].ptr;
2675 return parm_table[i].def.ivalue ==
2676 *(int *)parm_table[i].ptr;
2683 /***************************************************************************
2684 Display the contents of the global structure.
2685 ***************************************************************************/
2687 static void dump_globals(FILE *f)
2690 struct param_opt *data;
2692 fprintf(f, "# Global parameters\n[global]\n");
2694 for (i = 0; parm_table[i].label; i++)
2695 if (parm_table[i].class == P_GLOBAL &&
2696 parm_table[i].ptr &&
2697 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2698 if (defaults_saved && is_default(i))
2700 fprintf(f, "\t%s = ", parm_table[i].label);
2701 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2704 if (Globals.param_opt != NULL) {
2705 data = Globals.param_opt;
2707 fprintf(f, "\t%s = %s\n", data->key, data->value);
2714 /***************************************************************************
2715 Display the contents of a single services record.
2716 ***************************************************************************/
2718 static void dump_a_service(service * pService, FILE * f)
2721 struct param_opt *data;
2723 if (pService != &sDefault)
2724 fprintf(f, "\n[%s]\n", pService->szService);
2726 for (i = 0; parm_table[i].label; i++)
2727 if (parm_table[i].class == P_LOCAL &&
2728 parm_table[i].ptr &&
2729 (*parm_table[i].label != '-') &&
2730 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2731 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2733 if (pService == &sDefault) {
2734 if (defaults_saved && is_default(i))
2737 if (equal_parameter(parm_table[i].type,
2738 ((char *)pService) +
2740 ((char *)&sDefault) +
2745 fprintf(f, "\t%s = ", parm_table[i].label);
2746 print_parameter(&parm_table[i],
2747 ((char *)pService) + pdiff, f);
2750 if (pService->param_opt != NULL) {
2751 data = pService->param_opt;
2753 fprintf(f, "\t%s = %s\n", data->key, data->value);
2760 /***************************************************************************
2761 Return info about the next service in a service. snum==-1 gives the globals.
2762 Return NULL when out of parameters.
2763 ***************************************************************************/
2765 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2768 /* do the globals */
2769 for (; parm_table[*i].label; (*i)++) {
2770 if (parm_table[*i].class == P_SEPARATOR)
2771 return &parm_table[(*i)++];
2773 if (!parm_table[*i].ptr
2774 || (*parm_table[*i].label == '-'))
2778 && (parm_table[*i].ptr ==
2779 parm_table[(*i) - 1].ptr))
2782 return &parm_table[(*i)++];
2785 service *pService = ServicePtrs[snum];
2787 for (; parm_table[*i].label; (*i)++) {
2788 if (parm_table[*i].class == P_SEPARATOR)
2789 return &parm_table[(*i)++];
2791 if (parm_table[*i].class == P_LOCAL &&
2792 parm_table[*i].ptr &&
2793 (*parm_table[*i].label != '-') &&
2795 (parm_table[*i].ptr !=
2796 parm_table[(*i) - 1].ptr)))
2799 PTR_DIFF(parm_table[*i].ptr,
2802 if (allparameters ||
2803 !equal_parameter(parm_table[*i].type,
2804 ((char *)pService) +
2806 ((char *)&sDefault) +
2809 return &parm_table[(*i)++];
2819 /***************************************************************************
2820 Return TRUE if the passed service number is within range.
2821 ***************************************************************************/
2823 BOOL lp_snum_ok(int iService)
2825 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2828 /***************************************************************************
2829 Auto-load some home services.
2830 ***************************************************************************/
2832 static void lp_add_auto_services(const char *str)
2837 /***************************************************************************
2838 Auto-load one printer.
2839 ***************************************************************************/
2841 void lp_add_one_printer(char *name, char *comment)
2843 int printers = lp_servicenumber(PRINTERS_NAME);
2846 if (lp_servicenumber(name) < 0) {
2847 lp_add_printer(name, printers);
2848 if ((i = lp_servicenumber(name)) >= 0) {
2849 string_set(&ServicePtrs[i]->comment, comment);
2850 ServicePtrs[i]->autoloaded = True;
2855 /***************************************************************************
2856 Announce ourselves as a print server.
2857 ***************************************************************************/
2859 void update_server_announce_as_printserver(void)
2861 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2864 /***************************************************************************
2865 Have we loaded a services file yet?
2866 ***************************************************************************/
2868 BOOL lp_loaded(void)
2873 /***************************************************************************
2874 Unload unused services.
2875 ***************************************************************************/
2877 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2880 for (i = 0; i < iNumServices; i++) {
2884 if (!snumused || !snumused(smb, i)) {
2885 ServicePtrs[i]->valid = False;
2886 free_service(ServicePtrs[i]);
2891 /***************************************************************************
2893 ***************************************************************************/
2895 void lp_killservice(int iServiceIn)
2897 if (VALID(iServiceIn)) {
2898 ServicePtrs[iServiceIn]->valid = False;
2899 free_service(ServicePtrs[iServiceIn]);
2903 /***************************************************************************
2904 Save the curent values of all global and sDefault parameters into the
2905 defaults union. This allows swat and testparm to show only the
2906 changed (ie. non-default) parameters.
2907 ***************************************************************************/
2909 static void lp_save_defaults(void)
2912 for (i = 0; parm_table[i].label; i++) {
2913 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2915 switch (parm_table[i].type) {
2917 str_list_copy(&(parm_table[i].def.lvalue),
2918 *(const char ***)parm_table[i].ptr);
2922 if (parm_table[i].ptr) {
2923 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2925 parm_table[i].def.svalue = NULL;
2930 parm_table[i].def.bvalue =
2931 *(BOOL *)parm_table[i].ptr;
2934 parm_table[i].def.cvalue =
2935 *(char *)parm_table[i].ptr;
2940 parm_table[i].def.ivalue =
2941 *(int *)parm_table[i].ptr;
2947 defaults_saved = True;
2950 /*******************************************************************
2951 Set the server type we will announce as via nmbd.
2952 ********************************************************************/
2954 static void set_server_role(void)
2956 server_role = ROLE_STANDALONE;
2958 switch (lp_security()) {
2960 if (lp_domain_logons())
2961 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2966 if (lp_domain_logons()) {
2967 server_role = ROLE_DOMAIN_PDC;
2970 server_role = ROLE_DOMAIN_MEMBER;
2973 if (lp_domain_logons()) {
2975 if (Globals.bDomainMaster) /* auto or yes */
2976 server_role = ROLE_DOMAIN_PDC;
2978 server_role = ROLE_DOMAIN_BDC;
2982 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2986 DEBUG(10, ("set_server_role: role = "));
2988 switch(server_role) {
2989 case ROLE_STANDALONE:
2990 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2992 case ROLE_DOMAIN_MEMBER:
2993 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2995 case ROLE_DOMAIN_BDC:
2996 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2998 case ROLE_DOMAIN_PDC:
2999 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3004 /***************************************************************************
3005 Load the services array from the services file. Return True on success,
3007 ***************************************************************************/
3009 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3014 struct param_opt *data;
3016 pstrcpy(n2, pszFname);
3017 standard_sub_basic(n2,sizeof(n2));
3019 add_to_file_list(pszFname, n2);
3023 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3025 bInGlobalSection = True;
3026 bGlobalOnly = global_only;
3035 if (Globals.param_opt != NULL) {
3036 struct param_opt *next;
3037 for (data=Globals.param_opt; data; data=next) {
3039 if (data->flags & FLAG_CMDLINE) continue;
3042 DLIST_REMOVE(Globals.param_opt, data);
3047 /* We get sections first, so have to start 'behind' to make up */
3049 bRetval = pm_process(n2, do_section, do_parameter);
3051 /* finish up the last section */
3052 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3054 if (iServiceIndex >= 0)
3055 bRetval = service_ok(iServiceIndex);
3057 lp_add_auto_services(lp_auto_services());
3060 /* When 'restrict anonymous = 2' guest connections to ipc$
3062 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3063 lp_add_hidden("ADMIN$", "DISK", False);
3067 set_default_server_announce_type();
3071 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3072 /* if bWINSsupport is true and we are in the client */
3073 if (in_client && Globals.bWINSsupport) {
3074 lp_do_parameter(-1, "wins server", "127.0.0.1");
3077 lp_do_parameter(-1, "gensec:krb5", "False");
3078 lp_do_parameter(-1, "gensec:ms_krb5", "False");
3085 /***************************************************************************
3086 Reset the max number of services.
3087 ***************************************************************************/
3089 void lp_resetnumservices(void)
3094 /***************************************************************************
3095 Return the max number of services.
3096 ***************************************************************************/
3098 int lp_numservices(void)
3100 return (iNumServices);
3103 /***************************************************************************
3104 Display the contents of the services array in human-readable form.
3105 ***************************************************************************/
3107 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3112 defaults_saved = False;
3116 dump_a_service(&sDefault, f);
3118 for (iService = 0; iService < maxtoprint; iService++)
3119 lp_dump_one(f, show_defaults, iService);
3122 /***************************************************************************
3123 Display the contents of one service in human-readable form.
3124 ***************************************************************************/
3126 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3129 if (ServicePtrs[snum]->szService[0] == '\0')
3131 dump_a_service(ServicePtrs[snum], f);
3135 /***************************************************************************
3136 Return the number of the service with the given name, or -1 if it doesn't
3137 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3138 getservicebyname()! This works ONLY if all services have been loaded, and
3139 does not copy the found service.
3140 ***************************************************************************/
3142 int lp_servicenumber(const char *pszServiceName)
3145 fstring serviceName;
3148 for (iService = iNumServices - 1; iService >= 0; iService--) {
3149 if (VALID(iService) && ServicePtrs[iService]->szService) {
3151 * The substitution here is used to support %U is
3154 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3155 standard_sub_basic(serviceName,sizeof(serviceName));
3156 if (strequal(serviceName, pszServiceName))
3162 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3167 /*******************************************************************
3168 A useful volume label function.
3169 ********************************************************************/
3170 const char *volume_label(int snum)
3172 const char *ret = lp_volume(snum);
3174 return lp_servicename(snum);
3179 /*******************************************************************
3180 Set the server type we will announce as via nmbd.
3181 ********************************************************************/
3183 static void set_default_server_announce_type(void)
3185 default_server_announce = 0;
3186 default_server_announce |= SV_TYPE_WORKSTATION;
3187 default_server_announce |= SV_TYPE_SERVER;
3188 default_server_announce |= SV_TYPE_SERVER_UNIX;
3190 switch (lp_announce_as()) {
3191 case ANNOUNCE_AS_NT_SERVER:
3192 default_server_announce |= SV_TYPE_SERVER_NT;
3193 /* fall through... */
3194 case ANNOUNCE_AS_NT_WORKSTATION:
3195 default_server_announce |= SV_TYPE_NT;
3197 case ANNOUNCE_AS_WIN95:
3198 default_server_announce |= SV_TYPE_WIN95_PLUS;
3200 case ANNOUNCE_AS_WFW:
3201 default_server_announce |= SV_TYPE_WFW;
3207 switch (lp_server_role()) {
3208 case ROLE_DOMAIN_MEMBER:
3209 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3211 case ROLE_DOMAIN_PDC:
3212 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3214 case ROLE_DOMAIN_BDC:
3215 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3217 case ROLE_STANDALONE:
3221 if (lp_time_server())
3222 default_server_announce |= SV_TYPE_TIME_SOURCE;
3224 if (lp_host_msdfs())
3225 default_server_announce |= SV_TYPE_DFS_SERVER;
3228 /***********************************************************
3229 returns role of Samba server
3230 ************************************************************/
3232 int lp_server_role(void)
3237 /***********************************************************
3238 If we are PDC then prefer us as DMB
3239 ************************************************************/
3241 BOOL lp_domain_master(void)
3243 if (Globals.bDomainMaster == Auto)
3244 return (lp_server_role() == ROLE_DOMAIN_PDC);
3246 return Globals.bDomainMaster;
3249 /***********************************************************
3250 If we are DMB then prefer us as LMB
3251 ************************************************************/
3253 BOOL lp_preferred_master(void)
3255 if (Globals.bPreferredMaster == Auto)
3256 return (lp_local_master() && lp_domain_master());
3258 return Globals.bPreferredMaster;
3261 /*******************************************************************
3263 ********************************************************************/
3265 void lp_remove_service(int snum)
3267 ServicePtrs[snum]->valid = False;
3270 /*******************************************************************
3272 ********************************************************************/
3274 void lp_copy_service(int snum, const char *new_name)
3276 const char *oldname = lp_servicename(snum);
3277 do_section(new_name);
3279 snum = lp_servicenumber(new_name);
3281 lp_do_parameter(snum, "copy", oldname);
3286 /*******************************************************************
3287 Get the default server type we will announce as via nmbd.
3288 ********************************************************************/
3289 int lp_default_server_announce(void)
3291 return default_server_announce;
3294 const char *lp_printername(int snum)
3296 const char *ret = _lp_printername(snum);
3297 if (ret == NULL || (ret != NULL && *ret == '\0'))
3298 ret = lp_const_servicename(snum);
3304 /*******************************************************************
3305 Return the max print jobs per queue.
3306 ********************************************************************/
3308 int lp_maxprintjobs(int snum)
3310 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3311 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3312 maxjobs = PRINT_MAX_JOBID - 1;