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 "librpc/gen_ndr/ndr_samr.h"
63 #include "dlinklist.h"
65 BOOL in_client = False; /* Not in the client by default */
66 static BOOL bLoaded = False;
69 #define GLOBAL_NAME "global"
73 #define PRINTERS_NAME "printers"
77 #define HOMES_NAME "homes"
80 /* some helpful bits */
81 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
82 #define VALID(i) ServicePtrs[i]->valid
84 static BOOL do_parameter(const char *, const char *);
85 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
87 static BOOL defaults_saved = False;
90 #define FLAG_BASIC 0x0001 /* fundamental options */
91 #define FLAG_SHARE 0x0002 /* file sharing options */
92 #define FLAG_PRINT 0x0004 /* printing options */
93 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
94 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
95 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
96 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
97 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
98 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
99 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
100 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
103 /* the following are used by loadparm for option lists */
106 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
107 P_STRING,P_USTRING,P_ENUM,P_SEP
112 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
126 BOOL (*special)(const char *, char **);
127 const struct enum_list *enum_list;
140 struct param_opt *prev, *next;
147 * This structure describes global (ie., server-wide) parameters.
155 char *display_charset;
156 char *szPrintcapname;
160 char *szDefaultService;
162 char *szServerString;
163 char *szAutoServices;
164 char *szPasswdProgram;
168 char *szSMBPasswdFile;
172 char **szPreloadModules;
173 char **szPasswordServers;
174 char *szSocketOptions;
181 char **szWINSservers;
183 char *szRemoteAnnounce;
184 char *szRemoteBrowseSync;
185 char *szSocketAddress;
186 char *szAnnounceVersion; /* This is initialised in init_globals */
189 char **szNetbiosAliases;
190 char *szNetbiosScope;
191 char *szDomainOtherSIDs;
192 char *szNameResolveOrder;
194 char *szAddUserScript;
195 char *szAddMachineScript;
197 char *szWINSPartners;
198 char **dcerpc_ep_servers;
199 char **server_services;
202 char *szNonUnixAccountRange;
203 char *szTemplateHomedir;
204 char *szTemplateShell;
205 char *szWinbindSeparator;
206 BOOL bWinbindEnumUsers;
207 BOOL bWinbindEnumGroups;
208 BOOL bWinbindUseDefaultDomain;
209 char *szIDMapBackend;
210 char *szGuestaccount;
219 BOOL paranoid_server_security;
221 BOOL bDisableSpoolss;
223 int enhanced_browsing;
230 int announce_as; /* This is initialised in init_globals */
231 int machine_password_timeout;
232 int winbind_cache_time;
235 char *socket_options;
240 BOOL bPreferredMaster;
243 BOOL bEncryptPasswords;
245 BOOL bObeyPamRestrictions;
247 BOOL bLargeReadwrite;
251 BOOL bBindInterfacesOnly;
252 BOOL bPamPasswordChange;
254 BOOL bNTStatusSupport;
255 BOOL bAllowTrustedDomains;
261 BOOL bClientLanManAuth;
262 BOOL bClientNTLMv2Auth;
264 BOOL bHideLocalUsers;
267 BOOL bHostnameLookups;
268 BOOL bUnixExtensions;
269 BOOL bDisableNetbios;
271 int restrict_anonymous;
272 int name_cache_timeout;
273 struct param_opt *param_opt;
277 static global Globals;
280 * This structure describes a single service.
289 char **szInvalidUsers;
294 char *szPrintcommand;
297 char *szLppausecommand;
298 char *szLpresumecommand;
299 char *szQueuepausecommand;
300 char *szQueueresumecommand;
308 char **ntvfs_handler;
334 struct param_opt *param_opt;
336 char dummy[3]; /* for alignment */
341 /* This is a default service used to prime a services structure */
342 static service sDefault = {
344 False, /* not autoloaded */
345 NULL, /* szService */
347 NULL, /* szUsername */
348 NULL, /* szInvalidUsers */
349 NULL, /* szValidUsers */
350 NULL, /* szAdminUsers */
352 NULL, /* szInclude */
353 NULL, /* szPrintcommand */
354 NULL, /* szLpqcommand */
355 NULL, /* szLprmcommand */
356 NULL, /* szLppausecommand */
357 NULL, /* szLpresumecommand */
358 NULL, /* szQueuepausecommand */
359 NULL, /* szQueueresumecommand */
360 NULL, /* szPrintername */
361 NULL, /* szHostsallow */
362 NULL, /* szHostsdeny */
366 NULL, /* szMSDfsProxy */
367 NULL, /* ntvfs_handler */
368 0, /* iMinPrintSpace */
369 1000, /* iMaxPrintJobs */
370 0, /* iMaxConnections */
371 DEFAULT_PRINTING, /* iPrinting */
373 True, /* bAvailable */
374 True, /* bBrowseable */
375 True, /* bRead_only */
376 False, /* bPrint_ok */
377 False, /* bMap_system */
378 False, /* bMap_hidden */
379 True, /* bMap_archive */
381 True, /* bStrictLocking */
382 True, /* bPosixLocking */
384 True, /* bLevel2OpLocks */
385 False, /* bOnlyUser */
386 False, /* bGuest_only */
387 False, /* bGuest_ok */
389 False, /* bMSDfsRoot */
390 True, /* bShareModes */
391 False, /* bStrictSync */
392 False, /* bCIFileSystem */
393 NULL, /* Parametric options */
398 /* local variables */
399 static service **ServicePtrs = NULL;
400 static int iNumServices = 0;
401 static int iServiceIndex = 0;
402 static BOOL bInGlobalSection = True;
403 static BOOL bGlobalOnly = False;
404 static int server_role;
405 static int default_server_announce;
407 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
409 /* prototypes for the special type handlers */
410 static BOOL handle_include(const char *pszParmValue, char **ptr);
411 static BOOL handle_copy(const char *pszParmValue, char **ptr);
412 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
413 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
414 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
416 static void set_server_role(void);
417 static void set_default_server_announce_type(void);
419 static const struct enum_list enum_protocol[] = {
420 {PROTOCOL_NT1, "NT1"},
421 {PROTOCOL_LANMAN2, "LANMAN2"},
422 {PROTOCOL_LANMAN1, "LANMAN1"},
423 {PROTOCOL_CORE, "CORE"},
424 {PROTOCOL_COREPLUS, "COREPLUS"},
425 {PROTOCOL_COREPLUS, "CORE+"},
429 static const struct enum_list enum_security[] = {
430 {SEC_SHARE, "SHARE"},
432 {SEC_SERVER, "SERVER"},
433 {SEC_DOMAIN, "DOMAIN"},
440 static const struct enum_list enum_printing[] = {
441 {PRINT_SYSV, "sysv"},
443 {PRINT_HPUX, "hpux"},
447 {PRINT_LPRNG, "lprng"},
448 {PRINT_SOFTQ, "softq"},
449 {PRINT_CUPS, "cups"},
451 {PRINT_LPROS2, "os2"},
453 {PRINT_TEST, "test"},
455 #endif /* DEVELOPER */
459 /* Types of machine we can announce as. */
460 #define ANNOUNCE_AS_NT_SERVER 1
461 #define ANNOUNCE_AS_WIN95 2
462 #define ANNOUNCE_AS_WFW 3
463 #define ANNOUNCE_AS_NT_WORKSTATION 4
465 static const struct enum_list enum_announce_as[] = {
466 {ANNOUNCE_AS_NT_SERVER, "NT"},
467 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
468 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
469 {ANNOUNCE_AS_WIN95, "win95"},
470 {ANNOUNCE_AS_WFW, "WfW"},
474 static const struct enum_list enum_bool_auto[] = {
485 /* Client-side offline caching policy types */
486 #define CSC_POLICY_MANUAL 0
487 #define CSC_POLICY_DOCUMENTS 1
488 #define CSC_POLICY_PROGRAMS 2
489 #define CSC_POLICY_DISABLE 3
491 static const struct enum_list enum_csc_policy[] = {
492 {CSC_POLICY_MANUAL, "manual"},
493 {CSC_POLICY_DOCUMENTS, "documents"},
494 {CSC_POLICY_PROGRAMS, "programs"},
495 {CSC_POLICY_DISABLE, "disable"},
499 /* SMB signing types. */
500 static const struct enum_list enum_smb_signing_vals[] = {
501 {SMB_SIGNING_OFF, "No"},
502 {SMB_SIGNING_OFF, "False"},
503 {SMB_SIGNING_OFF, "0"},
504 {SMB_SIGNING_OFF, "Off"},
505 {SMB_SIGNING_OFF, "disabled"},
506 {SMB_SIGNING_SUPPORTED, "Yes"},
507 {SMB_SIGNING_SUPPORTED, "True"},
508 {SMB_SIGNING_SUPPORTED, "1"},
509 {SMB_SIGNING_SUPPORTED, "On"},
510 {SMB_SIGNING_SUPPORTED, "enabled"},
511 {SMB_SIGNING_REQUIRED, "required"},
512 {SMB_SIGNING_REQUIRED, "mandatory"},
513 {SMB_SIGNING_REQUIRED, "force"},
514 {SMB_SIGNING_REQUIRED, "forced"},
515 {SMB_SIGNING_REQUIRED, "enforced"},
516 {SMB_SIGNING_AUTO, "auto"},
521 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
523 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
524 * is implied in current control logic. This may change at some later time. A
525 * flag value of 0 means - show as development option only.
527 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
528 * screen in SWAT. This is used to exclude parameters as well as to squash all
529 * parameters that have been duplicated by pseudonyms.
531 static struct parm_struct parm_table[] = {
532 {"Base Options", P_SEP, P_SEPARATOR},
534 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
539 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
540 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
541 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
542 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
543 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
544 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
546 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
550 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
551 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
552 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
554 {"Security Options", P_SEP, P_SEPARATOR},
556 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
557 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
558 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
559 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
565 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
573 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
587 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
588 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
590 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
591 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
592 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
594 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
596 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
598 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
600 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
601 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
602 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
603 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
605 {"Logging Options", P_SEP, P_SEPARATOR},
607 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
608 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
609 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
611 {"Protocol Options", P_SEP, P_SEPARATOR},
613 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
614 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
615 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
616 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
617 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
618 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
619 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
620 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
622 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
624 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
625 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
626 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
627 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
629 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
630 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
635 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
636 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
637 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
638 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
640 {"Tuning Options", P_SEP, P_SEPARATOR},
642 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
643 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
644 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
645 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
647 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
648 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
649 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
651 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
652 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
653 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
655 {"Printing Options", P_SEP, P_SEPARATOR},
657 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
658 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
659 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
660 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
661 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
662 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
663 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
664 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
666 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
667 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
668 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
671 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
673 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
674 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
676 {"Filename Handling", P_SEP, P_SEPARATOR},
678 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
679 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
680 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
682 {"Domain Options", P_SEP, P_SEPARATOR},
684 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
686 {"Logon Options", P_SEP, P_SEPARATOR},
688 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
689 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
691 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
697 {"Browse Options", P_SEP, P_SEPARATOR},
699 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
703 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
704 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
706 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
707 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
708 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
710 {"WINS Options", P_SEP, P_SEPARATOR},
711 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
712 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
714 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
715 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
716 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
717 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
719 {"Locking Options", P_SEP, P_SEPARATOR},
721 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
722 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
723 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
724 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
726 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
727 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
729 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
730 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
732 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
734 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
735 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
737 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
738 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
739 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
743 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
746 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
749 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
750 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
752 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
753 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
754 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
756 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
760 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
761 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
762 {"Winbind options", P_SEP, P_SEPARATOR},
764 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
777 /***************************************************************************
778 Initialise the sDefault parameter structure for the printer values.
779 ***************************************************************************/
781 static void init_printer_values(void)
783 /* choose defaults depending on the type of printing */
784 switch (sDefault.iPrinting) {
789 do_parameter("Lpqcommand", "lpq -P'%p'");
790 do_parameter("Lprmcommand", "lprm -P'%p' %j");
791 do_parameter("Printcommand",
797 do_parameter("Lpqcommand", "lpq -P'%p'");
798 do_parameter("Lprmcommand", "lprm -P'%p' %j");
799 do_parameter("Printcommand",
801 do_parameter("Queuepausecommand",
803 do_parameter("Queueresumecommand",
805 do_parameter("Lppausecommand",
807 do_parameter("Lpresumecommand",
808 "lpc release '%p' %j");
813 do_parameter("Lpqcommand", "");
814 do_parameter("Lprmcommand", "");
815 do_parameter("Printcommand", "");
816 do_parameter("Lppausecommand", "");
817 do_parameter("Lpresumecommand", "");
818 do_parameter("Queuepausecommand", "");
819 do_parameter("Queueresumecommand", "");
821 do_parameter("Printcapname", "cups");
823 do_parameter("Lpqcommand",
824 "/usr/bin/lpstat -o '%p'");
825 do_parameter("Lprmcommand",
826 "/usr/bin/cancel '%p-%j'");
827 do_parameter("Printcommand",
828 "/usr/bin/lp -d '%p' %s; rm %s");
829 do_parameter("Lppausecommand",
830 "lp -i '%p-%j' -H hold");
831 do_parameter("Lpresumecommand",
832 "lp -i '%p-%j' -H resume");
833 do_parameter("Queuepausecommand",
834 "/usr/bin/disable '%p'");
835 do_parameter("Queueresumecommand",
836 "/usr/bin/enable '%p'");
837 do_parameter("Printcapname", "lpstat");
838 #endif /* HAVE_CUPS */
843 do_parameter("Lpqcommand", "lpstat -o%p");
844 do_parameter("Lprmcommand", "cancel %p-%j");
845 do_parameter("Printcommand",
846 "lp -c -d%p %s; rm %s");
847 do_parameter("Queuepausecommand",
849 do_parameter("Queueresumecommand",
852 do_parameter("Lppausecommand",
853 "lp -i %p-%j -H hold");
854 do_parameter("Lpresumecommand",
855 "lp -i %p-%j -H resume");
860 do_parameter("Lpqcommand", "lpq -P%p");
861 do_parameter("Lprmcommand", "lprm -P%p %j");
862 do_parameter("Printcommand", "lp -r -P%p %s");
866 do_parameter("Lpqcommand", "qstat -l -d%p");
867 do_parameter("Lprmcommand",
869 do_parameter("Printcommand",
870 "lp -d%p -s %s; rm %s");
871 do_parameter("Lppausecommand",
873 do_parameter("Lpresumecommand",
879 do_parameter("Printcommand", "vlp print %p %s");
880 do_parameter("Lpqcommand", "vlp lpq %p");
881 do_parameter("Lprmcommand", "vlp lprm %p %j");
882 do_parameter("Lppausecommand", "vlp lppause %p %j");
883 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
884 do_parameter("Queuepausecommand", "vlp queuepause %p");
885 do_parameter("Queueresumecommand", "vlp queueresume %p");
887 #endif /* DEVELOPER */
893 /***************************************************************************
894 Initialise the global parameter structure.
895 ***************************************************************************/
896 static void init_globals(void)
901 DEBUG(3, ("Initialising global parameters\n"));
903 for (i = 0; parm_table[i].label; i++) {
904 if ((parm_table[i].type == P_STRING ||
905 parm_table[i].type == P_USTRING) &&
907 !(parm_table[i].flags & FLAG_CMDLINE)) {
908 string_set(parm_table[i].ptr, "");
912 /* options that can be set on the command line must be initialised via
913 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
915 do_parameter("socket options", "TCP_NODELAY");
917 do_parameter("workgroup", DEFAULT_WORKGROUP);
918 myname = get_myname();
919 do_parameter("netbios name", myname);
921 do_parameter("max protocol", "NT1");
922 do_parameter("name resolve order", "lmhosts wins host bcast");
924 init_printer_values();
926 do_parameter("fstype", FSTYPE_STRING);
927 do_parameter("ntvfs handler", "unixuid default");
928 do_parameter("max connections", "-1");
930 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg IOXIDResolver IRemoteActivation dssetup");
931 do_parameter("server services", "smb rpc");
932 do_parameter("auth methods", "anonymous sam_ignoredomain");
933 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
934 do_parameter("private dir", dyn_PRIVATE_DIR);
935 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
936 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
937 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
938 do_parameter("guest account", GUEST_ACCOUNT);
940 /* using UTF8 by default allows us to support all chars */
941 do_parameter("unix charset", "UTF8");
943 /* Use codepage 850 as a default for the dos character set */
944 do_parameter("dos charset", "CP850");
947 * Allow the default PASSWD_CHAT to be overridden in local.h.
949 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
951 do_parameter("passwd program", "");
952 do_parameter("printcap name", PRINTCAP_NAME);
954 do_parameter("pid directory", dyn_PIDDIR);
955 do_parameter("lock dir", dyn_LOCKDIR);
956 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
958 do_parameter("socket address", "0.0.0.0");
959 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
961 do_parameter_var("announce version", "%d.%d",
962 DEFAULT_MAJOR_VERSION,
963 DEFAULT_MINOR_VERSION);
965 do_parameter("logon drive", "");
967 do_parameter("logon home", "\\\\%N\\%U");
968 do_parameter("logon path", "\\\\%N\\%U\\profile");
969 do_parameter("password server", "*");
971 do_parameter("load printers", "True");
973 do_parameter("max mux", "50");
974 do_parameter("max xmit", "12288");
975 do_parameter("lpqcachetime", "10");
976 do_parameter("DisableSpoolss", "False");
977 do_parameter("password level", "0");
978 do_parameter("username level", "0");
979 do_parameter("LargeReadwrite", "True");
980 do_parameter("minprotocol", "CORE");
981 do_parameter("security", "USER");
982 do_parameter("paranoid server security", "True");
983 do_parameter("EncryptPasswords", "True");
984 do_parameter("ReadRaw", "True");
985 do_parameter("WriteRaw", "True");
986 do_parameter("NullPasswords", "False");
987 do_parameter("ObeyPamRestrictions", "False");
988 do_parameter("lm announce", "Auto");
989 do_parameter("lm interval", "60");
990 do_parameter("announce as", "NT SERVER");
992 do_parameter("TimeServer", "False");
993 do_parameter("BindInterfacesOnly", "False");
994 do_parameter("PamPasswordChange", "False");
995 do_parameter("Unicode", "True");
996 do_parameter("restrict anonymous", "0");
997 do_parameter("ClientLanManAuth", "True");
998 do_parameter("LanmanAuth", "True");
999 do_parameter("NTLMAuth", "True");
1001 do_parameter("enhanced browsing", "True");
1002 do_parameter("LockSpinCount", "3");
1003 do_parameter("LockSpinTime", "10");
1004 #ifdef MMAP_BLACKLIST
1005 do_parameter("UseMmap", "False");
1007 do_parameter("UseMmap", "True");
1009 do_parameter("UnixExtensions", "False");
1011 /* hostname lookups can be very expensive and are broken on
1012 a large number of sites (tridge) */
1013 do_parameter("HostnameLookups", "False");
1015 do_parameter("PreferredMaster", "Auto");
1016 do_parameter("os level", "20");
1017 do_parameter("LocalMaster", "True");
1018 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1019 do_parameter("DomainLogons", "False");
1020 do_parameter("WINSsupport", "False");
1021 do_parameter("WINSproxy", "False");
1023 do_parameter("DNSproxy", "True");
1025 do_parameter("AllowTrustedDomains", "True");
1027 do_parameter("TemplateShell", "/bin/false");
1028 do_parameter("TemplateHomedir", "/home/%D/%U");
1029 do_parameter("WinbindSeparator", "\\");
1031 do_parameter("winbind cache time", "15");
1032 do_parameter("WinbindEnumUsers", "True");
1033 do_parameter("WinbindEnumGroups", "True");
1034 do_parameter("WinbindUseDefaultDomain", "False");
1036 do_parameter("IDMapBackend", "tdb");
1038 do_parameter("name cache timeout", "660"); /* In seconds */
1040 do_parameter("client signing", "Yes");
1041 do_parameter("server signing", "auto");
1043 do_parameter("use spnego", "True");
1045 do_parameter("smb ports", SMB_PORTS);
1047 do_parameter("nt status support", "True");
1050 static TALLOC_CTX *lp_talloc;
1052 /******************************************************************* a
1053 Free up temporary memory - called from the main loop.
1054 ********************************************************************/
1056 void lp_talloc_free(void)
1060 talloc_free(lp_talloc);
1064 /*******************************************************************
1065 Convenience routine to grab string parameters into temporary memory
1066 and run standard_sub_basic on them. The buffers can be written to by
1067 callers without affecting the source string.
1068 ********************************************************************/
1070 static const char *lp_string(const char *s)
1072 #if 0 /* until REWRITE done to make thread-safe */
1073 size_t len = s ? strlen(s) : 0;
1077 /* The follow debug is useful for tracking down memory problems
1078 especially if you have an inner loop that is calling a lp_*()
1079 function that returns a string. Perhaps this debug should be
1080 present all the time? */
1083 DEBUG(10, ("lp_string(%s)\n", s));
1086 #if 0 /* until REWRITE done to make thread-safe */
1088 lp_talloc = talloc_init("lp_talloc");
1090 ret = talloc_array_p(lp_talloc, char, len + 100); /* leave room for substitution */
1098 StrnCpy(ret, s, len);
1100 if (trim_string(ret, "\"", "\"")) {
1101 if (strchr(ret,'"') != NULL)
1102 StrnCpy(ret, s, len);
1105 standard_sub_basic(ret,len+100);
1112 In this section all the functions that are used to access the
1113 parameters from the rest of the program are defined
1116 #define FN_GLOBAL_STRING(fn_name,ptr) \
1117 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1118 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1119 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1120 #define FN_GLOBAL_LIST(fn_name,ptr) \
1121 const char **fn_name(void) {return(*(const char ***)(ptr));}
1122 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1123 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1124 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1125 char fn_name(void) {return(*(char *)(ptr));}
1126 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1127 int fn_name(void) {return(*(int *)(ptr));}
1129 #define FN_LOCAL_STRING(fn_name,val) \
1130 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1131 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1132 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1133 #define FN_LOCAL_LIST(fn_name,val) \
1134 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1135 #define FN_LOCAL_BOOL(fn_name,val) \
1136 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1137 #define FN_LOCAL_CHAR(fn_name,val) \
1138 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1139 #define FN_LOCAL_INTEGER(fn_name,val) \
1140 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1142 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1143 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1144 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1145 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1146 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1147 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1148 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1149 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1150 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1151 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1152 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1153 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1154 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1155 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1156 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1157 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1158 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1159 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1160 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1161 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1162 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1163 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1164 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1165 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1166 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1167 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1168 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1169 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1170 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1171 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1172 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1173 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1174 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1175 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1176 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1177 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1178 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1179 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1180 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1181 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1182 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1183 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1184 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1185 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1187 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1189 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1191 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1192 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1193 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1194 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1195 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1196 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1197 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1198 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1199 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1201 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1202 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1203 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1204 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1205 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1206 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1207 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1208 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1209 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1210 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1211 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1212 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1213 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1214 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1215 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1216 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1217 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1218 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1219 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1220 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1221 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1222 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1223 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1224 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1225 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1226 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1227 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1228 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1229 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1230 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1231 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1232 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1233 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1234 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1235 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1236 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1237 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1238 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1239 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1240 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1241 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1242 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1243 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1244 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1245 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1246 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1247 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1248 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1249 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1250 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1251 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1252 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1253 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1254 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1255 FN_LOCAL_STRING(lp_servicename, szService)
1256 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1257 FN_LOCAL_STRING(lp_pathname, szPath)
1258 FN_LOCAL_STRING(lp_username, szUsername)
1259 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1260 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1261 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1262 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1263 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1264 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1265 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1266 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1267 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1268 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1269 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1270 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1271 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1272 FN_LOCAL_STRING(lp_comment, comment)
1273 FN_LOCAL_STRING(lp_fstype, fstype)
1274 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1275 static FN_LOCAL_STRING(lp_volume, volume)
1276 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1277 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1278 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1279 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1280 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1281 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1282 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1283 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1284 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1285 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1286 FN_LOCAL_BOOL(lp_locking, bLocking)
1287 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1288 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1289 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1290 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1291 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1292 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1293 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1294 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1295 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1296 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1297 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1298 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1299 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1300 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1301 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1302 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1303 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1304 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1306 /* local prototypes */
1308 static int map_parameter(const char *pszParmName);
1309 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1310 static int getservicebyname(const char *pszServiceName,
1311 service * pserviceDest);
1312 static void copy_service(service * pserviceDest,
1313 service * pserviceSource, BOOL *pcopymapDest);
1314 static BOOL service_ok(int iService);
1315 static BOOL do_section(const char *pszSectionName);
1316 static void init_copymap(service * pservice);
1318 /* This is a helper function for parametrical options support. */
1319 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1320 /* Actual parametrical functions are quite simple */
1321 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1324 struct param_opt *data;
1326 if (lookup_service >= iNumServices) return NULL;
1328 data = (lookup_service < 0) ?
1329 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1331 asprintf(&vfskey, "%s:%s", type, option);
1335 if (strcmp(data->key, vfskey) == 0) {
1342 if (lookup_service >= 0) {
1343 /* Try to fetch the same option but from globals */
1344 /* but only if we are not already working with Globals */
1345 data = Globals.param_opt;
1347 if (strcmp(data->key, vfskey) == 0) {
1361 /*******************************************************************
1362 convenience routine to return int parameters.
1363 ********************************************************************/
1364 static int lp_int(const char *s)
1368 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1375 /*******************************************************************
1376 convenience routine to return unsigned long parameters.
1377 ********************************************************************/
1378 static int lp_ulong(const char *s)
1382 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1386 return strtoul(s, NULL, 10);
1389 /*******************************************************************
1390 convenience routine to return boolean parameters.
1391 ********************************************************************/
1392 static BOOL lp_bool(const char *s)
1397 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1401 if (!set_boolean(&ret,s)) {
1402 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1410 /* Return parametric option from a given service. Type is a part of option before ':' */
1411 /* Parametric option has following syntax: 'Type: option = value' */
1412 /* Returned value is allocated in 'lp_talloc' context */
1414 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1416 const char *value = get_parametrics(lookup_service, type, option);
1419 return lp_string(value);
1424 /* Return parametric option from a given service. Type is a part of option before ':' */
1425 /* Parametric option has following syntax: 'Type: option = value' */
1426 /* Returned value is allocated in 'lp_talloc' context */
1428 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1429 const char *separator)
1431 const char *value = get_parametrics(lookup_service, type, option);
1434 return str_list_make(value, separator);
1439 /* Return parametric option from a given service. Type is a part of option before ':' */
1440 /* Parametric option has following syntax: 'Type: option = value' */
1442 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1444 const char *value = get_parametrics(lookup_service, type, option);
1447 return lp_int(value);
1452 /* Return parametric option from a given service. Type is a part of option before ':' */
1453 /* Parametric option has following syntax: 'Type: option = value' */
1455 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1457 const char *value = get_parametrics(lookup_service, type, option);
1460 return lp_ulong(value);
1465 /* Return parametric option from a given service. Type is a part of option before ':' */
1466 /* Parametric option has following syntax: 'Type: option = value' */
1468 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1470 const char *value = get_parametrics(lookup_service, type, option);
1473 return lp_bool(value);
1479 /***************************************************************************
1480 Initialise a service to the defaults.
1481 ***************************************************************************/
1483 static void init_service(service * pservice)
1485 memset((char *)pservice, '\0', sizeof(service));
1486 copy_service(pservice, &sDefault, NULL);
1489 /***************************************************************************
1490 Free the dynamically allocated parts of a service struct.
1491 ***************************************************************************/
1493 static void free_service(service *pservice)
1496 struct param_opt *data, *pdata;
1500 if (pservice->szService)
1501 DEBUG(5, ("free_service: Freeing service %s\n",
1502 pservice->szService));
1504 string_free(&pservice->szService);
1505 SAFE_FREE(pservice->copymap);
1507 for (i = 0; parm_table[i].label; i++) {
1508 if ((parm_table[i].type == P_STRING ||
1509 parm_table[i].type == P_USTRING) &&
1510 parm_table[i].class == P_LOCAL)
1511 string_free((char **)
1512 (((char *)pservice) +
1513 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1514 else if (parm_table[i].type == P_LIST &&
1515 parm_table[i].class == P_LOCAL)
1516 str_list_free((char ***)
1517 (((char *)pservice) +
1518 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1521 DEBUG(5,("Freeing parametrics:\n"));
1522 data = pservice->param_opt;
1524 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1525 string_free(&data->key);
1526 string_free(&data->value);
1532 ZERO_STRUCTP(pservice);
1535 /***************************************************************************
1536 Add a new service to the services array initialising it with the given
1538 ***************************************************************************/
1540 static int add_a_service(const service *pservice, const char *name)
1544 int num_to_alloc = iNumServices + 1;
1545 struct param_opt *data, *pdata;
1547 tservice = *pservice;
1549 /* it might already exist */
1551 i = getservicebyname(name, NULL);
1553 /* Clean all parametric options for service */
1554 /* They will be added during parsing again */
1555 data = ServicePtrs[i]->param_opt;
1557 string_free(&data->key);
1558 string_free(&data->value);
1563 ServicePtrs[i]->param_opt = NULL;
1568 /* find an invalid one */
1569 for (i = 0; i < iNumServices; i++)
1570 if (!ServicePtrs[i]->valid)
1573 /* if not, then create one */
1574 if (i == iNumServices) {
1577 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1580 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1585 ServicePtrs[iNumServices] = malloc_p(service);
1587 if (!ServicePtrs[iNumServices]) {
1588 DEBUG(0,("add_a_service: out of memory!\n"));
1594 free_service(ServicePtrs[i]);
1596 ServicePtrs[i]->valid = True;
1598 init_service(ServicePtrs[i]);
1599 copy_service(ServicePtrs[i], &tservice, NULL);
1601 string_set(&ServicePtrs[i]->szService, name);
1605 /***************************************************************************
1606 Add a new home service, with the specified home directory, defaults coming
1608 ***************************************************************************/
1610 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1611 const char *user, const char *pszHomedir)
1616 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1621 if (!(*(ServicePtrs[iDefaultService]->szPath))
1622 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1623 pstrcpy(newHomedir, pszHomedir);
1625 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1626 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1629 string_set(&ServicePtrs[i]->szPath, newHomedir);
1631 if (!(*(ServicePtrs[i]->comment))) {
1633 slprintf(comment, sizeof(comment) - 1,
1634 "Home directory of %s", user);
1635 string_set(&ServicePtrs[i]->comment, comment);
1637 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1638 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1640 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1646 /***************************************************************************
1647 Add a new service, based on an old one.
1648 ***************************************************************************/
1650 int lp_add_service(const char *pszService, int iDefaultService)
1652 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1655 /***************************************************************************
1656 Add the IPC service.
1657 ***************************************************************************/
1659 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1662 int i = add_a_service(&sDefault, name);
1667 slprintf(comment, sizeof(comment) - 1,
1668 "%s Service (%s)", fstype, Globals.szServerString);
1670 string_set(&ServicePtrs[i]->szPath, tmpdir());
1671 string_set(&ServicePtrs[i]->szUsername, "");
1672 string_set(&ServicePtrs[i]->comment, comment);
1673 string_set(&ServicePtrs[i]->fstype, fstype);
1674 ServicePtrs[i]->iMaxConnections = -1;
1675 ServicePtrs[i]->bAvailable = True;
1676 ServicePtrs[i]->bRead_only = True;
1677 ServicePtrs[i]->bGuest_only = False;
1678 ServicePtrs[i]->bGuest_ok = guest_ok;
1679 ServicePtrs[i]->bPrint_ok = False;
1680 ServicePtrs[i]->bBrowseable = False;
1682 if (strcasecmp(fstype, "IPC") == 0) {
1683 lp_do_parameter(i, "ntvfs handler", "default");
1686 DEBUG(3, ("adding hidden service %s\n", name));
1691 /***************************************************************************
1692 Add a new printer service, with defaults coming from service iFrom.
1693 ***************************************************************************/
1695 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1697 const char *comment = "From Printcap";
1698 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1703 /* note that we do NOT default the availability flag to True - */
1704 /* we take it from the default service passed. This allows all */
1705 /* dynamic printers to be disabled by disabling the [printers] */
1706 /* entry (if/when the 'available' keyword is implemented!). */
1708 /* the printer name is set to the service name. */
1709 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1710 string_set(&ServicePtrs[i]->comment, comment);
1711 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1712 /* Printers cannot be read_only. */
1713 ServicePtrs[i]->bRead_only = False;
1714 /* No share modes on printer services. */
1715 ServicePtrs[i]->bShareModes = False;
1716 /* No oplocks on printer services. */
1717 ServicePtrs[i]->bOpLocks = False;
1718 /* Printer services must be printable. */
1719 ServicePtrs[i]->bPrint_ok = True;
1721 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1723 update_server_announce_as_printserver();
1728 /***************************************************************************
1729 Map a parameter's string representation to something we can use.
1730 Returns False if the parameter string is not recognised, else TRUE.
1731 ***************************************************************************/
1733 static int map_parameter(const char *pszParmName)
1737 if (*pszParmName == '-')
1740 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1741 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1744 /* Warn only if it isn't parametric option */
1745 if (strchr(pszParmName, ':') == NULL)
1746 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1747 /* We do return 'fail' for parametric options as well because they are
1748 stored in different storage
1753 /***************************************************************************
1754 Set a boolean variable from the text value stored in the passed string.
1755 Returns True in success, False if the passed string does not correctly
1756 represent a boolean.
1757 ***************************************************************************/
1759 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1764 if (strwicmp(pszParmValue, "yes") == 0 ||
1765 strwicmp(pszParmValue, "true") == 0 ||
1766 strwicmp(pszParmValue, "1") == 0)
1768 else if (strwicmp(pszParmValue, "no") == 0 ||
1769 strwicmp(pszParmValue, "False") == 0 ||
1770 strwicmp(pszParmValue, "0") == 0)
1774 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1781 /***************************************************************************
1782 Find a service by name. Otherwise works like get_service.
1783 ***************************************************************************/
1785 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1789 for (iService = iNumServices - 1; iService >= 0; iService--)
1790 if (VALID(iService) &&
1791 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1792 if (pserviceDest != NULL)
1793 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1800 /***************************************************************************
1801 Copy a service structure to another.
1802 If pcopymapDest is NULL then copy all fields
1803 ***************************************************************************/
1805 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1808 BOOL bcopyall = (pcopymapDest == NULL);
1809 struct param_opt *data, *pdata, *paramo;
1812 for (i = 0; parm_table[i].label; i++)
1813 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1814 (bcopyall || pcopymapDest[i])) {
1815 void *def_ptr = parm_table[i].ptr;
1817 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1820 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1823 switch (parm_table[i].type) {
1826 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1832 *(int *)dest_ptr = *(int *)src_ptr;
1836 *(char *)dest_ptr = *(char *)src_ptr;
1840 string_set(dest_ptr,
1845 string_set(dest_ptr,
1847 strupper(*(char **)dest_ptr);
1850 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1858 init_copymap(pserviceDest);
1859 if (pserviceSource->copymap)
1860 memcpy((void *)pserviceDest->copymap,
1861 (void *)pserviceSource->copymap,
1862 sizeof(BOOL) * NUMPARAMETERS);
1865 data = pserviceSource->param_opt;
1868 pdata = pserviceDest->param_opt;
1869 /* Traverse destination */
1871 /* If we already have same option, override it */
1872 if (strcmp(pdata->key, data->key) == 0) {
1873 string_free(&pdata->value);
1874 pdata->value = strdup(data->value);
1878 pdata = pdata->next;
1881 paramo = smb_xmalloc_p(struct param_opt);
1882 paramo->key = strdup(data->key);
1883 paramo->value = strdup(data->value);
1884 DLIST_ADD(pserviceDest->param_opt, paramo);
1890 /***************************************************************************
1891 Check a service for consistency. Return False if the service is in any way
1892 incomplete or faulty, else True.
1893 ***************************************************************************/
1895 static BOOL service_ok(int iService)
1900 if (ServicePtrs[iService]->szService[0] == '\0') {
1901 DEBUG(0, ("The following message indicates an internal error:\n"));
1902 DEBUG(0, ("No service name in service entry.\n"));
1906 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1907 /* I can't see why you'd want a non-printable printer service... */
1908 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1909 if (!ServicePtrs[iService]->bPrint_ok) {
1910 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1911 ServicePtrs[iService]->szService));
1912 ServicePtrs[iService]->bPrint_ok = True;
1914 /* [printers] service must also be non-browsable. */
1915 if (ServicePtrs[iService]->bBrowseable)
1916 ServicePtrs[iService]->bBrowseable = False;
1919 /* If a service is flagged unavailable, log the fact at level 0. */
1920 if (!ServicePtrs[iService]->bAvailable)
1921 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1922 ServicePtrs[iService]->szService));
1927 static struct file_lists {
1928 struct file_lists *next;
1932 } *file_lists = NULL;
1934 /*******************************************************************
1935 Keep a linked list of all config files so we know when one has changed
1936 it's date and needs to be reloaded.
1937 ********************************************************************/
1939 static void add_to_file_list(const char *fname, const char *subfname)
1941 struct file_lists *f = file_lists;
1944 if (f->name && !strcmp(f->name, fname))
1950 f = malloc_p(struct file_lists);
1953 f->next = file_lists;
1954 f->name = strdup(fname);
1959 f->subfname = strdup(subfname);
1965 f->modtime = file_modtime(subfname);
1967 time_t t = file_modtime(subfname);
1973 /*******************************************************************
1974 Check if a config file has changed date.
1975 ********************************************************************/
1977 BOOL lp_file_list_changed(void)
1979 struct file_lists *f = file_lists;
1980 DEBUG(6, ("lp_file_list_changed()\n"));
1986 pstrcpy(n2, f->name);
1987 standard_sub_basic(n2,sizeof(n2));
1989 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1990 f->name, n2, ctime(&f->modtime)));
1992 mod_time = file_modtime(n2);
1994 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1996 ("file %s modified: %s\n", n2,
1998 f->modtime = mod_time;
1999 SAFE_FREE(f->subfname);
2000 f->subfname = strdup(n2);
2008 /***************************************************************************
2009 Handle the include operation.
2010 ***************************************************************************/
2012 static BOOL handle_include(const char *pszParmValue, char **ptr)
2015 pstrcpy(fname, pszParmValue);
2017 standard_sub_basic(fname,sizeof(fname));
2019 add_to_file_list(pszParmValue, fname);
2021 string_set(ptr, fname);
2023 if (file_exist(fname, NULL))
2024 return (pm_process(fname, do_section, do_parameter));
2026 DEBUG(2, ("Can't find include file %s\n", fname));
2031 /***************************************************************************
2032 Handle the interpretation of the copy parameter.
2033 ***************************************************************************/
2035 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2039 service serviceTemp;
2041 string_set(ptr, pszParmValue);
2043 init_service(&serviceTemp);
2047 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2049 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2050 if (iTemp == iServiceIndex) {
2051 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2053 copy_service(ServicePtrs[iServiceIndex],
2055 ServicePtrs[iServiceIndex]->copymap);
2059 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2063 free_service(&serviceTemp);
2067 /***************************************************************************
2068 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2073 winbind uid = 1000-1999
2074 winbind gid = 700-899
2076 We only do simple parsing checks here. The strings are parsed into useful
2077 structures in the winbind daemon code.
2079 ***************************************************************************/
2081 /* Some lp_ routines to return winbind [ug]id information */
2083 static uid_t winbind_uid_low, winbind_uid_high;
2084 static gid_t winbind_gid_low, winbind_gid_high;
2085 static uint32_t non_unix_account_low, non_unix_account_high;
2087 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2089 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2093 *low = winbind_uid_low;
2096 *high = winbind_uid_high;
2101 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2103 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2107 *low = winbind_gid_low;
2110 *high = winbind_gid_high;
2115 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2117 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2121 *low = non_unix_account_low;
2124 *high = non_unix_account_high;
2129 /* Do some simple checks on "winbind [ug]id" parameter values */
2131 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2135 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2140 string_set(ptr, pszParmValue);
2142 winbind_uid_low = low;
2143 winbind_uid_high = high;
2148 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2152 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2157 string_set(ptr, pszParmValue);
2159 winbind_gid_low = low;
2160 winbind_gid_high = high;
2165 /***************************************************************************
2166 Do some simple checks on "non unix account range" parameter values.
2167 ***************************************************************************/
2169 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2173 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2178 string_set(ptr, pszParmValue);
2180 non_unix_account_low = low;
2181 non_unix_account_high = high;
2187 /***************************************************************************
2188 Initialise a copymap.
2189 ***************************************************************************/
2191 static void init_copymap(service * pservice)
2194 SAFE_FREE(pservice->copymap);
2195 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2196 if (!pservice->copymap)
2198 ("Couldn't allocate copymap!! (size %d)\n",
2199 (int)NUMPARAMETERS));
2201 for (i = 0; i < NUMPARAMETERS; i++)
2202 pservice->copymap[i] = True;
2205 /***************************************************************************
2206 Return the local pointer to a parameter given the service number and the
2207 pointer into the default structure.
2208 ***************************************************************************/
2210 void *lp_local_ptr(int snum, void *ptr)
2212 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2216 /***************************************************************************
2217 Process a parametric option
2218 ***************************************************************************/
2219 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2221 struct param_opt *paramo, *data;
2224 while (isspace(*pszParmName)) {
2228 name = strdup(pszParmName);
2229 if (!name) return False;
2234 data = Globals.param_opt;
2236 data = ServicePtrs[snum]->param_opt;
2239 /* Traverse destination */
2240 for (paramo=data; paramo; paramo=paramo->next) {
2241 /* If we already have the option set, override it unless
2242 it was a command line option and the new one isn't */
2243 if (strcmp(paramo->key, name) == 0) {
2244 if ((paramo->flags & FLAG_CMDLINE) &&
2245 !(flags & FLAG_CMDLINE)) {
2249 free(paramo->value);
2250 paramo->value = strdup(pszParmValue);
2251 paramo->flags = flags;
2257 paramo = smb_xmalloc_p(struct param_opt);
2258 paramo->key = strdup(name);
2259 paramo->value = strdup(pszParmValue);
2260 paramo->flags = flags;
2262 DLIST_ADD(Globals.param_opt, paramo);
2264 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2272 /***************************************************************************
2273 Process a parameter for a particular service number. If snum < 0
2274 then assume we are in the globals.
2275 ***************************************************************************/
2276 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2279 void *parm_ptr = NULL; /* where we are going to store the result */
2280 void *def_ptr = NULL;
2282 parmnum = map_parameter(pszParmName);
2285 if (strchr(pszParmName, ':')) {
2286 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2288 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2292 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2293 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2297 /* if the flag has been set on the command line, then don't allow override,
2298 but don't report an error */
2299 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2303 def_ptr = parm_table[parmnum].ptr;
2305 /* we might point at a service, the default service or a global */
2309 if (parm_table[parmnum].class == P_GLOBAL) {
2311 ("Global parameter %s found in service section!\n",
2316 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2321 if (!ServicePtrs[snum]->copymap)
2322 init_copymap(ServicePtrs[snum]);
2324 /* this handles the aliases - set the copymap for other entries with
2325 the same data pointer */
2326 for (i = 0; parm_table[i].label; i++)
2327 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2328 ServicePtrs[snum]->copymap[i] = False;
2331 /* if it is a special case then go ahead */
2332 if (parm_table[parmnum].special) {
2333 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2337 /* now switch on the type of variable it is */
2338 switch (parm_table[parmnum].type)
2341 set_boolean(parm_ptr, pszParmValue);
2345 set_boolean(parm_ptr, pszParmValue);
2346 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2350 *(int *)parm_ptr = atoi(pszParmValue);
2354 *(char *)parm_ptr = *pszParmValue;
2358 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2362 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2366 string_set(parm_ptr, pszParmValue);
2370 string_set(parm_ptr, pszParmValue);
2371 strupper(*(char **)parm_ptr);
2375 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2378 parm_table[parmnum].enum_list[i].name)) {
2380 parm_table[parmnum].
2385 if (!parm_table[parmnum].enum_list[i].name) {
2386 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2387 pszParmValue, pszParmName));
2398 /***************************************************************************
2399 Process a parameter.
2400 ***************************************************************************/
2402 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2404 if (!bInGlobalSection && bGlobalOnly)
2407 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2408 pszParmName, pszParmValue));
2412 variable argument do parameter
2414 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2416 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2423 s = talloc_vasprintf(NULL, fmt, ap);
2425 ret = do_parameter(pszParmName, s);
2432 set a parameter from the commandline - this is called from command line parameter
2433 parsing code. It sets the parameter then marks the parameter as unable to be modified
2434 by smb.conf processing
2436 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2438 int parmnum = map_parameter(pszParmName);
2441 while (isspace(*pszParmValue)) pszParmValue++;
2444 if (parmnum < 0 && strchr(pszParmName, ':')) {
2445 /* set a parametric option */
2446 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2450 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2454 /* reset the CMDLINE flag in case this has been called before */
2455 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2457 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2461 parm_table[parmnum].flags |= FLAG_CMDLINE;
2463 /* we have to also set FLAG_CMDLINE on aliases */
2464 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2465 parm_table[i].flags |= FLAG_CMDLINE;
2467 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2468 parm_table[i].flags |= FLAG_CMDLINE;
2475 set a option from the commandline in 'a=b' format. Use to support --option
2477 BOOL lp_set_option(const char *option)
2495 ret = lp_set_cmdline(s, p+1);
2501 /***************************************************************************
2502 Print a parameter of the specified type.
2503 ***************************************************************************/
2505 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2511 for (i = 0; p->enum_list[i].name; i++) {
2512 if (*(int *)ptr == p->enum_list[i].value) {
2514 p->enum_list[i].name);
2521 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2525 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2529 fprintf(f, "%d", *(int *)ptr);
2533 fprintf(f, "%c", *(char *)ptr);
2537 if (*(int *)ptr == -1) {
2540 fprintf(f, "0%o", *(int *)ptr);
2545 if ((char ***)ptr && *(char ***)ptr) {
2546 char **list = *(char ***)ptr;
2548 for (; *list; list++)
2549 fprintf(f, "%s%s", *list,
2550 ((*(list+1))?", ":""));
2556 if (*(char **)ptr) {
2557 fprintf(f, "%s", *(char **)ptr);
2565 /***************************************************************************
2566 Check if two parameters are equal.
2567 ***************************************************************************/
2569 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2574 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2579 return (*((int *)ptr1) == *((int *)ptr2));
2582 return (*((char *)ptr1) == *((char *)ptr2));
2585 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2590 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2595 return (p1 == p2 || strequal(p1, p2));
2603 /***************************************************************************
2604 Process a new section (service). At this stage all sections are services.
2605 Later we'll have special sections that permit server parameters to be set.
2606 Returns True on success, False on failure.
2607 ***************************************************************************/
2609 static BOOL do_section(const char *pszSectionName)
2612 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2613 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2616 /* if we've just struck a global section, note the fact. */
2617 bInGlobalSection = isglobal;
2619 /* check for multiple global sections */
2620 if (bInGlobalSection) {
2621 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2625 if (!bInGlobalSection && bGlobalOnly)
2628 /* if we have a current service, tidy it up before moving on */
2631 if (iServiceIndex >= 0)
2632 bRetval = service_ok(iServiceIndex);
2634 /* if all is still well, move to the next record in the services array */
2636 /* We put this here to avoid an odd message order if messages are */
2637 /* issued by the post-processing of a previous section. */
2638 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2640 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2642 DEBUG(0, ("Failed to add a new service\n"));
2651 /***************************************************************************
2652 Determine if a partcular base parameter is currentl set to the default value.
2653 ***************************************************************************/
2655 static BOOL is_default(int i)
2657 if (!defaults_saved)
2659 switch (parm_table[i].type) {
2661 return str_list_compare (parm_table[i].def.lvalue,
2662 *(char ***)parm_table[i].ptr);
2665 return strequal(parm_table[i].def.svalue,
2666 *(char **)parm_table[i].ptr);
2669 return parm_table[i].def.bvalue ==
2670 *(BOOL *)parm_table[i].ptr;
2672 return parm_table[i].def.cvalue ==
2673 *(char *)parm_table[i].ptr;
2677 return parm_table[i].def.ivalue ==
2678 *(int *)parm_table[i].ptr;
2685 /***************************************************************************
2686 Display the contents of the global structure.
2687 ***************************************************************************/
2689 static void dump_globals(FILE *f)
2692 struct param_opt *data;
2694 fprintf(f, "# Global parameters\n[global]\n");
2696 for (i = 0; parm_table[i].label; i++)
2697 if (parm_table[i].class == P_GLOBAL &&
2698 parm_table[i].ptr &&
2699 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2700 if (defaults_saved && is_default(i))
2702 fprintf(f, "\t%s = ", parm_table[i].label);
2703 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2706 if (Globals.param_opt != NULL) {
2707 data = Globals.param_opt;
2709 fprintf(f, "\t%s = %s\n", data->key, data->value);
2716 /***************************************************************************
2717 Display the contents of a single services record.
2718 ***************************************************************************/
2720 static void dump_a_service(service * pService, FILE * f)
2723 struct param_opt *data;
2725 if (pService != &sDefault)
2726 fprintf(f, "\n[%s]\n", pService->szService);
2728 for (i = 0; parm_table[i].label; i++)
2729 if (parm_table[i].class == P_LOCAL &&
2730 parm_table[i].ptr &&
2731 (*parm_table[i].label != '-') &&
2732 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2733 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2735 if (pService == &sDefault) {
2736 if (defaults_saved && is_default(i))
2739 if (equal_parameter(parm_table[i].type,
2740 ((char *)pService) +
2742 ((char *)&sDefault) +
2747 fprintf(f, "\t%s = ", parm_table[i].label);
2748 print_parameter(&parm_table[i],
2749 ((char *)pService) + pdiff, f);
2752 if (pService->param_opt != NULL) {
2753 data = pService->param_opt;
2755 fprintf(f, "\t%s = %s\n", data->key, data->value);
2762 /***************************************************************************
2763 Return info about the next service in a service. snum==-1 gives the globals.
2764 Return NULL when out of parameters.
2765 ***************************************************************************/
2767 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2770 /* do the globals */
2771 for (; parm_table[*i].label; (*i)++) {
2772 if (parm_table[*i].class == P_SEPARATOR)
2773 return &parm_table[(*i)++];
2775 if (!parm_table[*i].ptr
2776 || (*parm_table[*i].label == '-'))
2780 && (parm_table[*i].ptr ==
2781 parm_table[(*i) - 1].ptr))
2784 return &parm_table[(*i)++];
2787 service *pService = ServicePtrs[snum];
2789 for (; parm_table[*i].label; (*i)++) {
2790 if (parm_table[*i].class == P_SEPARATOR)
2791 return &parm_table[(*i)++];
2793 if (parm_table[*i].class == P_LOCAL &&
2794 parm_table[*i].ptr &&
2795 (*parm_table[*i].label != '-') &&
2797 (parm_table[*i].ptr !=
2798 parm_table[(*i) - 1].ptr)))
2801 PTR_DIFF(parm_table[*i].ptr,
2804 if (allparameters ||
2805 !equal_parameter(parm_table[*i].type,
2806 ((char *)pService) +
2808 ((char *)&sDefault) +
2811 return &parm_table[(*i)++];
2821 /***************************************************************************
2822 Return TRUE if the passed service number is within range.
2823 ***************************************************************************/
2825 BOOL lp_snum_ok(int iService)
2827 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2830 /***************************************************************************
2831 Auto-load some home services.
2832 ***************************************************************************/
2834 static void lp_add_auto_services(const char *str)
2839 /***************************************************************************
2840 Auto-load one printer.
2841 ***************************************************************************/
2843 void lp_add_one_printer(char *name, char *comment)
2845 int printers = lp_servicenumber(PRINTERS_NAME);
2848 if (lp_servicenumber(name) < 0) {
2849 lp_add_printer(name, printers);
2850 if ((i = lp_servicenumber(name)) >= 0) {
2851 string_set(&ServicePtrs[i]->comment, comment);
2852 ServicePtrs[i]->autoloaded = True;
2857 /***************************************************************************
2858 Announce ourselves as a print server.
2859 ***************************************************************************/
2861 void update_server_announce_as_printserver(void)
2863 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2866 /***************************************************************************
2867 Have we loaded a services file yet?
2868 ***************************************************************************/
2870 BOOL lp_loaded(void)
2875 /***************************************************************************
2876 Unload unused services.
2877 ***************************************************************************/
2879 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2882 for (i = 0; i < iNumServices; i++) {
2886 if (!snumused || !snumused(smb, i)) {
2887 ServicePtrs[i]->valid = False;
2888 free_service(ServicePtrs[i]);
2893 /***************************************************************************
2895 ***************************************************************************/
2897 void lp_killservice(int iServiceIn)
2899 if (VALID(iServiceIn)) {
2900 ServicePtrs[iServiceIn]->valid = False;
2901 free_service(ServicePtrs[iServiceIn]);
2905 /***************************************************************************
2906 Save the curent values of all global and sDefault parameters into the
2907 defaults union. This allows swat and testparm to show only the
2908 changed (ie. non-default) parameters.
2909 ***************************************************************************/
2911 static void lp_save_defaults(void)
2914 for (i = 0; parm_table[i].label; i++) {
2915 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2917 switch (parm_table[i].type) {
2919 str_list_copy(&(parm_table[i].def.lvalue),
2920 *(const char ***)parm_table[i].ptr);
2924 if (parm_table[i].ptr) {
2925 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2927 parm_table[i].def.svalue = NULL;
2932 parm_table[i].def.bvalue =
2933 *(BOOL *)parm_table[i].ptr;
2936 parm_table[i].def.cvalue =
2937 *(char *)parm_table[i].ptr;
2942 parm_table[i].def.ivalue =
2943 *(int *)parm_table[i].ptr;
2949 defaults_saved = True;
2952 /*******************************************************************
2953 Set the server type we will announce as via nmbd.
2954 ********************************************************************/
2956 static void set_server_role(void)
2958 server_role = ROLE_STANDALONE;
2960 switch (lp_security()) {
2962 if (lp_domain_logons())
2963 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2968 if (lp_domain_logons()) {
2969 if (Globals.bDomainMaster) /* auto or yes */
2970 server_role = ROLE_DOMAIN_PDC;
2972 server_role = ROLE_DOMAIN_BDC;
2975 server_role = ROLE_DOMAIN_MEMBER;
2978 if (lp_domain_logons()) {
2980 if (Globals.bDomainMaster) /* auto or yes */
2981 server_role = ROLE_DOMAIN_PDC;
2983 server_role = ROLE_DOMAIN_BDC;
2987 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2991 DEBUG(10, ("set_server_role: role = "));
2993 switch(server_role) {
2994 case ROLE_STANDALONE:
2995 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2997 case ROLE_DOMAIN_MEMBER:
2998 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3000 case ROLE_DOMAIN_BDC:
3001 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3003 case ROLE_DOMAIN_PDC:
3004 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3009 /***************************************************************************
3010 Load the services array from the services file. Return True on success,
3012 ***************************************************************************/
3014 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3019 struct param_opt *data;
3021 pstrcpy(n2, pszFname);
3022 standard_sub_basic(n2,sizeof(n2));
3024 add_to_file_list(pszFname, n2);
3028 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3030 bInGlobalSection = True;
3031 bGlobalOnly = global_only;
3033 if (Globals.param_opt != NULL) {
3034 struct param_opt *next;
3035 for (data=Globals.param_opt; data; data=next) {
3037 if (data->flags & FLAG_CMDLINE) continue;
3040 DLIST_REMOVE(Globals.param_opt, data);
3052 /* We get sections first, so have to start 'behind' to make up */
3054 bRetval = pm_process(n2, do_section, do_parameter);
3056 /* finish up the last section */
3057 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3059 if (iServiceIndex >= 0)
3060 bRetval = service_ok(iServiceIndex);
3062 lp_add_auto_services(lp_auto_services());
3065 /* When 'restrict anonymous = 2' guest connections to ipc$
3067 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3068 lp_add_hidden("ADMIN$", "DISK", False);
3072 set_default_server_announce_type();
3076 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3077 /* if bWINSsupport is true and we are in the client */
3078 if (in_client && Globals.bWINSsupport) {
3079 lp_do_parameter(-1, "wins server", "127.0.0.1");
3087 /***************************************************************************
3088 Reset the max number of services.
3089 ***************************************************************************/
3091 void lp_resetnumservices(void)
3096 /***************************************************************************
3097 Return the max number of services.
3098 ***************************************************************************/
3100 int lp_numservices(void)
3102 return (iNumServices);
3105 /***************************************************************************
3106 Display the contents of the services array in human-readable form.
3107 ***************************************************************************/
3109 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3114 defaults_saved = False;
3118 dump_a_service(&sDefault, f);
3120 for (iService = 0; iService < maxtoprint; iService++)
3121 lp_dump_one(f, show_defaults, iService);
3124 /***************************************************************************
3125 Display the contents of one service in human-readable form.
3126 ***************************************************************************/
3128 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3131 if (ServicePtrs[snum]->szService[0] == '\0')
3133 dump_a_service(ServicePtrs[snum], f);
3137 /***************************************************************************
3138 Return the number of the service with the given name, or -1 if it doesn't
3139 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3140 getservicebyname()! This works ONLY if all services have been loaded, and
3141 does not copy the found service.
3142 ***************************************************************************/
3144 int lp_servicenumber(const char *pszServiceName)
3147 fstring serviceName;
3150 for (iService = iNumServices - 1; iService >= 0; iService--) {
3151 if (VALID(iService) && ServicePtrs[iService]->szService) {
3153 * The substitution here is used to support %U is
3156 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3157 standard_sub_basic(serviceName,sizeof(serviceName));
3158 if (strequal(serviceName, pszServiceName))
3164 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3169 /*******************************************************************
3170 A useful volume label function.
3171 ********************************************************************/
3172 const char *volume_label(int snum)
3174 const char *ret = lp_volume(snum);
3176 return lp_servicename(snum);
3181 /*******************************************************************
3182 Set the server type we will announce as via nmbd.
3183 ********************************************************************/
3185 static void set_default_server_announce_type(void)
3187 default_server_announce = 0;
3188 default_server_announce |= SV_TYPE_WORKSTATION;
3189 default_server_announce |= SV_TYPE_SERVER;
3190 default_server_announce |= SV_TYPE_SERVER_UNIX;
3192 switch (lp_announce_as()) {
3193 case ANNOUNCE_AS_NT_SERVER:
3194 default_server_announce |= SV_TYPE_SERVER_NT;
3195 /* fall through... */
3196 case ANNOUNCE_AS_NT_WORKSTATION:
3197 default_server_announce |= SV_TYPE_NT;
3199 case ANNOUNCE_AS_WIN95:
3200 default_server_announce |= SV_TYPE_WIN95_PLUS;
3202 case ANNOUNCE_AS_WFW:
3203 default_server_announce |= SV_TYPE_WFW;
3209 switch (lp_server_role()) {
3210 case ROLE_DOMAIN_MEMBER:
3211 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3213 case ROLE_DOMAIN_PDC:
3214 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3216 case ROLE_DOMAIN_BDC:
3217 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3219 case ROLE_STANDALONE:
3223 if (lp_time_server())
3224 default_server_announce |= SV_TYPE_TIME_SOURCE;
3226 if (lp_host_msdfs())
3227 default_server_announce |= SV_TYPE_DFS_SERVER;
3230 /***********************************************************
3231 returns role of Samba server
3232 ************************************************************/
3234 int lp_server_role(void)
3239 /***********************************************************
3240 If we are PDC then prefer us as DMB
3241 ************************************************************/
3243 BOOL lp_domain_master(void)
3245 if (Globals.bDomainMaster == Auto)
3246 return (lp_server_role() == ROLE_DOMAIN_PDC);
3248 return Globals.bDomainMaster;
3251 /***********************************************************
3252 If we are DMB then prefer us as LMB
3253 ************************************************************/
3255 BOOL lp_preferred_master(void)
3257 if (Globals.bPreferredMaster == Auto)
3258 return (lp_local_master() && lp_domain_master());
3260 return Globals.bPreferredMaster;
3263 /*******************************************************************
3265 ********************************************************************/
3267 void lp_remove_service(int snum)
3269 ServicePtrs[snum]->valid = False;
3272 /*******************************************************************
3274 ********************************************************************/
3276 void lp_copy_service(int snum, const char *new_name)
3278 const char *oldname = lp_servicename(snum);
3279 do_section(new_name);
3281 snum = lp_servicenumber(new_name);
3283 lp_do_parameter(snum, "copy", oldname);
3288 /*******************************************************************
3289 Get the default server type we will announce as via nmbd.
3290 ********************************************************************/
3291 int lp_default_server_announce(void)
3293 return default_server_announce;
3296 const char *lp_printername(int snum)
3298 const char *ret = _lp_printername(snum);
3299 if (ret == NULL || (ret != NULL && *ret == '\0'))
3300 ret = lp_const_servicename(snum);
3306 /*******************************************************************
3307 Return the max print jobs per queue.
3308 ********************************************************************/
3310 int lp_maxprintjobs(int snum)
3312 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3313 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3314 maxjobs = PRINT_MAX_JOBID - 1;