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;
170 char *ntptr_providor;
173 char *szNonUnixAccountRange;
174 char *szTemplateHomedir;
175 char *szTemplateShell;
176 char *szWinbindSeparator;
177 BOOL bWinbindEnumUsers;
178 BOOL bWinbindEnumGroups;
179 BOOL bWinbindUseDefaultDomain;
180 char *szIDMapBackend;
181 char *szGuestaccount;
182 char *swat_directory;
196 BOOL paranoid_server_security;
198 BOOL bDisableSpoolss;
200 int enhanced_browsing;
207 int announce_as; /* This is initialised in init_globals */
208 int machine_password_timeout;
209 int winbind_cache_time;
217 char *socket_options;
222 BOOL bPreferredMaster;
225 BOOL bEncryptPasswords;
227 BOOL bObeyPamRestrictions;
229 BOOL bLargeReadwrite;
233 BOOL bBindInterfacesOnly;
234 BOOL bPamPasswordChange;
236 BOOL bNTStatusSupport;
237 BOOL bAllowTrustedDomains;
244 BOOL bClientPlaintextAuth;
245 BOOL bClientLanManAuth;
246 BOOL bClientNTLMv2Auth;
248 BOOL bHideLocalUsers;
251 BOOL bHostnameLookups;
252 BOOL bUnixExtensions;
253 BOOL bDisableNetbios;
255 int restrict_anonymous;
256 int name_cache_timeout;
257 struct param_opt *param_opt;
261 static global Globals;
264 * This structure describes a single service.
273 char **szInvalidUsers;
278 char *szPrintcommand;
281 char *szLppausecommand;
282 char *szLpresumecommand;
283 char *szQueuepausecommand;
284 char *szQueueresumecommand;
292 char **ntvfs_handler;
318 struct param_opt *param_opt;
320 char dummy[3]; /* for alignment */
325 /* This is a default service used to prime a services structure */
326 static service sDefault = {
328 False, /* not autoloaded */
329 NULL, /* szService */
331 NULL, /* szUsername */
332 NULL, /* szInvalidUsers */
333 NULL, /* szValidUsers */
334 NULL, /* szAdminUsers */
336 NULL, /* szInclude */
337 NULL, /* szPrintcommand */
338 NULL, /* szLpqcommand */
339 NULL, /* szLprmcommand */
340 NULL, /* szLppausecommand */
341 NULL, /* szLpresumecommand */
342 NULL, /* szQueuepausecommand */
343 NULL, /* szQueueresumecommand */
344 NULL, /* szPrintername */
345 NULL, /* szHostsallow */
346 NULL, /* szHostsdeny */
350 NULL, /* szMSDfsProxy */
351 NULL, /* ntvfs_handler */
352 0, /* iMinPrintSpace */
353 1000, /* iMaxPrintJobs */
354 0, /* iMaxConnections */
355 DEFAULT_PRINTING, /* iPrinting */
357 True, /* bAvailable */
358 True, /* bBrowseable */
359 True, /* bRead_only */
360 False, /* bPrint_ok */
361 False, /* bMap_system */
362 False, /* bMap_hidden */
363 True, /* bMap_archive */
365 True, /* bStrictLocking */
366 True, /* bPosixLocking */
368 True, /* bLevel2OpLocks */
369 False, /* bOnlyUser */
370 False, /* bGuest_only */
371 False, /* bGuest_ok */
373 False, /* bMSDfsRoot */
374 True, /* bShareModes */
375 False, /* bStrictSync */
376 False, /* bCIFileSystem */
377 NULL, /* Parametric options */
382 /* local variables */
383 static service **ServicePtrs = NULL;
384 static int iNumServices = 0;
385 static int iServiceIndex = 0;
386 static BOOL bInGlobalSection = True;
387 static int server_role;
388 static int default_server_announce;
390 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
392 /* prototypes for the special type handlers */
393 static BOOL handle_include(const char *pszParmValue, char **ptr);
394 static BOOL handle_copy(const char *pszParmValue, char **ptr);
395 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
396 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
397 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
399 static void set_server_role(void);
400 static void set_default_server_announce_type(void);
402 static const struct enum_list enum_protocol[] = {
403 {PROTOCOL_NT1, "NT1"},
404 {PROTOCOL_LANMAN2, "LANMAN2"},
405 {PROTOCOL_LANMAN1, "LANMAN1"},
406 {PROTOCOL_CORE, "CORE"},
407 {PROTOCOL_COREPLUS, "COREPLUS"},
408 {PROTOCOL_COREPLUS, "CORE+"},
412 static const struct enum_list enum_security[] = {
413 {SEC_SHARE, "SHARE"},
415 {SEC_SERVER, "SERVER"},
416 {SEC_DOMAIN, "DOMAIN"},
423 static const struct enum_list enum_printing[] = {
424 {PRINT_SYSV, "sysv"},
426 {PRINT_HPUX, "hpux"},
430 {PRINT_LPRNG, "lprng"},
431 {PRINT_SOFTQ, "softq"},
432 {PRINT_CUPS, "cups"},
434 {PRINT_LPROS2, "os2"},
436 {PRINT_TEST, "test"},
438 #endif /* DEVELOPER */
442 /* Types of machine we can announce as. */
443 #define ANNOUNCE_AS_NT_SERVER 1
444 #define ANNOUNCE_AS_WIN95 2
445 #define ANNOUNCE_AS_WFW 3
446 #define ANNOUNCE_AS_NT_WORKSTATION 4
448 static const struct enum_list enum_announce_as[] = {
449 {ANNOUNCE_AS_NT_SERVER, "NT"},
450 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
451 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
452 {ANNOUNCE_AS_WIN95, "win95"},
453 {ANNOUNCE_AS_WFW, "WfW"},
457 static const struct enum_list enum_bool_auto[] = {
468 /* Client-side offline caching policy types */
469 #define CSC_POLICY_MANUAL 0
470 #define CSC_POLICY_DOCUMENTS 1
471 #define CSC_POLICY_PROGRAMS 2
472 #define CSC_POLICY_DISABLE 3
474 static const struct enum_list enum_csc_policy[] = {
475 {CSC_POLICY_MANUAL, "manual"},
476 {CSC_POLICY_DOCUMENTS, "documents"},
477 {CSC_POLICY_PROGRAMS, "programs"},
478 {CSC_POLICY_DISABLE, "disable"},
482 /* SMB signing types. */
483 static const struct enum_list enum_smb_signing_vals[] = {
484 {SMB_SIGNING_OFF, "No"},
485 {SMB_SIGNING_OFF, "False"},
486 {SMB_SIGNING_OFF, "0"},
487 {SMB_SIGNING_OFF, "Off"},
488 {SMB_SIGNING_OFF, "disabled"},
489 {SMB_SIGNING_SUPPORTED, "Yes"},
490 {SMB_SIGNING_SUPPORTED, "True"},
491 {SMB_SIGNING_SUPPORTED, "1"},
492 {SMB_SIGNING_SUPPORTED, "On"},
493 {SMB_SIGNING_SUPPORTED, "enabled"},
494 {SMB_SIGNING_REQUIRED, "required"},
495 {SMB_SIGNING_REQUIRED, "mandatory"},
496 {SMB_SIGNING_REQUIRED, "force"},
497 {SMB_SIGNING_REQUIRED, "forced"},
498 {SMB_SIGNING_REQUIRED, "enforced"},
499 {SMB_SIGNING_AUTO, "auto"},
504 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
506 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
507 * is implied in current control logic. This may change at some later time. A
508 * flag value of 0 means - show as development option only.
510 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
511 * screen in SWAT. This is used to exclude parameters as well as to squash all
512 * parameters that have been duplicated by pseudonyms.
514 static struct parm_struct parm_table[] = {
515 {"Base Options", P_SEP, P_SEPARATOR},
517 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
518 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
519 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
520 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
521 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
522 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
523 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
524 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
525 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
526 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
527 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
528 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
529 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
530 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
531 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
532 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
533 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
534 {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
535 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
536 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
538 {"Security Options", P_SEP, P_SEPARATOR},
540 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
541 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
542 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
543 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
545 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
558 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"plaintext auth", P_BOOL, P_GLOBAL, &Globals.bPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
574 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
575 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
577 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
578 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
579 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
581 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
583 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
585 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
587 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
588 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
589 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
590 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
592 {"Logging Options", P_SEP, P_SEPARATOR},
594 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
595 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
596 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
598 {"Protocol Options", P_SEP, P_SEPARATOR},
600 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
601 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
602 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
603 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
605 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
606 {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
608 {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
609 {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
611 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
612 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
613 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
614 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
615 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
616 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
617 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
618 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
620 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
622 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
623 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
624 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
625 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
627 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
628 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
629 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
634 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
635 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
636 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
638 {"Tuning Options", P_SEP, P_SEPARATOR},
640 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
641 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
642 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
643 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
645 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
646 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
647 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
649 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
650 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
651 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
653 {"Printing Options", P_SEP, P_SEPARATOR},
655 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
656 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
657 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
658 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
659 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
660 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
661 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
662 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
663 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
664 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
666 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
667 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
668 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
671 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
672 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
674 {"Filename Handling", P_SEP, P_SEPARATOR},
676 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
677 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
678 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
680 {"Domain Options", P_SEP, P_SEPARATOR},
682 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
684 {"Logon Options", P_SEP, P_SEPARATOR},
686 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
687 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
689 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
690 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
691 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"Browse Options", P_SEP, P_SEPARATOR},
697 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
702 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
703 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
705 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
706 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
708 {"WINS Options", P_SEP, P_SEPARATOR},
709 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
712 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
713 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
714 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
715 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
717 {"Locking Options", P_SEP, P_SEPARATOR},
719 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
720 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
721 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
722 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
724 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
725 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
726 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
727 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
730 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
732 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
733 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
736 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
737 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
739 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
741 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
742 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
744 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
747 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
748 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
750 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
751 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
752 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
754 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
758 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
759 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760 {"Winbind options", P_SEP, P_SEPARATOR},
762 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
775 /***************************************************************************
776 Initialise the sDefault parameter structure for the printer values.
777 ***************************************************************************/
779 static void init_printer_values(void)
781 /* choose defaults depending on the type of printing */
782 switch (sDefault.iPrinting) {
787 do_parameter("Lpqcommand", "lpq -P'%p'");
788 do_parameter("Lprmcommand", "lprm -P'%p' %j");
789 do_parameter("Printcommand",
795 do_parameter("Lpqcommand", "lpq -P'%p'");
796 do_parameter("Lprmcommand", "lprm -P'%p' %j");
797 do_parameter("Printcommand",
799 do_parameter("Queuepausecommand",
801 do_parameter("Queueresumecommand",
803 do_parameter("Lppausecommand",
805 do_parameter("Lpresumecommand",
806 "lpc release '%p' %j");
811 do_parameter("Lpqcommand", "");
812 do_parameter("Lprmcommand", "");
813 do_parameter("Printcommand", "");
814 do_parameter("Lppausecommand", "");
815 do_parameter("Lpresumecommand", "");
816 do_parameter("Queuepausecommand", "");
817 do_parameter("Queueresumecommand", "");
819 do_parameter("Printcapname", "cups");
821 do_parameter("Lpqcommand",
822 "/usr/bin/lpstat -o '%p'");
823 do_parameter("Lprmcommand",
824 "/usr/bin/cancel '%p-%j'");
825 do_parameter("Printcommand",
826 "/usr/bin/lp -d '%p' %s; rm %s");
827 do_parameter("Lppausecommand",
828 "lp -i '%p-%j' -H hold");
829 do_parameter("Lpresumecommand",
830 "lp -i '%p-%j' -H resume");
831 do_parameter("Queuepausecommand",
832 "/usr/bin/disable '%p'");
833 do_parameter("Queueresumecommand",
834 "/usr/bin/enable '%p'");
835 do_parameter("Printcapname", "lpstat");
836 #endif /* HAVE_CUPS */
841 do_parameter("Lpqcommand", "lpstat -o%p");
842 do_parameter("Lprmcommand", "cancel %p-%j");
843 do_parameter("Printcommand",
844 "lp -c -d%p %s; rm %s");
845 do_parameter("Queuepausecommand",
847 do_parameter("Queueresumecommand",
850 do_parameter("Lppausecommand",
851 "lp -i %p-%j -H hold");
852 do_parameter("Lpresumecommand",
853 "lp -i %p-%j -H resume");
858 do_parameter("Lpqcommand", "lpq -P%p");
859 do_parameter("Lprmcommand", "lprm -P%p %j");
860 do_parameter("Printcommand", "lp -r -P%p %s");
864 do_parameter("Lpqcommand", "qstat -l -d%p");
865 do_parameter("Lprmcommand",
867 do_parameter("Printcommand",
868 "lp -d%p -s %s; rm %s");
869 do_parameter("Lppausecommand",
871 do_parameter("Lpresumecommand",
877 do_parameter("Printcommand", "vlp print %p %s");
878 do_parameter("Lpqcommand", "vlp lpq %p");
879 do_parameter("Lprmcommand", "vlp lprm %p %j");
880 do_parameter("Lppausecommand", "vlp lppause %p %j");
881 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
882 do_parameter("Queuepausecommand", "vlp queuepause %p");
883 do_parameter("Queueresumecommand", "vlp queueresume %p");
885 #endif /* DEVELOPER */
891 /***************************************************************************
892 Initialise the global parameter structure.
893 ***************************************************************************/
894 static void init_globals(void)
899 DEBUG(3, ("Initialising global parameters\n"));
901 for (i = 0; parm_table[i].label; i++) {
902 if ((parm_table[i].type == P_STRING ||
903 parm_table[i].type == P_USTRING) &&
905 !(parm_table[i].flags & FLAG_CMDLINE)) {
906 string_set(parm_table[i].ptr, "");
910 /* options that can be set on the command line must be initialised via
911 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
913 do_parameter("socket options", "TCP_NODELAY");
915 do_parameter("workgroup", DEFAULT_WORKGROUP);
916 myname = get_myname();
917 do_parameter("netbios name", myname);
919 do_parameter("max protocol", "NT1");
920 do_parameter("name resolve order", "lmhosts wins host bcast");
922 init_printer_values();
924 do_parameter("fstype", FSTYPE_STRING);
925 do_parameter("ntvfs handler", "unixuid default");
926 do_parameter("max connections", "-1");
928 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
929 do_parameter("server services", "smb rpc nbt ldap cldap web");
930 do_parameter("ntptr providor", "simple_ldb");
931 do_parameter("auth methods", "anonymous sam_ignoredomain");
932 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
933 do_parameter("private dir", dyn_PRIVATE_DIR);
934 do_parameter("sam database", "sam.ldb");
935 do_parameter("spoolss database", "spoolss.ldb");
936 do_parameter("wins database", "wins.ldb");
937 do_parameter("registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
938 do_parameter("guest account", GUEST_ACCOUNT);
940 /* using UTF8 by default allows us to support all chars */
941 do_parameter("unix charset", "UTF8");
943 /* Use codepage 850 as a default for the dos character set */
944 do_parameter("dos charset", "CP850");
947 * Allow the default PASSWD_CHAT to be overridden in local.h.
949 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
951 do_parameter("passwd program", "");
952 do_parameter("printcap name", PRINTCAP_NAME);
954 do_parameter("pid directory", dyn_PIDDIR);
955 do_parameter("lock dir", dyn_LOCKDIR);
956 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
958 do_parameter("socket address", "0.0.0.0");
959 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
961 do_parameter_var("announce version", "%d.%d",
962 DEFAULT_MAJOR_VERSION,
963 DEFAULT_MINOR_VERSION);
965 do_parameter("logon drive", "");
967 do_parameter("logon home", "\\\\%N\\%U");
968 do_parameter("logon path", "\\\\%N\\%U\\profile");
969 do_parameter("password server", "*");
971 do_parameter("load printers", "True");
973 do_parameter("max mux", "50");
974 do_parameter("max xmit", "12288");
975 do_parameter("lpqcachetime", "10");
976 do_parameter("DisableSpoolss", "False");
977 do_parameter("password level", "0");
978 do_parameter("username level", "0");
979 do_parameter("LargeReadwrite", "True");
980 do_parameter("minprotocol", "CORE");
981 do_parameter("security", "USER");
982 do_parameter("paranoid server security", "True");
983 do_parameter("EncryptPasswords", "True");
984 do_parameter("ReadRaw", "True");
985 do_parameter("WriteRaw", "True");
986 do_parameter("NullPasswords", "False");
987 do_parameter("ObeyPamRestrictions", "False");
988 do_parameter("lm announce", "Auto");
989 do_parameter("lm interval", "60");
990 do_parameter("announce as", "NT SERVER");
992 do_parameter("TimeServer", "False");
993 do_parameter("BindInterfacesOnly", "False");
994 do_parameter("PamPasswordChange", "False");
995 do_parameter("Unicode", "True");
996 do_parameter("restrict anonymous", "0");
997 do_parameter("ClientLanManAuth", "True");
998 do_parameter("LanmanAuth", "True");
999 do_parameter("NTLMAuth", "True");
1001 do_parameter("enhanced browsing", "True");
1002 do_parameter("LockSpinCount", "3");
1003 do_parameter("LockSpinTime", "10");
1004 #ifdef MMAP_BLACKLIST
1005 do_parameter("UseMmap", "False");
1007 do_parameter("UseMmap", "True");
1009 do_parameter("UnixExtensions", "False");
1011 /* hostname lookups can be very expensive and are broken on
1012 a large number of sites (tridge) */
1013 do_parameter("HostnameLookups", "False");
1015 do_parameter("PreferredMaster", "Auto");
1016 do_parameter("os level", "20");
1017 do_parameter("LocalMaster", "True");
1018 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1019 do_parameter("DomainLogons", "False");
1020 do_parameter("WINSsupport", "False");
1021 do_parameter("WINSproxy", "False");
1023 do_parameter("DNSproxy", "True");
1025 do_parameter("AllowTrustedDomains", "True");
1027 do_parameter("TemplateShell", "/bin/false");
1028 do_parameter("TemplateHomedir", "/home/%D/%U");
1029 do_parameter("WinbindSeparator", "\\");
1031 do_parameter("winbind cache time", "15");
1032 do_parameter("WinbindEnumUsers", "True");
1033 do_parameter("WinbindEnumGroups", "True");
1034 do_parameter("WinbindUseDefaultDomain", "False");
1036 do_parameter("IDMapBackend", "tdb");
1038 do_parameter("name cache timeout", "660"); /* In seconds */
1040 do_parameter("client signing", "Yes");
1041 do_parameter("server signing", "auto");
1043 do_parameter("use spnego", "True");
1045 do_parameter("smb ports", SMB_PORTS);
1046 do_parameter("nbt port", "137");
1047 do_parameter("dgram port", "138");
1048 do_parameter("cldap port", "389");
1049 do_parameter("krb5 port", "88");
1050 do_parameter("web port", "901");
1051 do_parameter("swat directory", dyn_SWATDIR);
1053 do_parameter("nt status support", "True");
1055 do_parameter("max wins ttl", "432000");
1056 do_parameter("min wins ttl", "10");
1058 do_parameter("tls enabled", "True");
1059 do_parameter("tls keyfile", "tls/key.pem");
1060 do_parameter("tls certfile", "tls/cert.pem");
1061 do_parameter("tls cafile", "tls/ca.pem");
1064 static TALLOC_CTX *lp_talloc;
1066 /******************************************************************* a
1067 Free up temporary memory - called from the main loop.
1068 ********************************************************************/
1070 void lp_talloc_free(void)
1074 talloc_free(lp_talloc);
1078 /*******************************************************************
1079 Convenience routine to grab string parameters into temporary memory
1080 and run standard_sub_basic on them. The buffers can be written to by
1081 callers without affecting the source string.
1082 ********************************************************************/
1084 static const char *lp_string(const char *s)
1086 #if 0 /* until REWRITE done to make thread-safe */
1087 size_t len = s ? strlen(s) : 0;
1091 /* The follow debug is useful for tracking down memory problems
1092 especially if you have an inner loop that is calling a lp_*()
1093 function that returns a string. Perhaps this debug should be
1094 present all the time? */
1097 DEBUG(10, ("lp_string(%s)\n", s));
1100 #if 0 /* until REWRITE done to make thread-safe */
1102 lp_talloc = talloc_init("lp_talloc");
1104 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1112 StrnCpy(ret, s, len);
1114 if (trim_string(ret, "\"", "\"")) {
1115 if (strchr(ret,'"') != NULL)
1116 StrnCpy(ret, s, len);
1119 standard_sub_basic(ret,len+100);
1126 In this section all the functions that are used to access the
1127 parameters from the rest of the program are defined
1130 #define FN_GLOBAL_STRING(fn_name,ptr) \
1131 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1132 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1133 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1134 #define FN_GLOBAL_LIST(fn_name,ptr) \
1135 const char **fn_name(void) {return(*(const char ***)(ptr));}
1136 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1137 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1138 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1139 char fn_name(void) {return(*(char *)(ptr));}
1140 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1141 int fn_name(void) {return(*(int *)(ptr));}
1143 #define FN_LOCAL_STRING(fn_name,val) \
1144 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1145 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1146 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1147 #define FN_LOCAL_LIST(fn_name,val) \
1148 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1149 #define FN_LOCAL_BOOL(fn_name,val) \
1150 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1151 #define FN_LOCAL_CHAR(fn_name,val) \
1152 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1153 #define FN_LOCAL_INTEGER(fn_name,val) \
1154 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1156 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1157 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1158 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
1159 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
1160 FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
1161 FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
1162 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1163 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
1164 FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled)
1165 FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile)
1166 FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile)
1167 FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile)
1168 FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile)
1169 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1170 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1171 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1172 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1173 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1174 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1175 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1176 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
1177 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1178 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1179 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1180 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1181 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1182 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1183 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1184 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1185 FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
1186 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1187 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1188 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1189 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1190 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1191 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1192 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1193 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1194 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1195 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1196 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1197 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1198 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1199 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1200 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1201 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1202 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1203 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1204 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1205 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1206 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1207 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1208 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1209 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1210 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1211 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1212 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1214 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1216 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1218 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1219 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1220 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1221 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1222 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1223 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1224 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1225 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1226 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1228 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1229 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1230 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1231 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1232 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1233 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1234 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1235 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1236 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1237 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1238 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1239 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1240 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1241 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1242 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1243 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1244 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1245 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1246 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1247 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1248 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1249 FN_GLOBAL_BOOL(lp_plaintext_auth, &Globals.bPlaintextAuth)
1250 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1251 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1252 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1253 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1254 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1255 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1256 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1257 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1258 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1259 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1260 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1261 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1262 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1263 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1264 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1265 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1266 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1267 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1268 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1269 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1270 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1271 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1272 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1273 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1274 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1275 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1276 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1277 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1278 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1279 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1280 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1281 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1282 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1283 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1284 FN_LOCAL_STRING(lp_servicename, szService)
1285 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1286 FN_LOCAL_STRING(lp_pathname, szPath)
1287 FN_LOCAL_STRING(lp_username, szUsername)
1288 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1289 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1290 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1291 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1292 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1293 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1294 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1295 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1296 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1297 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1298 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1299 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1300 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1301 FN_LOCAL_STRING(lp_comment, comment)
1302 FN_LOCAL_STRING(lp_fstype, fstype)
1303 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1304 static FN_LOCAL_STRING(lp_volume, volume)
1305 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1306 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1307 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1308 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1309 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1310 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1311 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1312 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1313 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1314 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1315 FN_LOCAL_BOOL(lp_locking, bLocking)
1316 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1317 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1318 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1319 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1320 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1321 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1322 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1323 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1324 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1325 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1326 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1327 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1328 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1329 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1330 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1331 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1332 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1333 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1335 /* local prototypes */
1337 static int map_parameter(const char *pszParmName);
1338 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1339 static int getservicebyname(const char *pszServiceName,
1340 service * pserviceDest);
1341 static void copy_service(service * pserviceDest,
1342 service * pserviceSource, BOOL *pcopymapDest);
1343 static BOOL service_ok(int iService);
1344 static BOOL do_section(const char *pszSectionName);
1345 static void init_copymap(service * pservice);
1347 /* This is a helper function for parametrical options support. */
1348 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1349 /* Actual parametrical functions are quite simple */
1350 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
1353 struct param_opt *data;
1355 if (lookup_service >= iNumServices) return NULL;
1357 data = (lookup_service < 0) ?
1358 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1360 asprintf(&vfskey, "%s:%s", type, option);
1364 if (strcmp(data->key, vfskey) == 0) {
1371 if (lookup_service >= 0) {
1372 /* Try to fetch the same option but from globals */
1373 /* but only if we are not already working with Globals */
1374 data = Globals.param_opt;
1376 if (strcmp(data->key, vfskey) == 0) {
1390 /*******************************************************************
1391 convenience routine to return int parameters.
1392 ********************************************************************/
1393 static int lp_int(const char *s)
1397 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1401 return strtol(s, NULL, 0);
1404 /*******************************************************************
1405 convenience routine to return unsigned long parameters.
1406 ********************************************************************/
1407 static int lp_ulong(const char *s)
1411 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1415 return strtoul(s, NULL, 0);
1418 /*******************************************************************
1419 convenience routine to return boolean parameters.
1420 ********************************************************************/
1421 static BOOL lp_bool(const char *s)
1426 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1430 if (!set_boolean(&ret,s)) {
1431 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1439 /* Return parametric option from a given service. Type is a part of option before ':' */
1440 /* Parametric option has following syntax: 'Type: option = value' */
1441 /* Returned value is allocated in 'lp_talloc' context */
1443 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1445 const char *value = lp_get_parametric(lookup_service, type, option);
1448 return lp_string(value);
1453 /* Return parametric option from a given service. Type is a part of option before ':' */
1454 /* Parametric option has following syntax: 'Type: option = value' */
1455 /* Returned value is allocated in 'lp_talloc' context */
1457 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1458 const char *separator)
1460 const char *value = lp_get_parametric(lookup_service, type, option);
1463 return str_list_make(talloc_autofree_context(), value, separator);
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 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1473 const char *value = lp_get_parametric(lookup_service, type, option);
1476 return lp_int(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 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1486 const char *value = lp_get_parametric(lookup_service, type, option);
1489 return lp_ulong(value);
1494 /* Return parametric option from a given service. Type is a part of option before ':' */
1495 /* Parametric option has following syntax: 'Type: option = value' */
1497 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1499 const char *value = lp_get_parametric(lookup_service, type, option);
1502 return lp_bool(value);
1508 /***************************************************************************
1509 Initialise a service to the defaults.
1510 ***************************************************************************/
1512 static void init_service(service * pservice)
1514 memset((char *)pservice, '\0', sizeof(service));
1515 copy_service(pservice, &sDefault, NULL);
1518 /***************************************************************************
1519 Free the dynamically allocated parts of a service struct.
1520 ***************************************************************************/
1522 static void free_service(service *pservice)
1525 struct param_opt *data, *pdata;
1529 if (pservice->szService)
1530 DEBUG(5, ("free_service: Freeing service %s\n",
1531 pservice->szService));
1533 string_free(&pservice->szService);
1534 SAFE_FREE(pservice->copymap);
1536 for (i = 0; parm_table[i].label; i++) {
1537 if ((parm_table[i].type == P_STRING ||
1538 parm_table[i].type == P_USTRING) &&
1539 parm_table[i].class == P_LOCAL) {
1540 string_free((char **)
1541 (((char *)pservice) +
1542 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1543 } else if (parm_table[i].type == P_LIST &&
1544 parm_table[i].class == P_LOCAL) {
1545 char ***listp = (char ***)(((char *)pservice) +
1546 PTR_DIFF(parm_table[i].ptr, &sDefault));
1547 talloc_free(*listp);
1552 DEBUG(5,("Freeing parametrics:\n"));
1553 data = pservice->param_opt;
1555 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1556 string_free(&data->key);
1557 string_free(&data->value);
1563 ZERO_STRUCTP(pservice);
1566 /***************************************************************************
1567 Add a new service to the services array initialising it with the given
1569 ***************************************************************************/
1571 static int add_a_service(const service *pservice, const char *name)
1575 int num_to_alloc = iNumServices + 1;
1576 struct param_opt *data, *pdata;
1578 tservice = *pservice;
1580 /* it might already exist */
1582 i = getservicebyname(name, NULL);
1584 /* Clean all parametric options for service */
1585 /* They will be added during parsing again */
1586 data = ServicePtrs[i]->param_opt;
1588 string_free(&data->key);
1589 string_free(&data->value);
1594 ServicePtrs[i]->param_opt = NULL;
1599 /* find an invalid one */
1600 for (i = 0; i < iNumServices; i++)
1601 if (!ServicePtrs[i]->valid)
1604 /* if not, then create one */
1605 if (i == iNumServices) {
1608 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1611 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1616 ServicePtrs[iNumServices] = malloc_p(service);
1618 if (!ServicePtrs[iNumServices]) {
1619 DEBUG(0,("add_a_service: out of memory!\n"));
1625 free_service(ServicePtrs[i]);
1627 ServicePtrs[i]->valid = True;
1629 init_service(ServicePtrs[i]);
1630 copy_service(ServicePtrs[i], &tservice, NULL);
1632 string_set(&ServicePtrs[i]->szService, name);
1636 /***************************************************************************
1637 Add a new home service, with the specified home directory, defaults coming
1639 ***************************************************************************/
1641 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1642 const char *user, const char *pszHomedir)
1647 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1652 if (!(*(ServicePtrs[iDefaultService]->szPath))
1653 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1654 pstrcpy(newHomedir, pszHomedir);
1656 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1657 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1660 string_set(&ServicePtrs[i]->szPath, newHomedir);
1662 if (!(*(ServicePtrs[i]->comment))) {
1664 slprintf(comment, sizeof(comment) - 1,
1665 "Home directory of %s", user);
1666 string_set(&ServicePtrs[i]->comment, comment);
1668 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1669 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1671 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1677 /***************************************************************************
1678 Add a new service, based on an old one.
1679 ***************************************************************************/
1681 int lp_add_service(const char *pszService, int iDefaultService)
1683 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1686 /***************************************************************************
1687 Add the IPC service.
1688 ***************************************************************************/
1690 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1693 int i = add_a_service(&sDefault, name);
1698 slprintf(comment, sizeof(comment) - 1,
1699 "%s Service (%s)", fstype, Globals.szServerString);
1701 string_set(&ServicePtrs[i]->szPath, tmpdir());
1702 string_set(&ServicePtrs[i]->szUsername, "");
1703 string_set(&ServicePtrs[i]->comment, comment);
1704 string_set(&ServicePtrs[i]->fstype, fstype);
1705 ServicePtrs[i]->iMaxConnections = -1;
1706 ServicePtrs[i]->bAvailable = True;
1707 ServicePtrs[i]->bRead_only = True;
1708 ServicePtrs[i]->bGuest_only = False;
1709 ServicePtrs[i]->bGuest_ok = guest_ok;
1710 ServicePtrs[i]->bPrint_ok = False;
1711 ServicePtrs[i]->bBrowseable = False;
1713 if (strcasecmp(fstype, "IPC") == 0) {
1714 lp_do_parameter(i, "ntvfs handler", "default");
1717 DEBUG(3, ("adding hidden service %s\n", name));
1722 /***************************************************************************
1723 Add a new printer service, with defaults coming from service iFrom.
1724 ***************************************************************************/
1726 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1728 const char *comment = "From Printcap";
1729 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1734 /* note that we do NOT default the availability flag to True - */
1735 /* we take it from the default service passed. This allows all */
1736 /* dynamic printers to be disabled by disabling the [printers] */
1737 /* entry (if/when the 'available' keyword is implemented!). */
1739 /* the printer name is set to the service name. */
1740 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1741 string_set(&ServicePtrs[i]->comment, comment);
1742 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1743 /* Printers cannot be read_only. */
1744 ServicePtrs[i]->bRead_only = False;
1745 /* No share modes on printer services. */
1746 ServicePtrs[i]->bShareModes = False;
1747 /* No oplocks on printer services. */
1748 ServicePtrs[i]->bOpLocks = False;
1749 /* Printer services must be printable. */
1750 ServicePtrs[i]->bPrint_ok = True;
1752 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1754 update_server_announce_as_printserver();
1759 /***************************************************************************
1760 Map a parameter's string representation to something we can use.
1761 Returns False if the parameter string is not recognised, else TRUE.
1762 ***************************************************************************/
1764 static int map_parameter(const char *pszParmName)
1768 if (*pszParmName == '-')
1771 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1772 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1775 /* Warn only if it isn't parametric option */
1776 if (strchr(pszParmName, ':') == NULL)
1777 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1778 /* We do return 'fail' for parametric options as well because they are
1779 stored in different storage
1786 return the parameter structure for a parameter
1788 struct parm_struct *lp_parm_struct(const char *name)
1790 int parmnum = map_parameter(name);
1791 if (parmnum == -1) return NULL;
1792 return &parm_table[parmnum];
1796 return the parameter pointer for a parameter
1798 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1803 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1806 /***************************************************************************
1807 Set a boolean variable from the text value stored in the passed string.
1808 Returns True in success, False if the passed string does not correctly
1809 represent a boolean.
1810 ***************************************************************************/
1812 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1817 if (strwicmp(pszParmValue, "yes") == 0 ||
1818 strwicmp(pszParmValue, "true") == 0 ||
1819 strwicmp(pszParmValue, "1") == 0)
1821 else if (strwicmp(pszParmValue, "no") == 0 ||
1822 strwicmp(pszParmValue, "False") == 0 ||
1823 strwicmp(pszParmValue, "0") == 0)
1827 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1834 /***************************************************************************
1835 Find a service by name. Otherwise works like get_service.
1836 ***************************************************************************/
1838 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1842 for (iService = iNumServices - 1; iService >= 0; iService--)
1843 if (VALID(iService) &&
1844 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1845 if (pserviceDest != NULL)
1846 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1853 /***************************************************************************
1854 Copy a service structure to another.
1855 If pcopymapDest is NULL then copy all fields
1856 ***************************************************************************/
1858 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1861 BOOL bcopyall = (pcopymapDest == NULL);
1862 struct param_opt *data, *pdata, *paramo;
1865 for (i = 0; parm_table[i].label; i++)
1866 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1867 (bcopyall || pcopymapDest[i])) {
1868 void *def_ptr = parm_table[i].ptr;
1870 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1873 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1876 switch (parm_table[i].type) {
1878 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1883 *(int *)dest_ptr = *(int *)src_ptr;
1887 string_set(dest_ptr,
1892 string_set(dest_ptr,
1894 strupper(*(char **)dest_ptr);
1897 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1898 *(const char ***)src_ptr);
1906 init_copymap(pserviceDest);
1907 if (pserviceSource->copymap)
1908 memcpy((void *)pserviceDest->copymap,
1909 (void *)pserviceSource->copymap,
1910 sizeof(BOOL) * NUMPARAMETERS);
1913 data = pserviceSource->param_opt;
1916 pdata = pserviceDest->param_opt;
1917 /* Traverse destination */
1919 /* If we already have same option, override it */
1920 if (strcmp(pdata->key, data->key) == 0) {
1921 string_free(&pdata->value);
1922 pdata->value = strdup(data->value);
1926 pdata = pdata->next;
1929 paramo = smb_xmalloc_p(struct param_opt);
1930 paramo->key = strdup(data->key);
1931 paramo->value = strdup(data->value);
1932 DLIST_ADD(pserviceDest->param_opt, paramo);
1938 /***************************************************************************
1939 Check a service for consistency. Return False if the service is in any way
1940 incomplete or faulty, else True.
1941 ***************************************************************************/
1943 static BOOL service_ok(int iService)
1948 if (ServicePtrs[iService]->szService[0] == '\0') {
1949 DEBUG(0, ("The following message indicates an internal error:\n"));
1950 DEBUG(0, ("No service name in service entry.\n"));
1954 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1955 /* I can't see why you'd want a non-printable printer service... */
1956 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1957 if (!ServicePtrs[iService]->bPrint_ok) {
1958 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1959 ServicePtrs[iService]->szService));
1960 ServicePtrs[iService]->bPrint_ok = True;
1961 update_server_announce_as_printserver();
1963 /* [printers] service must also be non-browsable. */
1964 if (ServicePtrs[iService]->bBrowseable)
1965 ServicePtrs[iService]->bBrowseable = False;
1968 /* If a service is flagged unavailable, log the fact at level 0. */
1969 if (!ServicePtrs[iService]->bAvailable)
1970 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1971 ServicePtrs[iService]->szService));
1976 static struct file_lists {
1977 struct file_lists *next;
1981 } *file_lists = NULL;
1983 /*******************************************************************
1984 Keep a linked list of all config files so we know when one has changed
1985 it's date and needs to be reloaded.
1986 ********************************************************************/
1988 static void add_to_file_list(const char *fname, const char *subfname)
1990 struct file_lists *f = file_lists;
1993 if (f->name && !strcmp(f->name, fname))
1999 f = malloc_p(struct file_lists);
2002 f->next = file_lists;
2003 f->name = strdup(fname);
2008 f->subfname = strdup(subfname);
2014 f->modtime = file_modtime(subfname);
2016 time_t t = file_modtime(subfname);
2022 /*******************************************************************
2023 Check if a config file has changed date.
2024 ********************************************************************/
2026 BOOL lp_file_list_changed(void)
2028 struct file_lists *f = file_lists;
2029 DEBUG(6, ("lp_file_list_changed()\n"));
2035 pstrcpy(n2, f->name);
2036 standard_sub_basic(n2,sizeof(n2));
2038 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2039 f->name, n2, ctime(&f->modtime)));
2041 mod_time = file_modtime(n2);
2043 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2045 ("file %s modified: %s\n", n2,
2047 f->modtime = mod_time;
2048 SAFE_FREE(f->subfname);
2049 f->subfname = strdup(n2);
2057 /***************************************************************************
2058 Handle the include operation.
2059 ***************************************************************************/
2061 static BOOL handle_include(const char *pszParmValue, char **ptr)
2064 pstrcpy(fname, pszParmValue);
2066 standard_sub_basic(fname,sizeof(fname));
2068 add_to_file_list(pszParmValue, fname);
2070 string_set(ptr, fname);
2072 if (file_exist(fname))
2073 return (pm_process(fname, do_section, do_parameter));
2075 DEBUG(2, ("Can't find include file %s\n", fname));
2080 /***************************************************************************
2081 Handle the interpretation of the copy parameter.
2082 ***************************************************************************/
2084 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2088 service serviceTemp;
2090 string_set(ptr, pszParmValue);
2092 init_service(&serviceTemp);
2096 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2098 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2099 if (iTemp == iServiceIndex) {
2100 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2102 copy_service(ServicePtrs[iServiceIndex],
2104 ServicePtrs[iServiceIndex]->copymap);
2108 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2112 free_service(&serviceTemp);
2116 /***************************************************************************
2117 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2122 winbind uid = 1000-1999
2123 winbind gid = 700-899
2125 We only do simple parsing checks here. The strings are parsed into useful
2126 structures in the winbind daemon code.
2128 ***************************************************************************/
2130 /* Some lp_ routines to return winbind [ug]id information */
2132 static uid_t winbind_uid_low, winbind_uid_high;
2133 static gid_t winbind_gid_low, winbind_gid_high;
2134 static uint32_t non_unix_account_low, non_unix_account_high;
2136 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2138 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2142 *low = winbind_uid_low;
2145 *high = winbind_uid_high;
2150 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2152 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2156 *low = winbind_gid_low;
2159 *high = winbind_gid_high;
2164 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2166 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2170 *low = non_unix_account_low;
2173 *high = non_unix_account_high;
2178 /* Do some simple checks on "winbind [ug]id" parameter values */
2180 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2184 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2189 string_set(ptr, pszParmValue);
2191 winbind_uid_low = low;
2192 winbind_uid_high = high;
2197 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2201 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2206 string_set(ptr, pszParmValue);
2208 winbind_gid_low = low;
2209 winbind_gid_high = high;
2214 /***************************************************************************
2215 Do some simple checks on "non unix account range" parameter values.
2216 ***************************************************************************/
2218 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2222 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2227 string_set(ptr, pszParmValue);
2229 non_unix_account_low = low;
2230 non_unix_account_high = high;
2236 /***************************************************************************
2237 Initialise a copymap.
2238 ***************************************************************************/
2240 static void init_copymap(service * pservice)
2243 SAFE_FREE(pservice->copymap);
2244 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2245 if (!pservice->copymap)
2247 ("Couldn't allocate copymap!! (size %d)\n",
2248 (int)NUMPARAMETERS));
2250 for (i = 0; i < NUMPARAMETERS; i++)
2251 pservice->copymap[i] = True;
2254 /***************************************************************************
2255 Return the local pointer to a parameter given the service number and the
2256 pointer into the default structure.
2257 ***************************************************************************/
2259 void *lp_local_ptr(int snum, void *ptr)
2261 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2265 /***************************************************************************
2266 Process a parametric option
2267 ***************************************************************************/
2268 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2270 struct param_opt *paramo, *data;
2273 while (isspace(*pszParmName)) {
2277 name = strdup(pszParmName);
2278 if (!name) return False;
2283 data = Globals.param_opt;
2285 data = ServicePtrs[snum]->param_opt;
2288 /* Traverse destination */
2289 for (paramo=data; paramo; paramo=paramo->next) {
2290 /* If we already have the option set, override it unless
2291 it was a command line option and the new one isn't */
2292 if (strcmp(paramo->key, name) == 0) {
2293 if ((paramo->flags & FLAG_CMDLINE) &&
2294 !(flags & FLAG_CMDLINE)) {
2298 free(paramo->value);
2299 paramo->value = strdup(pszParmValue);
2300 paramo->flags = flags;
2306 paramo = smb_xmalloc_p(struct param_opt);
2307 paramo->key = strdup(name);
2308 paramo->value = strdup(pszParmValue);
2309 paramo->flags = flags;
2311 DLIST_ADD(Globals.param_opt, paramo);
2313 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2321 /***************************************************************************
2322 Process a parameter for a particular service number. If snum < 0
2323 then assume we are in the globals.
2324 ***************************************************************************/
2325 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2328 void *parm_ptr = NULL; /* where we are going to store the result */
2329 void *def_ptr = NULL;
2331 parmnum = map_parameter(pszParmName);
2334 if (strchr(pszParmName, ':')) {
2335 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2337 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2341 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2342 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2346 /* if the flag has been set on the command line, then don't allow override,
2347 but don't report an error */
2348 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2352 def_ptr = parm_table[parmnum].ptr;
2354 /* we might point at a service, the default service or a global */
2358 if (parm_table[parmnum].class == P_GLOBAL) {
2360 ("Global parameter %s found in service section!\n",
2365 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2370 if (!ServicePtrs[snum]->copymap)
2371 init_copymap(ServicePtrs[snum]);
2373 /* this handles the aliases - set the copymap for other entries with
2374 the same data pointer */
2375 for (i = 0; parm_table[i].label; i++)
2376 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2377 ServicePtrs[snum]->copymap[i] = False;
2380 /* if it is a special case then go ahead */
2381 if (parm_table[parmnum].special) {
2382 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2386 /* now switch on the type of variable it is */
2387 switch (parm_table[parmnum].type)
2390 set_boolean(parm_ptr, pszParmValue);
2394 *(int *)parm_ptr = atoi(pszParmValue);
2398 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
2399 pszParmValue, NULL);
2403 string_set(parm_ptr, pszParmValue);
2407 string_set(parm_ptr, pszParmValue);
2408 strupper(*(char **)parm_ptr);
2412 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2415 parm_table[parmnum].enum_list[i].name)) {
2417 parm_table[parmnum].
2422 if (!parm_table[parmnum].enum_list[i].name) {
2423 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2424 pszParmValue, pszParmName));
2435 /***************************************************************************
2436 Process a parameter.
2437 ***************************************************************************/
2439 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2441 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2442 pszParmName, pszParmValue));
2446 variable argument do parameter
2448 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2450 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2457 s = talloc_vasprintf(NULL, fmt, ap);
2459 ret = do_parameter(pszParmName, s);
2466 set a parameter from the commandline - this is called from command line parameter
2467 parsing code. It sets the parameter then marks the parameter as unable to be modified
2468 by smb.conf processing
2470 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2472 int parmnum = map_parameter(pszParmName);
2475 while (isspace(*pszParmValue)) pszParmValue++;
2478 if (parmnum < 0 && strchr(pszParmName, ':')) {
2479 /* set a parametric option */
2480 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2484 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2488 /* reset the CMDLINE flag in case this has been called before */
2489 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2491 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2495 parm_table[parmnum].flags |= FLAG_CMDLINE;
2497 /* we have to also set FLAG_CMDLINE on aliases */
2498 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2499 parm_table[i].flags |= FLAG_CMDLINE;
2501 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2502 parm_table[i].flags |= FLAG_CMDLINE;
2509 set a option from the commandline in 'a=b' format. Use to support --option
2511 BOOL lp_set_option(const char *option)
2529 ret = lp_set_cmdline(s, p+1);
2535 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2537 /***************************************************************************
2538 Print a parameter of the specified type.
2539 ***************************************************************************/
2541 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2547 for (i = 0; p->enum_list[i].name; i++) {
2548 if (*(int *)ptr == p->enum_list[i].value) {
2550 p->enum_list[i].name);
2557 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2561 fprintf(f, "%d", *(int *)ptr);
2565 if ((char ***)ptr && *(char ***)ptr) {
2566 char **list = *(char ***)ptr;
2568 for (; *list; list++)
2569 fprintf(f, "%s%s", *list,
2570 ((*(list+1))?", ":""));
2576 if (*(char **)ptr) {
2577 fprintf(f, "%s", *(char **)ptr);
2585 /***************************************************************************
2586 Check if two parameters are equal.
2587 ***************************************************************************/
2589 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2593 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2597 return (*((int *)ptr1) == *((int *)ptr2));
2600 return str_list_equal((const char **)(*(char ***)ptr1),
2601 (const char **)(*(char ***)ptr2));
2606 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2611 return (p1 == p2 || strequal(p1, p2));
2619 /***************************************************************************
2620 Process a new section (service). At this stage all sections are services.
2621 Later we'll have special sections that permit server parameters to be set.
2622 Returns True on success, False on failure.
2623 ***************************************************************************/
2625 static BOOL do_section(const char *pszSectionName)
2628 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2629 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2632 /* if we've just struck a global section, note the fact. */
2633 bInGlobalSection = isglobal;
2635 /* check for multiple global sections */
2636 if (bInGlobalSection) {
2637 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2641 /* if we have a current service, tidy it up before moving on */
2644 if (iServiceIndex >= 0)
2645 bRetval = service_ok(iServiceIndex);
2647 /* if all is still well, move to the next record in the services array */
2649 /* We put this here to avoid an odd message order if messages are */
2650 /* issued by the post-processing of a previous section. */
2651 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2653 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2655 DEBUG(0, ("Failed to add a new service\n"));
2664 /***************************************************************************
2665 Determine if a partcular base parameter is currentl set to the default value.
2666 ***************************************************************************/
2668 static BOOL is_default(int i)
2670 if (!defaults_saved)
2672 switch (parm_table[i].type) {
2674 return str_list_equal((const char **)parm_table[i].def.lvalue,
2675 (const char **)(*(char ***)parm_table[i].ptr));
2678 return strequal(parm_table[i].def.svalue,
2679 *(char **)parm_table[i].ptr);
2681 return parm_table[i].def.bvalue ==
2682 *(BOOL *)parm_table[i].ptr;
2685 return parm_table[i].def.ivalue ==
2686 *(int *)parm_table[i].ptr;
2693 /***************************************************************************
2694 Display the contents of the global structure.
2695 ***************************************************************************/
2697 static void dump_globals(FILE *f)
2700 struct param_opt *data;
2702 fprintf(f, "# Global parameters\n[global]\n");
2704 for (i = 0; parm_table[i].label; i++)
2705 if (parm_table[i].class == P_GLOBAL &&
2706 parm_table[i].ptr &&
2707 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2708 if (defaults_saved && is_default(i))
2710 fprintf(f, "\t%s = ", parm_table[i].label);
2711 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2714 if (Globals.param_opt != NULL) {
2715 data = Globals.param_opt;
2717 fprintf(f, "\t%s = %s\n", data->key, data->value);
2724 /***************************************************************************
2725 Display the contents of a single services record.
2726 ***************************************************************************/
2728 static void dump_a_service(service * pService, FILE * f)
2731 struct param_opt *data;
2733 if (pService != &sDefault)
2734 fprintf(f, "\n[%s]\n", pService->szService);
2736 for (i = 0; parm_table[i].label; i++)
2737 if (parm_table[i].class == P_LOCAL &&
2738 parm_table[i].ptr &&
2739 (*parm_table[i].label != '-') &&
2740 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2741 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2743 if (pService == &sDefault) {
2744 if (defaults_saved && is_default(i))
2747 if (equal_parameter(parm_table[i].type,
2748 ((char *)pService) +
2750 ((char *)&sDefault) +
2755 fprintf(f, "\t%s = ", parm_table[i].label);
2756 print_parameter(&parm_table[i],
2757 ((char *)pService) + pdiff, f);
2760 if (pService->param_opt != NULL) {
2761 data = pService->param_opt;
2763 fprintf(f, "\t%s = %s\n", data->key, data->value);
2770 /***************************************************************************
2771 Return info about the next service in a service. snum==-1 gives the globals.
2772 Return NULL when out of parameters.
2773 ***************************************************************************/
2775 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2778 /* do the globals */
2779 for (; parm_table[*i].label; (*i)++) {
2780 if (parm_table[*i].class == P_SEPARATOR)
2781 return &parm_table[(*i)++];
2783 if (!parm_table[*i].ptr
2784 || (*parm_table[*i].label == '-'))
2788 && (parm_table[*i].ptr ==
2789 parm_table[(*i) - 1].ptr))
2792 return &parm_table[(*i)++];
2795 service *pService = ServicePtrs[snum];
2797 for (; parm_table[*i].label; (*i)++) {
2798 if (parm_table[*i].class == P_SEPARATOR)
2799 return &parm_table[(*i)++];
2801 if (parm_table[*i].class == P_LOCAL &&
2802 parm_table[*i].ptr &&
2803 (*parm_table[*i].label != '-') &&
2805 (parm_table[*i].ptr !=
2806 parm_table[(*i) - 1].ptr)))
2809 PTR_DIFF(parm_table[*i].ptr,
2812 if (allparameters ||
2813 !equal_parameter(parm_table[*i].type,
2814 ((char *)pService) +
2816 ((char *)&sDefault) +
2819 return &parm_table[(*i)++];
2829 /***************************************************************************
2830 Return TRUE if the passed service number is within range.
2831 ***************************************************************************/
2833 BOOL lp_snum_ok(int iService)
2835 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2838 /***************************************************************************
2839 Auto-load some home services.
2840 ***************************************************************************/
2842 static void lp_add_auto_services(const char *str)
2847 /***************************************************************************
2848 Auto-load one printer.
2849 ***************************************************************************/
2851 void lp_add_one_printer(char *name, char *comment)
2853 int printers = lp_servicenumber(PRINTERS_NAME);
2856 if (lp_servicenumber(name) < 0) {
2857 lp_add_printer(name, printers);
2858 if ((i = lp_servicenumber(name)) >= 0) {
2859 string_set(&ServicePtrs[i]->comment, comment);
2860 ServicePtrs[i]->autoloaded = True;
2865 /***************************************************************************
2866 Announce ourselves as a print server.
2867 ***************************************************************************/
2869 void update_server_announce_as_printserver(void)
2871 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2874 /***************************************************************************
2875 Have we loaded a services file yet?
2876 ***************************************************************************/
2878 BOOL lp_loaded(void)
2883 /***************************************************************************
2884 Unload unused services.
2885 ***************************************************************************/
2887 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2890 for (i = 0; i < iNumServices; i++) {
2894 if (!snumused || !snumused(smb, i)) {
2895 ServicePtrs[i]->valid = False;
2896 free_service(ServicePtrs[i]);
2901 /***************************************************************************
2903 ***************************************************************************/
2905 void lp_killservice(int iServiceIn)
2907 if (VALID(iServiceIn)) {
2908 ServicePtrs[iServiceIn]->valid = False;
2909 free_service(ServicePtrs[iServiceIn]);
2913 /*******************************************************************
2914 Set the server type we will announce as via nmbd.
2915 ********************************************************************/
2917 static void set_server_role(void)
2919 server_role = ROLE_STANDALONE;
2921 switch (lp_security()) {
2923 if (lp_domain_logons())
2924 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2929 if (lp_domain_logons()) {
2930 if (Globals.bDomainMaster) /* auto or yes */
2931 server_role = ROLE_DOMAIN_PDC;
2933 server_role = ROLE_DOMAIN_BDC;
2936 server_role = ROLE_DOMAIN_MEMBER;
2939 if (lp_domain_logons()) {
2941 if (Globals.bDomainMaster) /* auto or yes */
2942 server_role = ROLE_DOMAIN_PDC;
2944 server_role = ROLE_DOMAIN_BDC;
2948 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2952 DEBUG(10, ("set_server_role: role = "));
2954 switch(server_role) {
2955 case ROLE_STANDALONE:
2956 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2958 case ROLE_DOMAIN_MEMBER:
2959 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2961 case ROLE_DOMAIN_BDC:
2962 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2964 case ROLE_DOMAIN_PDC:
2965 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
2970 /***************************************************************************
2971 Load the services array from the services file. Return True on success,
2973 ***************************************************************************/
2975 BOOL lp_load(const char *pszFname)
2979 struct param_opt *data;
2981 pstrcpy(n2, pszFname);
2982 standard_sub_basic(n2,sizeof(n2));
2984 add_to_file_list(pszFname, n2);
2988 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
2990 bInGlobalSection = True;
2992 if (Globals.param_opt != NULL) {
2993 struct param_opt *next;
2994 for (data=Globals.param_opt; data; data=next) {
2996 if (data->flags & FLAG_CMDLINE) continue;
2999 DLIST_REMOVE(Globals.param_opt, data);
3006 /* We get sections first, so have to start 'behind' to make up */
3008 bRetval = pm_process(n2, do_section, do_parameter);
3010 /* finish up the last section */
3011 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3013 if (iServiceIndex >= 0)
3014 bRetval = service_ok(iServiceIndex);
3016 lp_add_auto_services(lp_auto_services());
3018 /* When 'restrict anonymous = 2' guest connections to ipc$
3020 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3021 lp_add_hidden("ADMIN$", "DISK", False);
3024 set_default_server_announce_type();
3028 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3029 /* if bWINSsupport is true and we are in the client */
3030 if (in_client && Globals.bWINSsupport) {
3031 lp_do_parameter(-1, "wins server", "127.0.0.1");
3039 /***************************************************************************
3040 Reset the max number of services.
3041 ***************************************************************************/
3043 void lp_resetnumservices(void)
3048 /***************************************************************************
3049 Return the max number of services.
3050 ***************************************************************************/
3052 int lp_numservices(void)
3054 return (iNumServices);
3057 /***************************************************************************
3058 Display the contents of the services array in human-readable form.
3059 ***************************************************************************/
3061 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3066 defaults_saved = False;
3070 dump_a_service(&sDefault, f);
3072 for (iService = 0; iService < maxtoprint; iService++)
3073 lp_dump_one(f, show_defaults, iService);
3076 /***************************************************************************
3077 Display the contents of one service in human-readable form.
3078 ***************************************************************************/
3080 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3083 if (ServicePtrs[snum]->szService[0] == '\0')
3085 dump_a_service(ServicePtrs[snum], f);
3089 /***************************************************************************
3090 Return the number of the service with the given name, or -1 if it doesn't
3091 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3092 getservicebyname()! This works ONLY if all services have been loaded, and
3093 does not copy the found service.
3094 ***************************************************************************/
3096 int lp_servicenumber(const char *pszServiceName)
3099 fstring serviceName;
3102 for (iService = iNumServices - 1; iService >= 0; iService--) {
3103 if (VALID(iService) && ServicePtrs[iService]->szService) {
3105 * The substitution here is used to support %U is
3108 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3109 standard_sub_basic(serviceName,sizeof(serviceName));
3110 if (strequal(serviceName, pszServiceName))
3116 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3121 /*******************************************************************
3122 A useful volume label function.
3123 ********************************************************************/
3124 const char *volume_label(int snum)
3126 const char *ret = lp_volume(snum);
3128 return lp_servicename(snum);
3133 /*******************************************************************
3134 Set the server type we will announce as via nmbd.
3135 ********************************************************************/
3137 static void set_default_server_announce_type(void)
3139 default_server_announce = 0;
3140 default_server_announce |= SV_TYPE_WORKSTATION;
3141 default_server_announce |= SV_TYPE_SERVER;
3142 default_server_announce |= SV_TYPE_SERVER_UNIX;
3144 switch (lp_announce_as()) {
3145 case ANNOUNCE_AS_NT_SERVER:
3146 default_server_announce |= SV_TYPE_SERVER_NT;
3147 /* fall through... */
3148 case ANNOUNCE_AS_NT_WORKSTATION:
3149 default_server_announce |= SV_TYPE_NT;
3151 case ANNOUNCE_AS_WIN95:
3152 default_server_announce |= SV_TYPE_WIN95_PLUS;
3154 case ANNOUNCE_AS_WFW:
3155 default_server_announce |= SV_TYPE_WFW;
3161 switch (lp_server_role()) {
3162 case ROLE_DOMAIN_MEMBER:
3163 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3165 case ROLE_DOMAIN_PDC:
3166 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3168 case ROLE_DOMAIN_BDC:
3169 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3171 case ROLE_STANDALONE:
3175 if (lp_time_server())
3176 default_server_announce |= SV_TYPE_TIME_SOURCE;
3178 if (lp_host_msdfs())
3179 default_server_announce |= SV_TYPE_DFS_SERVER;
3181 /* TODO: only announce us as print server when we are a print server */
3182 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3185 /***********************************************************
3186 returns role of Samba server
3187 ************************************************************/
3189 int lp_server_role(void)
3194 /***********************************************************
3195 If we are PDC then prefer us as DMB
3196 ************************************************************/
3198 BOOL lp_domain_master(void)
3200 if (Globals.bDomainMaster == Auto)
3201 return (lp_server_role() == ROLE_DOMAIN_PDC);
3203 return Globals.bDomainMaster;
3206 /***********************************************************
3207 If we are DMB then prefer us as LMB
3208 ************************************************************/
3210 BOOL lp_preferred_master(void)
3212 if (Globals.bPreferredMaster == Auto)
3213 return (lp_local_master() && lp_domain_master());
3215 return Globals.bPreferredMaster;
3218 /*******************************************************************
3220 ********************************************************************/
3222 void lp_remove_service(int snum)
3224 ServicePtrs[snum]->valid = False;
3227 /*******************************************************************
3229 ********************************************************************/
3231 void lp_copy_service(int snum, const char *new_name)
3233 const char *oldname = lp_servicename(snum);
3234 do_section(new_name);
3236 snum = lp_servicenumber(new_name);
3238 lp_do_parameter(snum, "copy", oldname);
3243 /*******************************************************************
3244 Get the default server type we will announce as via nmbd.
3245 ********************************************************************/
3246 int lp_default_server_announce(void)
3248 return default_server_announce;
3251 const char *lp_printername(int snum)
3253 const char *ret = _lp_printername(snum);
3254 if (ret == NULL || (ret != NULL && *ret == '\0'))
3255 ret = lp_const_servicename(snum);
3261 /*******************************************************************
3262 Return the max print jobs per queue.
3263 ********************************************************************/
3265 int lp_maxprintjobs(int snum)
3267 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3268 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3269 maxjobs = PRINT_MAX_JOBID - 1;