2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * This module provides suitable callback functions for the params
33 * module. It builds the internal table of service details which is
34 * then used by the rest of the server.
38 * 1) add it to the global or service structure definition
39 * 2) add it to the parm_table
40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41 * 4) If it's a global then initialise it in init_globals. If a local
42 * (ie. service) parameter then initialise it in the sDefault structure
46 * The configuration file is processed sequentially for speed. It is NOT
47 * accessed randomly as happens in 'real' Windows. For this reason, there
48 * is a fair bit of sequence-dependent code here - ie., code which assumes
49 * that certain things happen before others. In particular, the code which
50 * happens at the boundary between sections is delicately poised, so be
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/iconv.h"
60 #include "system/network.h"
61 #include "system/printing.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "librpc/gen_ndr/ndr_nbt.h"
65 #include "dlinklist.h"
66 #include "param/loadparm.h"
68 BOOL in_client = False; /* Not in the client by default */
69 static BOOL bLoaded = False;
72 #define GLOBAL_NAME "global"
76 #define PRINTERS_NAME "printers"
80 #define HOMES_NAME "homes"
83 /* some helpful bits */
84 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
85 #define VALID(i) ServicePtrs[i]->valid
87 static BOOL do_parameter(const char *, const char *);
88 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
90 static BOOL defaults_saved = False;
93 #define FLAG_BASIC 0x0001 /* fundamental options */
94 #define FLAG_SHARE 0x0002 /* file sharing options */
95 #define FLAG_PRINT 0x0004 /* printing options */
96 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
97 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
98 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
99 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
100 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
101 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
102 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
103 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
109 struct param_opt *prev, *next;
116 * This structure describes global (ie., server-wide) parameters.
124 char *display_charset;
125 char *szPrintcapname;
129 char *szDefaultService;
131 char *szServerString;
132 char *szAutoServices;
133 char *szPasswdProgram;
137 char *szSMBPasswdFile;
142 char **szPreloadModules;
143 char **szPasswordServers;
144 char *szSocketOptions;
151 char **szWINSservers;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szAnnounceVersion; /* This is initialised in init_globals */
159 char **szNetbiosAliases;
160 char *szNetbiosScope;
161 char *szDomainOtherSIDs;
162 char **szNameResolveOrder;
164 char *szAddUserScript;
165 char *szAddMachineScript;
167 char *szWINSPartners;
168 char **dcerpc_ep_servers;
169 char **server_services;
172 char *szNonUnixAccountRange;
173 char *szTemplateHomedir;
174 char *szTemplateShell;
175 char *szWinbindSeparator;
176 BOOL bWinbindEnumUsers;
177 BOOL bWinbindEnumGroups;
178 BOOL bWinbindUseDefaultDomain;
179 char *szIDMapBackend;
180 char *szGuestaccount;
181 char *swat_directory;
190 BOOL paranoid_server_security;
192 BOOL bDisableSpoolss;
194 int enhanced_browsing;
201 int announce_as; /* This is initialised in init_globals */
202 int machine_password_timeout;
203 int winbind_cache_time;
210 char *socket_options;
215 BOOL bPreferredMaster;
218 BOOL bEncryptPasswords;
220 BOOL bObeyPamRestrictions;
222 BOOL bLargeReadwrite;
226 BOOL bBindInterfacesOnly;
227 BOOL bPamPasswordChange;
229 BOOL bNTStatusSupport;
230 BOOL bAllowTrustedDomains;
236 BOOL bClientLanManAuth;
237 BOOL bClientNTLMv2Auth;
239 BOOL bHideLocalUsers;
242 BOOL bHostnameLookups;
243 BOOL bUnixExtensions;
244 BOOL bDisableNetbios;
246 int restrict_anonymous;
247 int name_cache_timeout;
248 struct param_opt *param_opt;
252 static global Globals;
255 * This structure describes a single service.
264 char **szInvalidUsers;
269 char *szPrintcommand;
272 char *szLppausecommand;
273 char *szLpresumecommand;
274 char *szQueuepausecommand;
275 char *szQueueresumecommand;
283 char **ntvfs_handler;
309 struct param_opt *param_opt;
311 char dummy[3]; /* for alignment */
316 /* This is a default service used to prime a services structure */
317 static service sDefault = {
319 False, /* not autoloaded */
320 NULL, /* szService */
322 NULL, /* szUsername */
323 NULL, /* szInvalidUsers */
324 NULL, /* szValidUsers */
325 NULL, /* szAdminUsers */
327 NULL, /* szInclude */
328 NULL, /* szPrintcommand */
329 NULL, /* szLpqcommand */
330 NULL, /* szLprmcommand */
331 NULL, /* szLppausecommand */
332 NULL, /* szLpresumecommand */
333 NULL, /* szQueuepausecommand */
334 NULL, /* szQueueresumecommand */
335 NULL, /* szPrintername */
336 NULL, /* szHostsallow */
337 NULL, /* szHostsdeny */
341 NULL, /* szMSDfsProxy */
342 NULL, /* ntvfs_handler */
343 0, /* iMinPrintSpace */
344 1000, /* iMaxPrintJobs */
345 0, /* iMaxConnections */
346 DEFAULT_PRINTING, /* iPrinting */
348 True, /* bAvailable */
349 True, /* bBrowseable */
350 True, /* bRead_only */
351 False, /* bPrint_ok */
352 False, /* bMap_system */
353 False, /* bMap_hidden */
354 True, /* bMap_archive */
356 True, /* bStrictLocking */
357 True, /* bPosixLocking */
359 True, /* bLevel2OpLocks */
360 False, /* bOnlyUser */
361 False, /* bGuest_only */
362 False, /* bGuest_ok */
364 False, /* bMSDfsRoot */
365 True, /* bShareModes */
366 False, /* bStrictSync */
367 False, /* bCIFileSystem */
368 NULL, /* Parametric options */
373 /* local variables */
374 static service **ServicePtrs = NULL;
375 static int iNumServices = 0;
376 static int iServiceIndex = 0;
377 static BOOL bInGlobalSection = True;
378 static BOOL bGlobalOnly = False;
379 static int server_role;
380 static int default_server_announce;
382 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
384 /* prototypes for the special type handlers */
385 static BOOL handle_include(const char *pszParmValue, char **ptr);
386 static BOOL handle_copy(const char *pszParmValue, char **ptr);
387 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
388 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
389 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
391 static void set_server_role(void);
392 static void set_default_server_announce_type(void);
394 static const struct enum_list enum_protocol[] = {
395 {PROTOCOL_NT1, "NT1"},
396 {PROTOCOL_LANMAN2, "LANMAN2"},
397 {PROTOCOL_LANMAN1, "LANMAN1"},
398 {PROTOCOL_CORE, "CORE"},
399 {PROTOCOL_COREPLUS, "COREPLUS"},
400 {PROTOCOL_COREPLUS, "CORE+"},
404 static const struct enum_list enum_security[] = {
405 {SEC_SHARE, "SHARE"},
407 {SEC_SERVER, "SERVER"},
408 {SEC_DOMAIN, "DOMAIN"},
415 static const struct enum_list enum_printing[] = {
416 {PRINT_SYSV, "sysv"},
418 {PRINT_HPUX, "hpux"},
422 {PRINT_LPRNG, "lprng"},
423 {PRINT_SOFTQ, "softq"},
424 {PRINT_CUPS, "cups"},
426 {PRINT_LPROS2, "os2"},
428 {PRINT_TEST, "test"},
430 #endif /* DEVELOPER */
434 /* Types of machine we can announce as. */
435 #define ANNOUNCE_AS_NT_SERVER 1
436 #define ANNOUNCE_AS_WIN95 2
437 #define ANNOUNCE_AS_WFW 3
438 #define ANNOUNCE_AS_NT_WORKSTATION 4
440 static const struct enum_list enum_announce_as[] = {
441 {ANNOUNCE_AS_NT_SERVER, "NT"},
442 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
443 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
444 {ANNOUNCE_AS_WIN95, "win95"},
445 {ANNOUNCE_AS_WFW, "WfW"},
449 static const struct enum_list enum_bool_auto[] = {
460 /* Client-side offline caching policy types */
461 #define CSC_POLICY_MANUAL 0
462 #define CSC_POLICY_DOCUMENTS 1
463 #define CSC_POLICY_PROGRAMS 2
464 #define CSC_POLICY_DISABLE 3
466 static const struct enum_list enum_csc_policy[] = {
467 {CSC_POLICY_MANUAL, "manual"},
468 {CSC_POLICY_DOCUMENTS, "documents"},
469 {CSC_POLICY_PROGRAMS, "programs"},
470 {CSC_POLICY_DISABLE, "disable"},
474 /* SMB signing types. */
475 static const struct enum_list enum_smb_signing_vals[] = {
476 {SMB_SIGNING_OFF, "No"},
477 {SMB_SIGNING_OFF, "False"},
478 {SMB_SIGNING_OFF, "0"},
479 {SMB_SIGNING_OFF, "Off"},
480 {SMB_SIGNING_OFF, "disabled"},
481 {SMB_SIGNING_SUPPORTED, "Yes"},
482 {SMB_SIGNING_SUPPORTED, "True"},
483 {SMB_SIGNING_SUPPORTED, "1"},
484 {SMB_SIGNING_SUPPORTED, "On"},
485 {SMB_SIGNING_SUPPORTED, "enabled"},
486 {SMB_SIGNING_REQUIRED, "required"},
487 {SMB_SIGNING_REQUIRED, "mandatory"},
488 {SMB_SIGNING_REQUIRED, "force"},
489 {SMB_SIGNING_REQUIRED, "forced"},
490 {SMB_SIGNING_REQUIRED, "enforced"},
491 {SMB_SIGNING_AUTO, "auto"},
496 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
498 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
499 * is implied in current control logic. This may change at some later time. A
500 * flag value of 0 means - show as development option only.
502 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
503 * screen in SWAT. This is used to exclude parameters as well as to squash all
504 * parameters that have been duplicated by pseudonyms.
506 static struct parm_struct parm_table[] = {
507 {"Base Options", P_SEP, P_SEPARATOR},
509 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
510 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
511 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
512 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
513 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
514 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
515 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
516 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
517 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
518 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
519 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
520 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
521 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
522 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
523 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
524 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
525 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
526 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
527 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
529 {"Security Options", P_SEP, P_SEPARATOR},
531 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
532 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
533 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
534 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
538 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
539 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
540 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
549 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
558 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
563 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
564 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
566 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
567 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
568 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
570 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
572 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
574 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
576 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
577 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
578 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
579 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
581 {"Logging Options", P_SEP, P_SEPARATOR},
583 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
585 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"Protocol Options", P_SEP, P_SEPARATOR},
589 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
590 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
591 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
592 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
593 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
594 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
595 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
596 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
597 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
598 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
599 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
600 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
601 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
603 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
605 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
606 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
607 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
608 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
611 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
612 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
614 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
615 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
616 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
617 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
618 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
619 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
621 {"Tuning Options", P_SEP, P_SEPARATOR},
623 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
624 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
625 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
626 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
628 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
629 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
630 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
634 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
636 {"Printing Options", P_SEP, P_SEPARATOR},
638 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
639 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
640 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
641 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
642 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
643 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
644 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
645 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
646 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
647 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
648 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
649 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
650 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
651 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
652 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
654 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
655 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
657 {"Filename Handling", P_SEP, P_SEPARATOR},
659 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
660 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
661 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
663 {"Domain Options", P_SEP, P_SEPARATOR},
665 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
667 {"Logon Options", P_SEP, P_SEPARATOR},
669 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
670 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
672 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
673 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
674 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
675 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
676 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
678 {"Browse Options", P_SEP, P_SEPARATOR},
680 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
681 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
682 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
683 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
684 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
685 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
686 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
687 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
688 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
689 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
691 {"WINS Options", P_SEP, P_SEPARATOR},
692 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
696 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
697 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
700 {"Locking Options", P_SEP, P_SEPARATOR},
702 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
703 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
704 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
705 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
707 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
708 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
709 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
710 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
711 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
713 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
715 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
716 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
717 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
718 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
719 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
720 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
722 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
723 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
724 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
725 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
726 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
727 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
728 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
730 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
731 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
733 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
734 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
735 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
737 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
741 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
742 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"Winbind options", P_SEP, P_SEPARATOR},
745 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
748 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
750 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
751 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
752 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
753 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
758 /***************************************************************************
759 Initialise the sDefault parameter structure for the printer values.
760 ***************************************************************************/
762 static void init_printer_values(void)
764 /* choose defaults depending on the type of printing */
765 switch (sDefault.iPrinting) {
770 do_parameter("Lpqcommand", "lpq -P'%p'");
771 do_parameter("Lprmcommand", "lprm -P'%p' %j");
772 do_parameter("Printcommand",
778 do_parameter("Lpqcommand", "lpq -P'%p'");
779 do_parameter("Lprmcommand", "lprm -P'%p' %j");
780 do_parameter("Printcommand",
782 do_parameter("Queuepausecommand",
784 do_parameter("Queueresumecommand",
786 do_parameter("Lppausecommand",
788 do_parameter("Lpresumecommand",
789 "lpc release '%p' %j");
794 do_parameter("Lpqcommand", "");
795 do_parameter("Lprmcommand", "");
796 do_parameter("Printcommand", "");
797 do_parameter("Lppausecommand", "");
798 do_parameter("Lpresumecommand", "");
799 do_parameter("Queuepausecommand", "");
800 do_parameter("Queueresumecommand", "");
802 do_parameter("Printcapname", "cups");
804 do_parameter("Lpqcommand",
805 "/usr/bin/lpstat -o '%p'");
806 do_parameter("Lprmcommand",
807 "/usr/bin/cancel '%p-%j'");
808 do_parameter("Printcommand",
809 "/usr/bin/lp -d '%p' %s; rm %s");
810 do_parameter("Lppausecommand",
811 "lp -i '%p-%j' -H hold");
812 do_parameter("Lpresumecommand",
813 "lp -i '%p-%j' -H resume");
814 do_parameter("Queuepausecommand",
815 "/usr/bin/disable '%p'");
816 do_parameter("Queueresumecommand",
817 "/usr/bin/enable '%p'");
818 do_parameter("Printcapname", "lpstat");
819 #endif /* HAVE_CUPS */
824 do_parameter("Lpqcommand", "lpstat -o%p");
825 do_parameter("Lprmcommand", "cancel %p-%j");
826 do_parameter("Printcommand",
827 "lp -c -d%p %s; rm %s");
828 do_parameter("Queuepausecommand",
830 do_parameter("Queueresumecommand",
833 do_parameter("Lppausecommand",
834 "lp -i %p-%j -H hold");
835 do_parameter("Lpresumecommand",
836 "lp -i %p-%j -H resume");
841 do_parameter("Lpqcommand", "lpq -P%p");
842 do_parameter("Lprmcommand", "lprm -P%p %j");
843 do_parameter("Printcommand", "lp -r -P%p %s");
847 do_parameter("Lpqcommand", "qstat -l -d%p");
848 do_parameter("Lprmcommand",
850 do_parameter("Printcommand",
851 "lp -d%p -s %s; rm %s");
852 do_parameter("Lppausecommand",
854 do_parameter("Lpresumecommand",
860 do_parameter("Printcommand", "vlp print %p %s");
861 do_parameter("Lpqcommand", "vlp lpq %p");
862 do_parameter("Lprmcommand", "vlp lprm %p %j");
863 do_parameter("Lppausecommand", "vlp lppause %p %j");
864 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
865 do_parameter("Queuepausecommand", "vlp queuepause %p");
866 do_parameter("Queueresumecommand", "vlp queueresume %p");
868 #endif /* DEVELOPER */
874 /***************************************************************************
875 Initialise the global parameter structure.
876 ***************************************************************************/
877 static void init_globals(void)
882 DEBUG(3, ("Initialising global parameters\n"));
884 for (i = 0; parm_table[i].label; i++) {
885 if ((parm_table[i].type == P_STRING ||
886 parm_table[i].type == P_USTRING) &&
888 !(parm_table[i].flags & FLAG_CMDLINE)) {
889 string_set(parm_table[i].ptr, "");
893 /* options that can be set on the command line must be initialised via
894 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
896 do_parameter("socket options", "TCP_NODELAY");
898 do_parameter("workgroup", DEFAULT_WORKGROUP);
899 myname = get_myname();
900 do_parameter("netbios name", myname);
902 do_parameter("max protocol", "NT1");
903 do_parameter("name resolve order", "lmhosts wins host bcast");
905 init_printer_values();
907 do_parameter("fstype", FSTYPE_STRING);
908 do_parameter("ntvfs handler", "unixuid default");
909 do_parameter("max connections", "-1");
911 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
912 do_parameter("server services", "smb rpc nbt ldap cldap web");
913 do_parameter("auth methods", "anonymous sam_ignoredomain");
914 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
915 do_parameter("private dir", dyn_PRIVATE_DIR);
916 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
917 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
918 do_parameter_var("wins database", "tdb://%s/wins.ldb", dyn_PRIVATE_DIR);
919 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
920 do_parameter("guest account", GUEST_ACCOUNT);
922 /* using UTF8 by default allows us to support all chars */
923 do_parameter("unix charset", "UTF8");
925 /* Use codepage 850 as a default for the dos character set */
926 do_parameter("dos charset", "CP850");
929 * Allow the default PASSWD_CHAT to be overridden in local.h.
931 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
933 do_parameter("passwd program", "");
934 do_parameter("printcap name", PRINTCAP_NAME);
936 do_parameter("pid directory", dyn_PIDDIR);
937 do_parameter("lock dir", dyn_LOCKDIR);
938 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
940 do_parameter("socket address", "0.0.0.0");
941 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
943 do_parameter_var("announce version", "%d.%d",
944 DEFAULT_MAJOR_VERSION,
945 DEFAULT_MINOR_VERSION);
947 do_parameter("logon drive", "");
949 do_parameter("logon home", "\\\\%N\\%U");
950 do_parameter("logon path", "\\\\%N\\%U\\profile");
951 do_parameter("password server", "*");
953 do_parameter("load printers", "True");
955 do_parameter("max mux", "50");
956 do_parameter("max xmit", "12288");
957 do_parameter("lpqcachetime", "10");
958 do_parameter("DisableSpoolss", "False");
959 do_parameter("password level", "0");
960 do_parameter("username level", "0");
961 do_parameter("LargeReadwrite", "True");
962 do_parameter("minprotocol", "CORE");
963 do_parameter("security", "USER");
964 do_parameter("paranoid server security", "True");
965 do_parameter("EncryptPasswords", "True");
966 do_parameter("ReadRaw", "True");
967 do_parameter("WriteRaw", "True");
968 do_parameter("NullPasswords", "False");
969 do_parameter("ObeyPamRestrictions", "False");
970 do_parameter("lm announce", "Auto");
971 do_parameter("lm interval", "60");
972 do_parameter("announce as", "NT SERVER");
974 do_parameter("TimeServer", "False");
975 do_parameter("BindInterfacesOnly", "False");
976 do_parameter("PamPasswordChange", "False");
977 do_parameter("Unicode", "True");
978 do_parameter("restrict anonymous", "0");
979 do_parameter("ClientLanManAuth", "True");
980 do_parameter("LanmanAuth", "True");
981 do_parameter("NTLMAuth", "True");
983 do_parameter("enhanced browsing", "True");
984 do_parameter("LockSpinCount", "3");
985 do_parameter("LockSpinTime", "10");
986 #ifdef MMAP_BLACKLIST
987 do_parameter("UseMmap", "False");
989 do_parameter("UseMmap", "True");
991 do_parameter("UnixExtensions", "False");
993 /* hostname lookups can be very expensive and are broken on
994 a large number of sites (tridge) */
995 do_parameter("HostnameLookups", "False");
997 do_parameter("PreferredMaster", "Auto");
998 do_parameter("os level", "20");
999 do_parameter("LocalMaster", "True");
1000 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1001 do_parameter("DomainLogons", "False");
1002 do_parameter("WINSsupport", "False");
1003 do_parameter("WINSproxy", "False");
1005 do_parameter("DNSproxy", "True");
1007 do_parameter("AllowTrustedDomains", "True");
1009 do_parameter("TemplateShell", "/bin/false");
1010 do_parameter("TemplateHomedir", "/home/%D/%U");
1011 do_parameter("WinbindSeparator", "\\");
1013 do_parameter("winbind cache time", "15");
1014 do_parameter("WinbindEnumUsers", "True");
1015 do_parameter("WinbindEnumGroups", "True");
1016 do_parameter("WinbindUseDefaultDomain", "False");
1018 do_parameter("IDMapBackend", "tdb");
1020 do_parameter("name cache timeout", "660"); /* In seconds */
1022 do_parameter("client signing", "Yes");
1023 do_parameter("server signing", "auto");
1025 do_parameter("use spnego", "True");
1027 do_parameter("smb ports", SMB_PORTS);
1028 do_parameter("nbt port", "137");
1029 do_parameter("dgram port", "138");
1030 do_parameter("cldap port", "389");
1031 do_parameter("web port", "901");
1032 do_parameter("swat directory", dyn_SWATDIR);
1034 do_parameter("nt status support", "True");
1036 do_parameter("max wins ttl", "432000");
1037 do_parameter("min wins ttl", "10");
1040 static TALLOC_CTX *lp_talloc;
1042 /******************************************************************* a
1043 Free up temporary memory - called from the main loop.
1044 ********************************************************************/
1046 void lp_talloc_free(void)
1050 talloc_free(lp_talloc);
1054 /*******************************************************************
1055 Convenience routine to grab string parameters into temporary memory
1056 and run standard_sub_basic on them. The buffers can be written to by
1057 callers without affecting the source string.
1058 ********************************************************************/
1060 static const char *lp_string(const char *s)
1062 #if 0 /* until REWRITE done to make thread-safe */
1063 size_t len = s ? strlen(s) : 0;
1067 /* The follow debug is useful for tracking down memory problems
1068 especially if you have an inner loop that is calling a lp_*()
1069 function that returns a string. Perhaps this debug should be
1070 present all the time? */
1073 DEBUG(10, ("lp_string(%s)\n", s));
1076 #if 0 /* until REWRITE done to make thread-safe */
1078 lp_talloc = talloc_init("lp_talloc");
1080 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1088 StrnCpy(ret, s, len);
1090 if (trim_string(ret, "\"", "\"")) {
1091 if (strchr(ret,'"') != NULL)
1092 StrnCpy(ret, s, len);
1095 standard_sub_basic(ret,len+100);
1102 In this section all the functions that are used to access the
1103 parameters from the rest of the program are defined
1106 #define FN_GLOBAL_STRING(fn_name,ptr) \
1107 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1108 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1109 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1110 #define FN_GLOBAL_LIST(fn_name,ptr) \
1111 const char **fn_name(void) {return(*(const char ***)(ptr));}
1112 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1113 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1114 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1115 char fn_name(void) {return(*(char *)(ptr));}
1116 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1117 int fn_name(void) {return(*(int *)(ptr));}
1119 #define FN_LOCAL_STRING(fn_name,val) \
1120 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1121 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1122 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1123 #define FN_LOCAL_LIST(fn_name,val) \
1124 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1125 #define FN_LOCAL_BOOL(fn_name,val) \
1126 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1127 #define FN_LOCAL_CHAR(fn_name,val) \
1128 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1129 #define FN_LOCAL_INTEGER(fn_name,val) \
1130 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1132 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1133 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1134 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
1135 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
1136 FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
1137 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1138 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
1139 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1140 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1141 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1142 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1143 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1144 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1145 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1146 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
1147 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1148 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1149 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1150 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1151 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1152 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1153 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1154 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1155 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1156 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1157 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1158 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1159 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1160 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1161 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1162 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1163 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1164 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1165 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1166 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1167 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1168 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1169 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1170 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1171 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1172 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1173 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1174 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1175 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1176 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1177 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1178 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1179 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1180 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1181 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1183 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1185 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1187 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1188 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1189 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1190 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1191 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1192 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1193 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1194 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1195 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1197 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1198 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1199 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1200 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1201 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1202 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1203 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1204 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1205 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1206 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1207 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1208 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1209 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1210 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1211 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1212 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1213 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1214 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1215 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1216 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1217 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1218 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1219 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1220 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1221 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1222 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1223 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1224 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1225 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1226 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1227 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1228 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1229 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1230 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1231 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1232 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1233 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1234 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1235 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1236 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1237 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1238 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1239 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1240 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1241 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1242 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1243 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1244 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1245 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1246 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1247 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1248 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1249 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1250 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1251 FN_LOCAL_STRING(lp_servicename, szService)
1252 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1253 FN_LOCAL_STRING(lp_pathname, szPath)
1254 FN_LOCAL_STRING(lp_username, szUsername)
1255 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1256 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1257 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1258 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1259 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1260 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1261 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1262 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1263 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1264 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1265 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1266 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1267 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1268 FN_LOCAL_STRING(lp_comment, comment)
1269 FN_LOCAL_STRING(lp_fstype, fstype)
1270 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1271 static FN_LOCAL_STRING(lp_volume, volume)
1272 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1273 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1274 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1275 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1276 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1277 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1278 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1279 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1280 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1281 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1282 FN_LOCAL_BOOL(lp_locking, bLocking)
1283 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1284 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1285 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1286 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1287 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1288 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1289 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1290 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1291 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1292 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1293 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1294 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1295 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1296 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1297 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1298 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1299 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1300 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1302 /* local prototypes */
1304 static int map_parameter(const char *pszParmName);
1305 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1306 static int getservicebyname(const char *pszServiceName,
1307 service * pserviceDest);
1308 static void copy_service(service * pserviceDest,
1309 service * pserviceSource, BOOL *pcopymapDest);
1310 static BOOL service_ok(int iService);
1311 static BOOL do_section(const char *pszSectionName);
1312 static void init_copymap(service * pservice);
1314 /* This is a helper function for parametrical options support. */
1315 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1316 /* Actual parametrical functions are quite simple */
1317 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
1320 struct param_opt *data;
1322 if (lookup_service >= iNumServices) return NULL;
1324 data = (lookup_service < 0) ?
1325 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1327 asprintf(&vfskey, "%s:%s", type, option);
1331 if (strcmp(data->key, vfskey) == 0) {
1338 if (lookup_service >= 0) {
1339 /* Try to fetch the same option but from globals */
1340 /* but only if we are not already working with Globals */
1341 data = Globals.param_opt;
1343 if (strcmp(data->key, vfskey) == 0) {
1357 /*******************************************************************
1358 convenience routine to return int parameters.
1359 ********************************************************************/
1360 static int lp_int(const char *s)
1364 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1371 /*******************************************************************
1372 convenience routine to return unsigned long parameters.
1373 ********************************************************************/
1374 static int lp_ulong(const char *s)
1378 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1382 return strtoul(s, NULL, 10);
1385 /*******************************************************************
1386 convenience routine to return boolean parameters.
1387 ********************************************************************/
1388 static BOOL lp_bool(const char *s)
1393 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1397 if (!set_boolean(&ret,s)) {
1398 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1406 /* Return parametric option from a given service. Type is a part of option before ':' */
1407 /* Parametric option has following syntax: 'Type: option = value' */
1408 /* Returned value is allocated in 'lp_talloc' context */
1410 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1412 const char *value = lp_get_parametric(lookup_service, type, option);
1415 return lp_string(value);
1420 /* Return parametric option from a given service. Type is a part of option before ':' */
1421 /* Parametric option has following syntax: 'Type: option = value' */
1422 /* Returned value is allocated in 'lp_talloc' context */
1424 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1425 const char *separator)
1427 const char *value = lp_get_parametric(lookup_service, type, option);
1430 return str_list_make(talloc_autofree_context(), value, separator);
1435 /* Return parametric option from a given service. Type is a part of option before ':' */
1436 /* Parametric option has following syntax: 'Type: option = value' */
1438 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1440 const char *value = lp_get_parametric(lookup_service, type, option);
1443 return lp_int(value);
1448 /* Return parametric option from a given service. Type is a part of option before ':' */
1449 /* Parametric option has following syntax: 'Type: option = value' */
1451 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1453 const char *value = lp_get_parametric(lookup_service, type, option);
1456 return lp_ulong(value);
1461 /* Return parametric option from a given service. Type is a part of option before ':' */
1462 /* Parametric option has following syntax: 'Type: option = value' */
1464 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1466 const char *value = lp_get_parametric(lookup_service, type, option);
1469 return lp_bool(value);
1475 /***************************************************************************
1476 Initialise a service to the defaults.
1477 ***************************************************************************/
1479 static void init_service(service * pservice)
1481 memset((char *)pservice, '\0', sizeof(service));
1482 copy_service(pservice, &sDefault, NULL);
1485 /***************************************************************************
1486 Free the dynamically allocated parts of a service struct.
1487 ***************************************************************************/
1489 static void free_service(service *pservice)
1492 struct param_opt *data, *pdata;
1496 if (pservice->szService)
1497 DEBUG(5, ("free_service: Freeing service %s\n",
1498 pservice->szService));
1500 string_free(&pservice->szService);
1501 SAFE_FREE(pservice->copymap);
1503 for (i = 0; parm_table[i].label; i++) {
1504 if ((parm_table[i].type == P_STRING ||
1505 parm_table[i].type == P_USTRING) &&
1506 parm_table[i].class == P_LOCAL) {
1507 string_free((char **)
1508 (((char *)pservice) +
1509 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1510 } else if (parm_table[i].type == P_LIST &&
1511 parm_table[i].class == P_LOCAL) {
1512 char ***listp = (char ***)(((char *)pservice) +
1513 PTR_DIFF(parm_table[i].ptr, &sDefault));
1514 talloc_free(*listp);
1519 DEBUG(5,("Freeing parametrics:\n"));
1520 data = pservice->param_opt;
1522 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1523 string_free(&data->key);
1524 string_free(&data->value);
1530 ZERO_STRUCTP(pservice);
1533 /***************************************************************************
1534 Add a new service to the services array initialising it with the given
1536 ***************************************************************************/
1538 static int add_a_service(const service *pservice, const char *name)
1542 int num_to_alloc = iNumServices + 1;
1543 struct param_opt *data, *pdata;
1545 tservice = *pservice;
1547 /* it might already exist */
1549 i = getservicebyname(name, NULL);
1551 /* Clean all parametric options for service */
1552 /* They will be added during parsing again */
1553 data = ServicePtrs[i]->param_opt;
1555 string_free(&data->key);
1556 string_free(&data->value);
1561 ServicePtrs[i]->param_opt = NULL;
1566 /* find an invalid one */
1567 for (i = 0; i < iNumServices; i++)
1568 if (!ServicePtrs[i]->valid)
1571 /* if not, then create one */
1572 if (i == iNumServices) {
1575 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1578 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1583 ServicePtrs[iNumServices] = malloc_p(service);
1585 if (!ServicePtrs[iNumServices]) {
1586 DEBUG(0,("add_a_service: out of memory!\n"));
1592 free_service(ServicePtrs[i]);
1594 ServicePtrs[i]->valid = True;
1596 init_service(ServicePtrs[i]);
1597 copy_service(ServicePtrs[i], &tservice, NULL);
1599 string_set(&ServicePtrs[i]->szService, name);
1603 /***************************************************************************
1604 Add a new home service, with the specified home directory, defaults coming
1606 ***************************************************************************/
1608 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1609 const char *user, const char *pszHomedir)
1614 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1619 if (!(*(ServicePtrs[iDefaultService]->szPath))
1620 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1621 pstrcpy(newHomedir, pszHomedir);
1623 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1624 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1627 string_set(&ServicePtrs[i]->szPath, newHomedir);
1629 if (!(*(ServicePtrs[i]->comment))) {
1631 slprintf(comment, sizeof(comment) - 1,
1632 "Home directory of %s", user);
1633 string_set(&ServicePtrs[i]->comment, comment);
1635 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1636 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1638 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1644 /***************************************************************************
1645 Add a new service, based on an old one.
1646 ***************************************************************************/
1648 int lp_add_service(const char *pszService, int iDefaultService)
1650 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1653 /***************************************************************************
1654 Add the IPC service.
1655 ***************************************************************************/
1657 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1660 int i = add_a_service(&sDefault, name);
1665 slprintf(comment, sizeof(comment) - 1,
1666 "%s Service (%s)", fstype, Globals.szServerString);
1668 string_set(&ServicePtrs[i]->szPath, tmpdir());
1669 string_set(&ServicePtrs[i]->szUsername, "");
1670 string_set(&ServicePtrs[i]->comment, comment);
1671 string_set(&ServicePtrs[i]->fstype, fstype);
1672 ServicePtrs[i]->iMaxConnections = -1;
1673 ServicePtrs[i]->bAvailable = True;
1674 ServicePtrs[i]->bRead_only = True;
1675 ServicePtrs[i]->bGuest_only = False;
1676 ServicePtrs[i]->bGuest_ok = guest_ok;
1677 ServicePtrs[i]->bPrint_ok = False;
1678 ServicePtrs[i]->bBrowseable = False;
1680 if (strcasecmp(fstype, "IPC") == 0) {
1681 lp_do_parameter(i, "ntvfs handler", "default");
1684 DEBUG(3, ("adding hidden service %s\n", name));
1689 /***************************************************************************
1690 Add a new printer service, with defaults coming from service iFrom.
1691 ***************************************************************************/
1693 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1695 const char *comment = "From Printcap";
1696 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1701 /* note that we do NOT default the availability flag to True - */
1702 /* we take it from the default service passed. This allows all */
1703 /* dynamic printers to be disabled by disabling the [printers] */
1704 /* entry (if/when the 'available' keyword is implemented!). */
1706 /* the printer name is set to the service name. */
1707 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1708 string_set(&ServicePtrs[i]->comment, comment);
1709 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1710 /* Printers cannot be read_only. */
1711 ServicePtrs[i]->bRead_only = False;
1712 /* No share modes on printer services. */
1713 ServicePtrs[i]->bShareModes = False;
1714 /* No oplocks on printer services. */
1715 ServicePtrs[i]->bOpLocks = False;
1716 /* Printer services must be printable. */
1717 ServicePtrs[i]->bPrint_ok = True;
1719 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1721 update_server_announce_as_printserver();
1726 /***************************************************************************
1727 Map a parameter's string representation to something we can use.
1728 Returns False if the parameter string is not recognised, else TRUE.
1729 ***************************************************************************/
1731 static int map_parameter(const char *pszParmName)
1735 if (*pszParmName == '-')
1738 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1739 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1742 /* Warn only if it isn't parametric option */
1743 if (strchr(pszParmName, ':') == NULL)
1744 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1745 /* We do return 'fail' for parametric options as well because they are
1746 stored in different storage
1753 return the parameter structure for a parameter
1755 struct parm_struct *lp_parm_struct(const char *name)
1757 int parmnum = map_parameter(name);
1758 if (parmnum == -1) return NULL;
1759 return &parm_table[parmnum];
1763 return the parameter pointer for a parameter
1765 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1770 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1773 /***************************************************************************
1774 Set a boolean variable from the text value stored in the passed string.
1775 Returns True in success, False if the passed string does not correctly
1776 represent a boolean.
1777 ***************************************************************************/
1779 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1784 if (strwicmp(pszParmValue, "yes") == 0 ||
1785 strwicmp(pszParmValue, "true") == 0 ||
1786 strwicmp(pszParmValue, "1") == 0)
1788 else if (strwicmp(pszParmValue, "no") == 0 ||
1789 strwicmp(pszParmValue, "False") == 0 ||
1790 strwicmp(pszParmValue, "0") == 0)
1794 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1801 /***************************************************************************
1802 Find a service by name. Otherwise works like get_service.
1803 ***************************************************************************/
1805 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1809 for (iService = iNumServices - 1; iService >= 0; iService--)
1810 if (VALID(iService) &&
1811 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1812 if (pserviceDest != NULL)
1813 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1820 /***************************************************************************
1821 Copy a service structure to another.
1822 If pcopymapDest is NULL then copy all fields
1823 ***************************************************************************/
1825 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1828 BOOL bcopyall = (pcopymapDest == NULL);
1829 struct param_opt *data, *pdata, *paramo;
1832 for (i = 0; parm_table[i].label; i++)
1833 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1834 (bcopyall || pcopymapDest[i])) {
1835 void *def_ptr = parm_table[i].ptr;
1837 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1840 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1843 switch (parm_table[i].type) {
1845 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1850 *(int *)dest_ptr = *(int *)src_ptr;
1854 string_set(dest_ptr,
1859 string_set(dest_ptr,
1861 strupper(*(char **)dest_ptr);
1864 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1865 *(const char ***)src_ptr);
1873 init_copymap(pserviceDest);
1874 if (pserviceSource->copymap)
1875 memcpy((void *)pserviceDest->copymap,
1876 (void *)pserviceSource->copymap,
1877 sizeof(BOOL) * NUMPARAMETERS);
1880 data = pserviceSource->param_opt;
1883 pdata = pserviceDest->param_opt;
1884 /* Traverse destination */
1886 /* If we already have same option, override it */
1887 if (strcmp(pdata->key, data->key) == 0) {
1888 string_free(&pdata->value);
1889 pdata->value = strdup(data->value);
1893 pdata = pdata->next;
1896 paramo = smb_xmalloc_p(struct param_opt);
1897 paramo->key = strdup(data->key);
1898 paramo->value = strdup(data->value);
1899 DLIST_ADD(pserviceDest->param_opt, paramo);
1905 /***************************************************************************
1906 Check a service for consistency. Return False if the service is in any way
1907 incomplete or faulty, else True.
1908 ***************************************************************************/
1910 static BOOL service_ok(int iService)
1915 if (ServicePtrs[iService]->szService[0] == '\0') {
1916 DEBUG(0, ("The following message indicates an internal error:\n"));
1917 DEBUG(0, ("No service name in service entry.\n"));
1921 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1922 /* I can't see why you'd want a non-printable printer service... */
1923 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1924 if (!ServicePtrs[iService]->bPrint_ok) {
1925 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1926 ServicePtrs[iService]->szService));
1927 ServicePtrs[iService]->bPrint_ok = True;
1928 update_server_announce_as_printserver();
1930 /* [printers] service must also be non-browsable. */
1931 if (ServicePtrs[iService]->bBrowseable)
1932 ServicePtrs[iService]->bBrowseable = False;
1935 /* If a service is flagged unavailable, log the fact at level 0. */
1936 if (!ServicePtrs[iService]->bAvailable)
1937 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1938 ServicePtrs[iService]->szService));
1943 static struct file_lists {
1944 struct file_lists *next;
1948 } *file_lists = NULL;
1950 /*******************************************************************
1951 Keep a linked list of all config files so we know when one has changed
1952 it's date and needs to be reloaded.
1953 ********************************************************************/
1955 static void add_to_file_list(const char *fname, const char *subfname)
1957 struct file_lists *f = file_lists;
1960 if (f->name && !strcmp(f->name, fname))
1966 f = malloc_p(struct file_lists);
1969 f->next = file_lists;
1970 f->name = strdup(fname);
1975 f->subfname = strdup(subfname);
1981 f->modtime = file_modtime(subfname);
1983 time_t t = file_modtime(subfname);
1989 /*******************************************************************
1990 Check if a config file has changed date.
1991 ********************************************************************/
1993 BOOL lp_file_list_changed(void)
1995 struct file_lists *f = file_lists;
1996 DEBUG(6, ("lp_file_list_changed()\n"));
2002 pstrcpy(n2, f->name);
2003 standard_sub_basic(n2,sizeof(n2));
2005 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2006 f->name, n2, ctime(&f->modtime)));
2008 mod_time = file_modtime(n2);
2010 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2012 ("file %s modified: %s\n", n2,
2014 f->modtime = mod_time;
2015 SAFE_FREE(f->subfname);
2016 f->subfname = strdup(n2);
2024 /***************************************************************************
2025 Handle the include operation.
2026 ***************************************************************************/
2028 static BOOL handle_include(const char *pszParmValue, char **ptr)
2031 pstrcpy(fname, pszParmValue);
2033 standard_sub_basic(fname,sizeof(fname));
2035 add_to_file_list(pszParmValue, fname);
2037 string_set(ptr, fname);
2039 if (file_exist(fname))
2040 return (pm_process(fname, do_section, do_parameter));
2042 DEBUG(2, ("Can't find include file %s\n", fname));
2047 /***************************************************************************
2048 Handle the interpretation of the copy parameter.
2049 ***************************************************************************/
2051 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2055 service serviceTemp;
2057 string_set(ptr, pszParmValue);
2059 init_service(&serviceTemp);
2063 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2065 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2066 if (iTemp == iServiceIndex) {
2067 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2069 copy_service(ServicePtrs[iServiceIndex],
2071 ServicePtrs[iServiceIndex]->copymap);
2075 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2079 free_service(&serviceTemp);
2083 /***************************************************************************
2084 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2089 winbind uid = 1000-1999
2090 winbind gid = 700-899
2092 We only do simple parsing checks here. The strings are parsed into useful
2093 structures in the winbind daemon code.
2095 ***************************************************************************/
2097 /* Some lp_ routines to return winbind [ug]id information */
2099 static uid_t winbind_uid_low, winbind_uid_high;
2100 static gid_t winbind_gid_low, winbind_gid_high;
2101 static uint32_t non_unix_account_low, non_unix_account_high;
2103 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2105 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2109 *low = winbind_uid_low;
2112 *high = winbind_uid_high;
2117 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2119 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2123 *low = winbind_gid_low;
2126 *high = winbind_gid_high;
2131 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2133 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2137 *low = non_unix_account_low;
2140 *high = non_unix_account_high;
2145 /* Do some simple checks on "winbind [ug]id" parameter values */
2147 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2151 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2156 string_set(ptr, pszParmValue);
2158 winbind_uid_low = low;
2159 winbind_uid_high = high;
2164 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2168 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2173 string_set(ptr, pszParmValue);
2175 winbind_gid_low = low;
2176 winbind_gid_high = high;
2181 /***************************************************************************
2182 Do some simple checks on "non unix account range" parameter values.
2183 ***************************************************************************/
2185 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2189 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2194 string_set(ptr, pszParmValue);
2196 non_unix_account_low = low;
2197 non_unix_account_high = high;
2203 /***************************************************************************
2204 Initialise a copymap.
2205 ***************************************************************************/
2207 static void init_copymap(service * pservice)
2210 SAFE_FREE(pservice->copymap);
2211 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2212 if (!pservice->copymap)
2214 ("Couldn't allocate copymap!! (size %d)\n",
2215 (int)NUMPARAMETERS));
2217 for (i = 0; i < NUMPARAMETERS; i++)
2218 pservice->copymap[i] = True;
2221 /***************************************************************************
2222 Return the local pointer to a parameter given the service number and the
2223 pointer into the default structure.
2224 ***************************************************************************/
2226 void *lp_local_ptr(int snum, void *ptr)
2228 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2232 /***************************************************************************
2233 Process a parametric option
2234 ***************************************************************************/
2235 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2237 struct param_opt *paramo, *data;
2240 while (isspace(*pszParmName)) {
2244 name = strdup(pszParmName);
2245 if (!name) return False;
2250 data = Globals.param_opt;
2252 data = ServicePtrs[snum]->param_opt;
2255 /* Traverse destination */
2256 for (paramo=data; paramo; paramo=paramo->next) {
2257 /* If we already have the option set, override it unless
2258 it was a command line option and the new one isn't */
2259 if (strcmp(paramo->key, name) == 0) {
2260 if ((paramo->flags & FLAG_CMDLINE) &&
2261 !(flags & FLAG_CMDLINE)) {
2265 free(paramo->value);
2266 paramo->value = strdup(pszParmValue);
2267 paramo->flags = flags;
2273 paramo = smb_xmalloc_p(struct param_opt);
2274 paramo->key = strdup(name);
2275 paramo->value = strdup(pszParmValue);
2276 paramo->flags = flags;
2278 DLIST_ADD(Globals.param_opt, paramo);
2280 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2288 /***************************************************************************
2289 Process a parameter for a particular service number. If snum < 0
2290 then assume we are in the globals.
2291 ***************************************************************************/
2292 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2295 void *parm_ptr = NULL; /* where we are going to store the result */
2296 void *def_ptr = NULL;
2298 parmnum = map_parameter(pszParmName);
2301 if (strchr(pszParmName, ':')) {
2302 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2304 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2308 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2309 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2313 /* if the flag has been set on the command line, then don't allow override,
2314 but don't report an error */
2315 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2319 def_ptr = parm_table[parmnum].ptr;
2321 /* we might point at a service, the default service or a global */
2325 if (parm_table[parmnum].class == P_GLOBAL) {
2327 ("Global parameter %s found in service section!\n",
2332 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2337 if (!ServicePtrs[snum]->copymap)
2338 init_copymap(ServicePtrs[snum]);
2340 /* this handles the aliases - set the copymap for other entries with
2341 the same data pointer */
2342 for (i = 0; parm_table[i].label; i++)
2343 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2344 ServicePtrs[snum]->copymap[i] = False;
2347 /* if it is a special case then go ahead */
2348 if (parm_table[parmnum].special) {
2349 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2353 /* now switch on the type of variable it is */
2354 switch (parm_table[parmnum].type)
2357 set_boolean(parm_ptr, pszParmValue);
2361 *(int *)parm_ptr = atoi(pszParmValue);
2365 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
2366 pszParmValue, NULL);
2370 string_set(parm_ptr, pszParmValue);
2374 string_set(parm_ptr, pszParmValue);
2375 strupper(*(char **)parm_ptr);
2379 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2382 parm_table[parmnum].enum_list[i].name)) {
2384 parm_table[parmnum].
2389 if (!parm_table[parmnum].enum_list[i].name) {
2390 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2391 pszParmValue, pszParmName));
2402 /***************************************************************************
2403 Process a parameter.
2404 ***************************************************************************/
2406 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2408 if (!bInGlobalSection && bGlobalOnly)
2411 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2412 pszParmName, pszParmValue));
2416 variable argument do parameter
2418 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2420 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2427 s = talloc_vasprintf(NULL, fmt, ap);
2429 ret = do_parameter(pszParmName, s);
2436 set a parameter from the commandline - this is called from command line parameter
2437 parsing code. It sets the parameter then marks the parameter as unable to be modified
2438 by smb.conf processing
2440 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2442 int parmnum = map_parameter(pszParmName);
2445 while (isspace(*pszParmValue)) pszParmValue++;
2448 if (parmnum < 0 && strchr(pszParmName, ':')) {
2449 /* set a parametric option */
2450 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2454 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2458 /* reset the CMDLINE flag in case this has been called before */
2459 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2461 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2465 parm_table[parmnum].flags |= FLAG_CMDLINE;
2467 /* we have to also set FLAG_CMDLINE on aliases */
2468 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2469 parm_table[i].flags |= FLAG_CMDLINE;
2471 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2472 parm_table[i].flags |= FLAG_CMDLINE;
2479 set a option from the commandline in 'a=b' format. Use to support --option
2481 BOOL lp_set_option(const char *option)
2499 ret = lp_set_cmdline(s, p+1);
2505 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2507 /***************************************************************************
2508 Print a parameter of the specified type.
2509 ***************************************************************************/
2511 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2517 for (i = 0; p->enum_list[i].name; i++) {
2518 if (*(int *)ptr == p->enum_list[i].value) {
2520 p->enum_list[i].name);
2527 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2531 fprintf(f, "%d", *(int *)ptr);
2535 if ((char ***)ptr && *(char ***)ptr) {
2536 char **list = *(char ***)ptr;
2538 for (; *list; list++)
2539 fprintf(f, "%s%s", *list,
2540 ((*(list+1))?", ":""));
2546 if (*(char **)ptr) {
2547 fprintf(f, "%s", *(char **)ptr);
2555 /***************************************************************************
2556 Check if two parameters are equal.
2557 ***************************************************************************/
2559 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2563 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2567 return (*((int *)ptr1) == *((int *)ptr2));
2570 return str_list_equal((const char **)(*(char ***)ptr1),
2571 (const char **)(*(char ***)ptr2));
2576 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2581 return (p1 == p2 || strequal(p1, p2));
2589 /***************************************************************************
2590 Process a new section (service). At this stage all sections are services.
2591 Later we'll have special sections that permit server parameters to be set.
2592 Returns True on success, False on failure.
2593 ***************************************************************************/
2595 static BOOL do_section(const char *pszSectionName)
2598 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2599 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2602 /* if we've just struck a global section, note the fact. */
2603 bInGlobalSection = isglobal;
2605 /* check for multiple global sections */
2606 if (bInGlobalSection) {
2607 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2611 if (!bInGlobalSection && bGlobalOnly)
2614 /* if we have a current service, tidy it up before moving on */
2617 if (iServiceIndex >= 0)
2618 bRetval = service_ok(iServiceIndex);
2620 /* if all is still well, move to the next record in the services array */
2622 /* We put this here to avoid an odd message order if messages are */
2623 /* issued by the post-processing of a previous section. */
2624 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2626 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2628 DEBUG(0, ("Failed to add a new service\n"));
2637 /***************************************************************************
2638 Determine if a partcular base parameter is currentl set to the default value.
2639 ***************************************************************************/
2641 static BOOL is_default(int i)
2643 if (!defaults_saved)
2645 switch (parm_table[i].type) {
2647 return str_list_equal((const char **)parm_table[i].def.lvalue,
2648 (const char **)(*(char ***)parm_table[i].ptr));
2651 return strequal(parm_table[i].def.svalue,
2652 *(char **)parm_table[i].ptr);
2654 return parm_table[i].def.bvalue ==
2655 *(BOOL *)parm_table[i].ptr;
2658 return parm_table[i].def.ivalue ==
2659 *(int *)parm_table[i].ptr;
2666 /***************************************************************************
2667 Display the contents of the global structure.
2668 ***************************************************************************/
2670 static void dump_globals(FILE *f)
2673 struct param_opt *data;
2675 fprintf(f, "# Global parameters\n[global]\n");
2677 for (i = 0; parm_table[i].label; i++)
2678 if (parm_table[i].class == P_GLOBAL &&
2679 parm_table[i].ptr &&
2680 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2681 if (defaults_saved && is_default(i))
2683 fprintf(f, "\t%s = ", parm_table[i].label);
2684 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2687 if (Globals.param_opt != NULL) {
2688 data = Globals.param_opt;
2690 fprintf(f, "\t%s = %s\n", data->key, data->value);
2697 /***************************************************************************
2698 Display the contents of a single services record.
2699 ***************************************************************************/
2701 static void dump_a_service(service * pService, FILE * f)
2704 struct param_opt *data;
2706 if (pService != &sDefault)
2707 fprintf(f, "\n[%s]\n", pService->szService);
2709 for (i = 0; parm_table[i].label; i++)
2710 if (parm_table[i].class == P_LOCAL &&
2711 parm_table[i].ptr &&
2712 (*parm_table[i].label != '-') &&
2713 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2714 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2716 if (pService == &sDefault) {
2717 if (defaults_saved && is_default(i))
2720 if (equal_parameter(parm_table[i].type,
2721 ((char *)pService) +
2723 ((char *)&sDefault) +
2728 fprintf(f, "\t%s = ", parm_table[i].label);
2729 print_parameter(&parm_table[i],
2730 ((char *)pService) + pdiff, f);
2733 if (pService->param_opt != NULL) {
2734 data = pService->param_opt;
2736 fprintf(f, "\t%s = %s\n", data->key, data->value);
2743 /***************************************************************************
2744 Return info about the next service in a service. snum==-1 gives the globals.
2745 Return NULL when out of parameters.
2746 ***************************************************************************/
2748 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2751 /* do the globals */
2752 for (; parm_table[*i].label; (*i)++) {
2753 if (parm_table[*i].class == P_SEPARATOR)
2754 return &parm_table[(*i)++];
2756 if (!parm_table[*i].ptr
2757 || (*parm_table[*i].label == '-'))
2761 && (parm_table[*i].ptr ==
2762 parm_table[(*i) - 1].ptr))
2765 return &parm_table[(*i)++];
2768 service *pService = ServicePtrs[snum];
2770 for (; parm_table[*i].label; (*i)++) {
2771 if (parm_table[*i].class == P_SEPARATOR)
2772 return &parm_table[(*i)++];
2774 if (parm_table[*i].class == P_LOCAL &&
2775 parm_table[*i].ptr &&
2776 (*parm_table[*i].label != '-') &&
2778 (parm_table[*i].ptr !=
2779 parm_table[(*i) - 1].ptr)))
2782 PTR_DIFF(parm_table[*i].ptr,
2785 if (allparameters ||
2786 !equal_parameter(parm_table[*i].type,
2787 ((char *)pService) +
2789 ((char *)&sDefault) +
2792 return &parm_table[(*i)++];
2802 /***************************************************************************
2803 Return TRUE if the passed service number is within range.
2804 ***************************************************************************/
2806 BOOL lp_snum_ok(int iService)
2808 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2811 /***************************************************************************
2812 Auto-load some home services.
2813 ***************************************************************************/
2815 static void lp_add_auto_services(const char *str)
2820 /***************************************************************************
2821 Auto-load one printer.
2822 ***************************************************************************/
2824 void lp_add_one_printer(char *name, char *comment)
2826 int printers = lp_servicenumber(PRINTERS_NAME);
2829 if (lp_servicenumber(name) < 0) {
2830 lp_add_printer(name, printers);
2831 if ((i = lp_servicenumber(name)) >= 0) {
2832 string_set(&ServicePtrs[i]->comment, comment);
2833 ServicePtrs[i]->autoloaded = True;
2838 /***************************************************************************
2839 Announce ourselves as a print server.
2840 ***************************************************************************/
2842 void update_server_announce_as_printserver(void)
2844 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2847 /***************************************************************************
2848 Have we loaded a services file yet?
2849 ***************************************************************************/
2851 BOOL lp_loaded(void)
2856 /***************************************************************************
2857 Unload unused services.
2858 ***************************************************************************/
2860 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2863 for (i = 0; i < iNumServices; i++) {
2867 if (!snumused || !snumused(smb, i)) {
2868 ServicePtrs[i]->valid = False;
2869 free_service(ServicePtrs[i]);
2874 /***************************************************************************
2876 ***************************************************************************/
2878 void lp_killservice(int iServiceIn)
2880 if (VALID(iServiceIn)) {
2881 ServicePtrs[iServiceIn]->valid = False;
2882 free_service(ServicePtrs[iServiceIn]);
2886 /***************************************************************************
2887 Save the curent values of all global and sDefault parameters into the
2888 defaults union. This allows swat and testparm to show only the
2889 changed (ie. non-default) parameters.
2890 ***************************************************************************/
2892 static void lp_save_defaults(void)
2895 for (i = 0; parm_table[i].label; i++) {
2896 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2898 switch (parm_table[i].type) {
2900 parm_table[i].def.lvalue = str_list_copy(talloc_autofree_context(),
2901 *(const char ***)parm_table[i].ptr);
2905 if (parm_table[i].ptr) {
2906 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2908 parm_table[i].def.svalue = NULL;
2912 parm_table[i].def.bvalue =
2913 *(BOOL *)parm_table[i].ptr;
2917 parm_table[i].def.ivalue =
2918 *(int *)parm_table[i].ptr;
2924 defaults_saved = True;
2927 /*******************************************************************
2928 Set the server type we will announce as via nmbd.
2929 ********************************************************************/
2931 static void set_server_role(void)
2933 server_role = ROLE_STANDALONE;
2935 switch (lp_security()) {
2937 if (lp_domain_logons())
2938 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2943 if (lp_domain_logons()) {
2944 if (Globals.bDomainMaster) /* auto or yes */
2945 server_role = ROLE_DOMAIN_PDC;
2947 server_role = ROLE_DOMAIN_BDC;
2950 server_role = ROLE_DOMAIN_MEMBER;
2953 if (lp_domain_logons()) {
2955 if (Globals.bDomainMaster) /* auto or yes */
2956 server_role = ROLE_DOMAIN_PDC;
2958 server_role = ROLE_DOMAIN_BDC;
2962 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2966 DEBUG(10, ("set_server_role: role = "));
2968 switch(server_role) {
2969 case ROLE_STANDALONE:
2970 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2972 case ROLE_DOMAIN_MEMBER:
2973 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2975 case ROLE_DOMAIN_BDC:
2976 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2978 case ROLE_DOMAIN_PDC:
2979 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
2984 /***************************************************************************
2985 Load the services array from the services file. Return True on success,
2987 ***************************************************************************/
2989 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
2994 struct param_opt *data;
2996 pstrcpy(n2, pszFname);
2997 standard_sub_basic(n2,sizeof(n2));
2999 add_to_file_list(pszFname, n2);
3003 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3005 bInGlobalSection = True;
3006 bGlobalOnly = global_only;
3008 if (Globals.param_opt != NULL) {
3009 struct param_opt *next;
3010 for (data=Globals.param_opt; data; data=next) {
3012 if (data->flags & FLAG_CMDLINE) continue;
3015 DLIST_REMOVE(Globals.param_opt, data);
3027 /* We get sections first, so have to start 'behind' to make up */
3029 bRetval = pm_process(n2, do_section, do_parameter);
3031 /* finish up the last section */
3032 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3034 if (iServiceIndex >= 0)
3035 bRetval = service_ok(iServiceIndex);
3037 lp_add_auto_services(lp_auto_services());
3040 /* When 'restrict anonymous = 2' guest connections to ipc$
3042 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3043 lp_add_hidden("ADMIN$", "DISK", False);
3047 set_default_server_announce_type();
3051 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3052 /* if bWINSsupport is true and we are in the client */
3053 if (in_client && Globals.bWINSsupport) {
3054 lp_do_parameter(-1, "wins server", "127.0.0.1");
3062 /***************************************************************************
3063 Reset the max number of services.
3064 ***************************************************************************/
3066 void lp_resetnumservices(void)
3071 /***************************************************************************
3072 Return the max number of services.
3073 ***************************************************************************/
3075 int lp_numservices(void)
3077 return (iNumServices);
3080 /***************************************************************************
3081 Display the contents of the services array in human-readable form.
3082 ***************************************************************************/
3084 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3089 defaults_saved = False;
3093 dump_a_service(&sDefault, f);
3095 for (iService = 0; iService < maxtoprint; iService++)
3096 lp_dump_one(f, show_defaults, iService);
3099 /***************************************************************************
3100 Display the contents of one service in human-readable form.
3101 ***************************************************************************/
3103 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3106 if (ServicePtrs[snum]->szService[0] == '\0')
3108 dump_a_service(ServicePtrs[snum], f);
3112 /***************************************************************************
3113 Return the number of the service with the given name, or -1 if it doesn't
3114 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3115 getservicebyname()! This works ONLY if all services have been loaded, and
3116 does not copy the found service.
3117 ***************************************************************************/
3119 int lp_servicenumber(const char *pszServiceName)
3122 fstring serviceName;
3125 for (iService = iNumServices - 1; iService >= 0; iService--) {
3126 if (VALID(iService) && ServicePtrs[iService]->szService) {
3128 * The substitution here is used to support %U is
3131 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3132 standard_sub_basic(serviceName,sizeof(serviceName));
3133 if (strequal(serviceName, pszServiceName))
3139 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3144 /*******************************************************************
3145 A useful volume label function.
3146 ********************************************************************/
3147 const char *volume_label(int snum)
3149 const char *ret = lp_volume(snum);
3151 return lp_servicename(snum);
3156 /*******************************************************************
3157 Set the server type we will announce as via nmbd.
3158 ********************************************************************/
3160 static void set_default_server_announce_type(void)
3162 default_server_announce = 0;
3163 default_server_announce |= SV_TYPE_WORKSTATION;
3164 default_server_announce |= SV_TYPE_SERVER;
3165 default_server_announce |= SV_TYPE_SERVER_UNIX;
3167 switch (lp_announce_as()) {
3168 case ANNOUNCE_AS_NT_SERVER:
3169 default_server_announce |= SV_TYPE_SERVER_NT;
3170 /* fall through... */
3171 case ANNOUNCE_AS_NT_WORKSTATION:
3172 default_server_announce |= SV_TYPE_NT;
3174 case ANNOUNCE_AS_WIN95:
3175 default_server_announce |= SV_TYPE_WIN95_PLUS;
3177 case ANNOUNCE_AS_WFW:
3178 default_server_announce |= SV_TYPE_WFW;
3184 switch (lp_server_role()) {
3185 case ROLE_DOMAIN_MEMBER:
3186 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3188 case ROLE_DOMAIN_PDC:
3189 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3191 case ROLE_DOMAIN_BDC:
3192 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3194 case ROLE_STANDALONE:
3198 if (lp_time_server())
3199 default_server_announce |= SV_TYPE_TIME_SOURCE;
3201 if (lp_host_msdfs())
3202 default_server_announce |= SV_TYPE_DFS_SERVER;
3204 /* TODO: only announce us as print server when we are a print server */
3205 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3208 /***********************************************************
3209 returns role of Samba server
3210 ************************************************************/
3212 int lp_server_role(void)
3217 /***********************************************************
3218 If we are PDC then prefer us as DMB
3219 ************************************************************/
3221 BOOL lp_domain_master(void)
3223 if (Globals.bDomainMaster == Auto)
3224 return (lp_server_role() == ROLE_DOMAIN_PDC);
3226 return Globals.bDomainMaster;
3229 /***********************************************************
3230 If we are DMB then prefer us as LMB
3231 ************************************************************/
3233 BOOL lp_preferred_master(void)
3235 if (Globals.bPreferredMaster == Auto)
3236 return (lp_local_master() && lp_domain_master());
3238 return Globals.bPreferredMaster;
3241 /*******************************************************************
3243 ********************************************************************/
3245 void lp_remove_service(int snum)
3247 ServicePtrs[snum]->valid = False;
3250 /*******************************************************************
3252 ********************************************************************/
3254 void lp_copy_service(int snum, const char *new_name)
3256 const char *oldname = lp_servicename(snum);
3257 do_section(new_name);
3259 snum = lp_servicenumber(new_name);
3261 lp_do_parameter(snum, "copy", oldname);
3266 /*******************************************************************
3267 Get the default server type we will announce as via nmbd.
3268 ********************************************************************/
3269 int lp_default_server_announce(void)
3271 return default_server_announce;
3274 const char *lp_printername(int snum)
3276 const char *ret = _lp_printername(snum);
3277 if (ret == NULL || (ret != NULL && *ret == '\0'))
3278 ret = lp_const_servicename(snum);
3284 /*******************************************************************
3285 Return the max print jobs per queue.
3286 ********************************************************************/
3288 int lp_maxprintjobs(int snum)
3290 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3291 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3292 maxjobs = PRINT_MAX_JOBID - 1;