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) Anthony Liguori 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 BOOL in_client = False; /* Not in the client by default */
58 static BOOL bLoaded = False;
61 #define GLOBAL_NAME "global"
65 #define PRINTERS_NAME "printers"
69 #define HOMES_NAME "homes"
72 /* some helpful bits */
73 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
74 #define VALID(i) ServicePtrs[i]->valid
76 static BOOL do_parameter(const char *, const char *);
78 static BOOL defaults_saved = False;
81 struct param_opt *prev, *next;
88 * This structure describes global (ie., server-wide) parameters.
95 char *display_charset;
100 char *szDefaultService;
102 char *szServerString;
103 char *szAutoServices;
104 char *szPasswdProgram;
108 char *szSMBPasswdFile;
111 char **szPassdbBackend;
112 char **szPreloadModules;
113 char *szPasswordServer;
114 char *szSocketOptions;
121 char **szWINSservers;
123 char *szRemoteAnnounce;
124 char *szRemoteBrowseSync;
125 char *szSocketAddress;
126 char *szAnnounceVersion; /* This is initialised in init_globals */
129 char **szNetbiosAliases;
130 char *szNetbiosScope;
131 char *szDomainOtherSIDs;
132 char *szNameResolveOrder;
134 char *szAddUserScript;
135 char *szAddMachineScript;
137 char *szWINSPartners;
138 char **dcerpc_ep_servers;
141 char *szNonUnixAccountRange;
142 char *szTemplateHomedir;
143 char *szTemplateShell;
144 char *szWinbindSeparator;
145 BOOL bWinbindEnumUsers;
146 BOOL bWinbindEnumGroups;
147 BOOL bWinbindUseDefaultDomain;
148 char *szIDMapBackend;
149 char *szGuestaccount;
159 BOOL paranoid_server_security;
161 BOOL bDisableSpoolss;
163 int enhanced_browsing;
170 int announce_as; /* This is initialised in init_globals */
171 int machine_password_timeout;
172 int winbind_cache_time;
175 char *szLdapMachineSuffix;
176 char *szLdapUserSuffix;
177 #ifdef WITH_LDAP_SAMCONFIG
181 char *socket_options;
187 int ldap_passwd_sync;
192 BOOL bPreferredMaster;
195 BOOL bEncryptPasswords;
198 BOOL bObeyPamRestrictions;
200 BOOL bLargeReadwrite;
204 BOOL bBindInterfacesOnly;
205 BOOL bPamPasswordChange;
206 BOOL bUnixPasswdSync;
208 BOOL bNTStatusSupport;
209 BOOL bAllowTrustedDomains;
214 BOOL bClientLanManAuth;
215 BOOL bClientNTLMv2Auth;
217 BOOL bHideLocalUsers;
220 BOOL bHostnameLookups;
221 BOOL bUnixExtensions;
222 BOOL bDisableNetbios;
224 int restrict_anonymous;
225 int name_cache_timeout;
226 struct param_opt *param_opt;
230 static global Globals;
233 * This structure describes a single service.
242 char **szInvalidUsers;
247 char *szPrintcommand;
250 char *szLppausecommand;
251 char *szLpresumecommand;
252 char *szQueuepausecommand;
253 char *szQueueresumecommand;
285 struct param_opt *param_opt;
287 char dummy[3]; /* for alignment */
292 /* This is a default service used to prime a services structure */
293 static service sDefault = {
295 False, /* not autoloaded */
296 NULL, /* szService */
298 NULL, /* szUsername */
299 NULL, /* szInvalidUsers */
300 NULL, /* szValidUsers */
301 NULL, /* szAdminUsers */
303 NULL, /* szInclude */
304 NULL, /* szPrintcommand */
305 NULL, /* szLpqcommand */
306 NULL, /* szLprmcommand */
307 NULL, /* szLppausecommand */
308 NULL, /* szLpresumecommand */
309 NULL, /* szQueuepausecommand */
310 NULL, /* szQueueresumecommand */
311 NULL, /* szPrintername */
312 NULL, /* szHostsallow */
313 NULL, /* szHostsdeny */
317 NULL, /* szMSDfsProxy */
318 NULL, /* ntvfs_handler */
319 0, /* iMinPrintSpace */
320 1000, /* iMaxPrintJobs */
321 0, /* iMaxConnections */
322 DEFAULT_PRINTING, /* iPrinting */
324 True, /* bAvailable */
325 True, /* bBrowseable */
326 True, /* bRead_only */
327 False, /* bPrint_ok */
328 False, /* bMap_system */
329 False, /* bMap_hidden */
330 True, /* bMap_archive */
332 True, /* bStrictLocking */
333 True, /* bPosixLocking */
335 True, /* bLevel2OpLocks */
336 False, /* bOnlyUser */
337 False, /* bGuest_only */
338 False, /* bGuest_ok */
340 False, /* bMSDfsRoot */
341 True, /* bShareModes */
342 NULL, /* Parametric options */
347 /* local variables */
348 static service **ServicePtrs = NULL;
349 static int iNumServices = 0;
350 static int iServiceIndex = 0;
351 static BOOL bInGlobalSection = True;
352 static BOOL bGlobalOnly = False;
353 static int server_role;
354 static int default_server_announce;
356 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
358 /* prototypes for the special type handlers */
359 static BOOL handle_include(const char *pszParmValue, char **ptr);
360 static BOOL handle_copy(const char *pszParmValue, char **ptr);
361 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
362 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
363 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
365 static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr );
366 static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr );
367 static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
369 static void set_server_role(void);
370 static void set_default_server_announce_type(void);
372 static const struct enum_list enum_protocol[] = {
373 {PROTOCOL_NT1, "NT1"},
374 {PROTOCOL_LANMAN2, "LANMAN2"},
375 {PROTOCOL_LANMAN1, "LANMAN1"},
376 {PROTOCOL_CORE, "CORE"},
377 {PROTOCOL_COREPLUS, "COREPLUS"},
378 {PROTOCOL_COREPLUS, "CORE+"},
382 static const struct enum_list enum_security[] = {
383 {SEC_SHARE, "SHARE"},
385 {SEC_SERVER, "SERVER"},
386 {SEC_DOMAIN, "DOMAIN"},
393 static const struct enum_list enum_printing[] = {
394 {PRINT_SYSV, "sysv"},
396 {PRINT_HPUX, "hpux"},
400 {PRINT_LPRNG, "lprng"},
401 {PRINT_SOFTQ, "softq"},
402 {PRINT_CUPS, "cups"},
404 {PRINT_LPROS2, "os2"},
406 {PRINT_TEST, "test"},
408 #endif /* DEVELOPER */
412 static const struct enum_list enum_ldap_ssl[] = {
413 #ifdef WITH_LDAP_SAMCONFIG
414 {LDAP_SSL_ON, "Yes"},
415 {LDAP_SSL_ON, "yes"},
419 {LDAP_SSL_OFF, "no"},
420 {LDAP_SSL_OFF, "No"},
421 {LDAP_SSL_OFF, "off"},
422 {LDAP_SSL_OFF, "Off"},
423 {LDAP_SSL_START_TLS, "start tls"},
424 {LDAP_SSL_START_TLS, "Start_tls"},
428 static const struct enum_list enum_ldap_passwd_sync[] = {
429 {LDAP_PASSWD_SYNC_ON, "Yes"},
430 {LDAP_PASSWD_SYNC_ON, "yes"},
431 {LDAP_PASSWD_SYNC_ON, "on"},
432 {LDAP_PASSWD_SYNC_ON, "On"},
433 {LDAP_PASSWD_SYNC_OFF, "no"},
434 {LDAP_PASSWD_SYNC_OFF, "No"},
435 {LDAP_PASSWD_SYNC_OFF, "off"},
436 {LDAP_PASSWD_SYNC_OFF, "Off"},
437 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
438 {LDAP_PASSWD_SYNC_ONLY, "Only"},
439 {LDAP_PASSWD_SYNC_ONLY, "only"},
440 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
444 /* Types of machine we can announce as. */
445 #define ANNOUNCE_AS_NT_SERVER 1
446 #define ANNOUNCE_AS_WIN95 2
447 #define ANNOUNCE_AS_WFW 3
448 #define ANNOUNCE_AS_NT_WORKSTATION 4
450 static const struct enum_list enum_announce_as[] = {
451 {ANNOUNCE_AS_NT_SERVER, "NT"},
452 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
453 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
454 {ANNOUNCE_AS_WIN95, "win95"},
455 {ANNOUNCE_AS_WFW, "WfW"},
459 static const struct enum_list enum_case[] = {
460 {CASE_LOWER, "lower"},
461 {CASE_UPPER, "upper"},
465 static const struct enum_list enum_bool_auto[] = {
476 /* Client-side offline caching policy types */
477 #define CSC_POLICY_MANUAL 0
478 #define CSC_POLICY_DOCUMENTS 1
479 #define CSC_POLICY_PROGRAMS 2
480 #define CSC_POLICY_DISABLE 3
482 static const struct enum_list enum_csc_policy[] = {
483 {CSC_POLICY_MANUAL, "manual"},
484 {CSC_POLICY_DOCUMENTS, "documents"},
485 {CSC_POLICY_PROGRAMS, "programs"},
486 {CSC_POLICY_DISABLE, "disable"},
490 /* SMB signing types. */
491 static const struct enum_list enum_smb_signing_vals[] = {
492 {SMB_SIGNING_OFF, "No"},
493 {SMB_SIGNING_OFF, "False"},
494 {SMB_SIGNING_OFF, "0"},
495 {SMB_SIGNING_OFF, "Off"},
496 {SMB_SIGNING_OFF, "disabled"},
497 {SMB_SIGNING_SUPPORTED, "Yes"},
498 {SMB_SIGNING_SUPPORTED, "True"},
499 {SMB_SIGNING_SUPPORTED, "1"},
500 {SMB_SIGNING_SUPPORTED, "On"},
501 {SMB_SIGNING_SUPPORTED, "enabled"},
502 {SMB_SIGNING_SUPPORTED, "auto"},
503 {SMB_SIGNING_REQUIRED, "required"},
504 {SMB_SIGNING_REQUIRED, "mandatory"},
505 {SMB_SIGNING_REQUIRED, "force"},
506 {SMB_SIGNING_REQUIRED, "forced"},
507 {SMB_SIGNING_REQUIRED, "enforced"},
512 Do you want session setups at user level security with a invalid
513 password to be rejected or allowed in as guest? WinNT rejects them
514 but it can be a pain as it means "net view" needs to use a password
516 You have 3 choices in the setting of map_to_guest:
518 "Never" means session setups with an invalid password
519 are rejected. This is the default.
521 "Bad User" means session setups with an invalid password
522 are rejected, unless the username does not exist, in which case it
523 is treated as a guest login
525 "Bad Password" means session setups with an invalid password
526 are treated as a guest login
528 Note that map_to_guest only has an effect in user or server
532 static const struct enum_list enum_map_to_guest[] = {
533 {NEVER_MAP_TO_GUEST, "Never"},
534 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
535 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
539 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
541 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
542 * is implied in current control logic. This may change at some later time. A
543 * flag value of 0 means - show as development option only.
545 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
546 * screen in SWAT. This is used to exclude parameters as well as to squash all
547 * parameters that have been duplicated by pseudonyms.
549 static struct parm_struct parm_table[] = {
550 {"Base Options", P_SEP, P_SEPARATOR},
552 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
556 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
557 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
558 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
559 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
560 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
561 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
562 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
563 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
566 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
567 {"ntvfs handler", P_STRING, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
568 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
570 {"Security Options", P_SEP, P_SEPARATOR},
572 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
573 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
574 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
575 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
582 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
588 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
590 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
592 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
593 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
594 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
595 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
596 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
597 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
598 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
599 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
600 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
601 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
602 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
605 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
606 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
608 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
609 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
610 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
612 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
614 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
616 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
618 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
619 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
620 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
621 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
623 {"Logging Options", P_SEP, P_SEPARATOR},
625 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
627 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
629 {"Protocol Options", P_SEP, P_SEPARATOR},
631 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
633 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
634 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
635 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
636 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
637 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
638 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
640 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
642 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
643 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
644 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
645 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
647 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
648 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
649 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
650 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
651 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
652 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
653 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
654 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
655 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
657 {"Tuning Options", P_SEP, P_SEPARATOR},
659 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
660 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
661 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
662 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
664 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
665 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
666 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
668 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
670 {"Printing Options", P_SEP, P_SEPARATOR},
672 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
673 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
674 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
675 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
676 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
677 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
678 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
679 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
680 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
681 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
682 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
683 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
684 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
685 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
686 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
688 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
689 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
691 {"Filename Handling", P_SEP, P_SEPARATOR},
693 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
695 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
696 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
698 {"Domain Options", P_SEP, P_SEPARATOR},
700 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
702 {"Logon Options", P_SEP, P_SEPARATOR},
704 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
708 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
709 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"Browse Options", P_SEP, P_SEPARATOR},
715 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
717 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
718 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
719 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
720 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
721 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
722 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
723 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
724 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
726 {"WINS Options", P_SEP, P_SEPARATOR},
727 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
728 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
730 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
731 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
732 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
733 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
735 {"Locking Options", P_SEP, P_SEPARATOR},
737 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
738 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
739 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
740 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
742 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
743 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
744 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
745 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
746 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
748 {"Ldap Options", P_SEP, P_SEPARATOR},
750 #ifdef WITH_LDAP_SAMCONFIG
751 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
752 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
754 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
760 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
765 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
766 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
769 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
774 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
777 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
780 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
781 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
783 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
784 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
785 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
787 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
788 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
790 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
791 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
792 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
793 {"Winbind options", P_SEP, P_SEPARATOR},
795 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
796 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
797 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
798 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
799 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
800 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
801 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
802 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
803 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
805 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
808 /***************************************************************************
809 Initialise the sDefault parameter structure for the printer values.
810 ***************************************************************************/
812 static void init_printer_values(void)
814 /* choose defaults depending on the type of printing */
815 switch (sDefault.iPrinting) {
820 string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
821 string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
822 string_set(&sDefault.szPrintcommand,
828 string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
829 string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
830 string_set(&sDefault.szPrintcommand,
832 string_set(&sDefault.szQueuepausecommand,
834 string_set(&sDefault.szQueueresumecommand,
836 string_set(&sDefault.szLppausecommand,
838 string_set(&sDefault.szLpresumecommand,
839 "lpc release '%p' %j");
844 string_set(&sDefault.szLpqcommand, "");
845 string_set(&sDefault.szLprmcommand, "");
846 string_set(&sDefault.szPrintcommand, "");
847 string_set(&sDefault.szLppausecommand, "");
848 string_set(&sDefault.szLpresumecommand, "");
849 string_set(&sDefault.szQueuepausecommand, "");
850 string_set(&sDefault.szQueueresumecommand, "");
852 string_set(&Globals.szPrintcapname, "cups");
854 string_set(&sDefault.szLpqcommand,
855 "/usr/bin/lpstat -o '%p'");
856 string_set(&sDefault.szLprmcommand,
857 "/usr/bin/cancel '%p-%j'");
858 string_set(&sDefault.szPrintcommand,
859 "/usr/bin/lp -d '%p' %s; rm %s");
860 string_set(&sDefault.szLppausecommand,
861 "lp -i '%p-%j' -H hold");
862 string_set(&sDefault.szLpresumecommand,
863 "lp -i '%p-%j' -H resume");
864 string_set(&sDefault.szQueuepausecommand,
865 "/usr/bin/disable '%p'");
866 string_set(&sDefault.szQueueresumecommand,
867 "/usr/bin/enable '%p'");
868 string_set(&Globals.szPrintcapname, "lpstat");
869 #endif /* HAVE_CUPS */
874 string_set(&sDefault.szLpqcommand, "lpstat -o%p");
875 string_set(&sDefault.szLprmcommand, "cancel %p-%j");
876 string_set(&sDefault.szPrintcommand,
877 "lp -c -d%p %s; rm %s");
878 string_set(&sDefault.szQueuepausecommand,
880 string_set(&sDefault.szQueueresumecommand,
883 string_set(&sDefault.szLppausecommand,
884 "lp -i %p-%j -H hold");
885 string_set(&sDefault.szLpresumecommand,
886 "lp -i %p-%j -H resume");
891 string_set(&sDefault.szLpqcommand, "lpq -P%p");
892 string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
893 string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
897 string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
898 string_set(&sDefault.szLprmcommand,
900 string_set(&sDefault.szPrintcommand,
901 "lp -d%p -s %s; rm %s");
902 string_set(&sDefault.szLppausecommand,
904 string_set(&sDefault.szLpresumecommand,
910 string_set(&sDefault.szPrintcommand, "vlp print %p %s");
911 string_set(&sDefault.szLpqcommand, "vlp lpq %p");
912 string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
913 string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
914 string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
915 string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
916 string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
918 #endif /* DEVELOPER */
924 /***************************************************************************
925 Initialise the global parameter structure.
926 ***************************************************************************/
927 static void init_globals(void)
932 DEBUG(3, ("Initialising global parameters\n"));
934 for (i = 0; parm_table[i].label; i++) {
935 if ((parm_table[i].type == P_STRING ||
936 parm_table[i].type == P_USTRING) &&
938 !(parm_table[i].flags & FLAG_CMDLINE)) {
939 string_set(parm_table[i].ptr, "");
943 /* options that can be set on the command line must be initialised via
944 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
945 do_parameter("socket options", DEFAULT_SOCKET_OPTIONS);
946 do_parameter("workgroup", DEFAULT_WORKGROUP);
947 do_parameter("netbios name", get_myname());
948 do_parameter("max protocol", "NT1");
949 do_parameter("name resolve order", "lmhosts wins host bcast");
951 init_printer_values();
953 string_set(&sDefault.fstype, FSTYPE_STRING);
954 string_set(&sDefault.ntvfs_handler, "default");
956 Globals.dcerpc_ep_servers = str_list_make("epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss", NULL);
958 Globals.AuthMethods = str_list_make("guest sam_ignoredomain", NULL);
960 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
961 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
962 asprintf(&Globals.szSAM_URL, "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
964 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
966 /* using UTF8 by default allows us to support all chars */
967 string_set(&Globals.unix_charset, "UTF8");
969 /* Use codepage 850 as a default for the dos character set */
970 string_set(&Globals.dos_charset, "CP850");
973 * Allow the default PASSWD_CHAT to be overridden in local.h.
975 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
977 string_set(&Globals.szPasswdProgram, "");
978 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
979 string_set(&Globals.szPidDir, dyn_PIDDIR);
980 string_set(&Globals.szLockDir, dyn_LOCKDIR);
981 string_set(&Globals.szSocketAddress, "0.0.0.0");
982 pstrcpy(s, "Samba ");
983 pstrcat(s, SAMBA_VERSION_STRING);
984 string_set(&Globals.szServerString, s);
985 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
986 DEFAULT_MINOR_VERSION);
987 string_set(&Globals.szAnnounceVersion, s);
989 string_set(&Globals.szLogonDrive, "");
990 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
991 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
992 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
994 string_set(&Globals.szPasswordServer, "*");
996 Globals.bLoadPrinters = True;
997 Globals.mangled_stack = 50;
998 Globals.max_mux = 50; /* This is *needed* for profile support. */
999 Globals.max_xmit = 4356; /* the value w2k3 chooses */
1000 Globals.lpqcachetime = 10;
1001 Globals.bDisableSpoolss = False;
1002 Globals.pwordlevel = 0;
1003 Globals.unamelevel = 0;
1004 Globals.bLargeReadwrite = True;
1005 Globals.minprotocol = PROTOCOL_CORE;
1006 Globals.security = SEC_USER;
1007 Globals.paranoid_server_security = True;
1008 Globals.bEncryptPasswords = True;
1009 Globals.bUpdateEncrypt = False;
1010 Globals.bReadRaw = True;
1011 Globals.bWriteRaw = True;
1012 Globals.bNullPasswords = False;
1013 Globals.bObeyPamRestrictions = False;
1014 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1015 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1016 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1017 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1018 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1019 Globals.lm_interval = 60;
1020 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1022 Globals.bTimeServer = False;
1023 Globals.bBindInterfacesOnly = False;
1024 Globals.bUnixPasswdSync = False;
1025 Globals.bPamPasswordChange = False;
1026 Globals.bUnicode = True; /* Do unicode on the wire by default */
1027 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1028 Globals.restrict_anonymous = 0;
1029 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1030 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1031 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1033 Globals.enhanced_browsing = True;
1034 Globals.iLockSpinCount = 3; /* Try 2 times. */
1035 Globals.iLockSpinTime = 10; /* usec. */
1036 #ifdef MMAP_BLACKLIST
1037 Globals.bUseMmap = False;
1039 Globals.bUseMmap = True;
1041 Globals.bUnixExtensions = False;
1043 /* hostname lookups can be very expensive and are broken on
1044 a large number of sites (tridge) */
1045 Globals.bHostnameLookups = False;
1047 #ifdef WITH_LDAP_SAMCONFIG
1048 string_set(&Globals.szLdapServer, "localhost");
1049 Globals.ldap_port = 636;
1050 Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1052 Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1053 #endif /* WITH_LDAP_SAMCONFIG */
1055 string_set(&Globals.szLdapSuffix, "");
1056 string_set(&Globals.szLdapMachineSuffix, "");
1057 string_set(&Globals.szLdapUserSuffix, "");
1059 string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
1060 string_set(&Globals.szLdapAdminDn, "");
1061 Globals.ldap_ssl = LDAP_SSL_ON;
1062 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1064 /* these parameters are set to defaults that are more appropriate
1065 for the increasing samba install base:
1067 as a member of the workgroup, that will possibly become a
1068 _local_ master browser (lm = True). this is opposed to a forced
1069 local master browser startup (pm = True).
1071 doesn't provide WINS server service by default (wsupp = False),
1072 and doesn't provide domain master browser services by default, either.
1076 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1077 Globals.os_level = 20;
1078 Globals.bLocalMaster = True;
1079 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1080 Globals.bDomainLogons = False;
1081 Globals.bWINSsupport = False;
1082 Globals.bWINSproxy = False;
1084 Globals.bDNSproxy = True;
1086 Globals.bAllowTrustedDomains = True;
1088 string_set(&Globals.szTemplateShell, "/bin/false");
1089 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1090 string_set(&Globals.szWinbindSeparator, "\\");
1092 Globals.winbind_cache_time = 15;
1093 Globals.bWinbindEnumUsers = True;
1094 Globals.bWinbindEnumGroups = True;
1095 Globals.bWinbindUseDefaultDomain = False;
1097 string_set(&Globals.szIDMapBackend, "tdb");
1099 Globals.name_cache_timeout = 660; /* In seconds */
1101 Globals.bUseSpnego = True;
1103 Globals.server_signing = False;
1105 string_set(&Globals.smb_ports, SMB_PORTS);
1108 static TALLOC_CTX *lp_talloc;
1110 /******************************************************************* a
1111 Free up temporary memory - called from the main loop.
1112 ********************************************************************/
1114 void lp_talloc_free(void)
1118 talloc_destroy(lp_talloc);
1122 /*******************************************************************
1123 Convenience routine to grab string parameters into temporary memory
1124 and run standard_sub_basic on them. The buffers can be written to by
1125 callers without affecting the source string.
1126 ********************************************************************/
1128 static const char *lp_string(const char *s)
1130 #if 0 /* until REWRITE done to make thread-safe */
1131 size_t len = s ? strlen(s) : 0;
1135 /* The follow debug is useful for tracking down memory problems
1136 especially if you have an inner loop that is calling a lp_*()
1137 function that returns a string. Perhaps this debug should be
1138 present all the time? */
1141 DEBUG(10, ("lp_string(%s)\n", s));
1144 #if 0 /* until REWRITE done to make thread-safe */
1146 lp_talloc = talloc_init("lp_talloc");
1148 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1156 StrnCpy(ret, s, len);
1158 if (trim_string(ret, "\"", "\"")) {
1159 if (strchr(ret,'"') != NULL)
1160 StrnCpy(ret, s, len);
1163 standard_sub_basic(ret,len+100);
1170 In this section all the functions that are used to access the
1171 parameters from the rest of the program are defined
1174 #define FN_GLOBAL_STRING(fn_name,ptr) \
1175 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1176 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1177 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1178 #define FN_GLOBAL_LIST(fn_name,ptr) \
1179 const char **fn_name(void) {return(*(const char ***)(ptr));}
1180 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1181 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1182 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1183 char fn_name(void) {return(*(char *)(ptr));}
1184 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1185 int fn_name(void) {return(*(int *)(ptr));}
1187 #define FN_LOCAL_STRING(fn_name,val) \
1188 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1189 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1190 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1191 #define FN_LOCAL_LIST(fn_name,val) \
1192 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1193 #define FN_LOCAL_BOOL(fn_name,val) \
1194 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1195 #define FN_LOCAL_CHAR(fn_name,val) \
1196 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1197 #define FN_LOCAL_INTEGER(fn_name,val) \
1198 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1200 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1201 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1202 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1203 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1204 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1205 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1206 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1207 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1208 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1209 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1210 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1211 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1212 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1213 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1214 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1215 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1216 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1217 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1218 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1219 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1220 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1221 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1222 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1223 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1224 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1225 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1226 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1227 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1228 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1229 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1230 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1231 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1232 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1233 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1234 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1235 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1236 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1237 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1238 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1239 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1240 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1241 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1242 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1244 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1246 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1248 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1249 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1250 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1251 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1252 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1253 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1254 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1255 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1256 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1258 #ifdef WITH_LDAP_SAMCONFIG
1259 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1260 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1262 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1263 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1264 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1265 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1266 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1267 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1268 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1269 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1271 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1272 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1273 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1274 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1275 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1276 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1277 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1278 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1279 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1280 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1281 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1282 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1283 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1284 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1285 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1286 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1287 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1288 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1289 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1290 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1291 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1292 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1293 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1294 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1295 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1296 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1297 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1298 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1299 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1300 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1301 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1302 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1303 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1304 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1305 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1306 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1307 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1308 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1309 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1310 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1311 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1312 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1313 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1314 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1315 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1316 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1317 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1318 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1319 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1320 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1321 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1322 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1323 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1324 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1325 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1326 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1327 FN_LOCAL_STRING(lp_servicename, szService)
1328 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1329 FN_LOCAL_STRING(lp_pathname, szPath)
1330 FN_LOCAL_STRING(lp_username, szUsername)
1331 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1332 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1333 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1334 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1335 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1336 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1337 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1338 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1339 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1340 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1341 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1342 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1343 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1344 FN_LOCAL_STRING(lp_comment, comment)
1345 FN_LOCAL_STRING(lp_fstype, fstype)
1346 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1347 static FN_LOCAL_STRING(lp_volume, volume)
1348 FN_LOCAL_STRING(lp_ntvfs_handler, ntvfs_handler)
1349 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1350 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1351 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1352 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1353 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1354 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1355 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1356 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1357 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1358 FN_LOCAL_BOOL(lp_locking, bLocking)
1359 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1360 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1361 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1362 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1363 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1364 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1365 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1366 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1367 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1368 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1369 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1370 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1371 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1372 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1373 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1375 /* local prototypes */
1377 static int map_parameter(const char *pszParmName);
1378 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1379 static int getservicebyname(const char *pszServiceName,
1380 service * pserviceDest);
1381 static void copy_service(service * pserviceDest,
1382 service * pserviceSource, BOOL *pcopymapDest);
1383 static BOOL service_ok(int iService);
1384 static BOOL do_section(const char *pszSectionName);
1385 static void init_copymap(service * pservice);
1387 /* This is a helper function for parametrical options support. */
1388 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1389 /* Actual parametrical functions are quite simple */
1390 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1393 struct param_opt *data;
1395 if (lookup_service >= iNumServices) return NULL;
1397 data = (lookup_service < 0) ?
1398 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1400 asprintf(&vfskey, "%s:%s", type, option);
1404 if (strcmp(data->key, vfskey) == 0) {
1411 if (lookup_service >= 0) {
1412 /* Try to fetch the same option but from globals */
1413 /* but only if we are not already working with Globals */
1414 data = Globals.param_opt;
1416 if (strcmp(data->key, vfskey) == 0) {
1430 /*******************************************************************
1431 convenience routine to return int parameters.
1432 ********************************************************************/
1433 static int lp_int(const char *s)
1437 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1444 /*******************************************************************
1445 convenience routine to return unsigned long parameters.
1446 ********************************************************************/
1447 static int lp_ulong(const char *s)
1451 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1455 return strtoul(s, NULL, 10);
1458 /*******************************************************************
1459 convenience routine to return boolean parameters.
1460 ********************************************************************/
1461 static BOOL lp_bool(const char *s)
1466 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1470 if (!set_boolean(&ret,s)) {
1471 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1478 /*******************************************************************
1479 convenience routine to return enum parameters.
1480 ********************************************************************/
1481 static int lp_enum(const char *s,const struct enum_list *_enum)
1486 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1490 for (i=0; _enum[i].name; i++) {
1491 if (strcasecmp(_enum[i].name,s)==0)
1492 return _enum[i].value;
1495 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1499 /* Return parametric option from a given service. Type is a part of option before ':' */
1500 /* Parametric option has following syntax: 'Type: option = value' */
1501 /* Returned value is allocated in 'lp_talloc' context */
1503 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1505 const char *value = get_parametrics(lookup_service, type, option);
1508 return lp_string(value);
1513 /* Return parametric option from a given service. Type is a part of option before ':' */
1514 /* Parametric option has following syntax: 'Type: option = value' */
1515 /* Returned value is allocated in 'lp_talloc' context */
1517 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1518 const char *separator)
1520 const char *value = get_parametrics(lookup_service, type, option);
1523 return str_list_make(value, separator);
1528 /* Return parametric option from a given service. Type is a part of option before ':' */
1529 /* Parametric option has following syntax: 'Type: option = value' */
1531 int lp_parm_int(int lookup_service, const char *type, const char *option)
1533 const char *value = get_parametrics(lookup_service, type, option);
1536 return lp_int(value);
1541 /* Return parametric option from a given service. Type is a part of option before ':' */
1542 /* Parametric option has following syntax: 'Type: option = value' */
1544 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1546 const char *value = get_parametrics(lookup_service, type, option);
1549 return lp_ulong(value);
1554 /* Return parametric option from a given service. Type is a part of option before ':' */
1555 /* Parametric option has following syntax: 'Type: option = value' */
1557 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1559 const char *value = get_parametrics(lookup_service, type, option);
1562 return lp_bool(value);
1567 /* Return parametric option from a given service. Type is a part of option before ':' */
1568 /* Parametric option has following syntax: 'Type: option = value' */
1570 int lp_parm_enum(int lookup_service, const char *type, const char *option,
1571 const struct enum_list *_enum)
1573 const char *value = get_parametrics(lookup_service, type, option);
1576 return lp_enum(value, _enum);
1582 /***************************************************************************
1583 Initialise a service to the defaults.
1584 ***************************************************************************/
1586 static void init_service(service * pservice)
1588 memset((char *)pservice, '\0', sizeof(service));
1589 copy_service(pservice, &sDefault, NULL);
1592 /***************************************************************************
1593 Free the dynamically allocated parts of a service struct.
1594 ***************************************************************************/
1596 static void free_service(service *pservice)
1599 struct param_opt *data, *pdata;
1603 if (pservice->szService)
1604 DEBUG(5, ("free_service: Freeing service %s\n",
1605 pservice->szService));
1607 string_free(&pservice->szService);
1608 SAFE_FREE(pservice->copymap);
1610 for (i = 0; parm_table[i].label; i++) {
1611 if ((parm_table[i].type == P_STRING ||
1612 parm_table[i].type == P_USTRING) &&
1613 parm_table[i].class == P_LOCAL)
1614 string_free((char **)
1615 (((char *)pservice) +
1616 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1617 else if (parm_table[i].type == P_LIST &&
1618 parm_table[i].class == P_LOCAL)
1619 str_list_free((char ***)
1620 (((char *)pservice) +
1621 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1624 DEBUG(5,("Freeing parametrics:\n"));
1625 data = pservice->param_opt;
1627 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1628 string_free(&data->key);
1629 string_free(&data->value);
1635 ZERO_STRUCTP(pservice);
1638 /***************************************************************************
1639 Add a new service to the services array initialising it with the given
1641 ***************************************************************************/
1643 static int add_a_service(const service *pservice, const char *name)
1647 int num_to_alloc = iNumServices + 1;
1648 struct param_opt *data, *pdata;
1650 tservice = *pservice;
1652 /* it might already exist */
1654 i = getservicebyname(name, NULL);
1656 /* Clean all parametric options for service */
1657 /* They will be added during parsing again */
1658 data = ServicePtrs[i]->param_opt;
1660 string_free(&data->key);
1661 string_free(&data->value);
1666 ServicePtrs[i]->param_opt = NULL;
1671 /* find an invalid one */
1672 for (i = 0; i < iNumServices; i++)
1673 if (!ServicePtrs[i]->valid)
1676 /* if not, then create one */
1677 if (i == iNumServices) {
1680 tsp = (service **) Realloc(ServicePtrs,
1685 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1690 ServicePtrs[iNumServices] =
1691 (service *) malloc(sizeof(service));
1693 if (!ServicePtrs[iNumServices]) {
1694 DEBUG(0,("add_a_service: out of memory!\n"));
1700 free_service(ServicePtrs[i]);
1702 ServicePtrs[i]->valid = True;
1704 init_service(ServicePtrs[i]);
1705 copy_service(ServicePtrs[i], &tservice, NULL);
1707 string_set(&ServicePtrs[i]->szService, name);
1711 /***************************************************************************
1712 Add a new home service, with the specified home directory, defaults coming
1714 ***************************************************************************/
1716 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1717 const char *user, const char *pszHomedir)
1722 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1727 if (!(*(ServicePtrs[iDefaultService]->szPath))
1728 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1729 pstrcpy(newHomedir, pszHomedir);
1731 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1732 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1735 string_set(&ServicePtrs[i]->szPath, newHomedir);
1737 if (!(*(ServicePtrs[i]->comment))) {
1739 slprintf(comment, sizeof(comment) - 1,
1740 "Home directory of %s", user);
1741 string_set(&ServicePtrs[i]->comment, comment);
1743 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1744 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1746 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1752 /***************************************************************************
1753 Add a new service, based on an old one.
1754 ***************************************************************************/
1756 int lp_add_service(const char *pszService, int iDefaultService)
1758 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1761 /***************************************************************************
1762 Add the IPC service.
1763 ***************************************************************************/
1765 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1768 int i = add_a_service(&sDefault, ipc_name);
1773 slprintf(comment, sizeof(comment) - 1,
1774 "IPC Service (%s)", Globals.szServerString);
1776 string_set(&ServicePtrs[i]->szPath, tmpdir());
1777 string_set(&ServicePtrs[i]->szUsername, "");
1778 string_set(&ServicePtrs[i]->comment, comment);
1779 string_set(&ServicePtrs[i]->fstype, "IPC");
1780 ServicePtrs[i]->iMaxConnections = 0;
1781 ServicePtrs[i]->bAvailable = True;
1782 ServicePtrs[i]->bRead_only = True;
1783 ServicePtrs[i]->bGuest_only = False;
1784 ServicePtrs[i]->bGuest_ok = guest_ok;
1785 ServicePtrs[i]->bPrint_ok = False;
1786 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1788 DEBUG(3, ("adding IPC service\n"));
1793 /***************************************************************************
1794 Add a new printer service, with defaults coming from service iFrom.
1795 ***************************************************************************/
1797 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1799 const char *comment = "From Printcap";
1800 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1805 /* note that we do NOT default the availability flag to True - */
1806 /* we take it from the default service passed. This allows all */
1807 /* dynamic printers to be disabled by disabling the [printers] */
1808 /* entry (if/when the 'available' keyword is implemented!). */
1810 /* the printer name is set to the service name. */
1811 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1812 string_set(&ServicePtrs[i]->comment, comment);
1813 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1814 /* Printers cannot be read_only. */
1815 ServicePtrs[i]->bRead_only = False;
1816 /* No share modes on printer services. */
1817 ServicePtrs[i]->bShareModes = False;
1818 /* No oplocks on printer services. */
1819 ServicePtrs[i]->bOpLocks = False;
1820 /* Printer services must be printable. */
1821 ServicePtrs[i]->bPrint_ok = True;
1823 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1825 update_server_announce_as_printserver();
1830 /***************************************************************************
1831 Map a parameter's string representation to something we can use.
1832 Returns False if the parameter string is not recognised, else TRUE.
1833 ***************************************************************************/
1835 static int map_parameter(const char *pszParmName)
1839 if (*pszParmName == '-')
1842 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1843 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1846 /* Warn only if it isn't parametric option */
1847 if (strchr(pszParmName, ':') == NULL)
1848 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1849 /* We do return 'fail' for parametric options as well because they are
1850 stored in different storage
1855 /***************************************************************************
1856 Set a boolean variable from the text value stored in the passed string.
1857 Returns True in success, False if the passed string does not correctly
1858 represent a boolean.
1859 ***************************************************************************/
1861 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1866 if (strwicmp(pszParmValue, "yes") == 0 ||
1867 strwicmp(pszParmValue, "true") == 0 ||
1868 strwicmp(pszParmValue, "1") == 0)
1870 else if (strwicmp(pszParmValue, "no") == 0 ||
1871 strwicmp(pszParmValue, "False") == 0 ||
1872 strwicmp(pszParmValue, "0") == 0)
1876 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1883 /***************************************************************************
1884 Find a service by name. Otherwise works like get_service.
1885 ***************************************************************************/
1887 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1891 for (iService = iNumServices - 1; iService >= 0; iService--)
1892 if (VALID(iService) &&
1893 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1894 if (pserviceDest != NULL)
1895 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1902 /***************************************************************************
1903 Copy a service structure to another.
1904 If pcopymapDest is NULL then copy all fields
1905 ***************************************************************************/
1907 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1910 BOOL bcopyall = (pcopymapDest == NULL);
1911 struct param_opt *data, *pdata, *paramo;
1914 for (i = 0; parm_table[i].label; i++)
1915 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1916 (bcopyall || pcopymapDest[i])) {
1917 void *def_ptr = parm_table[i].ptr;
1919 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1922 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1925 switch (parm_table[i].type) {
1928 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1934 *(int *)dest_ptr = *(int *)src_ptr;
1938 *(char *)dest_ptr = *(char *)src_ptr;
1942 string_set(dest_ptr,
1947 string_set(dest_ptr,
1949 strupper(*(char **)dest_ptr);
1952 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1960 init_copymap(pserviceDest);
1961 if (pserviceSource->copymap)
1962 memcpy((void *)pserviceDest->copymap,
1963 (void *)pserviceSource->copymap,
1964 sizeof(BOOL) * NUMPARAMETERS);
1967 data = pserviceSource->param_opt;
1970 pdata = pserviceDest->param_opt;
1971 /* Traverse destination */
1973 /* If we already have same option, override it */
1974 if (strcmp(pdata->key, data->key) == 0) {
1975 string_free(&pdata->value);
1976 pdata->value = strdup(data->value);
1980 pdata = pdata->next;
1983 paramo = smb_xmalloc(sizeof(*paramo));
1984 paramo->key = strdup(data->key);
1985 paramo->value = strdup(data->value);
1986 DLIST_ADD(pserviceDest->param_opt, paramo);
1992 /***************************************************************************
1993 Check a service for consistency. Return False if the service is in any way
1994 incomplete or faulty, else True.
1995 ***************************************************************************/
1997 static BOOL service_ok(int iService)
2002 if (ServicePtrs[iService]->szService[0] == '\0') {
2003 DEBUG(0, ("The following message indicates an internal error:\n"));
2004 DEBUG(0, ("No service name in service entry.\n"));
2008 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2009 /* I can't see why you'd want a non-printable printer service... */
2010 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2011 if (!ServicePtrs[iService]->bPrint_ok) {
2012 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2013 ServicePtrs[iService]->szService));
2014 ServicePtrs[iService]->bPrint_ok = True;
2016 /* [printers] service must also be non-browsable. */
2017 if (ServicePtrs[iService]->bBrowseable)
2018 ServicePtrs[iService]->bBrowseable = False;
2021 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2022 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2023 DEBUG(0, ("No path in service %s - using %s\n",
2024 ServicePtrs[iService]->szService, tmpdir()));
2025 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2028 /* If a service is flagged unavailable, log the fact at level 0. */
2029 if (!ServicePtrs[iService]->bAvailable)
2030 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2031 ServicePtrs[iService]->szService));
2036 static struct file_lists {
2037 struct file_lists *next;
2041 } *file_lists = NULL;
2043 /*******************************************************************
2044 Keep a linked list of all config files so we know when one has changed
2045 it's date and needs to be reloaded.
2046 ********************************************************************/
2048 static void add_to_file_list(const char *fname, const char *subfname)
2050 struct file_lists *f = file_lists;
2053 if (f->name && !strcmp(f->name, fname))
2059 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2062 f->next = file_lists;
2063 f->name = strdup(fname);
2068 f->subfname = strdup(subfname);
2074 f->modtime = file_modtime(subfname);
2076 time_t t = file_modtime(subfname);
2082 /*******************************************************************
2083 Check if a config file has changed date.
2084 ********************************************************************/
2086 BOOL lp_file_list_changed(void)
2088 struct file_lists *f = file_lists;
2089 DEBUG(6, ("lp_file_list_changed()\n"));
2095 pstrcpy(n2, f->name);
2096 standard_sub_basic(n2,sizeof(n2));
2098 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2099 f->name, n2, ctime(&f->modtime)));
2101 mod_time = file_modtime(n2);
2103 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2105 ("file %s modified: %s\n", n2,
2107 f->modtime = mod_time;
2108 SAFE_FREE(f->subfname);
2109 f->subfname = strdup(n2);
2117 /***************************************************************************
2118 Handle the include operation.
2119 ***************************************************************************/
2121 static BOOL handle_include(const char *pszParmValue, char **ptr)
2124 pstrcpy(fname, pszParmValue);
2126 standard_sub_basic(fname,sizeof(fname));
2128 add_to_file_list(pszParmValue, fname);
2130 string_set(ptr, fname);
2132 if (file_exist(fname, NULL))
2133 return (pm_process(fname, do_section, do_parameter));
2135 DEBUG(2, ("Can't find include file %s\n", fname));
2140 /***************************************************************************
2141 Handle the interpretation of the copy parameter.
2142 ***************************************************************************/
2144 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2148 service serviceTemp;
2150 string_set(ptr, pszParmValue);
2152 init_service(&serviceTemp);
2156 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2158 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2159 if (iTemp == iServiceIndex) {
2160 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2162 copy_service(ServicePtrs[iServiceIndex],
2164 ServicePtrs[iServiceIndex]->copymap);
2168 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2172 free_service(&serviceTemp);
2176 /***************************************************************************
2177 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2182 winbind uid = 1000-1999
2183 winbind gid = 700-899
2185 We only do simple parsing checks here. The strings are parsed into useful
2186 structures in the winbind daemon code.
2188 ***************************************************************************/
2190 /* Some lp_ routines to return winbind [ug]id information */
2192 static uid_t winbind_uid_low, winbind_uid_high;
2193 static gid_t winbind_gid_low, winbind_gid_high;
2194 static uint32_t non_unix_account_low, non_unix_account_high;
2196 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2198 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2202 *low = winbind_uid_low;
2205 *high = winbind_uid_high;
2210 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2212 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2216 *low = winbind_gid_low;
2219 *high = winbind_gid_high;
2224 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2226 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2230 *low = non_unix_account_low;
2233 *high = non_unix_account_high;
2238 /* Do some simple checks on "winbind [ug]id" parameter values */
2240 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2244 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2249 string_set(ptr, pszParmValue);
2251 winbind_uid_low = low;
2252 winbind_uid_high = high;
2257 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2261 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2266 string_set(ptr, pszParmValue);
2268 winbind_gid_low = low;
2269 winbind_gid_high = high;
2274 /***************************************************************************
2275 Do some simple checks on "non unix account range" parameter values.
2276 ***************************************************************************/
2278 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2282 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2287 string_set(ptr, pszParmValue);
2289 non_unix_account_low = low;
2290 non_unix_account_high = high;
2295 /***************************************************************************
2296 Handle the ldap machine suffix option.
2297 ***************************************************************************/
2299 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2303 pstrcpy(suffix, pszParmValue);
2305 if (! *Globals.szLdapSuffix ) {
2306 string_set( ptr, suffix );
2310 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2311 if ( *pszParmValue )
2312 pstrcat(suffix, ",");
2313 pstrcat(suffix, Globals.szLdapSuffix);
2315 string_set( ptr, suffix );
2319 /***************************************************************************
2320 Handle the ldap user suffix option.
2321 ***************************************************************************/
2323 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2327 pstrcpy(suffix, pszParmValue);
2329 if (! *Globals.szLdapSuffix ) {
2330 string_set( ptr, suffix );
2334 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2335 if ( *pszParmValue )
2336 pstrcat(suffix, ",");
2337 pstrcat(suffix, Globals.szLdapSuffix);
2339 string_set( ptr, suffix );
2343 /***************************************************************************
2344 Handle setting ldap suffix and determines whether ldap machine suffix needs
2346 ***************************************************************************/
2348 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
2351 pstring user_suffix;
2352 pstring machine_suffix;
2354 pstrcpy(suffix, pszParmValue);
2356 if (! *Globals.szLdapMachineSuffix )
2357 string_set(&Globals.szLdapMachineSuffix, suffix);
2358 if (! *Globals.szLdapUserSuffix )
2359 string_set(&Globals.szLdapUserSuffix, suffix);
2361 if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
2362 pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
2363 if ( *Globals.szLdapMachineSuffix )
2364 pstrcat(machine_suffix, ",");
2365 pstrcat(machine_suffix, suffix);
2366 string_set(&Globals.szLdapMachineSuffix, machine_suffix);
2369 if (! strstr(Globals.szLdapUserSuffix, suffix)) {
2370 pstrcpy(user_suffix, Globals.szLdapUserSuffix);
2371 if ( *Globals.szLdapUserSuffix )
2372 pstrcat(user_suffix, ",");
2373 pstrcat(user_suffix, suffix);
2374 string_set(&Globals.szLdapUserSuffix, user_suffix);
2377 string_set(ptr, suffix);
2382 /***************************************************************************
2383 Initialise a copymap.
2384 ***************************************************************************/
2386 static void init_copymap(service * pservice)
2389 SAFE_FREE(pservice->copymap);
2390 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2391 if (!pservice->copymap)
2393 ("Couldn't allocate copymap!! (size %d)\n",
2394 (int)NUMPARAMETERS));
2396 for (i = 0; i < NUMPARAMETERS; i++)
2397 pservice->copymap[i] = True;
2400 /***************************************************************************
2401 Return the local pointer to a parameter given the service number and the
2402 pointer into the default structure.
2403 ***************************************************************************/
2405 void *lp_local_ptr(int snum, void *ptr)
2407 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2411 /***************************************************************************
2412 Process a parametric option
2413 ***************************************************************************/
2414 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2416 struct param_opt *paramo, *data;
2419 while (isspace(*pszParmName)) {
2423 name = strdup(pszParmName);
2424 if (!name) return False;
2429 data = Globals.param_opt;
2431 data = ServicePtrs[snum]->param_opt;
2434 /* Traverse destination */
2435 for (paramo=data; paramo; paramo=paramo->next) {
2436 /* If we already have the option set, override it unless
2437 it was a command line option and the new one isn't */
2438 if (strcmp(paramo->key, name) == 0) {
2439 if ((paramo->flags & FLAG_CMDLINE) &&
2440 !(flags & FLAG_CMDLINE)) {
2444 free(paramo->value);
2445 paramo->value = strdup(pszParmValue);
2446 paramo->flags = flags;
2452 paramo = smb_xmalloc(sizeof(*paramo));
2453 paramo->key = strdup(name);
2454 paramo->value = strdup(pszParmValue);
2455 paramo->flags = flags;
2457 DLIST_ADD(Globals.param_opt, paramo);
2459 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2467 /***************************************************************************
2468 Process a parameter for a particular service number. If snum < 0
2469 then assume we are in the globals.
2470 ***************************************************************************/
2471 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2474 void *parm_ptr = NULL; /* where we are going to store the result */
2475 void *def_ptr = NULL;
2477 parmnum = map_parameter(pszParmName);
2480 if (strchr(pszParmName, ':')) {
2481 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2483 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2487 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2488 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2492 /* if the flag has been set on the command line, then don't allow override,
2493 but don't report an error */
2494 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2498 def_ptr = parm_table[parmnum].ptr;
2500 /* we might point at a service, the default service or a global */
2504 if (parm_table[parmnum].class == P_GLOBAL) {
2506 ("Global parameter %s found in service section!\n",
2511 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2516 if (!ServicePtrs[snum]->copymap)
2517 init_copymap(ServicePtrs[snum]);
2519 /* this handles the aliases - set the copymap for other entries with
2520 the same data pointer */
2521 for (i = 0; parm_table[i].label; i++)
2522 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2523 ServicePtrs[snum]->copymap[i] = False;
2526 /* if it is a special case then go ahead */
2527 if (parm_table[parmnum].special) {
2528 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2532 /* now switch on the type of variable it is */
2533 switch (parm_table[parmnum].type)
2536 set_boolean(parm_ptr, pszParmValue);
2540 set_boolean(parm_ptr, pszParmValue);
2541 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2545 *(int *)parm_ptr = atoi(pszParmValue);
2549 *(char *)parm_ptr = *pszParmValue;
2553 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2557 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2561 string_set(parm_ptr, pszParmValue);
2565 string_set(parm_ptr, pszParmValue);
2566 strupper(*(char **)parm_ptr);
2570 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2573 parm_table[parmnum].enum_list[i].name)) {
2575 parm_table[parmnum].
2588 /***************************************************************************
2589 Process a parameter.
2590 ***************************************************************************/
2592 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2594 if (!bInGlobalSection && bGlobalOnly)
2597 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2599 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2600 pszParmName, pszParmValue));
2605 set a parameter from the commandline - this is called from command line parameter
2606 parsing code. It sets the parameter then marks the parameter as unable to be modified
2607 by smb.conf processing
2609 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2611 int parmnum = map_parameter(pszParmName);
2613 if (parmnum < 0 && strchr(pszParmName, ':')) {
2614 /* set a parametric option */
2615 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2618 /* reset the CMDLINE flag in case this has been called before */
2619 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2621 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2625 parm_table[parmnum].flags |= FLAG_CMDLINE;
2629 /***************************************************************************
2630 Print a parameter of the specified type.
2631 ***************************************************************************/
2633 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2639 for (i = 0; p->enum_list[i].name; i++) {
2640 if (*(int *)ptr == p->enum_list[i].value) {
2642 p->enum_list[i].name);
2649 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2653 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2657 fprintf(f, "%d", *(int *)ptr);
2661 fprintf(f, "%c", *(char *)ptr);
2665 fprintf(f, "%s", octal_string(*(int *)ptr));
2669 if ((char ***)ptr && *(char ***)ptr) {
2670 char **list = *(char ***)ptr;
2672 for (; *list; list++)
2673 fprintf(f, "%s%s", *list,
2674 ((*(list+1))?", ":""));
2680 if (*(char **)ptr) {
2681 fprintf(f, "%s", *(char **)ptr);
2689 /***************************************************************************
2690 Check if two parameters are equal.
2691 ***************************************************************************/
2693 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2698 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2703 return (*((int *)ptr1) == *((int *)ptr2));
2706 return (*((char *)ptr1) == *((char *)ptr2));
2709 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2714 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2719 return (p1 == p2 || strequal(p1, p2));
2727 /***************************************************************************
2728 Process a new section (service). At this stage all sections are services.
2729 Later we'll have special sections that permit server parameters to be set.
2730 Returns True on success, False on failure.
2731 ***************************************************************************/
2733 static BOOL do_section(const char *pszSectionName)
2736 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2737 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2740 /* if we've just struck a global section, note the fact. */
2741 bInGlobalSection = isglobal;
2743 /* check for multiple global sections */
2744 if (bInGlobalSection) {
2745 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2749 if (!bInGlobalSection && bGlobalOnly)
2752 /* if we have a current service, tidy it up before moving on */
2755 if (iServiceIndex >= 0)
2756 bRetval = service_ok(iServiceIndex);
2758 /* if all is still well, move to the next record in the services array */
2760 /* We put this here to avoid an odd message order if messages are */
2761 /* issued by the post-processing of a previous section. */
2762 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2764 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2766 DEBUG(0, ("Failed to add a new service\n"));
2775 /***************************************************************************
2776 Determine if a partcular base parameter is currentl set to the default value.
2777 ***************************************************************************/
2779 static BOOL is_default(int i)
2781 if (!defaults_saved)
2783 switch (parm_table[i].type) {
2785 return str_list_compare (parm_table[i].def.lvalue,
2786 *(char ***)parm_table[i].ptr);
2789 return strequal(parm_table[i].def.svalue,
2790 *(char **)parm_table[i].ptr);
2793 return parm_table[i].def.bvalue ==
2794 *(BOOL *)parm_table[i].ptr;
2796 return parm_table[i].def.cvalue ==
2797 *(char *)parm_table[i].ptr;
2801 return parm_table[i].def.ivalue ==
2802 *(int *)parm_table[i].ptr;
2809 /***************************************************************************
2810 Display the contents of the global structure.
2811 ***************************************************************************/
2813 static void dump_globals(FILE *f)
2816 struct param_opt *data;
2818 fprintf(f, "# Global parameters\n[global]\n");
2820 for (i = 0; parm_table[i].label; i++)
2821 if (parm_table[i].class == P_GLOBAL &&
2822 parm_table[i].ptr &&
2823 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2824 if (defaults_saved && is_default(i))
2826 fprintf(f, "\t%s = ", parm_table[i].label);
2827 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2830 if (Globals.param_opt != NULL) {
2831 data = Globals.param_opt;
2833 fprintf(f, "\t%s = %s\n", data->key, data->value);
2840 /***************************************************************************
2841 Return True if a local parameter is currently set to the global default.
2842 ***************************************************************************/
2844 BOOL lp_is_default(int snum, struct parm_struct *parm)
2846 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
2848 return equal_parameter(parm->type,
2849 ((char *)ServicePtrs[snum]) + pdiff,
2850 ((char *)&sDefault) + pdiff);
2853 /***************************************************************************
2854 Display the contents of a single services record.
2855 ***************************************************************************/
2857 static void dump_a_service(service * pService, FILE * f)
2860 struct param_opt *data;
2862 if (pService != &sDefault)
2863 fprintf(f, "\n[%s]\n", pService->szService);
2865 for (i = 0; parm_table[i].label; i++)
2866 if (parm_table[i].class == P_LOCAL &&
2867 parm_table[i].ptr &&
2868 (*parm_table[i].label != '-') &&
2869 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2870 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2872 if (pService == &sDefault) {
2873 if (defaults_saved && is_default(i))
2876 if (equal_parameter(parm_table[i].type,
2877 ((char *)pService) +
2879 ((char *)&sDefault) +
2884 fprintf(f, "\t%s = ", parm_table[i].label);
2885 print_parameter(&parm_table[i],
2886 ((char *)pService) + pdiff, f);
2889 if (pService->param_opt != NULL) {
2890 data = pService->param_opt;
2892 fprintf(f, "\t%s = %s\n", data->key, data->value);
2899 /***************************************************************************
2900 Return info about the next service in a service. snum==-1 gives the globals.
2901 Return NULL when out of parameters.
2902 ***************************************************************************/
2904 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2907 /* do the globals */
2908 for (; parm_table[*i].label; (*i)++) {
2909 if (parm_table[*i].class == P_SEPARATOR)
2910 return &parm_table[(*i)++];
2912 if (!parm_table[*i].ptr
2913 || (*parm_table[*i].label == '-'))
2917 && (parm_table[*i].ptr ==
2918 parm_table[(*i) - 1].ptr))
2921 return &parm_table[(*i)++];
2924 service *pService = ServicePtrs[snum];
2926 for (; parm_table[*i].label; (*i)++) {
2927 if (parm_table[*i].class == P_SEPARATOR)
2928 return &parm_table[(*i)++];
2930 if (parm_table[*i].class == P_LOCAL &&
2931 parm_table[*i].ptr &&
2932 (*parm_table[*i].label != '-') &&
2934 (parm_table[*i].ptr !=
2935 parm_table[(*i) - 1].ptr)))
2938 PTR_DIFF(parm_table[*i].ptr,
2941 if (allparameters ||
2942 !equal_parameter(parm_table[*i].type,
2943 ((char *)pService) +
2945 ((char *)&sDefault) +
2948 return &parm_table[(*i)++];
2959 /***************************************************************************
2960 Display the contents of a single copy structure.
2961 ***************************************************************************/
2962 static void dump_copy_map(BOOL *pcopymap)
2968 printf("\n\tNon-Copied parameters:\n");
2970 for (i = 0; parm_table[i].label; i++)
2971 if (parm_table[i].class == P_LOCAL &&
2972 parm_table[i].ptr && !pcopymap[i] &&
2973 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2975 printf("\t\t%s\n", parm_table[i].label);
2980 /***************************************************************************
2981 Return TRUE if the passed service number is within range.
2982 ***************************************************************************/
2984 BOOL lp_snum_ok(int iService)
2986 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2989 /***************************************************************************
2990 Auto-load some home services.
2991 ***************************************************************************/
2993 static void lp_add_auto_services(const char *str)
2998 /***************************************************************************
2999 Auto-load one printer.
3000 ***************************************************************************/
3002 void lp_add_one_printer(char *name, char *comment)
3004 int printers = lp_servicenumber(PRINTERS_NAME);
3007 if (lp_servicenumber(name) < 0) {
3008 lp_add_printer(name, printers);
3009 if ((i = lp_servicenumber(name)) >= 0) {
3010 string_set(&ServicePtrs[i]->comment, comment);
3011 ServicePtrs[i]->autoloaded = True;
3016 /***************************************************************************
3017 Announce ourselves as a print server.
3018 ***************************************************************************/
3020 void update_server_announce_as_printserver(void)
3022 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3025 /***************************************************************************
3026 Have we loaded a services file yet?
3027 ***************************************************************************/
3029 BOOL lp_loaded(void)
3034 /***************************************************************************
3035 Unload unused services.
3036 ***************************************************************************/
3038 void lp_killunused(struct server_context *smb, BOOL (*snumused) (struct server_context *, int))
3041 for (i = 0; i < iNumServices; i++) {
3045 if (!snumused || !snumused(smb, i)) {
3046 ServicePtrs[i]->valid = False;
3047 free_service(ServicePtrs[i]);
3052 /***************************************************************************
3054 ***************************************************************************/
3056 void lp_killservice(int iServiceIn)
3058 if (VALID(iServiceIn)) {
3059 ServicePtrs[iServiceIn]->valid = False;
3060 free_service(ServicePtrs[iServiceIn]);
3064 /***************************************************************************
3065 Save the curent values of all global and sDefault parameters into the
3066 defaults union. This allows swat and testparm to show only the
3067 changed (ie. non-default) parameters.
3068 ***************************************************************************/
3070 static void lp_save_defaults(void)
3073 for (i = 0; parm_table[i].label; i++) {
3074 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3076 switch (parm_table[i].type) {
3078 str_list_copy(&(parm_table[i].def.lvalue),
3079 *(const char ***)parm_table[i].ptr);
3083 if (parm_table[i].ptr) {
3084 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
3086 parm_table[i].def.svalue = NULL;
3091 parm_table[i].def.bvalue =
3092 *(BOOL *)parm_table[i].ptr;
3095 parm_table[i].def.cvalue =
3096 *(char *)parm_table[i].ptr;
3101 parm_table[i].def.ivalue =
3102 *(int *)parm_table[i].ptr;
3108 defaults_saved = True;
3111 /*******************************************************************
3112 Set the server type we will announce as via nmbd.
3113 ********************************************************************/
3115 static void set_server_role(void)
3117 server_role = ROLE_STANDALONE;
3119 switch (lp_security()) {
3121 if (lp_domain_logons())
3122 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3127 if (lp_domain_logons()) {
3128 server_role = ROLE_DOMAIN_PDC;
3131 server_role = ROLE_DOMAIN_MEMBER;
3134 if (lp_domain_logons()) {
3136 if (Globals.bDomainMaster) /* auto or yes */
3137 server_role = ROLE_DOMAIN_PDC;
3139 server_role = ROLE_DOMAIN_BDC;
3143 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3147 DEBUG(10, ("set_server_role: role = "));
3149 switch(server_role) {
3150 case ROLE_STANDALONE:
3151 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3153 case ROLE_DOMAIN_MEMBER:
3154 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3156 case ROLE_DOMAIN_BDC:
3157 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3159 case ROLE_DOMAIN_PDC:
3160 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3165 /***************************************************************************
3166 Load the services array from the services file. Return True on success,
3168 ***************************************************************************/
3170 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3175 struct param_opt *data;
3177 pstrcpy(n2, pszFname);
3178 standard_sub_basic(n2,sizeof(n2));
3180 add_to_file_list(pszFname, n2);
3184 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3186 bInGlobalSection = True;
3187 bGlobalOnly = global_only;
3196 if (Globals.param_opt != NULL) {
3197 struct param_opt *next;
3198 for (data=Globals.param_opt; data; data=next) {
3200 if (data->flags & FLAG_CMDLINE) continue;
3203 DLIST_REMOVE(Globals.param_opt, data);
3208 /* We get sections first, so have to start 'behind' to make up */
3210 bRetval = pm_process(n2, do_section, do_parameter);
3212 /* finish up the last section */
3213 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3215 if (iServiceIndex >= 0)
3216 bRetval = service_ok(iServiceIndex);
3218 lp_add_auto_services(lp_auto_services());
3221 /* When 'restrict anonymous = 2' guest connections to ipc$
3223 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3224 lp_add_ipc("ADMIN$", False);
3228 set_default_server_announce_type();
3232 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3233 /* if bWINSsupport is true and we are in the client */
3234 if (in_client && Globals.bWINSsupport) {
3235 lp_do_parameter(-1, "wins server", "127.0.0.1");
3243 /***************************************************************************
3244 Reset the max number of services.
3245 ***************************************************************************/
3247 void lp_resetnumservices(void)
3252 /***************************************************************************
3253 Return the max number of services.
3254 ***************************************************************************/
3256 int lp_numservices(void)
3258 return (iNumServices);
3261 /***************************************************************************
3262 Display the contents of the services array in human-readable form.
3263 ***************************************************************************/
3265 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3270 defaults_saved = False;
3274 dump_a_service(&sDefault, f);
3276 for (iService = 0; iService < maxtoprint; iService++)
3277 lp_dump_one(f, show_defaults, iService);
3280 /***************************************************************************
3281 Display the contents of one service in human-readable form.
3282 ***************************************************************************/
3284 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3287 if (ServicePtrs[snum]->szService[0] == '\0')
3289 dump_a_service(ServicePtrs[snum], f);
3293 /***************************************************************************
3294 Return the number of the service with the given name, or -1 if it doesn't
3295 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3296 getservicebyname()! This works ONLY if all services have been loaded, and
3297 does not copy the found service.
3298 ***************************************************************************/
3300 int lp_servicenumber(const char *pszServiceName)
3303 fstring serviceName;
3306 for (iService = iNumServices - 1; iService >= 0; iService--) {
3307 if (VALID(iService) && ServicePtrs[iService]->szService) {
3309 * The substitution here is used to support %U is
3312 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3313 standard_sub_basic(serviceName,sizeof(serviceName));
3314 if (strequal(serviceName, pszServiceName))
3320 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3325 /*******************************************************************
3326 A useful volume label function.
3327 ********************************************************************/
3328 const char *volume_label(int snum)
3330 const char *ret = lp_volume(snum);
3332 return lp_servicename(snum);
3337 /*******************************************************************
3338 Set the server type we will announce as via nmbd.
3339 ********************************************************************/
3341 static void set_default_server_announce_type(void)
3343 default_server_announce = 0;
3344 default_server_announce |= SV_TYPE_WORKSTATION;
3345 default_server_announce |= SV_TYPE_SERVER;
3346 default_server_announce |= SV_TYPE_SERVER_UNIX;
3348 switch (lp_announce_as()) {
3349 case ANNOUNCE_AS_NT_SERVER:
3350 default_server_announce |= SV_TYPE_SERVER_NT;
3351 /* fall through... */
3352 case ANNOUNCE_AS_NT_WORKSTATION:
3353 default_server_announce |= SV_TYPE_NT;
3355 case ANNOUNCE_AS_WIN95:
3356 default_server_announce |= SV_TYPE_WIN95_PLUS;
3358 case ANNOUNCE_AS_WFW:
3359 default_server_announce |= SV_TYPE_WFW;
3365 switch (lp_server_role()) {
3366 case ROLE_DOMAIN_MEMBER:
3367 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3369 case ROLE_DOMAIN_PDC:
3370 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3372 case ROLE_DOMAIN_BDC:
3373 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3375 case ROLE_STANDALONE:
3379 if (lp_time_server())
3380 default_server_announce |= SV_TYPE_TIME_SOURCE;
3382 if (lp_host_msdfs())
3383 default_server_announce |= SV_TYPE_DFS_SERVER;
3386 /***********************************************************
3387 returns role of Samba server
3388 ************************************************************/
3390 int lp_server_role(void)
3395 /***********************************************************
3396 If we are PDC then prefer us as DMB
3397 ************************************************************/
3399 BOOL lp_domain_master(void)
3401 if (Globals.bDomainMaster == Auto)
3402 return (lp_server_role() == ROLE_DOMAIN_PDC);
3404 return Globals.bDomainMaster;
3407 /***********************************************************
3408 If we are DMB then prefer us as LMB
3409 ************************************************************/
3411 BOOL lp_preferred_master(void)
3413 if (Globals.bPreferredMaster == Auto)
3414 return (lp_local_master() && lp_domain_master());
3416 return Globals.bPreferredMaster;
3419 /*******************************************************************
3421 ********************************************************************/
3423 void lp_remove_service(int snum)
3425 ServicePtrs[snum]->valid = False;
3428 /*******************************************************************
3430 ********************************************************************/
3432 void lp_copy_service(int snum, const char *new_name)
3434 const char *oldname = lp_servicename(snum);
3435 do_section(new_name);
3437 snum = lp_servicenumber(new_name);
3439 lp_do_parameter(snum, "copy", oldname);
3444 /*******************************************************************
3445 Get the default server type we will announce as via nmbd.
3446 ********************************************************************/
3448 int lp_default_server_announce(void)
3450 return default_server_announce;
3453 /*******************************************************************
3454 Split the announce version into major and minor numbers.
3455 ********************************************************************/
3457 int lp_major_announce_version(void)
3459 static BOOL got_major = False;
3460 static int major_version = DEFAULT_MAJOR_VERSION;
3465 return major_version;
3468 if ((vers = lp_announce_version()) == NULL)
3469 return major_version;
3471 if ((p = strchr_m(vers, '.')) == 0)
3472 return major_version;
3475 major_version = atoi(vers);
3476 return major_version;
3479 int lp_minor_announce_version(void)
3481 static BOOL got_minor = False;
3482 static int minor_version = DEFAULT_MINOR_VERSION;
3487 return minor_version;
3490 if ((vers = lp_announce_version()) == NULL)
3491 return minor_version;
3493 if ((p = strchr_m(vers, '.')) == 0)
3494 return minor_version;
3497 minor_version = atoi(p);
3498 return minor_version;
3501 const char *lp_printername(int snum)
3503 const char *ret = _lp_printername(snum);
3504 if (ret == NULL || (ret != NULL && *ret == '\0'))
3505 ret = lp_const_servicename(snum);
3511 /*******************************************************************
3512 Return the max print jobs per queue.
3513 ********************************************************************/
3515 int lp_maxprintjobs(int snum)
3517 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3518 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3519 maxjobs = PRINT_MAX_JOBID - 1;