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", 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 /* use the new 'hash2' method by default, with a prefix of 1 */
966 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
968 /* using UTF8 by default allows us to support all chars */
969 string_set(&Globals.unix_charset, "UTF8");
971 /* Use codepage 850 as a default for the dos character set */
972 string_set(&Globals.dos_charset, "CP850");
975 * Allow the default PASSWD_CHAT to be overridden in local.h.
977 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
979 string_set(&Globals.szPasswdProgram, "");
980 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
981 string_set(&Globals.szPidDir, dyn_PIDDIR);
982 string_set(&Globals.szLockDir, dyn_LOCKDIR);
983 string_set(&Globals.szSocketAddress, "0.0.0.0");
984 pstrcpy(s, "Samba ");
985 pstrcat(s, SAMBA_VERSION_STRING);
986 string_set(&Globals.szServerString, s);
987 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
988 DEFAULT_MINOR_VERSION);
989 string_set(&Globals.szAnnounceVersion, s);
991 string_set(&Globals.szLogonDrive, "");
992 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
993 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
994 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
996 string_set(&Globals.szPasswordServer, "*");
998 Globals.bLoadPrinters = True;
999 Globals.mangled_stack = 50;
1000 Globals.max_mux = 50; /* This is *needed* for profile support. */
1001 Globals.max_xmit = 4356; /* the value w2k3 chooses */
1002 Globals.lpqcachetime = 10;
1003 Globals.bDisableSpoolss = False;
1004 Globals.pwordlevel = 0;
1005 Globals.unamelevel = 0;
1006 Globals.bLargeReadwrite = True;
1007 Globals.minprotocol = PROTOCOL_CORE;
1008 Globals.security = SEC_USER;
1009 Globals.paranoid_server_security = True;
1010 Globals.bEncryptPasswords = True;
1011 Globals.bUpdateEncrypt = False;
1012 Globals.bReadRaw = True;
1013 Globals.bWriteRaw = True;
1014 Globals.bNullPasswords = False;
1015 Globals.bObeyPamRestrictions = False;
1016 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1017 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1018 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1019 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1020 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1021 Globals.lm_interval = 60;
1022 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1024 Globals.bTimeServer = False;
1025 Globals.bBindInterfacesOnly = False;
1026 Globals.bUnixPasswdSync = False;
1027 Globals.bPamPasswordChange = False;
1028 Globals.bUnicode = True; /* Do unicode on the wire by default */
1029 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1030 Globals.restrict_anonymous = 0;
1031 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1032 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1033 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1035 Globals.enhanced_browsing = True;
1036 Globals.iLockSpinCount = 3; /* Try 2 times. */
1037 Globals.iLockSpinTime = 10; /* usec. */
1038 #ifdef MMAP_BLACKLIST
1039 Globals.bUseMmap = False;
1041 Globals.bUseMmap = True;
1043 Globals.bUnixExtensions = False;
1045 /* hostname lookups can be very expensive and are broken on
1046 a large number of sites (tridge) */
1047 Globals.bHostnameLookups = False;
1049 #ifdef WITH_LDAP_SAMCONFIG
1050 string_set(&Globals.szLdapServer, "localhost");
1051 Globals.ldap_port = 636;
1052 Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1054 Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1055 #endif /* WITH_LDAP_SAMCONFIG */
1057 string_set(&Globals.szLdapSuffix, "");
1058 string_set(&Globals.szLdapMachineSuffix, "");
1059 string_set(&Globals.szLdapUserSuffix, "");
1061 string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
1062 string_set(&Globals.szLdapAdminDn, "");
1063 Globals.ldap_ssl = LDAP_SSL_ON;
1064 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1066 /* these parameters are set to defaults that are more appropriate
1067 for the increasing samba install base:
1069 as a member of the workgroup, that will possibly become a
1070 _local_ master browser (lm = True). this is opposed to a forced
1071 local master browser startup (pm = True).
1073 doesn't provide WINS server service by default (wsupp = False),
1074 and doesn't provide domain master browser services by default, either.
1078 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1079 Globals.os_level = 20;
1080 Globals.bLocalMaster = True;
1081 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1082 Globals.bDomainLogons = False;
1083 Globals.bWINSsupport = False;
1084 Globals.bWINSproxy = False;
1086 Globals.bDNSproxy = True;
1088 Globals.bAllowTrustedDomains = True;
1090 string_set(&Globals.szTemplateShell, "/bin/false");
1091 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1092 string_set(&Globals.szWinbindSeparator, "\\");
1094 Globals.winbind_cache_time = 15;
1095 Globals.bWinbindEnumUsers = True;
1096 Globals.bWinbindEnumGroups = True;
1097 Globals.bWinbindUseDefaultDomain = False;
1099 string_set(&Globals.szIDMapBackend, "tdb");
1101 Globals.name_cache_timeout = 660; /* In seconds */
1103 Globals.bUseSpnego = True;
1105 Globals.server_signing = False;
1107 string_set(&Globals.smb_ports, SMB_PORTS);
1110 static TALLOC_CTX *lp_talloc;
1112 /******************************************************************* a
1113 Free up temporary memory - called from the main loop.
1114 ********************************************************************/
1116 void lp_talloc_free(void)
1120 talloc_destroy(lp_talloc);
1124 /*******************************************************************
1125 Convenience routine to grab string parameters into temporary memory
1126 and run standard_sub_basic on them. The buffers can be written to by
1127 callers without affecting the source string.
1128 ********************************************************************/
1130 static char *lp_string(const char *s)
1132 #if 0 /* until REWRITE done to make thread-safe */
1133 size_t len = s ? strlen(s) : 0;
1137 /* The follow debug is useful for tracking down memory problems
1138 especially if you have an inner loop that is calling a lp_*()
1139 function that returns a string. Perhaps this debug should be
1140 present all the time? */
1143 DEBUG(10, ("lp_string(%s)\n", s));
1146 #if 0 /* until REWRITE done to make thread-safe */
1148 lp_talloc = talloc_init("lp_talloc");
1150 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1158 StrnCpy(ret, s, len);
1160 if (trim_string(ret, "\"", "\"")) {
1161 if (strchr(ret,'"') != NULL)
1162 StrnCpy(ret, s, len);
1165 standard_sub_basic(ret,len+100);
1172 In this section all the functions that are used to access the
1173 parameters from the rest of the program are defined
1176 #define FN_GLOBAL_STRING(fn_name,ptr) \
1177 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1178 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1179 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1180 #define FN_GLOBAL_LIST(fn_name,ptr) \
1181 const char **fn_name(void) {return(*(const char ***)(ptr));}
1182 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1183 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1184 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1185 char fn_name(void) {return(*(char *)(ptr));}
1186 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1187 int fn_name(void) {return(*(int *)(ptr));}
1189 #define FN_LOCAL_STRING(fn_name,val) \
1190 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1191 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1192 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1193 #define FN_LOCAL_LIST(fn_name,val) \
1194 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1195 #define FN_LOCAL_BOOL(fn_name,val) \
1196 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1197 #define FN_LOCAL_CHAR(fn_name,val) \
1198 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1199 #define FN_LOCAL_INTEGER(fn_name,val) \
1200 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1202 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1203 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1204 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1205 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1206 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1207 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1208 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1209 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1210 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1211 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1212 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1213 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1214 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1215 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1216 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1217 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1218 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1219 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1220 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1221 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1222 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1223 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1224 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1225 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1226 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1227 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1228 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1229 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1230 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1231 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1232 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1233 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1234 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1235 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1236 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1237 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1238 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1239 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1240 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1241 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1242 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1243 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1244 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1246 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1248 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1250 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1251 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1252 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1253 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1254 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1255 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1256 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1257 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1258 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1260 #ifdef WITH_LDAP_SAMCONFIG
1261 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1262 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1264 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1265 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1266 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1267 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1268 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1269 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1270 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1271 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1273 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1274 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1275 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1276 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1277 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1278 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1279 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1280 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1281 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1282 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1283 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1284 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1285 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1286 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1287 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1288 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1289 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1290 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1291 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1292 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1293 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1294 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1295 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1296 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1297 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1298 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1299 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1300 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1301 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1302 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1303 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1304 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1305 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1306 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1307 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1308 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1309 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1310 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1311 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1312 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1313 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1314 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1315 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1316 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1317 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1318 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1319 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1320 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1321 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1322 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1323 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1324 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1325 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1326 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1327 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1328 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1329 FN_LOCAL_STRING(lp_servicename, szService)
1330 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1331 FN_LOCAL_STRING(lp_pathname, szPath)
1332 FN_LOCAL_STRING(lp_username, szUsername)
1333 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1334 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1335 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1336 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1337 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1338 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1339 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1340 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1341 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1342 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1343 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1344 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1345 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1346 FN_LOCAL_STRING(lp_comment, comment)
1347 FN_LOCAL_STRING(lp_fstype, fstype)
1348 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1349 static FN_LOCAL_STRING(lp_volume, volume)
1350 FN_LOCAL_STRING(lp_ntvfs_handler, ntvfs_handler)
1351 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1352 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1353 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1354 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1355 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1356 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1357 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1358 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1359 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1360 FN_LOCAL_BOOL(lp_locking, bLocking)
1361 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1362 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1363 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1364 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1365 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1366 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1367 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1368 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1369 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1370 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1371 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1372 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1373 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1374 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1375 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1377 /* local prototypes */
1379 static int map_parameter(const char *pszParmName);
1380 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1381 static int getservicebyname(const char *pszServiceName,
1382 service * pserviceDest);
1383 static void copy_service(service * pserviceDest,
1384 service * pserviceSource, BOOL *pcopymapDest);
1385 static BOOL service_ok(int iService);
1386 static BOOL do_section(const char *pszSectionName);
1387 static void init_copymap(service * pservice);
1389 /* This is a helper function for parametrical options support. */
1390 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1391 /* Actual parametrical functions are quite simple */
1392 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1395 struct param_opt *data;
1397 if (lookup_service >= iNumServices) return NULL;
1399 data = (lookup_service < 0) ?
1400 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1402 asprintf(&vfskey, "%s:%s", type, option);
1406 if (strcmp(data->key, vfskey) == 0) {
1413 if (lookup_service >= 0) {
1414 /* Try to fetch the same option but from globals */
1415 /* but only if we are not already working with Globals */
1416 data = Globals.param_opt;
1418 if (strcmp(data->key, vfskey) == 0) {
1432 /*******************************************************************
1433 convenience routine to return int parameters.
1434 ********************************************************************/
1435 static int lp_int(const char *s)
1439 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1446 /*******************************************************************
1447 convenience routine to return unsigned long parameters.
1448 ********************************************************************/
1449 static int lp_ulong(const char *s)
1453 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1457 return strtoul(s, NULL, 10);
1460 /*******************************************************************
1461 convenience routine to return boolean parameters.
1462 ********************************************************************/
1463 static BOOL lp_bool(const char *s)
1468 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1472 if (!set_boolean(&ret,s)) {
1473 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1480 /*******************************************************************
1481 convenience routine to return enum parameters.
1482 ********************************************************************/
1483 static int lp_enum(const char *s,const struct enum_list *_enum)
1488 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1492 for (i=0; _enum[i].name; i++) {
1493 if (strcasecmp(_enum[i].name,s)==0)
1494 return _enum[i].value;
1497 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1501 /* Return parametric option from a given service. Type is a part of option before ':' */
1502 /* Parametric option has following syntax: 'Type: option = value' */
1503 /* Returned value is allocated in 'lp_talloc' context */
1505 char *lp_parm_string(int lookup_service, const char *type, const char *option)
1507 const char *value = get_parametrics(lookup_service, type, option);
1510 return lp_string(value);
1515 /* Return parametric option from a given service. Type is a part of option before ':' */
1516 /* Parametric option has following syntax: 'Type: option = value' */
1517 /* Returned value is allocated in 'lp_talloc' context */
1519 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1520 const char *separator)
1522 const char *value = get_parametrics(lookup_service, type, option);
1525 return str_list_make(value, separator);
1530 /* Return parametric option from a given service. Type is a part of option before ':' */
1531 /* Parametric option has following syntax: 'Type: option = value' */
1533 int lp_parm_int(int lookup_service, const char *type, const char *option)
1535 const char *value = get_parametrics(lookup_service, type, option);
1538 return lp_int(value);
1543 /* Return parametric option from a given service. Type is a part of option before ':' */
1544 /* Parametric option has following syntax: 'Type: option = value' */
1546 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1548 const char *value = get_parametrics(lookup_service, type, option);
1551 return lp_ulong(value);
1556 /* Return parametric option from a given service. Type is a part of option before ':' */
1557 /* Parametric option has following syntax: 'Type: option = value' */
1559 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1561 const char *value = get_parametrics(lookup_service, type, option);
1564 return lp_bool(value);
1569 /* Return parametric option from a given service. Type is a part of option before ':' */
1570 /* Parametric option has following syntax: 'Type: option = value' */
1572 int lp_parm_enum(int lookup_service, const char *type, const char *option,
1573 const struct enum_list *_enum)
1575 const char *value = get_parametrics(lookup_service, type, option);
1578 return lp_enum(value, _enum);
1584 /***************************************************************************
1585 Initialise a service to the defaults.
1586 ***************************************************************************/
1588 static void init_service(service * pservice)
1590 memset((char *)pservice, '\0', sizeof(service));
1591 copy_service(pservice, &sDefault, NULL);
1594 /***************************************************************************
1595 Free the dynamically allocated parts of a service struct.
1596 ***************************************************************************/
1598 static void free_service(service *pservice)
1601 struct param_opt *data, *pdata;
1605 if (pservice->szService)
1606 DEBUG(5, ("free_service: Freeing service %s\n",
1607 pservice->szService));
1609 string_free(&pservice->szService);
1610 SAFE_FREE(pservice->copymap);
1612 for (i = 0; parm_table[i].label; i++) {
1613 if ((parm_table[i].type == P_STRING ||
1614 parm_table[i].type == P_USTRING) &&
1615 parm_table[i].class == P_LOCAL)
1616 string_free((char **)
1617 (((char *)pservice) +
1618 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1619 else if (parm_table[i].type == P_LIST &&
1620 parm_table[i].class == P_LOCAL)
1621 str_list_free((char ***)
1622 (((char *)pservice) +
1623 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1626 DEBUG(5,("Freeing parametrics:\n"));
1627 data = pservice->param_opt;
1629 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1630 string_free(&data->key);
1631 string_free(&data->value);
1637 ZERO_STRUCTP(pservice);
1640 /***************************************************************************
1641 Add a new service to the services array initialising it with the given
1643 ***************************************************************************/
1645 static int add_a_service(const service *pservice, const char *name)
1649 int num_to_alloc = iNumServices + 1;
1650 struct param_opt *data, *pdata;
1652 tservice = *pservice;
1654 /* it might already exist */
1656 i = getservicebyname(name, NULL);
1658 /* Clean all parametric options for service */
1659 /* They will be added during parsing again */
1660 data = ServicePtrs[i]->param_opt;
1662 string_free(&data->key);
1663 string_free(&data->value);
1668 ServicePtrs[i]->param_opt = NULL;
1673 /* find an invalid one */
1674 for (i = 0; i < iNumServices; i++)
1675 if (!ServicePtrs[i]->valid)
1678 /* if not, then create one */
1679 if (i == iNumServices) {
1682 tsp = (service **) Realloc(ServicePtrs,
1687 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1692 ServicePtrs[iNumServices] =
1693 (service *) malloc(sizeof(service));
1695 if (!ServicePtrs[iNumServices]) {
1696 DEBUG(0,("add_a_service: out of memory!\n"));
1702 free_service(ServicePtrs[i]);
1704 ServicePtrs[i]->valid = True;
1706 init_service(ServicePtrs[i]);
1707 copy_service(ServicePtrs[i], &tservice, NULL);
1709 string_set(&ServicePtrs[i]->szService, name);
1713 /***************************************************************************
1714 Add a new home service, with the specified home directory, defaults coming
1716 ***************************************************************************/
1718 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1719 const char *user, const char *pszHomedir)
1724 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1729 if (!(*(ServicePtrs[iDefaultService]->szPath))
1730 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1731 pstrcpy(newHomedir, pszHomedir);
1733 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1734 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1737 string_set(&ServicePtrs[i]->szPath, newHomedir);
1739 if (!(*(ServicePtrs[i]->comment))) {
1741 slprintf(comment, sizeof(comment) - 1,
1742 "Home directory of %s", user);
1743 string_set(&ServicePtrs[i]->comment, comment);
1745 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1746 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1748 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1754 /***************************************************************************
1755 Add a new service, based on an old one.
1756 ***************************************************************************/
1758 int lp_add_service(const char *pszService, int iDefaultService)
1760 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1763 /***************************************************************************
1764 Add the IPC service.
1765 ***************************************************************************/
1767 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1770 int i = add_a_service(&sDefault, ipc_name);
1775 slprintf(comment, sizeof(comment) - 1,
1776 "IPC Service (%s)", Globals.szServerString);
1778 string_set(&ServicePtrs[i]->szPath, tmpdir());
1779 string_set(&ServicePtrs[i]->szUsername, "");
1780 string_set(&ServicePtrs[i]->comment, comment);
1781 string_set(&ServicePtrs[i]->fstype, "IPC");
1782 ServicePtrs[i]->iMaxConnections = 0;
1783 ServicePtrs[i]->bAvailable = True;
1784 ServicePtrs[i]->bRead_only = True;
1785 ServicePtrs[i]->bGuest_only = False;
1786 ServicePtrs[i]->bGuest_ok = guest_ok;
1787 ServicePtrs[i]->bPrint_ok = False;
1788 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1790 DEBUG(3, ("adding IPC service\n"));
1795 /***************************************************************************
1796 Add a new printer service, with defaults coming from service iFrom.
1797 ***************************************************************************/
1799 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1801 const char *comment = "From Printcap";
1802 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1807 /* note that we do NOT default the availability flag to True - */
1808 /* we take it from the default service passed. This allows all */
1809 /* dynamic printers to be disabled by disabling the [printers] */
1810 /* entry (if/when the 'available' keyword is implemented!). */
1812 /* the printer name is set to the service name. */
1813 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1814 string_set(&ServicePtrs[i]->comment, comment);
1815 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1816 /* Printers cannot be read_only. */
1817 ServicePtrs[i]->bRead_only = False;
1818 /* No share modes on printer services. */
1819 ServicePtrs[i]->bShareModes = False;
1820 /* No oplocks on printer services. */
1821 ServicePtrs[i]->bOpLocks = False;
1822 /* Printer services must be printable. */
1823 ServicePtrs[i]->bPrint_ok = True;
1825 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1827 update_server_announce_as_printserver();
1832 /***************************************************************************
1833 Map a parameter's string representation to something we can use.
1834 Returns False if the parameter string is not recognised, else TRUE.
1835 ***************************************************************************/
1837 static int map_parameter(const char *pszParmName)
1841 if (*pszParmName == '-')
1844 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1845 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1848 /* Warn only if it isn't parametric option */
1849 if (strchr(pszParmName, ':') == NULL)
1850 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1851 /* We do return 'fail' for parametric options as well because they are
1852 stored in different storage
1857 /***************************************************************************
1858 Set a boolean variable from the text value stored in the passed string.
1859 Returns True in success, False if the passed string does not correctly
1860 represent a boolean.
1861 ***************************************************************************/
1863 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1868 if (strwicmp(pszParmValue, "yes") == 0 ||
1869 strwicmp(pszParmValue, "true") == 0 ||
1870 strwicmp(pszParmValue, "1") == 0)
1872 else if (strwicmp(pszParmValue, "no") == 0 ||
1873 strwicmp(pszParmValue, "False") == 0 ||
1874 strwicmp(pszParmValue, "0") == 0)
1878 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1885 /***************************************************************************
1886 Find a service by name. Otherwise works like get_service.
1887 ***************************************************************************/
1889 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1893 for (iService = iNumServices - 1; iService >= 0; iService--)
1894 if (VALID(iService) &&
1895 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1896 if (pserviceDest != NULL)
1897 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1904 /***************************************************************************
1905 Copy a service structure to another.
1906 If pcopymapDest is NULL then copy all fields
1907 ***************************************************************************/
1909 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1912 BOOL bcopyall = (pcopymapDest == NULL);
1913 struct param_opt *data, *pdata, *paramo;
1916 for (i = 0; parm_table[i].label; i++)
1917 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1918 (bcopyall || pcopymapDest[i])) {
1919 void *def_ptr = parm_table[i].ptr;
1921 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1924 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1927 switch (parm_table[i].type) {
1930 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1936 *(int *)dest_ptr = *(int *)src_ptr;
1940 *(char *)dest_ptr = *(char *)src_ptr;
1944 string_set(dest_ptr,
1949 string_set(dest_ptr,
1951 strupper(*(char **)dest_ptr);
1954 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1962 init_copymap(pserviceDest);
1963 if (pserviceSource->copymap)
1964 memcpy((void *)pserviceDest->copymap,
1965 (void *)pserviceSource->copymap,
1966 sizeof(BOOL) * NUMPARAMETERS);
1969 data = pserviceSource->param_opt;
1972 pdata = pserviceDest->param_opt;
1973 /* Traverse destination */
1975 /* If we already have same option, override it */
1976 if (strcmp(pdata->key, data->key) == 0) {
1977 string_free(&pdata->value);
1978 pdata->value = strdup(data->value);
1982 pdata = pdata->next;
1985 paramo = smb_xmalloc(sizeof(*paramo));
1986 paramo->key = strdup(data->key);
1987 paramo->value = strdup(data->value);
1988 DLIST_ADD(pserviceDest->param_opt, paramo);
1994 /***************************************************************************
1995 Check a service for consistency. Return False if the service is in any way
1996 incomplete or faulty, else True.
1997 ***************************************************************************/
1999 static BOOL service_ok(int iService)
2004 if (ServicePtrs[iService]->szService[0] == '\0') {
2005 DEBUG(0, ("The following message indicates an internal error:\n"));
2006 DEBUG(0, ("No service name in service entry.\n"));
2010 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2011 /* I can't see why you'd want a non-printable printer service... */
2012 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2013 if (!ServicePtrs[iService]->bPrint_ok) {
2014 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2015 ServicePtrs[iService]->szService));
2016 ServicePtrs[iService]->bPrint_ok = True;
2018 /* [printers] service must also be non-browsable. */
2019 if (ServicePtrs[iService]->bBrowseable)
2020 ServicePtrs[iService]->bBrowseable = False;
2023 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2024 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2025 DEBUG(0, ("No path in service %s - using %s\n",
2026 ServicePtrs[iService]->szService, tmpdir()));
2027 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2030 /* If a service is flagged unavailable, log the fact at level 0. */
2031 if (!ServicePtrs[iService]->bAvailable)
2032 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2033 ServicePtrs[iService]->szService));
2038 static struct file_lists {
2039 struct file_lists *next;
2043 } *file_lists = NULL;
2045 /*******************************************************************
2046 Keep a linked list of all config files so we know when one has changed
2047 it's date and needs to be reloaded.
2048 ********************************************************************/
2050 static void add_to_file_list(const char *fname, const char *subfname)
2052 struct file_lists *f = file_lists;
2055 if (f->name && !strcmp(f->name, fname))
2061 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2064 f->next = file_lists;
2065 f->name = strdup(fname);
2070 f->subfname = strdup(subfname);
2076 f->modtime = file_modtime(subfname);
2078 time_t t = file_modtime(subfname);
2084 /*******************************************************************
2085 Check if a config file has changed date.
2086 ********************************************************************/
2088 BOOL lp_file_list_changed(void)
2090 struct file_lists *f = file_lists;
2091 DEBUG(6, ("lp_file_list_changed()\n"));
2097 pstrcpy(n2, f->name);
2098 standard_sub_basic(n2,sizeof(n2));
2100 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2101 f->name, n2, ctime(&f->modtime)));
2103 mod_time = file_modtime(n2);
2105 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2107 ("file %s modified: %s\n", n2,
2109 f->modtime = mod_time;
2110 SAFE_FREE(f->subfname);
2111 f->subfname = strdup(n2);
2119 /***************************************************************************
2120 Handle the include operation.
2121 ***************************************************************************/
2123 static BOOL handle_include(const char *pszParmValue, char **ptr)
2126 pstrcpy(fname, pszParmValue);
2128 standard_sub_basic(fname,sizeof(fname));
2130 add_to_file_list(pszParmValue, fname);
2132 string_set(ptr, fname);
2134 if (file_exist(fname, NULL))
2135 return (pm_process(fname, do_section, do_parameter));
2137 DEBUG(2, ("Can't find include file %s\n", fname));
2142 /***************************************************************************
2143 Handle the interpretation of the copy parameter.
2144 ***************************************************************************/
2146 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2150 service serviceTemp;
2152 string_set(ptr, pszParmValue);
2154 init_service(&serviceTemp);
2158 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2160 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2161 if (iTemp == iServiceIndex) {
2162 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2164 copy_service(ServicePtrs[iServiceIndex],
2166 ServicePtrs[iServiceIndex]->copymap);
2170 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2174 free_service(&serviceTemp);
2178 /***************************************************************************
2179 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2184 winbind uid = 1000-1999
2185 winbind gid = 700-899
2187 We only do simple parsing checks here. The strings are parsed into useful
2188 structures in the winbind daemon code.
2190 ***************************************************************************/
2192 /* Some lp_ routines to return winbind [ug]id information */
2194 static uid_t winbind_uid_low, winbind_uid_high;
2195 static gid_t winbind_gid_low, winbind_gid_high;
2196 static uint32 non_unix_account_low, non_unix_account_high;
2198 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2200 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2204 *low = winbind_uid_low;
2207 *high = winbind_uid_high;
2212 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2214 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2218 *low = winbind_gid_low;
2221 *high = winbind_gid_high;
2226 BOOL lp_non_unix_account_range(uint32 *low, uint32 *high)
2228 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2232 *low = non_unix_account_low;
2235 *high = non_unix_account_high;
2240 /* Do some simple checks on "winbind [ug]id" parameter values */
2242 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2246 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2251 string_set(ptr, pszParmValue);
2253 winbind_uid_low = low;
2254 winbind_uid_high = high;
2259 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2263 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2268 string_set(ptr, pszParmValue);
2270 winbind_gid_low = low;
2271 winbind_gid_high = high;
2276 /***************************************************************************
2277 Do some simple checks on "non unix account range" parameter values.
2278 ***************************************************************************/
2280 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2284 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2289 string_set(ptr, pszParmValue);
2291 non_unix_account_low = low;
2292 non_unix_account_high = high;
2297 /***************************************************************************
2298 Handle the ldap machine suffix option.
2299 ***************************************************************************/
2301 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2305 pstrcpy(suffix, pszParmValue);
2307 if (! *Globals.szLdapSuffix ) {
2308 string_set( ptr, suffix );
2312 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2313 if ( *pszParmValue )
2314 pstrcat(suffix, ",");
2315 pstrcat(suffix, Globals.szLdapSuffix);
2317 string_set( ptr, suffix );
2321 /***************************************************************************
2322 Handle the ldap user suffix option.
2323 ***************************************************************************/
2325 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2329 pstrcpy(suffix, pszParmValue);
2331 if (! *Globals.szLdapSuffix ) {
2332 string_set( ptr, suffix );
2336 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2337 if ( *pszParmValue )
2338 pstrcat(suffix, ",");
2339 pstrcat(suffix, Globals.szLdapSuffix);
2341 string_set( ptr, suffix );
2345 /***************************************************************************
2346 Handle setting ldap suffix and determines whether ldap machine suffix needs
2348 ***************************************************************************/
2350 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
2353 pstring user_suffix;
2354 pstring machine_suffix;
2356 pstrcpy(suffix, pszParmValue);
2358 if (! *Globals.szLdapMachineSuffix )
2359 string_set(&Globals.szLdapMachineSuffix, suffix);
2360 if (! *Globals.szLdapUserSuffix )
2361 string_set(&Globals.szLdapUserSuffix, suffix);
2363 if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
2364 pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
2365 if ( *Globals.szLdapMachineSuffix )
2366 pstrcat(machine_suffix, ",");
2367 pstrcat(machine_suffix, suffix);
2368 string_set(&Globals.szLdapMachineSuffix, machine_suffix);
2371 if (! strstr(Globals.szLdapUserSuffix, suffix)) {
2372 pstrcpy(user_suffix, Globals.szLdapUserSuffix);
2373 if ( *Globals.szLdapUserSuffix )
2374 pstrcat(user_suffix, ",");
2375 pstrcat(user_suffix, suffix);
2376 string_set(&Globals.szLdapUserSuffix, user_suffix);
2379 string_set(ptr, suffix);
2384 /***************************************************************************
2385 Initialise a copymap.
2386 ***************************************************************************/
2388 static void init_copymap(service * pservice)
2391 SAFE_FREE(pservice->copymap);
2392 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2393 if (!pservice->copymap)
2395 ("Couldn't allocate copymap!! (size %d)\n",
2396 (int)NUMPARAMETERS));
2398 for (i = 0; i < NUMPARAMETERS; i++)
2399 pservice->copymap[i] = True;
2402 /***************************************************************************
2403 Return the local pointer to a parameter given the service number and the
2404 pointer into the default structure.
2405 ***************************************************************************/
2407 void *lp_local_ptr(int snum, void *ptr)
2409 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2413 /***************************************************************************
2414 Process a parametric option
2415 ***************************************************************************/
2416 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2418 struct param_opt *paramo, *data;
2421 while (isspace(*pszParmName)) {
2425 name = strdup(pszParmName);
2426 if (!name) return False;
2431 data = Globals.param_opt;
2433 data = ServicePtrs[snum]->param_opt;
2436 /* Traverse destination */
2437 for (paramo=data; paramo; paramo=paramo->next) {
2438 /* If we already have the option set, override it unless
2439 it was a command line option and the new one isn't */
2440 if (strcmp(paramo->key, name) == 0) {
2441 if ((paramo->flags & FLAG_CMDLINE) &&
2442 !(flags & FLAG_CMDLINE)) {
2446 free(paramo->value);
2447 paramo->value = strdup(pszParmValue);
2448 paramo->flags = flags;
2454 paramo = smb_xmalloc(sizeof(*paramo));
2455 paramo->key = strdup(name);
2456 paramo->value = strdup(pszParmValue);
2457 paramo->flags = flags;
2459 DLIST_ADD(Globals.param_opt, paramo);
2461 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2469 /***************************************************************************
2470 Process a parameter for a particular service number. If snum < 0
2471 then assume we are in the globals.
2472 ***************************************************************************/
2473 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2476 void *parm_ptr = NULL; /* where we are going to store the result */
2477 void *def_ptr = NULL;
2479 parmnum = map_parameter(pszParmName);
2482 if (strchr(pszParmName, ':')) {
2483 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2485 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2489 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2490 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2494 /* if the flag has been set on the command line, then don't allow override,
2495 but don't report an error */
2496 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2500 def_ptr = parm_table[parmnum].ptr;
2502 /* we might point at a service, the default service or a global */
2506 if (parm_table[parmnum].class == P_GLOBAL) {
2508 ("Global parameter %s found in service section!\n",
2513 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2518 if (!ServicePtrs[snum]->copymap)
2519 init_copymap(ServicePtrs[snum]);
2521 /* this handles the aliases - set the copymap for other entries with
2522 the same data pointer */
2523 for (i = 0; parm_table[i].label; i++)
2524 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2525 ServicePtrs[snum]->copymap[i] = False;
2528 /* if it is a special case then go ahead */
2529 if (parm_table[parmnum].special) {
2530 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2534 /* now switch on the type of variable it is */
2535 switch (parm_table[parmnum].type)
2538 set_boolean(parm_ptr, pszParmValue);
2542 set_boolean(parm_ptr, pszParmValue);
2543 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2547 *(int *)parm_ptr = atoi(pszParmValue);
2551 *(char *)parm_ptr = *pszParmValue;
2555 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2559 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2563 string_set(parm_ptr, pszParmValue);
2567 string_set(parm_ptr, pszParmValue);
2568 strupper(*(char **)parm_ptr);
2572 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2575 parm_table[parmnum].enum_list[i].name)) {
2577 parm_table[parmnum].
2590 /***************************************************************************
2591 Process a parameter.
2592 ***************************************************************************/
2594 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2596 if (!bInGlobalSection && bGlobalOnly)
2599 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2601 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2602 pszParmName, pszParmValue));
2607 set a parameter from the commandline - this is called from command line parameter
2608 parsing code. It sets the parameter then marks the parameter as unable to be modified
2609 by smb.conf processing
2611 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2613 int parmnum = map_parameter(pszParmName);
2615 if (parmnum < 0 && strchr(pszParmName, ':')) {
2616 /* set a parametric option */
2617 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2620 /* reset the CMDLINE flag in case this has been called before */
2621 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2623 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2627 parm_table[parmnum].flags |= FLAG_CMDLINE;
2631 /***************************************************************************
2632 Print a parameter of the specified type.
2633 ***************************************************************************/
2635 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2641 for (i = 0; p->enum_list[i].name; i++) {
2642 if (*(int *)ptr == p->enum_list[i].value) {
2644 p->enum_list[i].name);
2651 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2655 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2659 fprintf(f, "%d", *(int *)ptr);
2663 fprintf(f, "%c", *(char *)ptr);
2667 fprintf(f, "%s", octal_string(*(int *)ptr));
2671 if ((char ***)ptr && *(char ***)ptr) {
2672 char **list = *(char ***)ptr;
2674 for (; *list; list++)
2675 fprintf(f, "%s%s", *list,
2676 ((*(list+1))?", ":""));
2682 if (*(char **)ptr) {
2683 fprintf(f, "%s", *(char **)ptr);
2691 /***************************************************************************
2692 Check if two parameters are equal.
2693 ***************************************************************************/
2695 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2700 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2705 return (*((int *)ptr1) == *((int *)ptr2));
2708 return (*((char *)ptr1) == *((char *)ptr2));
2711 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2716 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2721 return (p1 == p2 || strequal(p1, p2));
2729 /***************************************************************************
2730 Process a new section (service). At this stage all sections are services.
2731 Later we'll have special sections that permit server parameters to be set.
2732 Returns True on success, False on failure.
2733 ***************************************************************************/
2735 static BOOL do_section(const char *pszSectionName)
2738 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2739 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2742 /* if we've just struck a global section, note the fact. */
2743 bInGlobalSection = isglobal;
2745 /* check for multiple global sections */
2746 if (bInGlobalSection) {
2747 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2751 if (!bInGlobalSection && bGlobalOnly)
2754 /* if we have a current service, tidy it up before moving on */
2757 if (iServiceIndex >= 0)
2758 bRetval = service_ok(iServiceIndex);
2760 /* if all is still well, move to the next record in the services array */
2762 /* We put this here to avoid an odd message order if messages are */
2763 /* issued by the post-processing of a previous section. */
2764 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2766 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2768 DEBUG(0, ("Failed to add a new service\n"));
2777 /***************************************************************************
2778 Determine if a partcular base parameter is currentl set to the default value.
2779 ***************************************************************************/
2781 static BOOL is_default(int i)
2783 if (!defaults_saved)
2785 switch (parm_table[i].type) {
2787 return str_list_compare (parm_table[i].def.lvalue,
2788 *(char ***)parm_table[i].ptr);
2791 return strequal(parm_table[i].def.svalue,
2792 *(char **)parm_table[i].ptr);
2795 return parm_table[i].def.bvalue ==
2796 *(BOOL *)parm_table[i].ptr;
2798 return parm_table[i].def.cvalue ==
2799 *(char *)parm_table[i].ptr;
2803 return parm_table[i].def.ivalue ==
2804 *(int *)parm_table[i].ptr;
2811 /***************************************************************************
2812 Display the contents of the global structure.
2813 ***************************************************************************/
2815 static void dump_globals(FILE *f)
2818 struct param_opt *data;
2820 fprintf(f, "# Global parameters\n[global]\n");
2822 for (i = 0; parm_table[i].label; i++)
2823 if (parm_table[i].class == P_GLOBAL &&
2824 parm_table[i].ptr &&
2825 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2826 if (defaults_saved && is_default(i))
2828 fprintf(f, "\t%s = ", parm_table[i].label);
2829 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2832 if (Globals.param_opt != NULL) {
2833 data = Globals.param_opt;
2835 fprintf(f, "\t%s = %s\n", data->key, data->value);
2842 /***************************************************************************
2843 Return True if a local parameter is currently set to the global default.
2844 ***************************************************************************/
2846 BOOL lp_is_default(int snum, struct parm_struct *parm)
2848 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
2850 return equal_parameter(parm->type,
2851 ((char *)ServicePtrs[snum]) + pdiff,
2852 ((char *)&sDefault) + pdiff);
2855 /***************************************************************************
2856 Display the contents of a single services record.
2857 ***************************************************************************/
2859 static void dump_a_service(service * pService, FILE * f)
2862 struct param_opt *data;
2864 if (pService != &sDefault)
2865 fprintf(f, "\n[%s]\n", pService->szService);
2867 for (i = 0; parm_table[i].label; i++)
2868 if (parm_table[i].class == P_LOCAL &&
2869 parm_table[i].ptr &&
2870 (*parm_table[i].label != '-') &&
2871 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2872 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2874 if (pService == &sDefault) {
2875 if (defaults_saved && is_default(i))
2878 if (equal_parameter(parm_table[i].type,
2879 ((char *)pService) +
2881 ((char *)&sDefault) +
2886 fprintf(f, "\t%s = ", parm_table[i].label);
2887 print_parameter(&parm_table[i],
2888 ((char *)pService) + pdiff, f);
2891 if (pService->param_opt != NULL) {
2892 data = pService->param_opt;
2894 fprintf(f, "\t%s = %s\n", data->key, data->value);
2901 /***************************************************************************
2902 Return info about the next service in a service. snum==-1 gives the globals.
2903 Return NULL when out of parameters.
2904 ***************************************************************************/
2906 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2909 /* do the globals */
2910 for (; parm_table[*i].label; (*i)++) {
2911 if (parm_table[*i].class == P_SEPARATOR)
2912 return &parm_table[(*i)++];
2914 if (!parm_table[*i].ptr
2915 || (*parm_table[*i].label == '-'))
2919 && (parm_table[*i].ptr ==
2920 parm_table[(*i) - 1].ptr))
2923 return &parm_table[(*i)++];
2926 service *pService = ServicePtrs[snum];
2928 for (; parm_table[*i].label; (*i)++) {
2929 if (parm_table[*i].class == P_SEPARATOR)
2930 return &parm_table[(*i)++];
2932 if (parm_table[*i].class == P_LOCAL &&
2933 parm_table[*i].ptr &&
2934 (*parm_table[*i].label != '-') &&
2936 (parm_table[*i].ptr !=
2937 parm_table[(*i) - 1].ptr)))
2940 PTR_DIFF(parm_table[*i].ptr,
2943 if (allparameters ||
2944 !equal_parameter(parm_table[*i].type,
2945 ((char *)pService) +
2947 ((char *)&sDefault) +
2950 return &parm_table[(*i)++];
2961 /***************************************************************************
2962 Display the contents of a single copy structure.
2963 ***************************************************************************/
2964 static void dump_copy_map(BOOL *pcopymap)
2970 printf("\n\tNon-Copied parameters:\n");
2972 for (i = 0; parm_table[i].label; i++)
2973 if (parm_table[i].class == P_LOCAL &&
2974 parm_table[i].ptr && !pcopymap[i] &&
2975 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2977 printf("\t\t%s\n", parm_table[i].label);
2982 /***************************************************************************
2983 Return TRUE if the passed service number is within range.
2984 ***************************************************************************/
2986 BOOL lp_snum_ok(int iService)
2988 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2991 /***************************************************************************
2992 Auto-load some home services.
2993 ***************************************************************************/
2995 static void lp_add_auto_services(char *str)
3000 /***************************************************************************
3001 Auto-load one printer.
3002 ***************************************************************************/
3004 void lp_add_one_printer(char *name, char *comment)
3006 int printers = lp_servicenumber(PRINTERS_NAME);
3009 if (lp_servicenumber(name) < 0) {
3010 lp_add_printer(name, printers);
3011 if ((i = lp_servicenumber(name)) >= 0) {
3012 string_set(&ServicePtrs[i]->comment, comment);
3013 ServicePtrs[i]->autoloaded = True;
3018 /***************************************************************************
3019 Announce ourselves as a print server.
3020 ***************************************************************************/
3022 void update_server_announce_as_printserver(void)
3024 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3027 /***************************************************************************
3028 Have we loaded a services file yet?
3029 ***************************************************************************/
3031 BOOL lp_loaded(void)
3036 /***************************************************************************
3037 Unload unused services.
3038 ***************************************************************************/
3040 void lp_killunused(struct server_context *smb, BOOL (*snumused) (struct server_context *, int))
3043 for (i = 0; i < iNumServices; i++) {
3047 if (!snumused || !snumused(smb, i)) {
3048 ServicePtrs[i]->valid = False;
3049 free_service(ServicePtrs[i]);
3054 /***************************************************************************
3056 ***************************************************************************/
3058 void lp_killservice(int iServiceIn)
3060 if (VALID(iServiceIn)) {
3061 ServicePtrs[iServiceIn]->valid = False;
3062 free_service(ServicePtrs[iServiceIn]);
3066 /***************************************************************************
3067 Save the curent values of all global and sDefault parameters into the
3068 defaults union. This allows swat and testparm to show only the
3069 changed (ie. non-default) parameters.
3070 ***************************************************************************/
3072 static void lp_save_defaults(void)
3075 for (i = 0; parm_table[i].label; i++) {
3076 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3078 switch (parm_table[i].type) {
3080 str_list_copy(&(parm_table[i].def.lvalue),
3081 *(const char ***)parm_table[i].ptr);
3085 if (parm_table[i].ptr) {
3086 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
3088 parm_table[i].def.svalue = NULL;
3093 parm_table[i].def.bvalue =
3094 *(BOOL *)parm_table[i].ptr;
3097 parm_table[i].def.cvalue =
3098 *(char *)parm_table[i].ptr;
3103 parm_table[i].def.ivalue =
3104 *(int *)parm_table[i].ptr;
3110 defaults_saved = True;
3113 /*******************************************************************
3114 Set the server type we will announce as via nmbd.
3115 ********************************************************************/
3117 static void set_server_role(void)
3119 server_role = ROLE_STANDALONE;
3121 switch (lp_security()) {
3123 if (lp_domain_logons())
3124 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3129 if (lp_domain_logons()) {
3130 server_role = ROLE_DOMAIN_PDC;
3133 server_role = ROLE_DOMAIN_MEMBER;
3136 if (lp_domain_logons()) {
3138 if (Globals.bDomainMaster) /* auto or yes */
3139 server_role = ROLE_DOMAIN_PDC;
3141 server_role = ROLE_DOMAIN_BDC;
3145 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3149 DEBUG(10, ("set_server_role: role = "));
3151 switch(server_role) {
3152 case ROLE_STANDALONE:
3153 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3155 case ROLE_DOMAIN_MEMBER:
3156 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3158 case ROLE_DOMAIN_BDC:
3159 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3161 case ROLE_DOMAIN_PDC:
3162 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3167 /***************************************************************************
3168 Load the services array from the services file. Return True on success,
3170 ***************************************************************************/
3172 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3177 struct param_opt *data;
3179 pstrcpy(n2, pszFname);
3180 standard_sub_basic(n2,sizeof(n2));
3182 add_to_file_list(pszFname, n2);
3186 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3188 bInGlobalSection = True;
3189 bGlobalOnly = global_only;
3198 if (Globals.param_opt != NULL) {
3199 struct param_opt *next;
3200 for (data=Globals.param_opt; data; data=next) {
3202 if (data->flags & FLAG_CMDLINE) continue;
3205 DLIST_REMOVE(Globals.param_opt, data);
3210 /* We get sections first, so have to start 'behind' to make up */
3212 bRetval = pm_process(n2, do_section, do_parameter);
3214 /* finish up the last section */
3215 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3217 if (iServiceIndex >= 0)
3218 bRetval = service_ok(iServiceIndex);
3220 lp_add_auto_services(lp_auto_services());
3223 /* When 'restrict anonymous = 2' guest connections to ipc$
3225 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3226 lp_add_ipc("ADMIN$", False);
3230 set_default_server_announce_type();
3234 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3235 /* if bWINSsupport is true and we are in the client */
3236 if (in_client && Globals.bWINSsupport) {
3237 lp_do_parameter(-1, "wins server", "127.0.0.1");
3245 /***************************************************************************
3246 Reset the max number of services.
3247 ***************************************************************************/
3249 void lp_resetnumservices(void)
3254 /***************************************************************************
3255 Return the max number of services.
3256 ***************************************************************************/
3258 int lp_numservices(void)
3260 return (iNumServices);
3263 /***************************************************************************
3264 Display the contents of the services array in human-readable form.
3265 ***************************************************************************/
3267 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3272 defaults_saved = False;
3276 dump_a_service(&sDefault, f);
3278 for (iService = 0; iService < maxtoprint; iService++)
3279 lp_dump_one(f, show_defaults, iService);
3282 /***************************************************************************
3283 Display the contents of one service in human-readable form.
3284 ***************************************************************************/
3286 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3289 if (ServicePtrs[snum]->szService[0] == '\0')
3291 dump_a_service(ServicePtrs[snum], f);
3295 /***************************************************************************
3296 Return the number of the service with the given name, or -1 if it doesn't
3297 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3298 getservicebyname()! This works ONLY if all services have been loaded, and
3299 does not copy the found service.
3300 ***************************************************************************/
3302 int lp_servicenumber(const char *pszServiceName)
3305 fstring serviceName;
3308 for (iService = iNumServices - 1; iService >= 0; iService--) {
3309 if (VALID(iService) && ServicePtrs[iService]->szService) {
3311 * The substitution here is used to support %U is
3314 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3315 standard_sub_basic(serviceName,sizeof(serviceName));
3316 if (strequal(serviceName, pszServiceName))
3322 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3327 /*******************************************************************
3328 A useful volume label function.
3329 ********************************************************************/
3330 char *volume_label(int snum)
3332 char *ret = lp_volume(snum);
3334 return lp_servicename(snum);
3339 /*******************************************************************
3340 Set the server type we will announce as via nmbd.
3341 ********************************************************************/
3343 static void set_default_server_announce_type(void)
3345 default_server_announce = 0;
3346 default_server_announce |= SV_TYPE_WORKSTATION;
3347 default_server_announce |= SV_TYPE_SERVER;
3348 default_server_announce |= SV_TYPE_SERVER_UNIX;
3350 switch (lp_announce_as()) {
3351 case ANNOUNCE_AS_NT_SERVER:
3352 default_server_announce |= SV_TYPE_SERVER_NT;
3353 /* fall through... */
3354 case ANNOUNCE_AS_NT_WORKSTATION:
3355 default_server_announce |= SV_TYPE_NT;
3357 case ANNOUNCE_AS_WIN95:
3358 default_server_announce |= SV_TYPE_WIN95_PLUS;
3360 case ANNOUNCE_AS_WFW:
3361 default_server_announce |= SV_TYPE_WFW;
3367 switch (lp_server_role()) {
3368 case ROLE_DOMAIN_MEMBER:
3369 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3371 case ROLE_DOMAIN_PDC:
3372 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3374 case ROLE_DOMAIN_BDC:
3375 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3377 case ROLE_STANDALONE:
3381 if (lp_time_server())
3382 default_server_announce |= SV_TYPE_TIME_SOURCE;
3384 if (lp_host_msdfs())
3385 default_server_announce |= SV_TYPE_DFS_SERVER;
3388 /***********************************************************
3389 returns role of Samba server
3390 ************************************************************/
3392 int lp_server_role(void)
3397 /***********************************************************
3398 If we are PDC then prefer us as DMB
3399 ************************************************************/
3401 BOOL lp_domain_master(void)
3403 if (Globals.bDomainMaster == Auto)
3404 return (lp_server_role() == ROLE_DOMAIN_PDC);
3406 return Globals.bDomainMaster;
3409 /***********************************************************
3410 If we are DMB then prefer us as LMB
3411 ************************************************************/
3413 BOOL lp_preferred_master(void)
3415 if (Globals.bPreferredMaster == Auto)
3416 return (lp_local_master() && lp_domain_master());
3418 return Globals.bPreferredMaster;
3421 /*******************************************************************
3423 ********************************************************************/
3425 void lp_remove_service(int snum)
3427 ServicePtrs[snum]->valid = False;
3430 /*******************************************************************
3432 ********************************************************************/
3434 void lp_copy_service(int snum, const char *new_name)
3436 char *oldname = lp_servicename(snum);
3437 do_section(new_name);
3439 snum = lp_servicenumber(new_name);
3441 lp_do_parameter(snum, "copy", oldname);
3446 /*******************************************************************
3447 Get the default server type we will announce as via nmbd.
3448 ********************************************************************/
3450 int lp_default_server_announce(void)
3452 return default_server_announce;
3455 /*******************************************************************
3456 Split the announce version into major and minor numbers.
3457 ********************************************************************/
3459 int lp_major_announce_version(void)
3461 static BOOL got_major = False;
3462 static int major_version = DEFAULT_MAJOR_VERSION;
3467 return major_version;
3470 if ((vers = lp_announce_version()) == NULL)
3471 return major_version;
3473 if ((p = strchr_m(vers, '.')) == 0)
3474 return major_version;
3477 major_version = atoi(vers);
3478 return major_version;
3481 int lp_minor_announce_version(void)
3483 static BOOL got_minor = False;
3484 static int minor_version = DEFAULT_MINOR_VERSION;
3489 return minor_version;
3492 if ((vers = lp_announce_version()) == NULL)
3493 return minor_version;
3495 if ((p = strchr_m(vers, '.')) == 0)
3496 return minor_version;
3499 minor_version = atoi(p);
3500 return minor_version;
3503 const char *lp_printername(int snum)
3505 const char *ret = _lp_printername(snum);
3506 if (ret == NULL || (ret != NULL && *ret == '\0'))
3507 ret = lp_const_servicename(snum);
3513 /*******************************************************************
3514 Return the max print jobs per queue.
3515 ********************************************************************/
3517 int lp_maxprintjobs(int snum)
3519 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3520 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3521 maxjobs = PRINT_MAX_JOBID - 1;