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;
195 BOOL paranoid_server_security;
197 BOOL bDisableSpoolss;
199 int enhanced_browsing;
206 int announce_as; /* This is initialised in init_globals */
207 int machine_password_timeout;
208 int winbind_cache_time;
215 char *socket_options;
220 BOOL bPreferredMaster;
223 BOOL bEncryptPasswords;
225 BOOL bObeyPamRestrictions;
227 BOOL bLargeReadwrite;
231 BOOL bBindInterfacesOnly;
232 BOOL bPamPasswordChange;
234 BOOL bNTStatusSupport;
235 BOOL bAllowTrustedDomains;
241 BOOL bClientLanManAuth;
242 BOOL bClientNTLMv2Auth;
244 BOOL bHideLocalUsers;
247 BOOL bHostnameLookups;
248 BOOL bUnixExtensions;
249 BOOL bDisableNetbios;
251 int restrict_anonymous;
252 int name_cache_timeout;
253 struct param_opt *param_opt;
257 static global Globals;
260 * This structure describes a single service.
269 char **szInvalidUsers;
274 char *szPrintcommand;
277 char *szLppausecommand;
278 char *szLpresumecommand;
279 char *szQueuepausecommand;
280 char *szQueueresumecommand;
288 char **ntvfs_handler;
314 struct param_opt *param_opt;
316 char dummy[3]; /* for alignment */
321 /* This is a default service used to prime a services structure */
322 static service sDefault = {
324 False, /* not autoloaded */
325 NULL, /* szService */
327 NULL, /* szUsername */
328 NULL, /* szInvalidUsers */
329 NULL, /* szValidUsers */
330 NULL, /* szAdminUsers */
332 NULL, /* szInclude */
333 NULL, /* szPrintcommand */
334 NULL, /* szLpqcommand */
335 NULL, /* szLprmcommand */
336 NULL, /* szLppausecommand */
337 NULL, /* szLpresumecommand */
338 NULL, /* szQueuepausecommand */
339 NULL, /* szQueueresumecommand */
340 NULL, /* szPrintername */
341 NULL, /* szHostsallow */
342 NULL, /* szHostsdeny */
346 NULL, /* szMSDfsProxy */
347 NULL, /* ntvfs_handler */
348 0, /* iMinPrintSpace */
349 1000, /* iMaxPrintJobs */
350 0, /* iMaxConnections */
351 DEFAULT_PRINTING, /* iPrinting */
353 True, /* bAvailable */
354 True, /* bBrowseable */
355 True, /* bRead_only */
356 False, /* bPrint_ok */
357 False, /* bMap_system */
358 False, /* bMap_hidden */
359 True, /* bMap_archive */
361 True, /* bStrictLocking */
362 True, /* bPosixLocking */
364 True, /* bLevel2OpLocks */
365 False, /* bOnlyUser */
366 False, /* bGuest_only */
367 False, /* bGuest_ok */
369 False, /* bMSDfsRoot */
370 True, /* bShareModes */
371 False, /* bStrictSync */
372 False, /* bCIFileSystem */
373 NULL, /* Parametric options */
378 /* local variables */
379 static service **ServicePtrs = NULL;
380 static int iNumServices = 0;
381 static int iServiceIndex = 0;
382 static BOOL bInGlobalSection = True;
383 static BOOL bGlobalOnly = False;
384 static int server_role;
385 static int default_server_announce;
387 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
389 /* prototypes for the special type handlers */
390 static BOOL handle_include(const char *pszParmValue, char **ptr);
391 static BOOL handle_copy(const char *pszParmValue, char **ptr);
392 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
393 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
394 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
396 static void set_server_role(void);
397 static void set_default_server_announce_type(void);
399 static const struct enum_list enum_protocol[] = {
400 {PROTOCOL_NT1, "NT1"},
401 {PROTOCOL_LANMAN2, "LANMAN2"},
402 {PROTOCOL_LANMAN1, "LANMAN1"},
403 {PROTOCOL_CORE, "CORE"},
404 {PROTOCOL_COREPLUS, "COREPLUS"},
405 {PROTOCOL_COREPLUS, "CORE+"},
409 static const struct enum_list enum_security[] = {
410 {SEC_SHARE, "SHARE"},
412 {SEC_SERVER, "SERVER"},
413 {SEC_DOMAIN, "DOMAIN"},
420 static const struct enum_list enum_printing[] = {
421 {PRINT_SYSV, "sysv"},
423 {PRINT_HPUX, "hpux"},
427 {PRINT_LPRNG, "lprng"},
428 {PRINT_SOFTQ, "softq"},
429 {PRINT_CUPS, "cups"},
431 {PRINT_LPROS2, "os2"},
433 {PRINT_TEST, "test"},
435 #endif /* DEVELOPER */
439 /* Types of machine we can announce as. */
440 #define ANNOUNCE_AS_NT_SERVER 1
441 #define ANNOUNCE_AS_WIN95 2
442 #define ANNOUNCE_AS_WFW 3
443 #define ANNOUNCE_AS_NT_WORKSTATION 4
445 static const struct enum_list enum_announce_as[] = {
446 {ANNOUNCE_AS_NT_SERVER, "NT"},
447 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
448 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
449 {ANNOUNCE_AS_WIN95, "win95"},
450 {ANNOUNCE_AS_WFW, "WfW"},
454 static const struct enum_list enum_bool_auto[] = {
465 /* Client-side offline caching policy types */
466 #define CSC_POLICY_MANUAL 0
467 #define CSC_POLICY_DOCUMENTS 1
468 #define CSC_POLICY_PROGRAMS 2
469 #define CSC_POLICY_DISABLE 3
471 static const struct enum_list enum_csc_policy[] = {
472 {CSC_POLICY_MANUAL, "manual"},
473 {CSC_POLICY_DOCUMENTS, "documents"},
474 {CSC_POLICY_PROGRAMS, "programs"},
475 {CSC_POLICY_DISABLE, "disable"},
479 /* SMB signing types. */
480 static const struct enum_list enum_smb_signing_vals[] = {
481 {SMB_SIGNING_OFF, "No"},
482 {SMB_SIGNING_OFF, "False"},
483 {SMB_SIGNING_OFF, "0"},
484 {SMB_SIGNING_OFF, "Off"},
485 {SMB_SIGNING_OFF, "disabled"},
486 {SMB_SIGNING_SUPPORTED, "Yes"},
487 {SMB_SIGNING_SUPPORTED, "True"},
488 {SMB_SIGNING_SUPPORTED, "1"},
489 {SMB_SIGNING_SUPPORTED, "On"},
490 {SMB_SIGNING_SUPPORTED, "enabled"},
491 {SMB_SIGNING_REQUIRED, "required"},
492 {SMB_SIGNING_REQUIRED, "mandatory"},
493 {SMB_SIGNING_REQUIRED, "force"},
494 {SMB_SIGNING_REQUIRED, "forced"},
495 {SMB_SIGNING_REQUIRED, "enforced"},
496 {SMB_SIGNING_AUTO, "auto"},
501 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
503 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
504 * is implied in current control logic. This may change at some later time. A
505 * flag value of 0 means - show as development option only.
507 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
508 * screen in SWAT. This is used to exclude parameters as well as to squash all
509 * parameters that have been duplicated by pseudonyms.
511 static struct parm_struct parm_table[] = {
512 {"Base Options", P_SEP, P_SEPARATOR},
514 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
515 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
516 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
517 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
518 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
519 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
520 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
521 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
522 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
523 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
524 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
525 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
526 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
527 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
528 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
529 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
530 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
531 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
532 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
534 {"Security Options", P_SEP, P_SEPARATOR},
536 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
537 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
538 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
539 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
554 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
558 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
568 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
569 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
571 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
572 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
573 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
575 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
577 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
579 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
581 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
582 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
583 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
584 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
586 {"Logging Options", P_SEP, P_SEPARATOR},
588 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
590 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
592 {"Protocol Options", P_SEP, P_SEPARATOR},
594 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
595 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
596 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
597 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
598 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
599 {"web tls", P_BOOL, P_GLOBAL, &Globals.web_tls, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
600 {"web tls keyfile", P_STRING, P_GLOBAL, &Globals.web_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
601 {"web tls certfile", P_STRING, P_GLOBAL, &Globals.web_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
602 {"web tls cafile", P_STRING, P_GLOBAL, &Globals.web_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
603 {"web tls crlfile", P_STRING, P_GLOBAL, &Globals.web_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
605 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
606 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
607 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
608 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
609 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
610 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
611 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
615 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
616 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
617 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
618 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
620 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
621 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
622 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
624 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
625 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
627 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
628 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
629 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
631 {"Tuning Options", P_SEP, P_SEPARATOR},
633 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
634 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
635 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
636 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
638 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
639 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
640 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
642 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
643 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
644 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
646 {"Printing Options", P_SEP, P_SEPARATOR},
648 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
649 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
650 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
651 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
652 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
653 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
654 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
655 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
656 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
657 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
658 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
659 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
660 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
661 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
662 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
664 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
665 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
667 {"Filename Handling", P_SEP, P_SEPARATOR},
669 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
670 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
671 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
673 {"Domain Options", P_SEP, P_SEPARATOR},
675 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
677 {"Logon Options", P_SEP, P_SEPARATOR},
679 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
680 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
682 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
683 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
684 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
685 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
686 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
688 {"Browse Options", P_SEP, P_SEPARATOR},
690 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
691 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
695 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
697 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
698 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
699 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
701 {"WINS Options", P_SEP, P_SEPARATOR},
702 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
703 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
706 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
707 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
708 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
710 {"Locking Options", P_SEP, P_SEPARATOR},
712 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
713 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
714 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
715 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
717 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
718 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
719 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
720 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
721 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
723 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
725 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
726 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
727 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
728 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
729 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
730 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
732 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
733 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
734 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
737 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
740 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
741 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
743 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
744 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
745 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
747 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
748 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
750 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
751 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
752 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
753 {"Winbind options", P_SEP, P_SEPARATOR},
755 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
762 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
768 /***************************************************************************
769 Initialise the sDefault parameter structure for the printer values.
770 ***************************************************************************/
772 static void init_printer_values(void)
774 /* choose defaults depending on the type of printing */
775 switch (sDefault.iPrinting) {
780 do_parameter("Lpqcommand", "lpq -P'%p'");
781 do_parameter("Lprmcommand", "lprm -P'%p' %j");
782 do_parameter("Printcommand",
788 do_parameter("Lpqcommand", "lpq -P'%p'");
789 do_parameter("Lprmcommand", "lprm -P'%p' %j");
790 do_parameter("Printcommand",
792 do_parameter("Queuepausecommand",
794 do_parameter("Queueresumecommand",
796 do_parameter("Lppausecommand",
798 do_parameter("Lpresumecommand",
799 "lpc release '%p' %j");
804 do_parameter("Lpqcommand", "");
805 do_parameter("Lprmcommand", "");
806 do_parameter("Printcommand", "");
807 do_parameter("Lppausecommand", "");
808 do_parameter("Lpresumecommand", "");
809 do_parameter("Queuepausecommand", "");
810 do_parameter("Queueresumecommand", "");
812 do_parameter("Printcapname", "cups");
814 do_parameter("Lpqcommand",
815 "/usr/bin/lpstat -o '%p'");
816 do_parameter("Lprmcommand",
817 "/usr/bin/cancel '%p-%j'");
818 do_parameter("Printcommand",
819 "/usr/bin/lp -d '%p' %s; rm %s");
820 do_parameter("Lppausecommand",
821 "lp -i '%p-%j' -H hold");
822 do_parameter("Lpresumecommand",
823 "lp -i '%p-%j' -H resume");
824 do_parameter("Queuepausecommand",
825 "/usr/bin/disable '%p'");
826 do_parameter("Queueresumecommand",
827 "/usr/bin/enable '%p'");
828 do_parameter("Printcapname", "lpstat");
829 #endif /* HAVE_CUPS */
834 do_parameter("Lpqcommand", "lpstat -o%p");
835 do_parameter("Lprmcommand", "cancel %p-%j");
836 do_parameter("Printcommand",
837 "lp -c -d%p %s; rm %s");
838 do_parameter("Queuepausecommand",
840 do_parameter("Queueresumecommand",
843 do_parameter("Lppausecommand",
844 "lp -i %p-%j -H hold");
845 do_parameter("Lpresumecommand",
846 "lp -i %p-%j -H resume");
851 do_parameter("Lpqcommand", "lpq -P%p");
852 do_parameter("Lprmcommand", "lprm -P%p %j");
853 do_parameter("Printcommand", "lp -r -P%p %s");
857 do_parameter("Lpqcommand", "qstat -l -d%p");
858 do_parameter("Lprmcommand",
860 do_parameter("Printcommand",
861 "lp -d%p -s %s; rm %s");
862 do_parameter("Lppausecommand",
864 do_parameter("Lpresumecommand",
870 do_parameter("Printcommand", "vlp print %p %s");
871 do_parameter("Lpqcommand", "vlp lpq %p");
872 do_parameter("Lprmcommand", "vlp lprm %p %j");
873 do_parameter("Lppausecommand", "vlp lppause %p %j");
874 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
875 do_parameter("Queuepausecommand", "vlp queuepause %p");
876 do_parameter("Queueresumecommand", "vlp queueresume %p");
878 #endif /* DEVELOPER */
884 /***************************************************************************
885 Initialise the global parameter structure.
886 ***************************************************************************/
887 static void init_globals(void)
892 DEBUG(3, ("Initialising global parameters\n"));
894 for (i = 0; parm_table[i].label; i++) {
895 if ((parm_table[i].type == P_STRING ||
896 parm_table[i].type == P_USTRING) &&
898 !(parm_table[i].flags & FLAG_CMDLINE)) {
899 string_set(parm_table[i].ptr, "");
903 /* options that can be set on the command line must be initialised via
904 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
906 do_parameter("socket options", "TCP_NODELAY");
908 do_parameter("workgroup", DEFAULT_WORKGROUP);
909 myname = get_myname();
910 do_parameter("netbios name", myname);
912 do_parameter("max protocol", "NT1");
913 do_parameter("name resolve order", "lmhosts wins host bcast");
915 init_printer_values();
917 do_parameter("fstype", FSTYPE_STRING);
918 do_parameter("ntvfs handler", "unixuid default");
919 do_parameter("max connections", "-1");
921 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
922 do_parameter("server services", "smb rpc nbt ldap cldap web");
923 do_parameter("auth methods", "anonymous sam_ignoredomain");
924 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
925 do_parameter("private dir", dyn_PRIVATE_DIR);
926 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
927 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
928 do_parameter_var("wins database", "tdb://%s/wins.ldb", dyn_PRIVATE_DIR);
929 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
930 do_parameter("guest account", GUEST_ACCOUNT);
932 /* using UTF8 by default allows us to support all chars */
933 do_parameter("unix charset", "UTF8");
935 /* Use codepage 850 as a default for the dos character set */
936 do_parameter("dos charset", "CP850");
939 * Allow the default PASSWD_CHAT to be overridden in local.h.
941 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
943 do_parameter("passwd program", "");
944 do_parameter("printcap name", PRINTCAP_NAME);
946 do_parameter("pid directory", dyn_PIDDIR);
947 do_parameter("lock dir", dyn_LOCKDIR);
948 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
950 do_parameter("socket address", "0.0.0.0");
951 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
953 do_parameter_var("announce version", "%d.%d",
954 DEFAULT_MAJOR_VERSION,
955 DEFAULT_MINOR_VERSION);
957 do_parameter("logon drive", "");
959 do_parameter("logon home", "\\\\%N\\%U");
960 do_parameter("logon path", "\\\\%N\\%U\\profile");
961 do_parameter("password server", "*");
963 do_parameter("load printers", "True");
965 do_parameter("max mux", "50");
966 do_parameter("max xmit", "12288");
967 do_parameter("lpqcachetime", "10");
968 do_parameter("DisableSpoolss", "False");
969 do_parameter("password level", "0");
970 do_parameter("username level", "0");
971 do_parameter("LargeReadwrite", "True");
972 do_parameter("minprotocol", "CORE");
973 do_parameter("security", "USER");
974 do_parameter("paranoid server security", "True");
975 do_parameter("EncryptPasswords", "True");
976 do_parameter("ReadRaw", "True");
977 do_parameter("WriteRaw", "True");
978 do_parameter("NullPasswords", "False");
979 do_parameter("ObeyPamRestrictions", "False");
980 do_parameter("lm announce", "Auto");
981 do_parameter("lm interval", "60");
982 do_parameter("announce as", "NT SERVER");
984 do_parameter("TimeServer", "False");
985 do_parameter("BindInterfacesOnly", "False");
986 do_parameter("PamPasswordChange", "False");
987 do_parameter("Unicode", "True");
988 do_parameter("restrict anonymous", "0");
989 do_parameter("ClientLanManAuth", "True");
990 do_parameter("LanmanAuth", "True");
991 do_parameter("NTLMAuth", "True");
993 do_parameter("enhanced browsing", "True");
994 do_parameter("LockSpinCount", "3");
995 do_parameter("LockSpinTime", "10");
996 #ifdef MMAP_BLACKLIST
997 do_parameter("UseMmap", "False");
999 do_parameter("UseMmap", "True");
1001 do_parameter("UnixExtensions", "False");
1003 /* hostname lookups can be very expensive and are broken on
1004 a large number of sites (tridge) */
1005 do_parameter("HostnameLookups", "False");
1007 do_parameter("PreferredMaster", "Auto");
1008 do_parameter("os level", "20");
1009 do_parameter("LocalMaster", "True");
1010 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1011 do_parameter("DomainLogons", "False");
1012 do_parameter("WINSsupport", "False");
1013 do_parameter("WINSproxy", "False");
1015 do_parameter("DNSproxy", "True");
1017 do_parameter("AllowTrustedDomains", "True");
1019 do_parameter("TemplateShell", "/bin/false");
1020 do_parameter("TemplateHomedir", "/home/%D/%U");
1021 do_parameter("WinbindSeparator", "\\");
1023 do_parameter("winbind cache time", "15");
1024 do_parameter("WinbindEnumUsers", "True");
1025 do_parameter("WinbindEnumGroups", "True");
1026 do_parameter("WinbindUseDefaultDomain", "False");
1028 do_parameter("IDMapBackend", "tdb");
1030 do_parameter("name cache timeout", "660"); /* In seconds */
1032 do_parameter("client signing", "Yes");
1033 do_parameter("server signing", "auto");
1035 do_parameter("use spnego", "True");
1037 do_parameter("smb ports", SMB_PORTS);
1038 do_parameter("nbt port", "137");
1039 do_parameter("dgram port", "138");
1040 do_parameter("cldap port", "389");
1041 do_parameter("web port", "901");
1042 do_parameter("swat directory", dyn_SWATDIR);
1044 do_parameter("nt status support", "True");
1046 do_parameter("max wins ttl", "432000");
1047 do_parameter("min wins ttl", "10");
1049 do_parameter("web tls", "True");
1050 do_parameter_var("web tls keyfile", "%s/tls/key.pem", dyn_PRIVATE_DIR);
1051 do_parameter_var("web tls certfile", "%s/tls/cert.pem", dyn_PRIVATE_DIR);
1052 do_parameter_var("web tls cafile", "%s/tls/ca.pem", dyn_PRIVATE_DIR);
1055 static TALLOC_CTX *lp_talloc;
1057 /******************************************************************* a
1058 Free up temporary memory - called from the main loop.
1059 ********************************************************************/
1061 void lp_talloc_free(void)
1065 talloc_free(lp_talloc);
1069 /*******************************************************************
1070 Convenience routine to grab string parameters into temporary memory
1071 and run standard_sub_basic on them. The buffers can be written to by
1072 callers without affecting the source string.
1073 ********************************************************************/
1075 static const char *lp_string(const char *s)
1077 #if 0 /* until REWRITE done to make thread-safe */
1078 size_t len = s ? strlen(s) : 0;
1082 /* The follow debug is useful for tracking down memory problems
1083 especially if you have an inner loop that is calling a lp_*()
1084 function that returns a string. Perhaps this debug should be
1085 present all the time? */
1088 DEBUG(10, ("lp_string(%s)\n", s));
1091 #if 0 /* until REWRITE done to make thread-safe */
1093 lp_talloc = talloc_init("lp_talloc");
1095 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1103 StrnCpy(ret, s, len);
1105 if (trim_string(ret, "\"", "\"")) {
1106 if (strchr(ret,'"') != NULL)
1107 StrnCpy(ret, s, len);
1110 standard_sub_basic(ret,len+100);
1117 In this section all the functions that are used to access the
1118 parameters from the rest of the program are defined
1121 #define FN_GLOBAL_STRING(fn_name,ptr) \
1122 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1123 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1124 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1125 #define FN_GLOBAL_LIST(fn_name,ptr) \
1126 const char **fn_name(void) {return(*(const char ***)(ptr));}
1127 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1128 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1129 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1130 char fn_name(void) {return(*(char *)(ptr));}
1131 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1132 int fn_name(void) {return(*(int *)(ptr));}
1134 #define FN_LOCAL_STRING(fn_name,val) \
1135 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1136 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1137 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1138 #define FN_LOCAL_LIST(fn_name,val) \
1139 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1140 #define FN_LOCAL_BOOL(fn_name,val) \
1141 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1142 #define FN_LOCAL_CHAR(fn_name,val) \
1143 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1144 #define FN_LOCAL_INTEGER(fn_name,val) \
1145 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1147 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1148 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1149 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
1150 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
1151 FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
1152 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1153 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
1154 FN_GLOBAL_BOOL(lp_web_tls, &Globals.web_tls)
1155 FN_GLOBAL_STRING(lp_web_keyfile, &Globals.web_keyfile)
1156 FN_GLOBAL_STRING(lp_web_certfile, &Globals.web_certfile)
1157 FN_GLOBAL_STRING(lp_web_cafile, &Globals.web_cafile)
1158 FN_GLOBAL_STRING(lp_web_crlfile, &Globals.web_crlfile)
1159 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1160 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1161 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1162 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1163 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1164 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1165 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1166 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
1167 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1168 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1169 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1170 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1171 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1172 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1173 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1174 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1175 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1176 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1177 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1178 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1179 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1180 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1181 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1182 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1183 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1184 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1185 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1186 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1187 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1188 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1189 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1190 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1191 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1192 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1193 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1194 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1195 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1196 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1197 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1198 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1199 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1200 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1201 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1203 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1205 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1207 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1208 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1209 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1210 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1211 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1212 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1213 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1214 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1215 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1217 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1218 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1219 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1220 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1221 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1222 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1223 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1224 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1225 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1226 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1227 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1228 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1229 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1230 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1231 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1232 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1233 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1234 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1235 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1236 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1237 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1238 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1239 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1240 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1241 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1242 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1243 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1244 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1245 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1246 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1247 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1248 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1249 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1250 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1251 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1252 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1253 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1254 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1255 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1256 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1257 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1258 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1259 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1260 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1261 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1262 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1263 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1264 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1265 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1266 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1267 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1268 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1269 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1270 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1271 FN_LOCAL_STRING(lp_servicename, szService)
1272 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1273 FN_LOCAL_STRING(lp_pathname, szPath)
1274 FN_LOCAL_STRING(lp_username, szUsername)
1275 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1276 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1277 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1278 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1279 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1280 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1281 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1282 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1283 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1284 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1285 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1286 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1287 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1288 FN_LOCAL_STRING(lp_comment, comment)
1289 FN_LOCAL_STRING(lp_fstype, fstype)
1290 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1291 static FN_LOCAL_STRING(lp_volume, volume)
1292 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1293 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1294 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1295 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1296 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1297 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1298 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1299 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1300 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1301 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1302 FN_LOCAL_BOOL(lp_locking, bLocking)
1303 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1304 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1305 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1306 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1307 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1308 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1309 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1310 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1311 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1312 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1313 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1314 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1315 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1316 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1317 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1318 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1319 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1320 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1322 /* local prototypes */
1324 static int map_parameter(const char *pszParmName);
1325 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1326 static int getservicebyname(const char *pszServiceName,
1327 service * pserviceDest);
1328 static void copy_service(service * pserviceDest,
1329 service * pserviceSource, BOOL *pcopymapDest);
1330 static BOOL service_ok(int iService);
1331 static BOOL do_section(const char *pszSectionName);
1332 static void init_copymap(service * pservice);
1334 /* This is a helper function for parametrical options support. */
1335 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1336 /* Actual parametrical functions are quite simple */
1337 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
1340 struct param_opt *data;
1342 if (lookup_service >= iNumServices) return NULL;
1344 data = (lookup_service < 0) ?
1345 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1347 asprintf(&vfskey, "%s:%s", type, option);
1351 if (strcmp(data->key, vfskey) == 0) {
1358 if (lookup_service >= 0) {
1359 /* Try to fetch the same option but from globals */
1360 /* but only if we are not already working with Globals */
1361 data = Globals.param_opt;
1363 if (strcmp(data->key, vfskey) == 0) {
1377 /*******************************************************************
1378 convenience routine to return int parameters.
1379 ********************************************************************/
1380 static int lp_int(const char *s)
1384 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1391 /*******************************************************************
1392 convenience routine to return unsigned long parameters.
1393 ********************************************************************/
1394 static int lp_ulong(const char *s)
1398 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1402 return strtoul(s, NULL, 10);
1405 /*******************************************************************
1406 convenience routine to return boolean parameters.
1407 ********************************************************************/
1408 static BOOL lp_bool(const char *s)
1413 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1417 if (!set_boolean(&ret,s)) {
1418 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1426 /* Return parametric option from a given service. Type is a part of option before ':' */
1427 /* Parametric option has following syntax: 'Type: option = value' */
1428 /* Returned value is allocated in 'lp_talloc' context */
1430 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1432 const char *value = lp_get_parametric(lookup_service, type, option);
1435 return lp_string(value);
1440 /* Return parametric option from a given service. Type is a part of option before ':' */
1441 /* Parametric option has following syntax: 'Type: option = value' */
1442 /* Returned value is allocated in 'lp_talloc' context */
1444 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1445 const char *separator)
1447 const char *value = lp_get_parametric(lookup_service, type, option);
1450 return str_list_make(talloc_autofree_context(), value, separator);
1455 /* Return parametric option from a given service. Type is a part of option before ':' */
1456 /* Parametric option has following syntax: 'Type: option = value' */
1458 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1460 const char *value = lp_get_parametric(lookup_service, type, option);
1463 return lp_int(value);
1468 /* Return parametric option from a given service. Type is a part of option before ':' */
1469 /* Parametric option has following syntax: 'Type: option = value' */
1471 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1473 const char *value = lp_get_parametric(lookup_service, type, option);
1476 return lp_ulong(value);
1481 /* Return parametric option from a given service. Type is a part of option before ':' */
1482 /* Parametric option has following syntax: 'Type: option = value' */
1484 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1486 const char *value = lp_get_parametric(lookup_service, type, option);
1489 return lp_bool(value);
1495 /***************************************************************************
1496 Initialise a service to the defaults.
1497 ***************************************************************************/
1499 static void init_service(service * pservice)
1501 memset((char *)pservice, '\0', sizeof(service));
1502 copy_service(pservice, &sDefault, NULL);
1505 /***************************************************************************
1506 Free the dynamically allocated parts of a service struct.
1507 ***************************************************************************/
1509 static void free_service(service *pservice)
1512 struct param_opt *data, *pdata;
1516 if (pservice->szService)
1517 DEBUG(5, ("free_service: Freeing service %s\n",
1518 pservice->szService));
1520 string_free(&pservice->szService);
1521 SAFE_FREE(pservice->copymap);
1523 for (i = 0; parm_table[i].label; i++) {
1524 if ((parm_table[i].type == P_STRING ||
1525 parm_table[i].type == P_USTRING) &&
1526 parm_table[i].class == P_LOCAL) {
1527 string_free((char **)
1528 (((char *)pservice) +
1529 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1530 } else if (parm_table[i].type == P_LIST &&
1531 parm_table[i].class == P_LOCAL) {
1532 char ***listp = (char ***)(((char *)pservice) +
1533 PTR_DIFF(parm_table[i].ptr, &sDefault));
1534 talloc_free(*listp);
1539 DEBUG(5,("Freeing parametrics:\n"));
1540 data = pservice->param_opt;
1542 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1543 string_free(&data->key);
1544 string_free(&data->value);
1550 ZERO_STRUCTP(pservice);
1553 /***************************************************************************
1554 Add a new service to the services array initialising it with the given
1556 ***************************************************************************/
1558 static int add_a_service(const service *pservice, const char *name)
1562 int num_to_alloc = iNumServices + 1;
1563 struct param_opt *data, *pdata;
1565 tservice = *pservice;
1567 /* it might already exist */
1569 i = getservicebyname(name, NULL);
1571 /* Clean all parametric options for service */
1572 /* They will be added during parsing again */
1573 data = ServicePtrs[i]->param_opt;
1575 string_free(&data->key);
1576 string_free(&data->value);
1581 ServicePtrs[i]->param_opt = NULL;
1586 /* find an invalid one */
1587 for (i = 0; i < iNumServices; i++)
1588 if (!ServicePtrs[i]->valid)
1591 /* if not, then create one */
1592 if (i == iNumServices) {
1595 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1598 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1603 ServicePtrs[iNumServices] = malloc_p(service);
1605 if (!ServicePtrs[iNumServices]) {
1606 DEBUG(0,("add_a_service: out of memory!\n"));
1612 free_service(ServicePtrs[i]);
1614 ServicePtrs[i]->valid = True;
1616 init_service(ServicePtrs[i]);
1617 copy_service(ServicePtrs[i], &tservice, NULL);
1619 string_set(&ServicePtrs[i]->szService, name);
1623 /***************************************************************************
1624 Add a new home service, with the specified home directory, defaults coming
1626 ***************************************************************************/
1628 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1629 const char *user, const char *pszHomedir)
1634 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1639 if (!(*(ServicePtrs[iDefaultService]->szPath))
1640 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1641 pstrcpy(newHomedir, pszHomedir);
1643 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1644 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1647 string_set(&ServicePtrs[i]->szPath, newHomedir);
1649 if (!(*(ServicePtrs[i]->comment))) {
1651 slprintf(comment, sizeof(comment) - 1,
1652 "Home directory of %s", user);
1653 string_set(&ServicePtrs[i]->comment, comment);
1655 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1656 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1658 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1664 /***************************************************************************
1665 Add a new service, based on an old one.
1666 ***************************************************************************/
1668 int lp_add_service(const char *pszService, int iDefaultService)
1670 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1673 /***************************************************************************
1674 Add the IPC service.
1675 ***************************************************************************/
1677 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1680 int i = add_a_service(&sDefault, name);
1685 slprintf(comment, sizeof(comment) - 1,
1686 "%s Service (%s)", fstype, Globals.szServerString);
1688 string_set(&ServicePtrs[i]->szPath, tmpdir());
1689 string_set(&ServicePtrs[i]->szUsername, "");
1690 string_set(&ServicePtrs[i]->comment, comment);
1691 string_set(&ServicePtrs[i]->fstype, fstype);
1692 ServicePtrs[i]->iMaxConnections = -1;
1693 ServicePtrs[i]->bAvailable = True;
1694 ServicePtrs[i]->bRead_only = True;
1695 ServicePtrs[i]->bGuest_only = False;
1696 ServicePtrs[i]->bGuest_ok = guest_ok;
1697 ServicePtrs[i]->bPrint_ok = False;
1698 ServicePtrs[i]->bBrowseable = False;
1700 if (strcasecmp(fstype, "IPC") == 0) {
1701 lp_do_parameter(i, "ntvfs handler", "default");
1704 DEBUG(3, ("adding hidden service %s\n", name));
1709 /***************************************************************************
1710 Add a new printer service, with defaults coming from service iFrom.
1711 ***************************************************************************/
1713 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1715 const char *comment = "From Printcap";
1716 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1721 /* note that we do NOT default the availability flag to True - */
1722 /* we take it from the default service passed. This allows all */
1723 /* dynamic printers to be disabled by disabling the [printers] */
1724 /* entry (if/when the 'available' keyword is implemented!). */
1726 /* the printer name is set to the service name. */
1727 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1728 string_set(&ServicePtrs[i]->comment, comment);
1729 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1730 /* Printers cannot be read_only. */
1731 ServicePtrs[i]->bRead_only = False;
1732 /* No share modes on printer services. */
1733 ServicePtrs[i]->bShareModes = False;
1734 /* No oplocks on printer services. */
1735 ServicePtrs[i]->bOpLocks = False;
1736 /* Printer services must be printable. */
1737 ServicePtrs[i]->bPrint_ok = True;
1739 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1741 update_server_announce_as_printserver();
1746 /***************************************************************************
1747 Map a parameter's string representation to something we can use.
1748 Returns False if the parameter string is not recognised, else TRUE.
1749 ***************************************************************************/
1751 static int map_parameter(const char *pszParmName)
1755 if (*pszParmName == '-')
1758 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1759 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1762 /* Warn only if it isn't parametric option */
1763 if (strchr(pszParmName, ':') == NULL)
1764 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1765 /* We do return 'fail' for parametric options as well because they are
1766 stored in different storage
1773 return the parameter structure for a parameter
1775 struct parm_struct *lp_parm_struct(const char *name)
1777 int parmnum = map_parameter(name);
1778 if (parmnum == -1) return NULL;
1779 return &parm_table[parmnum];
1783 return the parameter pointer for a parameter
1785 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1790 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1793 /***************************************************************************
1794 Set a boolean variable from the text value stored in the passed string.
1795 Returns True in success, False if the passed string does not correctly
1796 represent a boolean.
1797 ***************************************************************************/
1799 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1804 if (strwicmp(pszParmValue, "yes") == 0 ||
1805 strwicmp(pszParmValue, "true") == 0 ||
1806 strwicmp(pszParmValue, "1") == 0)
1808 else if (strwicmp(pszParmValue, "no") == 0 ||
1809 strwicmp(pszParmValue, "False") == 0 ||
1810 strwicmp(pszParmValue, "0") == 0)
1814 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1821 /***************************************************************************
1822 Find a service by name. Otherwise works like get_service.
1823 ***************************************************************************/
1825 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1829 for (iService = iNumServices - 1; iService >= 0; iService--)
1830 if (VALID(iService) &&
1831 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1832 if (pserviceDest != NULL)
1833 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1840 /***************************************************************************
1841 Copy a service structure to another.
1842 If pcopymapDest is NULL then copy all fields
1843 ***************************************************************************/
1845 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1848 BOOL bcopyall = (pcopymapDest == NULL);
1849 struct param_opt *data, *pdata, *paramo;
1852 for (i = 0; parm_table[i].label; i++)
1853 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1854 (bcopyall || pcopymapDest[i])) {
1855 void *def_ptr = parm_table[i].ptr;
1857 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1860 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1863 switch (parm_table[i].type) {
1865 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1870 *(int *)dest_ptr = *(int *)src_ptr;
1874 string_set(dest_ptr,
1879 string_set(dest_ptr,
1881 strupper(*(char **)dest_ptr);
1884 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1885 *(const char ***)src_ptr);
1893 init_copymap(pserviceDest);
1894 if (pserviceSource->copymap)
1895 memcpy((void *)pserviceDest->copymap,
1896 (void *)pserviceSource->copymap,
1897 sizeof(BOOL) * NUMPARAMETERS);
1900 data = pserviceSource->param_opt;
1903 pdata = pserviceDest->param_opt;
1904 /* Traverse destination */
1906 /* If we already have same option, override it */
1907 if (strcmp(pdata->key, data->key) == 0) {
1908 string_free(&pdata->value);
1909 pdata->value = strdup(data->value);
1913 pdata = pdata->next;
1916 paramo = smb_xmalloc_p(struct param_opt);
1917 paramo->key = strdup(data->key);
1918 paramo->value = strdup(data->value);
1919 DLIST_ADD(pserviceDest->param_opt, paramo);
1925 /***************************************************************************
1926 Check a service for consistency. Return False if the service is in any way
1927 incomplete or faulty, else True.
1928 ***************************************************************************/
1930 static BOOL service_ok(int iService)
1935 if (ServicePtrs[iService]->szService[0] == '\0') {
1936 DEBUG(0, ("The following message indicates an internal error:\n"));
1937 DEBUG(0, ("No service name in service entry.\n"));
1941 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1942 /* I can't see why you'd want a non-printable printer service... */
1943 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1944 if (!ServicePtrs[iService]->bPrint_ok) {
1945 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1946 ServicePtrs[iService]->szService));
1947 ServicePtrs[iService]->bPrint_ok = True;
1948 update_server_announce_as_printserver();
1950 /* [printers] service must also be non-browsable. */
1951 if (ServicePtrs[iService]->bBrowseable)
1952 ServicePtrs[iService]->bBrowseable = False;
1955 /* If a service is flagged unavailable, log the fact at level 0. */
1956 if (!ServicePtrs[iService]->bAvailable)
1957 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1958 ServicePtrs[iService]->szService));
1963 static struct file_lists {
1964 struct file_lists *next;
1968 } *file_lists = NULL;
1970 /*******************************************************************
1971 Keep a linked list of all config files so we know when one has changed
1972 it's date and needs to be reloaded.
1973 ********************************************************************/
1975 static void add_to_file_list(const char *fname, const char *subfname)
1977 struct file_lists *f = file_lists;
1980 if (f->name && !strcmp(f->name, fname))
1986 f = malloc_p(struct file_lists);
1989 f->next = file_lists;
1990 f->name = strdup(fname);
1995 f->subfname = strdup(subfname);
2001 f->modtime = file_modtime(subfname);
2003 time_t t = file_modtime(subfname);
2009 /*******************************************************************
2010 Check if a config file has changed date.
2011 ********************************************************************/
2013 BOOL lp_file_list_changed(void)
2015 struct file_lists *f = file_lists;
2016 DEBUG(6, ("lp_file_list_changed()\n"));
2022 pstrcpy(n2, f->name);
2023 standard_sub_basic(n2,sizeof(n2));
2025 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2026 f->name, n2, ctime(&f->modtime)));
2028 mod_time = file_modtime(n2);
2030 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2032 ("file %s modified: %s\n", n2,
2034 f->modtime = mod_time;
2035 SAFE_FREE(f->subfname);
2036 f->subfname = strdup(n2);
2044 /***************************************************************************
2045 Handle the include operation.
2046 ***************************************************************************/
2048 static BOOL handle_include(const char *pszParmValue, char **ptr)
2051 pstrcpy(fname, pszParmValue);
2053 standard_sub_basic(fname,sizeof(fname));
2055 add_to_file_list(pszParmValue, fname);
2057 string_set(ptr, fname);
2059 if (file_exist(fname))
2060 return (pm_process(fname, do_section, do_parameter));
2062 DEBUG(2, ("Can't find include file %s\n", fname));
2067 /***************************************************************************
2068 Handle the interpretation of the copy parameter.
2069 ***************************************************************************/
2071 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2075 service serviceTemp;
2077 string_set(ptr, pszParmValue);
2079 init_service(&serviceTemp);
2083 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2085 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2086 if (iTemp == iServiceIndex) {
2087 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2089 copy_service(ServicePtrs[iServiceIndex],
2091 ServicePtrs[iServiceIndex]->copymap);
2095 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2099 free_service(&serviceTemp);
2103 /***************************************************************************
2104 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2109 winbind uid = 1000-1999
2110 winbind gid = 700-899
2112 We only do simple parsing checks here. The strings are parsed into useful
2113 structures in the winbind daemon code.
2115 ***************************************************************************/
2117 /* Some lp_ routines to return winbind [ug]id information */
2119 static uid_t winbind_uid_low, winbind_uid_high;
2120 static gid_t winbind_gid_low, winbind_gid_high;
2121 static uint32_t non_unix_account_low, non_unix_account_high;
2123 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2125 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2129 *low = winbind_uid_low;
2132 *high = winbind_uid_high;
2137 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2139 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2143 *low = winbind_gid_low;
2146 *high = winbind_gid_high;
2151 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2153 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2157 *low = non_unix_account_low;
2160 *high = non_unix_account_high;
2165 /* Do some simple checks on "winbind [ug]id" parameter values */
2167 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2171 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2176 string_set(ptr, pszParmValue);
2178 winbind_uid_low = low;
2179 winbind_uid_high = high;
2184 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2188 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2193 string_set(ptr, pszParmValue);
2195 winbind_gid_low = low;
2196 winbind_gid_high = high;
2201 /***************************************************************************
2202 Do some simple checks on "non unix account range" parameter values.
2203 ***************************************************************************/
2205 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2209 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2214 string_set(ptr, pszParmValue);
2216 non_unix_account_low = low;
2217 non_unix_account_high = high;
2223 /***************************************************************************
2224 Initialise a copymap.
2225 ***************************************************************************/
2227 static void init_copymap(service * pservice)
2230 SAFE_FREE(pservice->copymap);
2231 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2232 if (!pservice->copymap)
2234 ("Couldn't allocate copymap!! (size %d)\n",
2235 (int)NUMPARAMETERS));
2237 for (i = 0; i < NUMPARAMETERS; i++)
2238 pservice->copymap[i] = True;
2241 /***************************************************************************
2242 Return the local pointer to a parameter given the service number and the
2243 pointer into the default structure.
2244 ***************************************************************************/
2246 void *lp_local_ptr(int snum, void *ptr)
2248 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2252 /***************************************************************************
2253 Process a parametric option
2254 ***************************************************************************/
2255 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2257 struct param_opt *paramo, *data;
2260 while (isspace(*pszParmName)) {
2264 name = strdup(pszParmName);
2265 if (!name) return False;
2270 data = Globals.param_opt;
2272 data = ServicePtrs[snum]->param_opt;
2275 /* Traverse destination */
2276 for (paramo=data; paramo; paramo=paramo->next) {
2277 /* If we already have the option set, override it unless
2278 it was a command line option and the new one isn't */
2279 if (strcmp(paramo->key, name) == 0) {
2280 if ((paramo->flags & FLAG_CMDLINE) &&
2281 !(flags & FLAG_CMDLINE)) {
2285 free(paramo->value);
2286 paramo->value = strdup(pszParmValue);
2287 paramo->flags = flags;
2293 paramo = smb_xmalloc_p(struct param_opt);
2294 paramo->key = strdup(name);
2295 paramo->value = strdup(pszParmValue);
2296 paramo->flags = flags;
2298 DLIST_ADD(Globals.param_opt, paramo);
2300 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2308 /***************************************************************************
2309 Process a parameter for a particular service number. If snum < 0
2310 then assume we are in the globals.
2311 ***************************************************************************/
2312 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2315 void *parm_ptr = NULL; /* where we are going to store the result */
2316 void *def_ptr = NULL;
2318 parmnum = map_parameter(pszParmName);
2321 if (strchr(pszParmName, ':')) {
2322 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2324 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2328 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2329 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2333 /* if the flag has been set on the command line, then don't allow override,
2334 but don't report an error */
2335 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2339 def_ptr = parm_table[parmnum].ptr;
2341 /* we might point at a service, the default service or a global */
2345 if (parm_table[parmnum].class == P_GLOBAL) {
2347 ("Global parameter %s found in service section!\n",
2352 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2357 if (!ServicePtrs[snum]->copymap)
2358 init_copymap(ServicePtrs[snum]);
2360 /* this handles the aliases - set the copymap for other entries with
2361 the same data pointer */
2362 for (i = 0; parm_table[i].label; i++)
2363 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2364 ServicePtrs[snum]->copymap[i] = False;
2367 /* if it is a special case then go ahead */
2368 if (parm_table[parmnum].special) {
2369 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2373 /* now switch on the type of variable it is */
2374 switch (parm_table[parmnum].type)
2377 set_boolean(parm_ptr, pszParmValue);
2381 *(int *)parm_ptr = atoi(pszParmValue);
2385 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
2386 pszParmValue, NULL);
2390 string_set(parm_ptr, pszParmValue);
2394 string_set(parm_ptr, pszParmValue);
2395 strupper(*(char **)parm_ptr);
2399 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2402 parm_table[parmnum].enum_list[i].name)) {
2404 parm_table[parmnum].
2409 if (!parm_table[parmnum].enum_list[i].name) {
2410 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2411 pszParmValue, pszParmName));
2422 /***************************************************************************
2423 Process a parameter.
2424 ***************************************************************************/
2426 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2428 if (!bInGlobalSection && bGlobalOnly)
2431 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2432 pszParmName, pszParmValue));
2436 variable argument do parameter
2438 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2440 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2447 s = talloc_vasprintf(NULL, fmt, ap);
2449 ret = do_parameter(pszParmName, s);
2456 set a parameter from the commandline - this is called from command line parameter
2457 parsing code. It sets the parameter then marks the parameter as unable to be modified
2458 by smb.conf processing
2460 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2462 int parmnum = map_parameter(pszParmName);
2465 while (isspace(*pszParmValue)) pszParmValue++;
2468 if (parmnum < 0 && strchr(pszParmName, ':')) {
2469 /* set a parametric option */
2470 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2474 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2478 /* reset the CMDLINE flag in case this has been called before */
2479 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2481 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2485 parm_table[parmnum].flags |= FLAG_CMDLINE;
2487 /* we have to also set FLAG_CMDLINE on aliases */
2488 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2489 parm_table[i].flags |= FLAG_CMDLINE;
2491 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2492 parm_table[i].flags |= FLAG_CMDLINE;
2499 set a option from the commandline in 'a=b' format. Use to support --option
2501 BOOL lp_set_option(const char *option)
2519 ret = lp_set_cmdline(s, p+1);
2525 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2527 /***************************************************************************
2528 Print a parameter of the specified type.
2529 ***************************************************************************/
2531 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2537 for (i = 0; p->enum_list[i].name; i++) {
2538 if (*(int *)ptr == p->enum_list[i].value) {
2540 p->enum_list[i].name);
2547 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2551 fprintf(f, "%d", *(int *)ptr);
2555 if ((char ***)ptr && *(char ***)ptr) {
2556 char **list = *(char ***)ptr;
2558 for (; *list; list++)
2559 fprintf(f, "%s%s", *list,
2560 ((*(list+1))?", ":""));
2566 if (*(char **)ptr) {
2567 fprintf(f, "%s", *(char **)ptr);
2575 /***************************************************************************
2576 Check if two parameters are equal.
2577 ***************************************************************************/
2579 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2583 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2587 return (*((int *)ptr1) == *((int *)ptr2));
2590 return str_list_equal((const char **)(*(char ***)ptr1),
2591 (const char **)(*(char ***)ptr2));
2596 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2601 return (p1 == p2 || strequal(p1, p2));
2609 /***************************************************************************
2610 Process a new section (service). At this stage all sections are services.
2611 Later we'll have special sections that permit server parameters to be set.
2612 Returns True on success, False on failure.
2613 ***************************************************************************/
2615 static BOOL do_section(const char *pszSectionName)
2618 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2619 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2622 /* if we've just struck a global section, note the fact. */
2623 bInGlobalSection = isglobal;
2625 /* check for multiple global sections */
2626 if (bInGlobalSection) {
2627 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2631 if (!bInGlobalSection && bGlobalOnly)
2634 /* if we have a current service, tidy it up before moving on */
2637 if (iServiceIndex >= 0)
2638 bRetval = service_ok(iServiceIndex);
2640 /* if all is still well, move to the next record in the services array */
2642 /* We put this here to avoid an odd message order if messages are */
2643 /* issued by the post-processing of a previous section. */
2644 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2646 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2648 DEBUG(0, ("Failed to add a new service\n"));
2657 /***************************************************************************
2658 Determine if a partcular base parameter is currentl set to the default value.
2659 ***************************************************************************/
2661 static BOOL is_default(int i)
2663 if (!defaults_saved)
2665 switch (parm_table[i].type) {
2667 return str_list_equal((const char **)parm_table[i].def.lvalue,
2668 (const char **)(*(char ***)parm_table[i].ptr));
2671 return strequal(parm_table[i].def.svalue,
2672 *(char **)parm_table[i].ptr);
2674 return parm_table[i].def.bvalue ==
2675 *(BOOL *)parm_table[i].ptr;
2678 return parm_table[i].def.ivalue ==
2679 *(int *)parm_table[i].ptr;
2686 /***************************************************************************
2687 Display the contents of the global structure.
2688 ***************************************************************************/
2690 static void dump_globals(FILE *f)
2693 struct param_opt *data;
2695 fprintf(f, "# Global parameters\n[global]\n");
2697 for (i = 0; parm_table[i].label; i++)
2698 if (parm_table[i].class == P_GLOBAL &&
2699 parm_table[i].ptr &&
2700 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2701 if (defaults_saved && is_default(i))
2703 fprintf(f, "\t%s = ", parm_table[i].label);
2704 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2707 if (Globals.param_opt != NULL) {
2708 data = Globals.param_opt;
2710 fprintf(f, "\t%s = %s\n", data->key, data->value);
2717 /***************************************************************************
2718 Display the contents of a single services record.
2719 ***************************************************************************/
2721 static void dump_a_service(service * pService, FILE * f)
2724 struct param_opt *data;
2726 if (pService != &sDefault)
2727 fprintf(f, "\n[%s]\n", pService->szService);
2729 for (i = 0; parm_table[i].label; i++)
2730 if (parm_table[i].class == P_LOCAL &&
2731 parm_table[i].ptr &&
2732 (*parm_table[i].label != '-') &&
2733 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2734 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2736 if (pService == &sDefault) {
2737 if (defaults_saved && is_default(i))
2740 if (equal_parameter(parm_table[i].type,
2741 ((char *)pService) +
2743 ((char *)&sDefault) +
2748 fprintf(f, "\t%s = ", parm_table[i].label);
2749 print_parameter(&parm_table[i],
2750 ((char *)pService) + pdiff, f);
2753 if (pService->param_opt != NULL) {
2754 data = pService->param_opt;
2756 fprintf(f, "\t%s = %s\n", data->key, data->value);
2763 /***************************************************************************
2764 Return info about the next service in a service. snum==-1 gives the globals.
2765 Return NULL when out of parameters.
2766 ***************************************************************************/
2768 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2771 /* do the globals */
2772 for (; parm_table[*i].label; (*i)++) {
2773 if (parm_table[*i].class == P_SEPARATOR)
2774 return &parm_table[(*i)++];
2776 if (!parm_table[*i].ptr
2777 || (*parm_table[*i].label == '-'))
2781 && (parm_table[*i].ptr ==
2782 parm_table[(*i) - 1].ptr))
2785 return &parm_table[(*i)++];
2788 service *pService = ServicePtrs[snum];
2790 for (; parm_table[*i].label; (*i)++) {
2791 if (parm_table[*i].class == P_SEPARATOR)
2792 return &parm_table[(*i)++];
2794 if (parm_table[*i].class == P_LOCAL &&
2795 parm_table[*i].ptr &&
2796 (*parm_table[*i].label != '-') &&
2798 (parm_table[*i].ptr !=
2799 parm_table[(*i) - 1].ptr)))
2802 PTR_DIFF(parm_table[*i].ptr,
2805 if (allparameters ||
2806 !equal_parameter(parm_table[*i].type,
2807 ((char *)pService) +
2809 ((char *)&sDefault) +
2812 return &parm_table[(*i)++];
2822 /***************************************************************************
2823 Return TRUE if the passed service number is within range.
2824 ***************************************************************************/
2826 BOOL lp_snum_ok(int iService)
2828 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2831 /***************************************************************************
2832 Auto-load some home services.
2833 ***************************************************************************/
2835 static void lp_add_auto_services(const char *str)
2840 /***************************************************************************
2841 Auto-load one printer.
2842 ***************************************************************************/
2844 void lp_add_one_printer(char *name, char *comment)
2846 int printers = lp_servicenumber(PRINTERS_NAME);
2849 if (lp_servicenumber(name) < 0) {
2850 lp_add_printer(name, printers);
2851 if ((i = lp_servicenumber(name)) >= 0) {
2852 string_set(&ServicePtrs[i]->comment, comment);
2853 ServicePtrs[i]->autoloaded = True;
2858 /***************************************************************************
2859 Announce ourselves as a print server.
2860 ***************************************************************************/
2862 void update_server_announce_as_printserver(void)
2864 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2867 /***************************************************************************
2868 Have we loaded a services file yet?
2869 ***************************************************************************/
2871 BOOL lp_loaded(void)
2876 /***************************************************************************
2877 Unload unused services.
2878 ***************************************************************************/
2880 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2883 for (i = 0; i < iNumServices; i++) {
2887 if (!snumused || !snumused(smb, i)) {
2888 ServicePtrs[i]->valid = False;
2889 free_service(ServicePtrs[i]);
2894 /***************************************************************************
2896 ***************************************************************************/
2898 void lp_killservice(int iServiceIn)
2900 if (VALID(iServiceIn)) {
2901 ServicePtrs[iServiceIn]->valid = False;
2902 free_service(ServicePtrs[iServiceIn]);
2906 /***************************************************************************
2907 Save the curent values of all global and sDefault parameters into the
2908 defaults union. This allows swat and testparm to show only the
2909 changed (ie. non-default) parameters.
2910 ***************************************************************************/
2912 static void lp_save_defaults(void)
2915 for (i = 0; parm_table[i].label; i++) {
2916 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2918 switch (parm_table[i].type) {
2920 parm_table[i].def.lvalue = str_list_copy(talloc_autofree_context(),
2921 *(const char ***)parm_table[i].ptr);
2925 if (parm_table[i].ptr) {
2926 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2928 parm_table[i].def.svalue = NULL;
2932 parm_table[i].def.bvalue =
2933 *(BOOL *)parm_table[i].ptr;
2937 parm_table[i].def.ivalue =
2938 *(int *)parm_table[i].ptr;
2944 defaults_saved = True;
2947 /*******************************************************************
2948 Set the server type we will announce as via nmbd.
2949 ********************************************************************/
2951 static void set_server_role(void)
2953 server_role = ROLE_STANDALONE;
2955 switch (lp_security()) {
2957 if (lp_domain_logons())
2958 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2963 if (lp_domain_logons()) {
2964 if (Globals.bDomainMaster) /* auto or yes */
2965 server_role = ROLE_DOMAIN_PDC;
2967 server_role = ROLE_DOMAIN_BDC;
2970 server_role = ROLE_DOMAIN_MEMBER;
2973 if (lp_domain_logons()) {
2975 if (Globals.bDomainMaster) /* auto or yes */
2976 server_role = ROLE_DOMAIN_PDC;
2978 server_role = ROLE_DOMAIN_BDC;
2982 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2986 DEBUG(10, ("set_server_role: role = "));
2988 switch(server_role) {
2989 case ROLE_STANDALONE:
2990 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2992 case ROLE_DOMAIN_MEMBER:
2993 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2995 case ROLE_DOMAIN_BDC:
2996 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2998 case ROLE_DOMAIN_PDC:
2999 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3004 /***************************************************************************
3005 Load the services array from the services file. Return True on success,
3007 ***************************************************************************/
3009 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3014 struct param_opt *data;
3016 pstrcpy(n2, pszFname);
3017 standard_sub_basic(n2,sizeof(n2));
3019 add_to_file_list(pszFname, n2);
3023 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3025 bInGlobalSection = True;
3026 bGlobalOnly = global_only;
3028 if (Globals.param_opt != NULL) {
3029 struct param_opt *next;
3030 for (data=Globals.param_opt; data; data=next) {
3032 if (data->flags & FLAG_CMDLINE) continue;
3035 DLIST_REMOVE(Globals.param_opt, data);
3047 /* We get sections first, so have to start 'behind' to make up */
3049 bRetval = pm_process(n2, do_section, do_parameter);
3051 /* finish up the last section */
3052 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3054 if (iServiceIndex >= 0)
3055 bRetval = service_ok(iServiceIndex);
3057 lp_add_auto_services(lp_auto_services());
3060 /* When 'restrict anonymous = 2' guest connections to ipc$
3062 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3063 lp_add_hidden("ADMIN$", "DISK", False);
3067 set_default_server_announce_type();
3071 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3072 /* if bWINSsupport is true and we are in the client */
3073 if (in_client && Globals.bWINSsupport) {
3074 lp_do_parameter(-1, "wins server", "127.0.0.1");
3082 /***************************************************************************
3083 Reset the max number of services.
3084 ***************************************************************************/
3086 void lp_resetnumservices(void)
3091 /***************************************************************************
3092 Return the max number of services.
3093 ***************************************************************************/
3095 int lp_numservices(void)
3097 return (iNumServices);
3100 /***************************************************************************
3101 Display the contents of the services array in human-readable form.
3102 ***************************************************************************/
3104 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3109 defaults_saved = False;
3113 dump_a_service(&sDefault, f);
3115 for (iService = 0; iService < maxtoprint; iService++)
3116 lp_dump_one(f, show_defaults, iService);
3119 /***************************************************************************
3120 Display the contents of one service in human-readable form.
3121 ***************************************************************************/
3123 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3126 if (ServicePtrs[snum]->szService[0] == '\0')
3128 dump_a_service(ServicePtrs[snum], f);
3132 /***************************************************************************
3133 Return the number of the service with the given name, or -1 if it doesn't
3134 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3135 getservicebyname()! This works ONLY if all services have been loaded, and
3136 does not copy the found service.
3137 ***************************************************************************/
3139 int lp_servicenumber(const char *pszServiceName)
3142 fstring serviceName;
3145 for (iService = iNumServices - 1; iService >= 0; iService--) {
3146 if (VALID(iService) && ServicePtrs[iService]->szService) {
3148 * The substitution here is used to support %U is
3151 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3152 standard_sub_basic(serviceName,sizeof(serviceName));
3153 if (strequal(serviceName, pszServiceName))
3159 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3164 /*******************************************************************
3165 A useful volume label function.
3166 ********************************************************************/
3167 const char *volume_label(int snum)
3169 const char *ret = lp_volume(snum);
3171 return lp_servicename(snum);
3176 /*******************************************************************
3177 Set the server type we will announce as via nmbd.
3178 ********************************************************************/
3180 static void set_default_server_announce_type(void)
3182 default_server_announce = 0;
3183 default_server_announce |= SV_TYPE_WORKSTATION;
3184 default_server_announce |= SV_TYPE_SERVER;
3185 default_server_announce |= SV_TYPE_SERVER_UNIX;
3187 switch (lp_announce_as()) {
3188 case ANNOUNCE_AS_NT_SERVER:
3189 default_server_announce |= SV_TYPE_SERVER_NT;
3190 /* fall through... */
3191 case ANNOUNCE_AS_NT_WORKSTATION:
3192 default_server_announce |= SV_TYPE_NT;
3194 case ANNOUNCE_AS_WIN95:
3195 default_server_announce |= SV_TYPE_WIN95_PLUS;
3197 case ANNOUNCE_AS_WFW:
3198 default_server_announce |= SV_TYPE_WFW;
3204 switch (lp_server_role()) {
3205 case ROLE_DOMAIN_MEMBER:
3206 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3208 case ROLE_DOMAIN_PDC:
3209 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3211 case ROLE_DOMAIN_BDC:
3212 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3214 case ROLE_STANDALONE:
3218 if (lp_time_server())
3219 default_server_announce |= SV_TYPE_TIME_SOURCE;
3221 if (lp_host_msdfs())
3222 default_server_announce |= SV_TYPE_DFS_SERVER;
3224 /* TODO: only announce us as print server when we are a print server */
3225 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3228 /***********************************************************
3229 returns role of Samba server
3230 ************************************************************/
3232 int lp_server_role(void)
3237 /***********************************************************
3238 If we are PDC then prefer us as DMB
3239 ************************************************************/
3241 BOOL lp_domain_master(void)
3243 if (Globals.bDomainMaster == Auto)
3244 return (lp_server_role() == ROLE_DOMAIN_PDC);
3246 return Globals.bDomainMaster;
3249 /***********************************************************
3250 If we are DMB then prefer us as LMB
3251 ************************************************************/
3253 BOOL lp_preferred_master(void)
3255 if (Globals.bPreferredMaster == Auto)
3256 return (lp_local_master() && lp_domain_master());
3258 return Globals.bPreferredMaster;
3261 /*******************************************************************
3263 ********************************************************************/
3265 void lp_remove_service(int snum)
3267 ServicePtrs[snum]->valid = False;
3270 /*******************************************************************
3272 ********************************************************************/
3274 void lp_copy_service(int snum, const char *new_name)
3276 const char *oldname = lp_servicename(snum);
3277 do_section(new_name);
3279 snum = lp_servicenumber(new_name);
3281 lp_do_parameter(snum, "copy", oldname);
3286 /*******************************************************************
3287 Get the default server type we will announce as via nmbd.
3288 ********************************************************************/
3289 int lp_default_server_announce(void)
3291 return default_server_announce;
3294 const char *lp_printername(int snum)
3296 const char *ret = _lp_printername(snum);
3297 if (ret == NULL || (ret != NULL && *ret == '\0'))
3298 ret = lp_const_servicename(snum);
3304 /*******************************************************************
3305 Return the max print jobs per queue.
3306 ********************************************************************/
3308 int lp_maxprintjobs(int snum)
3310 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3311 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3312 maxjobs = PRINT_MAX_JOBID - 1;