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;
112 char **szPassdbBackend;
113 char **szPreloadModules;
114 char *szPasswordServer;
115 char *szSocketOptions;
122 char **szWINSservers;
124 char *szRemoteAnnounce;
125 char *szRemoteBrowseSync;
126 char *szSocketAddress;
127 char *szAnnounceVersion; /* This is initialised in init_globals */
130 char **szNetbiosAliases;
131 char *szNetbiosScope;
132 char *szDomainOtherSIDs;
133 char *szNameResolveOrder;
135 char *szAddUserScript;
136 char *szAddMachineScript;
138 char *szWINSPartners;
139 char **dcerpc_ep_servers;
142 char *szNonUnixAccountRange;
143 char *szTemplateHomedir;
144 char *szTemplateShell;
145 char *szWinbindSeparator;
146 BOOL bWinbindEnumUsers;
147 BOOL bWinbindEnumGroups;
148 BOOL bWinbindUseDefaultDomain;
149 char *szIDMapBackend;
150 char *szGuestaccount;
160 BOOL paranoid_server_security;
162 BOOL bDisableSpoolss;
164 int enhanced_browsing;
171 int announce_as; /* This is initialised in init_globals */
172 int machine_password_timeout;
173 int winbind_cache_time;
176 char *szLdapMachineSuffix;
177 char *szLdapUserSuffix;
178 #ifdef WITH_LDAP_SAMCONFIG
182 char *socket_options;
188 int ldap_passwd_sync;
193 BOOL bPreferredMaster;
196 BOOL bEncryptPasswords;
199 BOOL bObeyPamRestrictions;
201 BOOL bLargeReadwrite;
205 BOOL bBindInterfacesOnly;
206 BOOL bPamPasswordChange;
207 BOOL bUnixPasswdSync;
209 BOOL bNTStatusSupport;
210 BOOL bAllowTrustedDomains;
215 BOOL bClientLanManAuth;
216 BOOL bClientNTLMv2Auth;
218 BOOL bHideLocalUsers;
221 BOOL bHostnameLookups;
222 BOOL bUnixExtensions;
223 BOOL bDisableNetbios;
225 int restrict_anonymous;
226 int name_cache_timeout;
227 struct param_opt *param_opt;
231 static global Globals;
234 * This structure describes a single service.
243 char **szInvalidUsers;
248 char *szPrintcommand;
251 char *szLppausecommand;
252 char *szLpresumecommand;
253 char *szQueuepausecommand;
254 char *szQueueresumecommand;
286 struct param_opt *param_opt;
288 char dummy[3]; /* for alignment */
293 /* This is a default service used to prime a services structure */
294 static service sDefault = {
296 False, /* not autoloaded */
297 NULL, /* szService */
299 NULL, /* szUsername */
300 NULL, /* szInvalidUsers */
301 NULL, /* szValidUsers */
302 NULL, /* szAdminUsers */
304 NULL, /* szInclude */
305 NULL, /* szPrintcommand */
306 NULL, /* szLpqcommand */
307 NULL, /* szLprmcommand */
308 NULL, /* szLppausecommand */
309 NULL, /* szLpresumecommand */
310 NULL, /* szQueuepausecommand */
311 NULL, /* szQueueresumecommand */
312 NULL, /* szPrintername */
313 NULL, /* szHostsallow */
314 NULL, /* szHostsdeny */
318 NULL, /* szMSDfsProxy */
319 NULL, /* ntvfs_handler */
320 0, /* iMinPrintSpace */
321 1000, /* iMaxPrintJobs */
322 0, /* iMaxConnections */
323 DEFAULT_PRINTING, /* iPrinting */
325 True, /* bAvailable */
326 True, /* bBrowseable */
327 True, /* bRead_only */
328 False, /* bPrint_ok */
329 False, /* bMap_system */
330 False, /* bMap_hidden */
331 True, /* bMap_archive */
333 True, /* bStrictLocking */
334 True, /* bPosixLocking */
336 True, /* bLevel2OpLocks */
337 False, /* bOnlyUser */
338 False, /* bGuest_only */
339 False, /* bGuest_ok */
341 False, /* bMSDfsRoot */
342 True, /* bShareModes */
343 NULL, /* Parametric options */
348 /* local variables */
349 static service **ServicePtrs = NULL;
350 static int iNumServices = 0;
351 static int iServiceIndex = 0;
352 static BOOL bInGlobalSection = True;
353 static BOOL bGlobalOnly = False;
354 static int server_role;
355 static int default_server_announce;
357 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
359 /* prototypes for the special type handlers */
360 static BOOL handle_include(const char *pszParmValue, char **ptr);
361 static BOOL handle_copy(const char *pszParmValue, char **ptr);
362 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
363 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
364 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
366 static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr );
367 static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr );
368 static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
370 static void set_server_role(void);
371 static void set_default_server_announce_type(void);
373 static const struct enum_list enum_protocol[] = {
374 {PROTOCOL_NT1, "NT1"},
375 {PROTOCOL_LANMAN2, "LANMAN2"},
376 {PROTOCOL_LANMAN1, "LANMAN1"},
377 {PROTOCOL_CORE, "CORE"},
378 {PROTOCOL_COREPLUS, "COREPLUS"},
379 {PROTOCOL_COREPLUS, "CORE+"},
383 static const struct enum_list enum_security[] = {
384 {SEC_SHARE, "SHARE"},
386 {SEC_SERVER, "SERVER"},
387 {SEC_DOMAIN, "DOMAIN"},
394 static const struct enum_list enum_printing[] = {
395 {PRINT_SYSV, "sysv"},
397 {PRINT_HPUX, "hpux"},
401 {PRINT_LPRNG, "lprng"},
402 {PRINT_SOFTQ, "softq"},
403 {PRINT_CUPS, "cups"},
405 {PRINT_LPROS2, "os2"},
407 {PRINT_TEST, "test"},
409 #endif /* DEVELOPER */
413 static const struct enum_list enum_ldap_ssl[] = {
414 #ifdef WITH_LDAP_SAMCONFIG
415 {LDAP_SSL_ON, "Yes"},
416 {LDAP_SSL_ON, "yes"},
420 {LDAP_SSL_OFF, "no"},
421 {LDAP_SSL_OFF, "No"},
422 {LDAP_SSL_OFF, "off"},
423 {LDAP_SSL_OFF, "Off"},
424 {LDAP_SSL_START_TLS, "start tls"},
425 {LDAP_SSL_START_TLS, "Start_tls"},
429 static const struct enum_list enum_ldap_passwd_sync[] = {
430 {LDAP_PASSWD_SYNC_ON, "Yes"},
431 {LDAP_PASSWD_SYNC_ON, "yes"},
432 {LDAP_PASSWD_SYNC_ON, "on"},
433 {LDAP_PASSWD_SYNC_ON, "On"},
434 {LDAP_PASSWD_SYNC_OFF, "no"},
435 {LDAP_PASSWD_SYNC_OFF, "No"},
436 {LDAP_PASSWD_SYNC_OFF, "off"},
437 {LDAP_PASSWD_SYNC_OFF, "Off"},
438 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
439 {LDAP_PASSWD_SYNC_ONLY, "Only"},
440 {LDAP_PASSWD_SYNC_ONLY, "only"},
441 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
445 /* Types of machine we can announce as. */
446 #define ANNOUNCE_AS_NT_SERVER 1
447 #define ANNOUNCE_AS_WIN95 2
448 #define ANNOUNCE_AS_WFW 3
449 #define ANNOUNCE_AS_NT_WORKSTATION 4
451 static const struct enum_list enum_announce_as[] = {
452 {ANNOUNCE_AS_NT_SERVER, "NT"},
453 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
454 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
455 {ANNOUNCE_AS_WIN95, "win95"},
456 {ANNOUNCE_AS_WFW, "WfW"},
460 static const struct enum_list enum_case[] = {
461 {CASE_LOWER, "lower"},
462 {CASE_UPPER, "upper"},
466 static const struct enum_list enum_bool_auto[] = {
477 /* Client-side offline caching policy types */
478 #define CSC_POLICY_MANUAL 0
479 #define CSC_POLICY_DOCUMENTS 1
480 #define CSC_POLICY_PROGRAMS 2
481 #define CSC_POLICY_DISABLE 3
483 static const struct enum_list enum_csc_policy[] = {
484 {CSC_POLICY_MANUAL, "manual"},
485 {CSC_POLICY_DOCUMENTS, "documents"},
486 {CSC_POLICY_PROGRAMS, "programs"},
487 {CSC_POLICY_DISABLE, "disable"},
491 /* SMB signing types. */
492 static const struct enum_list enum_smb_signing_vals[] = {
493 {SMB_SIGNING_OFF, "No"},
494 {SMB_SIGNING_OFF, "False"},
495 {SMB_SIGNING_OFF, "0"},
496 {SMB_SIGNING_OFF, "Off"},
497 {SMB_SIGNING_OFF, "disabled"},
498 {SMB_SIGNING_SUPPORTED, "Yes"},
499 {SMB_SIGNING_SUPPORTED, "True"},
500 {SMB_SIGNING_SUPPORTED, "1"},
501 {SMB_SIGNING_SUPPORTED, "On"},
502 {SMB_SIGNING_SUPPORTED, "enabled"},
503 {SMB_SIGNING_SUPPORTED, "auto"},
504 {SMB_SIGNING_REQUIRED, "required"},
505 {SMB_SIGNING_REQUIRED, "mandatory"},
506 {SMB_SIGNING_REQUIRED, "force"},
507 {SMB_SIGNING_REQUIRED, "forced"},
508 {SMB_SIGNING_REQUIRED, "enforced"},
513 Do you want session setups at user level security with a invalid
514 password to be rejected or allowed in as guest? WinNT rejects them
515 but it can be a pain as it means "net view" needs to use a password
517 You have 3 choices in the setting of map_to_guest:
519 "Never" means session setups with an invalid password
520 are rejected. This is the default.
522 "Bad User" means session setups with an invalid password
523 are rejected, unless the username does not exist, in which case it
524 is treated as a guest login
526 "Bad Password" means session setups with an invalid password
527 are treated as a guest login
529 Note that map_to_guest only has an effect in user or server
533 static const struct enum_list enum_map_to_guest[] = {
534 {NEVER_MAP_TO_GUEST, "Never"},
535 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
536 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
540 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
542 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
543 * is implied in current control logic. This may change at some later time. A
544 * flag value of 0 means - show as development option only.
546 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
547 * screen in SWAT. This is used to exclude parameters as well as to squash all
548 * parameters that have been duplicated by pseudonyms.
550 static struct parm_struct parm_table[] = {
551 {"Base Options", P_SEP, P_SEPARATOR},
553 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
557 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
558 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
559 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
560 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
561 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
562 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
563 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
567 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
568 {"ntvfs handler", P_STRING, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
569 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
571 {"Security Options", P_SEP, P_SEPARATOR},
573 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
574 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
575 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
576 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
583 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
584 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
586 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
587 {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
588 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
590 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
591 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
592 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
594 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
595 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
596 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
597 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
598 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
599 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
600 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
601 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
602 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
603 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
606 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
607 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
608 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
610 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
611 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
612 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
614 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
616 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
618 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
620 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
621 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
622 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
623 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
625 {"Logging Options", P_SEP, P_SEPARATOR},
627 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
629 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"Protocol Options", P_SEP, P_SEPARATOR},
633 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
635 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
636 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
637 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
638 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
639 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
640 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
642 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
644 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
645 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
646 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
647 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
649 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
650 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
651 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
652 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
653 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
654 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
655 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
656 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
657 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
659 {"Tuning Options", P_SEP, P_SEPARATOR},
661 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
662 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
663 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
664 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
666 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
667 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
668 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
670 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
672 {"Printing Options", P_SEP, P_SEPARATOR},
674 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
675 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
676 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
677 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
678 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
679 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
680 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
681 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
682 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
683 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
684 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
685 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
686 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
687 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
688 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
690 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
691 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
693 {"Filename Handling", P_SEP, P_SEPARATOR},
695 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
697 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
698 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
700 {"Domain Options", P_SEP, P_SEPARATOR},
702 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
704 {"Logon Options", P_SEP, P_SEPARATOR},
706 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
709 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
712 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
715 {"Browse Options", P_SEP, P_SEPARATOR},
717 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
718 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
719 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
720 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
721 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
722 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
723 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
724 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
725 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
726 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
728 {"WINS Options", P_SEP, P_SEPARATOR},
729 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
730 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
732 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
733 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
734 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
737 {"Locking Options", P_SEP, P_SEPARATOR},
739 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
740 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
741 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
742 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
744 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
745 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
746 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
747 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
748 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
750 {"Ldap Options", P_SEP, P_SEPARATOR},
752 #ifdef WITH_LDAP_SAMCONFIG
753 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
754 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
756 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
762 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
767 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
768 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
771 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
776 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
779 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
782 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
783 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
785 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
786 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
787 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
789 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
790 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
792 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
793 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
794 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
795 {"Winbind options", P_SEP, P_SEPARATOR},
797 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
798 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
799 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
800 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
801 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
802 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
803 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
804 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
805 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
807 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
810 /***************************************************************************
811 Initialise the sDefault parameter structure for the printer values.
812 ***************************************************************************/
814 static void init_printer_values(void)
816 /* choose defaults depending on the type of printing */
817 switch (sDefault.iPrinting) {
822 string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
823 string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
824 string_set(&sDefault.szPrintcommand,
830 string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
831 string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
832 string_set(&sDefault.szPrintcommand,
834 string_set(&sDefault.szQueuepausecommand,
836 string_set(&sDefault.szQueueresumecommand,
838 string_set(&sDefault.szLppausecommand,
840 string_set(&sDefault.szLpresumecommand,
841 "lpc release '%p' %j");
846 string_set(&sDefault.szLpqcommand, "");
847 string_set(&sDefault.szLprmcommand, "");
848 string_set(&sDefault.szPrintcommand, "");
849 string_set(&sDefault.szLppausecommand, "");
850 string_set(&sDefault.szLpresumecommand, "");
851 string_set(&sDefault.szQueuepausecommand, "");
852 string_set(&sDefault.szQueueresumecommand, "");
854 string_set(&Globals.szPrintcapname, "cups");
856 string_set(&sDefault.szLpqcommand,
857 "/usr/bin/lpstat -o '%p'");
858 string_set(&sDefault.szLprmcommand,
859 "/usr/bin/cancel '%p-%j'");
860 string_set(&sDefault.szPrintcommand,
861 "/usr/bin/lp -d '%p' %s; rm %s");
862 string_set(&sDefault.szLppausecommand,
863 "lp -i '%p-%j' -H hold");
864 string_set(&sDefault.szLpresumecommand,
865 "lp -i '%p-%j' -H resume");
866 string_set(&sDefault.szQueuepausecommand,
867 "/usr/bin/disable '%p'");
868 string_set(&sDefault.szQueueresumecommand,
869 "/usr/bin/enable '%p'");
870 string_set(&Globals.szPrintcapname, "lpstat");
871 #endif /* HAVE_CUPS */
876 string_set(&sDefault.szLpqcommand, "lpstat -o%p");
877 string_set(&sDefault.szLprmcommand, "cancel %p-%j");
878 string_set(&sDefault.szPrintcommand,
879 "lp -c -d%p %s; rm %s");
880 string_set(&sDefault.szQueuepausecommand,
882 string_set(&sDefault.szQueueresumecommand,
885 string_set(&sDefault.szLppausecommand,
886 "lp -i %p-%j -H hold");
887 string_set(&sDefault.szLpresumecommand,
888 "lp -i %p-%j -H resume");
893 string_set(&sDefault.szLpqcommand, "lpq -P%p");
894 string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
895 string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
899 string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
900 string_set(&sDefault.szLprmcommand,
902 string_set(&sDefault.szPrintcommand,
903 "lp -d%p -s %s; rm %s");
904 string_set(&sDefault.szLppausecommand,
906 string_set(&sDefault.szLpresumecommand,
912 string_set(&sDefault.szPrintcommand, "vlp print %p %s");
913 string_set(&sDefault.szLpqcommand, "vlp lpq %p");
914 string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
915 string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
916 string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
917 string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
918 string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
920 #endif /* DEVELOPER */
926 /***************************************************************************
927 Initialise the global parameter structure.
928 ***************************************************************************/
929 static void init_globals(void)
934 DEBUG(3, ("Initialising global parameters\n"));
936 for (i = 0; parm_table[i].label; i++) {
937 if ((parm_table[i].type == P_STRING ||
938 parm_table[i].type == P_USTRING) &&
940 !(parm_table[i].flags & FLAG_CMDLINE)) {
941 string_set(parm_table[i].ptr, "");
945 /* options that can be set on the command line must be initialised via
946 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
947 do_parameter("socket options", DEFAULT_SOCKET_OPTIONS);
948 do_parameter("workgroup", DEFAULT_WORKGROUP);
949 do_parameter("netbios name", get_myname());
950 do_parameter("max protocol", "NT1");
951 do_parameter("name resolve order", "lmhosts wins host bcast");
953 init_printer_values();
955 string_set(&sDefault.fstype, FSTYPE_STRING);
956 string_set(&sDefault.ntvfs_handler, "default");
958 Globals.dcerpc_ep_servers = str_list_make("epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss", NULL);
960 Globals.AuthMethods = str_list_make("guest sam_ignoredomain", NULL);
962 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
963 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
964 asprintf(&Globals.szSAM_URL, "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
965 asprintf(&Globals.szSPOOLSS_URL, "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
967 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
969 /* using UTF8 by default allows us to support all chars */
970 string_set(&Globals.unix_charset, "UTF8");
972 /* Use codepage 850 as a default for the dos character set */
973 string_set(&Globals.dos_charset, "CP850");
976 * Allow the default PASSWD_CHAT to be overridden in local.h.
978 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
980 string_set(&Globals.szPasswdProgram, "");
981 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
982 string_set(&Globals.szPidDir, dyn_PIDDIR);
983 string_set(&Globals.szLockDir, dyn_LOCKDIR);
984 string_set(&Globals.szSocketAddress, "0.0.0.0");
985 pstrcpy(s, "Samba ");
986 pstrcat(s, SAMBA_VERSION_STRING);
987 string_set(&Globals.szServerString, s);
988 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
989 DEFAULT_MINOR_VERSION);
990 string_set(&Globals.szAnnounceVersion, s);
992 string_set(&Globals.szLogonDrive, "");
993 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
994 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
995 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
997 string_set(&Globals.szPasswordServer, "*");
999 Globals.bLoadPrinters = True;
1000 Globals.mangled_stack = 50;
1001 Globals.max_mux = 50; /* This is *needed* for profile support. */
1002 Globals.max_xmit = 4356; /* the value w2k3 chooses */
1003 Globals.lpqcachetime = 10;
1004 Globals.bDisableSpoolss = False;
1005 Globals.pwordlevel = 0;
1006 Globals.unamelevel = 0;
1007 Globals.bLargeReadwrite = True;
1008 Globals.minprotocol = PROTOCOL_CORE;
1009 Globals.security = SEC_USER;
1010 Globals.paranoid_server_security = True;
1011 Globals.bEncryptPasswords = True;
1012 Globals.bUpdateEncrypt = False;
1013 Globals.bReadRaw = True;
1014 Globals.bWriteRaw = True;
1015 Globals.bNullPasswords = False;
1016 Globals.bObeyPamRestrictions = False;
1017 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1018 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1019 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1020 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1021 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1022 Globals.lm_interval = 60;
1023 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1025 Globals.bTimeServer = False;
1026 Globals.bBindInterfacesOnly = False;
1027 Globals.bUnixPasswdSync = False;
1028 Globals.bPamPasswordChange = False;
1029 Globals.bUnicode = True; /* Do unicode on the wire by default */
1030 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1031 Globals.restrict_anonymous = 0;
1032 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1033 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1034 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1036 Globals.enhanced_browsing = True;
1037 Globals.iLockSpinCount = 3; /* Try 2 times. */
1038 Globals.iLockSpinTime = 10; /* usec. */
1039 #ifdef MMAP_BLACKLIST
1040 Globals.bUseMmap = False;
1042 Globals.bUseMmap = True;
1044 Globals.bUnixExtensions = False;
1046 /* hostname lookups can be very expensive and are broken on
1047 a large number of sites (tridge) */
1048 Globals.bHostnameLookups = False;
1050 #ifdef WITH_LDAP_SAMCONFIG
1051 string_set(&Globals.szLdapServer, "localhost");
1052 Globals.ldap_port = 636;
1053 Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1055 Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1056 #endif /* WITH_LDAP_SAMCONFIG */
1058 string_set(&Globals.szLdapSuffix, "");
1059 string_set(&Globals.szLdapMachineSuffix, "");
1060 string_set(&Globals.szLdapUserSuffix, "");
1062 string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
1063 string_set(&Globals.szLdapAdminDn, "");
1064 Globals.ldap_ssl = LDAP_SSL_ON;
1065 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1067 /* these parameters are set to defaults that are more appropriate
1068 for the increasing samba install base:
1070 as a member of the workgroup, that will possibly become a
1071 _local_ master browser (lm = True). this is opposed to a forced
1072 local master browser startup (pm = True).
1074 doesn't provide WINS server service by default (wsupp = False),
1075 and doesn't provide domain master browser services by default, either.
1079 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1080 Globals.os_level = 20;
1081 Globals.bLocalMaster = True;
1082 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1083 Globals.bDomainLogons = False;
1084 Globals.bWINSsupport = False;
1085 Globals.bWINSproxy = False;
1087 Globals.bDNSproxy = True;
1089 Globals.bAllowTrustedDomains = True;
1091 string_set(&Globals.szTemplateShell, "/bin/false");
1092 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1093 string_set(&Globals.szWinbindSeparator, "\\");
1095 Globals.winbind_cache_time = 15;
1096 Globals.bWinbindEnumUsers = True;
1097 Globals.bWinbindEnumGroups = True;
1098 Globals.bWinbindUseDefaultDomain = False;
1100 string_set(&Globals.szIDMapBackend, "tdb");
1102 Globals.name_cache_timeout = 660; /* In seconds */
1104 Globals.bUseSpnego = False;
1106 Globals.server_signing = False;
1108 string_set(&Globals.smb_ports, SMB_PORTS);
1111 static TALLOC_CTX *lp_talloc;
1113 /******************************************************************* a
1114 Free up temporary memory - called from the main loop.
1115 ********************************************************************/
1117 void lp_talloc_free(void)
1121 talloc_destroy(lp_talloc);
1125 /*******************************************************************
1126 Convenience routine to grab string parameters into temporary memory
1127 and run standard_sub_basic on them. The buffers can be written to by
1128 callers without affecting the source string.
1129 ********************************************************************/
1131 static const char *lp_string(const char *s)
1133 #if 0 /* until REWRITE done to make thread-safe */
1134 size_t len = s ? strlen(s) : 0;
1138 /* The follow debug is useful for tracking down memory problems
1139 especially if you have an inner loop that is calling a lp_*()
1140 function that returns a string. Perhaps this debug should be
1141 present all the time? */
1144 DEBUG(10, ("lp_string(%s)\n", s));
1147 #if 0 /* until REWRITE done to make thread-safe */
1149 lp_talloc = talloc_init("lp_talloc");
1151 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1159 StrnCpy(ret, s, len);
1161 if (trim_string(ret, "\"", "\"")) {
1162 if (strchr(ret,'"') != NULL)
1163 StrnCpy(ret, s, len);
1166 standard_sub_basic(ret,len+100);
1173 In this section all the functions that are used to access the
1174 parameters from the rest of the program are defined
1177 #define FN_GLOBAL_STRING(fn_name,ptr) \
1178 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1179 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1180 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1181 #define FN_GLOBAL_LIST(fn_name,ptr) \
1182 const char **fn_name(void) {return(*(const char ***)(ptr));}
1183 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1184 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1185 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1186 char fn_name(void) {return(*(char *)(ptr));}
1187 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1188 int fn_name(void) {return(*(int *)(ptr));}
1190 #define FN_LOCAL_STRING(fn_name,val) \
1191 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1192 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1193 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1194 #define FN_LOCAL_LIST(fn_name,val) \
1195 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1196 #define FN_LOCAL_BOOL(fn_name,val) \
1197 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1198 #define FN_LOCAL_CHAR(fn_name,val) \
1199 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1200 #define FN_LOCAL_INTEGER(fn_name,val) \
1201 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1203 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1204 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1205 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1206 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1207 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1208 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1209 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1210 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1211 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1212 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1213 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1214 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1215 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1216 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1217 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1218 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1219 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1220 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1221 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1222 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1223 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1224 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1225 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1226 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1227 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1228 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1229 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1230 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1231 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1232 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1233 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1234 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1235 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1236 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1237 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1238 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1239 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1240 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1241 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1242 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1243 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1244 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1245 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1246 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1248 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1250 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1252 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1253 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1254 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1255 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1256 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1257 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1258 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1259 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1260 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1262 #ifdef WITH_LDAP_SAMCONFIG
1263 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1264 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1266 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1267 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1268 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1269 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1270 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1271 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1272 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1273 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1275 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1276 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1277 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1278 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1279 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1280 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1281 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1282 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1283 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1284 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1285 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1286 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1287 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1288 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1289 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1290 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1291 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1292 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1293 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1294 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1295 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1296 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1297 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1298 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1299 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1300 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1301 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1302 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1303 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1304 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1305 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1306 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1307 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1308 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1309 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1310 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1311 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1312 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1313 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1314 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1315 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1316 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1317 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1318 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1319 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1320 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1321 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1322 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1323 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1324 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1325 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1326 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1327 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1328 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1329 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1330 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1331 FN_LOCAL_STRING(lp_servicename, szService)
1332 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1333 FN_LOCAL_STRING(lp_pathname, szPath)
1334 FN_LOCAL_STRING(lp_username, szUsername)
1335 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1336 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1337 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1338 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1339 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1340 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1341 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1342 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1343 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1344 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1345 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1346 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1347 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1348 FN_LOCAL_STRING(lp_comment, comment)
1349 FN_LOCAL_STRING(lp_fstype, fstype)
1350 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1351 static FN_LOCAL_STRING(lp_volume, volume)
1352 FN_LOCAL_STRING(lp_ntvfs_handler, ntvfs_handler)
1353 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1354 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1355 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1356 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1357 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1358 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1359 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1360 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1361 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1362 FN_LOCAL_BOOL(lp_locking, bLocking)
1363 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1364 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1365 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1366 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1367 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1368 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1369 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1370 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1371 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1372 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1373 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1374 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1375 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1376 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1377 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1379 /* local prototypes */
1381 static int map_parameter(const char *pszParmName);
1382 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1383 static int getservicebyname(const char *pszServiceName,
1384 service * pserviceDest);
1385 static void copy_service(service * pserviceDest,
1386 service * pserviceSource, BOOL *pcopymapDest);
1387 static BOOL service_ok(int iService);
1388 static BOOL do_section(const char *pszSectionName);
1389 static void init_copymap(service * pservice);
1391 /* This is a helper function for parametrical options support. */
1392 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1393 /* Actual parametrical functions are quite simple */
1394 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1397 struct param_opt *data;
1399 if (lookup_service >= iNumServices) return NULL;
1401 data = (lookup_service < 0) ?
1402 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1404 asprintf(&vfskey, "%s:%s", type, option);
1408 if (strcmp(data->key, vfskey) == 0) {
1415 if (lookup_service >= 0) {
1416 /* Try to fetch the same option but from globals */
1417 /* but only if we are not already working with Globals */
1418 data = Globals.param_opt;
1420 if (strcmp(data->key, vfskey) == 0) {
1434 /*******************************************************************
1435 convenience routine to return int parameters.
1436 ********************************************************************/
1437 static int lp_int(const char *s)
1441 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1448 /*******************************************************************
1449 convenience routine to return unsigned long parameters.
1450 ********************************************************************/
1451 static int lp_ulong(const char *s)
1455 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1459 return strtoul(s, NULL, 10);
1462 /*******************************************************************
1463 convenience routine to return boolean parameters.
1464 ********************************************************************/
1465 static BOOL lp_bool(const char *s)
1470 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1474 if (!set_boolean(&ret,s)) {
1475 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1482 /*******************************************************************
1483 convenience routine to return enum parameters.
1484 ********************************************************************/
1485 static int lp_enum(const char *s,const struct enum_list *_enum)
1490 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1494 for (i=0; _enum[i].name; i++) {
1495 if (strcasecmp(_enum[i].name,s)==0)
1496 return _enum[i].value;
1499 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1503 /* Return parametric option from a given service. Type is a part of option before ':' */
1504 /* Parametric option has following syntax: 'Type: option = value' */
1505 /* Returned value is allocated in 'lp_talloc' context */
1507 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1509 const char *value = get_parametrics(lookup_service, type, option);
1512 return lp_string(value);
1517 /* Return parametric option from a given service. Type is a part of option before ':' */
1518 /* Parametric option has following syntax: 'Type: option = value' */
1519 /* Returned value is allocated in 'lp_talloc' context */
1521 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1522 const char *separator)
1524 const char *value = get_parametrics(lookup_service, type, option);
1527 return str_list_make(value, separator);
1532 /* Return parametric option from a given service. Type is a part of option before ':' */
1533 /* Parametric option has following syntax: 'Type: option = value' */
1535 int lp_parm_int(int lookup_service, const char *type, const char *option)
1537 const char *value = get_parametrics(lookup_service, type, option);
1540 return lp_int(value);
1545 /* Return parametric option from a given service. Type is a part of option before ':' */
1546 /* Parametric option has following syntax: 'Type: option = value' */
1548 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1550 const char *value = get_parametrics(lookup_service, type, option);
1553 return lp_ulong(value);
1558 /* Return parametric option from a given service. Type is a part of option before ':' */
1559 /* Parametric option has following syntax: 'Type: option = value' */
1561 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1563 const char *value = get_parametrics(lookup_service, type, option);
1566 return lp_bool(value);
1571 /* Return parametric option from a given service. Type is a part of option before ':' */
1572 /* Parametric option has following syntax: 'Type: option = value' */
1574 int lp_parm_enum(int lookup_service, const char *type, const char *option,
1575 const struct enum_list *_enum)
1577 const char *value = get_parametrics(lookup_service, type, option);
1580 return lp_enum(value, _enum);
1586 /***************************************************************************
1587 Initialise a service to the defaults.
1588 ***************************************************************************/
1590 static void init_service(service * pservice)
1592 memset((char *)pservice, '\0', sizeof(service));
1593 copy_service(pservice, &sDefault, NULL);
1596 /***************************************************************************
1597 Free the dynamically allocated parts of a service struct.
1598 ***************************************************************************/
1600 static void free_service(service *pservice)
1603 struct param_opt *data, *pdata;
1607 if (pservice->szService)
1608 DEBUG(5, ("free_service: Freeing service %s\n",
1609 pservice->szService));
1611 string_free(&pservice->szService);
1612 SAFE_FREE(pservice->copymap);
1614 for (i = 0; parm_table[i].label; i++) {
1615 if ((parm_table[i].type == P_STRING ||
1616 parm_table[i].type == P_USTRING) &&
1617 parm_table[i].class == P_LOCAL)
1618 string_free((char **)
1619 (((char *)pservice) +
1620 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1621 else if (parm_table[i].type == P_LIST &&
1622 parm_table[i].class == P_LOCAL)
1623 str_list_free((char ***)
1624 (((char *)pservice) +
1625 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1628 DEBUG(5,("Freeing parametrics:\n"));
1629 data = pservice->param_opt;
1631 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1632 string_free(&data->key);
1633 string_free(&data->value);
1639 ZERO_STRUCTP(pservice);
1642 /***************************************************************************
1643 Add a new service to the services array initialising it with the given
1645 ***************************************************************************/
1647 static int add_a_service(const service *pservice, const char *name)
1651 int num_to_alloc = iNumServices + 1;
1652 struct param_opt *data, *pdata;
1654 tservice = *pservice;
1656 /* it might already exist */
1658 i = getservicebyname(name, NULL);
1660 /* Clean all parametric options for service */
1661 /* They will be added during parsing again */
1662 data = ServicePtrs[i]->param_opt;
1664 string_free(&data->key);
1665 string_free(&data->value);
1670 ServicePtrs[i]->param_opt = NULL;
1675 /* find an invalid one */
1676 for (i = 0; i < iNumServices; i++)
1677 if (!ServicePtrs[i]->valid)
1680 /* if not, then create one */
1681 if (i == iNumServices) {
1684 tsp = (service **) Realloc(ServicePtrs,
1689 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1694 ServicePtrs[iNumServices] =
1695 (service *) malloc(sizeof(service));
1697 if (!ServicePtrs[iNumServices]) {
1698 DEBUG(0,("add_a_service: out of memory!\n"));
1704 free_service(ServicePtrs[i]);
1706 ServicePtrs[i]->valid = True;
1708 init_service(ServicePtrs[i]);
1709 copy_service(ServicePtrs[i], &tservice, NULL);
1711 string_set(&ServicePtrs[i]->szService, name);
1715 /***************************************************************************
1716 Add a new home service, with the specified home directory, defaults coming
1718 ***************************************************************************/
1720 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1721 const char *user, const char *pszHomedir)
1726 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1731 if (!(*(ServicePtrs[iDefaultService]->szPath))
1732 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1733 pstrcpy(newHomedir, pszHomedir);
1735 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1736 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1739 string_set(&ServicePtrs[i]->szPath, newHomedir);
1741 if (!(*(ServicePtrs[i]->comment))) {
1743 slprintf(comment, sizeof(comment) - 1,
1744 "Home directory of %s", user);
1745 string_set(&ServicePtrs[i]->comment, comment);
1747 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1748 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1750 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1756 /***************************************************************************
1757 Add a new service, based on an old one.
1758 ***************************************************************************/
1760 int lp_add_service(const char *pszService, int iDefaultService)
1762 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1765 /***************************************************************************
1766 Add the IPC service.
1767 ***************************************************************************/
1769 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1772 int i = add_a_service(&sDefault, ipc_name);
1777 slprintf(comment, sizeof(comment) - 1,
1778 "IPC Service (%s)", Globals.szServerString);
1780 string_set(&ServicePtrs[i]->szPath, tmpdir());
1781 string_set(&ServicePtrs[i]->szUsername, "");
1782 string_set(&ServicePtrs[i]->comment, comment);
1783 string_set(&ServicePtrs[i]->fstype, "IPC");
1784 ServicePtrs[i]->iMaxConnections = 0;
1785 ServicePtrs[i]->bAvailable = True;
1786 ServicePtrs[i]->bRead_only = True;
1787 ServicePtrs[i]->bGuest_only = False;
1788 ServicePtrs[i]->bGuest_ok = guest_ok;
1789 ServicePtrs[i]->bPrint_ok = False;
1790 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1792 DEBUG(3, ("adding IPC service\n"));
1797 /***************************************************************************
1798 Add a new printer service, with defaults coming from service iFrom.
1799 ***************************************************************************/
1801 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1803 const char *comment = "From Printcap";
1804 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1809 /* note that we do NOT default the availability flag to True - */
1810 /* we take it from the default service passed. This allows all */
1811 /* dynamic printers to be disabled by disabling the [printers] */
1812 /* entry (if/when the 'available' keyword is implemented!). */
1814 /* the printer name is set to the service name. */
1815 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1816 string_set(&ServicePtrs[i]->comment, comment);
1817 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1818 /* Printers cannot be read_only. */
1819 ServicePtrs[i]->bRead_only = False;
1820 /* No share modes on printer services. */
1821 ServicePtrs[i]->bShareModes = False;
1822 /* No oplocks on printer services. */
1823 ServicePtrs[i]->bOpLocks = False;
1824 /* Printer services must be printable. */
1825 ServicePtrs[i]->bPrint_ok = True;
1827 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1829 update_server_announce_as_printserver();
1834 /***************************************************************************
1835 Map a parameter's string representation to something we can use.
1836 Returns False if the parameter string is not recognised, else TRUE.
1837 ***************************************************************************/
1839 static int map_parameter(const char *pszParmName)
1843 if (*pszParmName == '-')
1846 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1847 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1850 /* Warn only if it isn't parametric option */
1851 if (strchr(pszParmName, ':') == NULL)
1852 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1853 /* We do return 'fail' for parametric options as well because they are
1854 stored in different storage
1859 /***************************************************************************
1860 Set a boolean variable from the text value stored in the passed string.
1861 Returns True in success, False if the passed string does not correctly
1862 represent a boolean.
1863 ***************************************************************************/
1865 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1870 if (strwicmp(pszParmValue, "yes") == 0 ||
1871 strwicmp(pszParmValue, "true") == 0 ||
1872 strwicmp(pszParmValue, "1") == 0)
1874 else if (strwicmp(pszParmValue, "no") == 0 ||
1875 strwicmp(pszParmValue, "False") == 0 ||
1876 strwicmp(pszParmValue, "0") == 0)
1880 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1887 /***************************************************************************
1888 Find a service by name. Otherwise works like get_service.
1889 ***************************************************************************/
1891 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1895 for (iService = iNumServices - 1; iService >= 0; iService--)
1896 if (VALID(iService) &&
1897 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1898 if (pserviceDest != NULL)
1899 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1906 /***************************************************************************
1907 Copy a service structure to another.
1908 If pcopymapDest is NULL then copy all fields
1909 ***************************************************************************/
1911 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1914 BOOL bcopyall = (pcopymapDest == NULL);
1915 struct param_opt *data, *pdata, *paramo;
1918 for (i = 0; parm_table[i].label; i++)
1919 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1920 (bcopyall || pcopymapDest[i])) {
1921 void *def_ptr = parm_table[i].ptr;
1923 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1926 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1929 switch (parm_table[i].type) {
1932 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1938 *(int *)dest_ptr = *(int *)src_ptr;
1942 *(char *)dest_ptr = *(char *)src_ptr;
1946 string_set(dest_ptr,
1951 string_set(dest_ptr,
1953 strupper(*(char **)dest_ptr);
1956 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1964 init_copymap(pserviceDest);
1965 if (pserviceSource->copymap)
1966 memcpy((void *)pserviceDest->copymap,
1967 (void *)pserviceSource->copymap,
1968 sizeof(BOOL) * NUMPARAMETERS);
1971 data = pserviceSource->param_opt;
1974 pdata = pserviceDest->param_opt;
1975 /* Traverse destination */
1977 /* If we already have same option, override it */
1978 if (strcmp(pdata->key, data->key) == 0) {
1979 string_free(&pdata->value);
1980 pdata->value = strdup(data->value);
1984 pdata = pdata->next;
1987 paramo = smb_xmalloc(sizeof(*paramo));
1988 paramo->key = strdup(data->key);
1989 paramo->value = strdup(data->value);
1990 DLIST_ADD(pserviceDest->param_opt, paramo);
1996 /***************************************************************************
1997 Check a service for consistency. Return False if the service is in any way
1998 incomplete or faulty, else True.
1999 ***************************************************************************/
2001 static BOOL service_ok(int iService)
2006 if (ServicePtrs[iService]->szService[0] == '\0') {
2007 DEBUG(0, ("The following message indicates an internal error:\n"));
2008 DEBUG(0, ("No service name in service entry.\n"));
2012 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2013 /* I can't see why you'd want a non-printable printer service... */
2014 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2015 if (!ServicePtrs[iService]->bPrint_ok) {
2016 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2017 ServicePtrs[iService]->szService));
2018 ServicePtrs[iService]->bPrint_ok = True;
2020 /* [printers] service must also be non-browsable. */
2021 if (ServicePtrs[iService]->bBrowseable)
2022 ServicePtrs[iService]->bBrowseable = False;
2025 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2026 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2027 DEBUG(0, ("No path in service %s - using %s\n",
2028 ServicePtrs[iService]->szService, tmpdir()));
2029 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2032 /* If a service is flagged unavailable, log the fact at level 0. */
2033 if (!ServicePtrs[iService]->bAvailable)
2034 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2035 ServicePtrs[iService]->szService));
2040 static struct file_lists {
2041 struct file_lists *next;
2045 } *file_lists = NULL;
2047 /*******************************************************************
2048 Keep a linked list of all config files so we know when one has changed
2049 it's date and needs to be reloaded.
2050 ********************************************************************/
2052 static void add_to_file_list(const char *fname, const char *subfname)
2054 struct file_lists *f = file_lists;
2057 if (f->name && !strcmp(f->name, fname))
2063 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2066 f->next = file_lists;
2067 f->name = strdup(fname);
2072 f->subfname = strdup(subfname);
2078 f->modtime = file_modtime(subfname);
2080 time_t t = file_modtime(subfname);
2086 /*******************************************************************
2087 Check if a config file has changed date.
2088 ********************************************************************/
2090 BOOL lp_file_list_changed(void)
2092 struct file_lists *f = file_lists;
2093 DEBUG(6, ("lp_file_list_changed()\n"));
2099 pstrcpy(n2, f->name);
2100 standard_sub_basic(n2,sizeof(n2));
2102 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2103 f->name, n2, ctime(&f->modtime)));
2105 mod_time = file_modtime(n2);
2107 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2109 ("file %s modified: %s\n", n2,
2111 f->modtime = mod_time;
2112 SAFE_FREE(f->subfname);
2113 f->subfname = strdup(n2);
2121 /***************************************************************************
2122 Handle the include operation.
2123 ***************************************************************************/
2125 static BOOL handle_include(const char *pszParmValue, char **ptr)
2128 pstrcpy(fname, pszParmValue);
2130 standard_sub_basic(fname,sizeof(fname));
2132 add_to_file_list(pszParmValue, fname);
2134 string_set(ptr, fname);
2136 if (file_exist(fname, NULL))
2137 return (pm_process(fname, do_section, do_parameter));
2139 DEBUG(2, ("Can't find include file %s\n", fname));
2144 /***************************************************************************
2145 Handle the interpretation of the copy parameter.
2146 ***************************************************************************/
2148 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2152 service serviceTemp;
2154 string_set(ptr, pszParmValue);
2156 init_service(&serviceTemp);
2160 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2162 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2163 if (iTemp == iServiceIndex) {
2164 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2166 copy_service(ServicePtrs[iServiceIndex],
2168 ServicePtrs[iServiceIndex]->copymap);
2172 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2176 free_service(&serviceTemp);
2180 /***************************************************************************
2181 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2186 winbind uid = 1000-1999
2187 winbind gid = 700-899
2189 We only do simple parsing checks here. The strings are parsed into useful
2190 structures in the winbind daemon code.
2192 ***************************************************************************/
2194 /* Some lp_ routines to return winbind [ug]id information */
2196 static uid_t winbind_uid_low, winbind_uid_high;
2197 static gid_t winbind_gid_low, winbind_gid_high;
2198 static uint32_t non_unix_account_low, non_unix_account_high;
2200 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2202 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2206 *low = winbind_uid_low;
2209 *high = winbind_uid_high;
2214 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2216 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2220 *low = winbind_gid_low;
2223 *high = winbind_gid_high;
2228 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2230 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2234 *low = non_unix_account_low;
2237 *high = non_unix_account_high;
2242 /* Do some simple checks on "winbind [ug]id" parameter values */
2244 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2248 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2253 string_set(ptr, pszParmValue);
2255 winbind_uid_low = low;
2256 winbind_uid_high = high;
2261 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2265 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2270 string_set(ptr, pszParmValue);
2272 winbind_gid_low = low;
2273 winbind_gid_high = high;
2278 /***************************************************************************
2279 Do some simple checks on "non unix account range" parameter values.
2280 ***************************************************************************/
2282 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2286 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2291 string_set(ptr, pszParmValue);
2293 non_unix_account_low = low;
2294 non_unix_account_high = high;
2299 /***************************************************************************
2300 Handle the ldap machine suffix option.
2301 ***************************************************************************/
2303 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2307 pstrcpy(suffix, pszParmValue);
2309 if (! *Globals.szLdapSuffix ) {
2310 string_set( ptr, suffix );
2314 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2315 if ( *pszParmValue )
2316 pstrcat(suffix, ",");
2317 pstrcat(suffix, Globals.szLdapSuffix);
2319 string_set( ptr, suffix );
2323 /***************************************************************************
2324 Handle the ldap user suffix option.
2325 ***************************************************************************/
2327 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2331 pstrcpy(suffix, pszParmValue);
2333 if (! *Globals.szLdapSuffix ) {
2334 string_set( ptr, suffix );
2338 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2339 if ( *pszParmValue )
2340 pstrcat(suffix, ",");
2341 pstrcat(suffix, Globals.szLdapSuffix);
2343 string_set( ptr, suffix );
2347 /***************************************************************************
2348 Handle setting ldap suffix and determines whether ldap machine suffix needs
2350 ***************************************************************************/
2352 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
2355 pstring user_suffix;
2356 pstring machine_suffix;
2358 pstrcpy(suffix, pszParmValue);
2360 if (! *Globals.szLdapMachineSuffix )
2361 string_set(&Globals.szLdapMachineSuffix, suffix);
2362 if (! *Globals.szLdapUserSuffix )
2363 string_set(&Globals.szLdapUserSuffix, suffix);
2365 if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
2366 pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
2367 if ( *Globals.szLdapMachineSuffix )
2368 pstrcat(machine_suffix, ",");
2369 pstrcat(machine_suffix, suffix);
2370 string_set(&Globals.szLdapMachineSuffix, machine_suffix);
2373 if (! strstr(Globals.szLdapUserSuffix, suffix)) {
2374 pstrcpy(user_suffix, Globals.szLdapUserSuffix);
2375 if ( *Globals.szLdapUserSuffix )
2376 pstrcat(user_suffix, ",");
2377 pstrcat(user_suffix, suffix);
2378 string_set(&Globals.szLdapUserSuffix, user_suffix);
2381 string_set(ptr, suffix);
2386 /***************************************************************************
2387 Initialise a copymap.
2388 ***************************************************************************/
2390 static void init_copymap(service * pservice)
2393 SAFE_FREE(pservice->copymap);
2394 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2395 if (!pservice->copymap)
2397 ("Couldn't allocate copymap!! (size %d)\n",
2398 (int)NUMPARAMETERS));
2400 for (i = 0; i < NUMPARAMETERS; i++)
2401 pservice->copymap[i] = True;
2404 /***************************************************************************
2405 Return the local pointer to a parameter given the service number and the
2406 pointer into the default structure.
2407 ***************************************************************************/
2409 void *lp_local_ptr(int snum, void *ptr)
2411 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2415 /***************************************************************************
2416 Process a parametric option
2417 ***************************************************************************/
2418 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2420 struct param_opt *paramo, *data;
2423 while (isspace(*pszParmName)) {
2427 name = strdup(pszParmName);
2428 if (!name) return False;
2433 data = Globals.param_opt;
2435 data = ServicePtrs[snum]->param_opt;
2438 /* Traverse destination */
2439 for (paramo=data; paramo; paramo=paramo->next) {
2440 /* If we already have the option set, override it unless
2441 it was a command line option and the new one isn't */
2442 if (strcmp(paramo->key, name) == 0) {
2443 if ((paramo->flags & FLAG_CMDLINE) &&
2444 !(flags & FLAG_CMDLINE)) {
2448 free(paramo->value);
2449 paramo->value = strdup(pszParmValue);
2450 paramo->flags = flags;
2456 paramo = smb_xmalloc(sizeof(*paramo));
2457 paramo->key = strdup(name);
2458 paramo->value = strdup(pszParmValue);
2459 paramo->flags = flags;
2461 DLIST_ADD(Globals.param_opt, paramo);
2463 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2471 /***************************************************************************
2472 Process a parameter for a particular service number. If snum < 0
2473 then assume we are in the globals.
2474 ***************************************************************************/
2475 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2478 void *parm_ptr = NULL; /* where we are going to store the result */
2479 void *def_ptr = NULL;
2481 parmnum = map_parameter(pszParmName);
2484 if (strchr(pszParmName, ':')) {
2485 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2487 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2491 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2492 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2496 /* if the flag has been set on the command line, then don't allow override,
2497 but don't report an error */
2498 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2502 def_ptr = parm_table[parmnum].ptr;
2504 /* we might point at a service, the default service or a global */
2508 if (parm_table[parmnum].class == P_GLOBAL) {
2510 ("Global parameter %s found in service section!\n",
2515 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2520 if (!ServicePtrs[snum]->copymap)
2521 init_copymap(ServicePtrs[snum]);
2523 /* this handles the aliases - set the copymap for other entries with
2524 the same data pointer */
2525 for (i = 0; parm_table[i].label; i++)
2526 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2527 ServicePtrs[snum]->copymap[i] = False;
2530 /* if it is a special case then go ahead */
2531 if (parm_table[parmnum].special) {
2532 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2536 /* now switch on the type of variable it is */
2537 switch (parm_table[parmnum].type)
2540 set_boolean(parm_ptr, pszParmValue);
2544 set_boolean(parm_ptr, pszParmValue);
2545 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2549 *(int *)parm_ptr = atoi(pszParmValue);
2553 *(char *)parm_ptr = *pszParmValue;
2557 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2561 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2565 string_set(parm_ptr, pszParmValue);
2569 string_set(parm_ptr, pszParmValue);
2570 strupper(*(char **)parm_ptr);
2574 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2577 parm_table[parmnum].enum_list[i].name)) {
2579 parm_table[parmnum].
2592 /***************************************************************************
2593 Process a parameter.
2594 ***************************************************************************/
2596 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2598 if (!bInGlobalSection && bGlobalOnly)
2601 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2603 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2604 pszParmName, pszParmValue));
2609 set a parameter from the commandline - this is called from command line parameter
2610 parsing code. It sets the parameter then marks the parameter as unable to be modified
2611 by smb.conf processing
2613 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2615 int parmnum = map_parameter(pszParmName);
2617 if (parmnum < 0 && strchr(pszParmName, ':')) {
2618 /* set a parametric option */
2619 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2622 /* reset the CMDLINE flag in case this has been called before */
2623 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2625 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2629 parm_table[parmnum].flags |= FLAG_CMDLINE;
2633 /***************************************************************************
2634 Print a parameter of the specified type.
2635 ***************************************************************************/
2637 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2643 for (i = 0; p->enum_list[i].name; i++) {
2644 if (*(int *)ptr == p->enum_list[i].value) {
2646 p->enum_list[i].name);
2653 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2657 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2661 fprintf(f, "%d", *(int *)ptr);
2665 fprintf(f, "%c", *(char *)ptr);
2669 fprintf(f, "%s", octal_string(*(int *)ptr));
2673 if ((char ***)ptr && *(char ***)ptr) {
2674 char **list = *(char ***)ptr;
2676 for (; *list; list++)
2677 fprintf(f, "%s%s", *list,
2678 ((*(list+1))?", ":""));
2684 if (*(char **)ptr) {
2685 fprintf(f, "%s", *(char **)ptr);
2693 /***************************************************************************
2694 Check if two parameters are equal.
2695 ***************************************************************************/
2697 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2702 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2707 return (*((int *)ptr1) == *((int *)ptr2));
2710 return (*((char *)ptr1) == *((char *)ptr2));
2713 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2718 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2723 return (p1 == p2 || strequal(p1, p2));
2731 /***************************************************************************
2732 Process a new section (service). At this stage all sections are services.
2733 Later we'll have special sections that permit server parameters to be set.
2734 Returns True on success, False on failure.
2735 ***************************************************************************/
2737 static BOOL do_section(const char *pszSectionName)
2740 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2741 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2744 /* if we've just struck a global section, note the fact. */
2745 bInGlobalSection = isglobal;
2747 /* check for multiple global sections */
2748 if (bInGlobalSection) {
2749 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2753 if (!bInGlobalSection && bGlobalOnly)
2756 /* if we have a current service, tidy it up before moving on */
2759 if (iServiceIndex >= 0)
2760 bRetval = service_ok(iServiceIndex);
2762 /* if all is still well, move to the next record in the services array */
2764 /* We put this here to avoid an odd message order if messages are */
2765 /* issued by the post-processing of a previous section. */
2766 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2768 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2770 DEBUG(0, ("Failed to add a new service\n"));
2779 /***************************************************************************
2780 Determine if a partcular base parameter is currentl set to the default value.
2781 ***************************************************************************/
2783 static BOOL is_default(int i)
2785 if (!defaults_saved)
2787 switch (parm_table[i].type) {
2789 return str_list_compare (parm_table[i].def.lvalue,
2790 *(char ***)parm_table[i].ptr);
2793 return strequal(parm_table[i].def.svalue,
2794 *(char **)parm_table[i].ptr);
2797 return parm_table[i].def.bvalue ==
2798 *(BOOL *)parm_table[i].ptr;
2800 return parm_table[i].def.cvalue ==
2801 *(char *)parm_table[i].ptr;
2805 return parm_table[i].def.ivalue ==
2806 *(int *)parm_table[i].ptr;
2813 /***************************************************************************
2814 Display the contents of the global structure.
2815 ***************************************************************************/
2817 static void dump_globals(FILE *f)
2820 struct param_opt *data;
2822 fprintf(f, "# Global parameters\n[global]\n");
2824 for (i = 0; parm_table[i].label; i++)
2825 if (parm_table[i].class == P_GLOBAL &&
2826 parm_table[i].ptr &&
2827 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2828 if (defaults_saved && is_default(i))
2830 fprintf(f, "\t%s = ", parm_table[i].label);
2831 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2834 if (Globals.param_opt != NULL) {
2835 data = Globals.param_opt;
2837 fprintf(f, "\t%s = %s\n", data->key, data->value);
2844 /***************************************************************************
2845 Return True if a local parameter is currently set to the global default.
2846 ***************************************************************************/
2848 BOOL lp_is_default(int snum, struct parm_struct *parm)
2850 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
2852 return equal_parameter(parm->type,
2853 ((char *)ServicePtrs[snum]) + pdiff,
2854 ((char *)&sDefault) + pdiff);
2857 /***************************************************************************
2858 Display the contents of a single services record.
2859 ***************************************************************************/
2861 static void dump_a_service(service * pService, FILE * f)
2864 struct param_opt *data;
2866 if (pService != &sDefault)
2867 fprintf(f, "\n[%s]\n", pService->szService);
2869 for (i = 0; parm_table[i].label; i++)
2870 if (parm_table[i].class == P_LOCAL &&
2871 parm_table[i].ptr &&
2872 (*parm_table[i].label != '-') &&
2873 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2874 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2876 if (pService == &sDefault) {
2877 if (defaults_saved && is_default(i))
2880 if (equal_parameter(parm_table[i].type,
2881 ((char *)pService) +
2883 ((char *)&sDefault) +
2888 fprintf(f, "\t%s = ", parm_table[i].label);
2889 print_parameter(&parm_table[i],
2890 ((char *)pService) + pdiff, f);
2893 if (pService->param_opt != NULL) {
2894 data = pService->param_opt;
2896 fprintf(f, "\t%s = %s\n", data->key, data->value);
2903 /***************************************************************************
2904 Return info about the next service in a service. snum==-1 gives the globals.
2905 Return NULL when out of parameters.
2906 ***************************************************************************/
2908 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2911 /* do the globals */
2912 for (; parm_table[*i].label; (*i)++) {
2913 if (parm_table[*i].class == P_SEPARATOR)
2914 return &parm_table[(*i)++];
2916 if (!parm_table[*i].ptr
2917 || (*parm_table[*i].label == '-'))
2921 && (parm_table[*i].ptr ==
2922 parm_table[(*i) - 1].ptr))
2925 return &parm_table[(*i)++];
2928 service *pService = ServicePtrs[snum];
2930 for (; parm_table[*i].label; (*i)++) {
2931 if (parm_table[*i].class == P_SEPARATOR)
2932 return &parm_table[(*i)++];
2934 if (parm_table[*i].class == P_LOCAL &&
2935 parm_table[*i].ptr &&
2936 (*parm_table[*i].label != '-') &&
2938 (parm_table[*i].ptr !=
2939 parm_table[(*i) - 1].ptr)))
2942 PTR_DIFF(parm_table[*i].ptr,
2945 if (allparameters ||
2946 !equal_parameter(parm_table[*i].type,
2947 ((char *)pService) +
2949 ((char *)&sDefault) +
2952 return &parm_table[(*i)++];
2963 /***************************************************************************
2964 Display the contents of a single copy structure.
2965 ***************************************************************************/
2966 static void dump_copy_map(BOOL *pcopymap)
2972 printf("\n\tNon-Copied parameters:\n");
2974 for (i = 0; parm_table[i].label; i++)
2975 if (parm_table[i].class == P_LOCAL &&
2976 parm_table[i].ptr && !pcopymap[i] &&
2977 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2979 printf("\t\t%s\n", parm_table[i].label);
2984 /***************************************************************************
2985 Return TRUE if the passed service number is within range.
2986 ***************************************************************************/
2988 BOOL lp_snum_ok(int iService)
2990 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2993 /***************************************************************************
2994 Auto-load some home services.
2995 ***************************************************************************/
2997 static void lp_add_auto_services(const char *str)
3002 /***************************************************************************
3003 Auto-load one printer.
3004 ***************************************************************************/
3006 void lp_add_one_printer(char *name, char *comment)
3008 int printers = lp_servicenumber(PRINTERS_NAME);
3011 if (lp_servicenumber(name) < 0) {
3012 lp_add_printer(name, printers);
3013 if ((i = lp_servicenumber(name)) >= 0) {
3014 string_set(&ServicePtrs[i]->comment, comment);
3015 ServicePtrs[i]->autoloaded = True;
3020 /***************************************************************************
3021 Announce ourselves as a print server.
3022 ***************************************************************************/
3024 void update_server_announce_as_printserver(void)
3026 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3029 /***************************************************************************
3030 Have we loaded a services file yet?
3031 ***************************************************************************/
3033 BOOL lp_loaded(void)
3038 /***************************************************************************
3039 Unload unused services.
3040 ***************************************************************************/
3042 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
3045 for (i = 0; i < iNumServices; i++) {
3049 if (!snumused || !snumused(smb, i)) {
3050 ServicePtrs[i]->valid = False;
3051 free_service(ServicePtrs[i]);
3056 /***************************************************************************
3058 ***************************************************************************/
3060 void lp_killservice(int iServiceIn)
3062 if (VALID(iServiceIn)) {
3063 ServicePtrs[iServiceIn]->valid = False;
3064 free_service(ServicePtrs[iServiceIn]);
3068 /***************************************************************************
3069 Save the curent values of all global and sDefault parameters into the
3070 defaults union. This allows swat and testparm to show only the
3071 changed (ie. non-default) parameters.
3072 ***************************************************************************/
3074 static void lp_save_defaults(void)
3077 for (i = 0; parm_table[i].label; i++) {
3078 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3080 switch (parm_table[i].type) {
3082 str_list_copy(&(parm_table[i].def.lvalue),
3083 *(const char ***)parm_table[i].ptr);
3087 if (parm_table[i].ptr) {
3088 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
3090 parm_table[i].def.svalue = NULL;
3095 parm_table[i].def.bvalue =
3096 *(BOOL *)parm_table[i].ptr;
3099 parm_table[i].def.cvalue =
3100 *(char *)parm_table[i].ptr;
3105 parm_table[i].def.ivalue =
3106 *(int *)parm_table[i].ptr;
3112 defaults_saved = True;
3115 /*******************************************************************
3116 Set the server type we will announce as via nmbd.
3117 ********************************************************************/
3119 static void set_server_role(void)
3121 server_role = ROLE_STANDALONE;
3123 switch (lp_security()) {
3125 if (lp_domain_logons())
3126 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3131 if (lp_domain_logons()) {
3132 server_role = ROLE_DOMAIN_PDC;
3135 server_role = ROLE_DOMAIN_MEMBER;
3138 if (lp_domain_logons()) {
3140 if (Globals.bDomainMaster) /* auto or yes */
3141 server_role = ROLE_DOMAIN_PDC;
3143 server_role = ROLE_DOMAIN_BDC;
3147 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3151 DEBUG(10, ("set_server_role: role = "));
3153 switch(server_role) {
3154 case ROLE_STANDALONE:
3155 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3157 case ROLE_DOMAIN_MEMBER:
3158 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3160 case ROLE_DOMAIN_BDC:
3161 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3163 case ROLE_DOMAIN_PDC:
3164 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3169 /***************************************************************************
3170 Load the services array from the services file. Return True on success,
3172 ***************************************************************************/
3174 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3179 struct param_opt *data;
3181 pstrcpy(n2, pszFname);
3182 standard_sub_basic(n2,sizeof(n2));
3184 add_to_file_list(pszFname, n2);
3188 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3190 bInGlobalSection = True;
3191 bGlobalOnly = global_only;
3200 if (Globals.param_opt != NULL) {
3201 struct param_opt *next;
3202 for (data=Globals.param_opt; data; data=next) {
3204 if (data->flags & FLAG_CMDLINE) continue;
3207 DLIST_REMOVE(Globals.param_opt, data);
3212 /* We get sections first, so have to start 'behind' to make up */
3214 bRetval = pm_process(n2, do_section, do_parameter);
3216 /* finish up the last section */
3217 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3219 if (iServiceIndex >= 0)
3220 bRetval = service_ok(iServiceIndex);
3222 lp_add_auto_services(lp_auto_services());
3225 /* When 'restrict anonymous = 2' guest connections to ipc$
3227 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3228 lp_add_ipc("ADMIN$", False);
3232 set_default_server_announce_type();
3236 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3237 /* if bWINSsupport is true and we are in the client */
3238 if (in_client && Globals.bWINSsupport) {
3239 lp_do_parameter(-1, "wins server", "127.0.0.1");
3247 /***************************************************************************
3248 Reset the max number of services.
3249 ***************************************************************************/
3251 void lp_resetnumservices(void)
3256 /***************************************************************************
3257 Return the max number of services.
3258 ***************************************************************************/
3260 int lp_numservices(void)
3262 return (iNumServices);
3265 /***************************************************************************
3266 Display the contents of the services array in human-readable form.
3267 ***************************************************************************/
3269 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3274 defaults_saved = False;
3278 dump_a_service(&sDefault, f);
3280 for (iService = 0; iService < maxtoprint; iService++)
3281 lp_dump_one(f, show_defaults, iService);
3284 /***************************************************************************
3285 Display the contents of one service in human-readable form.
3286 ***************************************************************************/
3288 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3291 if (ServicePtrs[snum]->szService[0] == '\0')
3293 dump_a_service(ServicePtrs[snum], f);
3297 /***************************************************************************
3298 Return the number of the service with the given name, or -1 if it doesn't
3299 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3300 getservicebyname()! This works ONLY if all services have been loaded, and
3301 does not copy the found service.
3302 ***************************************************************************/
3304 int lp_servicenumber(const char *pszServiceName)
3307 fstring serviceName;
3310 for (iService = iNumServices - 1; iService >= 0; iService--) {
3311 if (VALID(iService) && ServicePtrs[iService]->szService) {
3313 * The substitution here is used to support %U is
3316 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3317 standard_sub_basic(serviceName,sizeof(serviceName));
3318 if (strequal(serviceName, pszServiceName))
3324 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3329 /*******************************************************************
3330 A useful volume label function.
3331 ********************************************************************/
3332 const char *volume_label(int snum)
3334 const char *ret = lp_volume(snum);
3336 return lp_servicename(snum);
3341 /*******************************************************************
3342 Set the server type we will announce as via nmbd.
3343 ********************************************************************/
3345 static void set_default_server_announce_type(void)
3347 default_server_announce = 0;
3348 default_server_announce |= SV_TYPE_WORKSTATION;
3349 default_server_announce |= SV_TYPE_SERVER;
3350 default_server_announce |= SV_TYPE_SERVER_UNIX;
3352 switch (lp_announce_as()) {
3353 case ANNOUNCE_AS_NT_SERVER:
3354 default_server_announce |= SV_TYPE_SERVER_NT;
3355 /* fall through... */
3356 case ANNOUNCE_AS_NT_WORKSTATION:
3357 default_server_announce |= SV_TYPE_NT;
3359 case ANNOUNCE_AS_WIN95:
3360 default_server_announce |= SV_TYPE_WIN95_PLUS;
3362 case ANNOUNCE_AS_WFW:
3363 default_server_announce |= SV_TYPE_WFW;
3369 switch (lp_server_role()) {
3370 case ROLE_DOMAIN_MEMBER:
3371 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3373 case ROLE_DOMAIN_PDC:
3374 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3376 case ROLE_DOMAIN_BDC:
3377 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3379 case ROLE_STANDALONE:
3383 if (lp_time_server())
3384 default_server_announce |= SV_TYPE_TIME_SOURCE;
3386 if (lp_host_msdfs())
3387 default_server_announce |= SV_TYPE_DFS_SERVER;
3390 /***********************************************************
3391 returns role of Samba server
3392 ************************************************************/
3394 int lp_server_role(void)
3399 /***********************************************************
3400 If we are PDC then prefer us as DMB
3401 ************************************************************/
3403 BOOL lp_domain_master(void)
3405 if (Globals.bDomainMaster == Auto)
3406 return (lp_server_role() == ROLE_DOMAIN_PDC);
3408 return Globals.bDomainMaster;
3411 /***********************************************************
3412 If we are DMB then prefer us as LMB
3413 ************************************************************/
3415 BOOL lp_preferred_master(void)
3417 if (Globals.bPreferredMaster == Auto)
3418 return (lp_local_master() && lp_domain_master());
3420 return Globals.bPreferredMaster;
3423 /*******************************************************************
3425 ********************************************************************/
3427 void lp_remove_service(int snum)
3429 ServicePtrs[snum]->valid = False;
3432 /*******************************************************************
3434 ********************************************************************/
3436 void lp_copy_service(int snum, const char *new_name)
3438 const char *oldname = lp_servicename(snum);
3439 do_section(new_name);
3441 snum = lp_servicenumber(new_name);
3443 lp_do_parameter(snum, "copy", oldname);
3448 /*******************************************************************
3449 Get the default server type we will announce as via nmbd.
3450 ********************************************************************/
3452 int lp_default_server_announce(void)
3454 return default_server_announce;
3457 /*******************************************************************
3458 Split the announce version into major and minor numbers.
3459 ********************************************************************/
3461 int lp_major_announce_version(void)
3463 static BOOL got_major = False;
3464 static int major_version = DEFAULT_MAJOR_VERSION;
3469 return major_version;
3472 if ((vers = lp_announce_version()) == NULL)
3473 return major_version;
3475 if ((p = strchr_m(vers, '.')) == 0)
3476 return major_version;
3479 major_version = atoi(vers);
3480 return major_version;
3483 int lp_minor_announce_version(void)
3485 static BOOL got_minor = False;
3486 static int minor_version = DEFAULT_MINOR_VERSION;
3491 return minor_version;
3494 if ((vers = lp_announce_version()) == NULL)
3495 return minor_version;
3497 if ((p = strchr_m(vers, '.')) == 0)
3498 return minor_version;
3501 minor_version = atoi(p);
3502 return minor_version;
3505 const char *lp_printername(int snum)
3507 const char *ret = _lp_printername(snum);
3508 if (ret == NULL || (ret != NULL && *ret == '\0'))
3509 ret = lp_const_servicename(snum);
3515 /*******************************************************************
3516 Return the max print jobs per queue.
3517 ********************************************************************/
3519 int lp_maxprintjobs(int snum)
3521 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3522 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3523 maxjobs = PRINT_MAX_JOBID - 1;