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;
110 char **szPassdbBackend;
111 char **szPreloadModules;
112 char *szPasswordServer;
113 char *szSocketOptions;
120 char **szWINSservers;
122 char *szRemoteAnnounce;
123 char *szRemoteBrowseSync;
124 char *szSocketAddress;
125 char *szAnnounceVersion; /* This is initialised in init_globals */
128 char **szNetbiosAliases;
129 char *szNetbiosScope;
130 char *szDomainOtherSIDs;
131 char *szNameResolveOrder;
133 char *szAddUserScript;
134 char *szAddMachineScript;
136 char *szWINSPartners;
137 char **dcerpc_ep_servers;
140 char *szNonUnixAccountRange;
141 int AlgorithmicRidBase;
142 char *szTemplateHomedir;
143 char *szTemplateShell;
144 char *szWinbindSeparator;
145 BOOL bWinbindEnumUsers;
146 BOOL bWinbindEnumGroups;
147 BOOL bWinbindUseDefaultDomain;
148 char *szIDMapBackend;
149 char *szGuestaccount;
159 BOOL paranoid_server_security;
161 BOOL bDisableSpoolss;
163 int enhanced_browsing;
170 int announce_as; /* This is initialised in init_globals */
171 int machine_password_timeout;
172 int winbind_cache_time;
175 char *szLdapMachineSuffix;
176 char *szLdapUserSuffix;
177 #ifdef WITH_LDAP_SAMCONFIG
181 char *socket_options;
187 int ldap_passwd_sync;
192 BOOL bPreferredMaster;
195 BOOL bEncryptPasswords;
198 BOOL bObeyPamRestrictions;
200 BOOL bLargeReadwrite;
204 BOOL bBindInterfacesOnly;
205 BOOL bPamPasswordChange;
206 BOOL bUnixPasswdSync;
208 BOOL bNTStatusSupport;
209 BOOL bAllowTrustedDomains;
213 BOOL bClientLanManAuth;
214 BOOL bClientNTLMv2Auth;
216 BOOL bHideLocalUsers;
219 BOOL bHostnameLookups;
220 BOOL bUnixExtensions;
221 BOOL bDisableNetbios;
223 int restrict_anonymous;
224 int name_cache_timeout;
225 struct param_opt *param_opt;
229 static global Globals;
232 * This structure describes a single service.
241 char **szInvalidUsers;
246 char *szPrintcommand;
249 char *szLppausecommand;
250 char *szLpresumecommand;
251 char *szQueuepausecommand;
252 char *szQueueresumecommand;
284 struct param_opt *param_opt;
286 char dummy[3]; /* for alignment */
291 /* This is a default service used to prime a services structure */
292 static service sDefault = {
294 False, /* not autoloaded */
295 NULL, /* szService */
297 NULL, /* szUsername */
298 NULL, /* szInvalidUsers */
299 NULL, /* szValidUsers */
300 NULL, /* szAdminUsers */
302 NULL, /* szInclude */
303 NULL, /* szPrintcommand */
304 NULL, /* szLpqcommand */
305 NULL, /* szLprmcommand */
306 NULL, /* szLppausecommand */
307 NULL, /* szLpresumecommand */
308 NULL, /* szQueuepausecommand */
309 NULL, /* szQueueresumecommand */
310 NULL, /* szPrintername */
311 NULL, /* szHostsallow */
312 NULL, /* szHostsdeny */
316 NULL, /* szMSDfsProxy */
317 NULL, /* ntvfs_handler */
318 0, /* iMinPrintSpace */
319 1000, /* iMaxPrintJobs */
320 0, /* iMaxConnections */
321 DEFAULT_PRINTING, /* iPrinting */
323 True, /* bAvailable */
324 True, /* bBrowseable */
325 True, /* bRead_only */
326 False, /* bPrint_ok */
327 False, /* bMap_system */
328 False, /* bMap_hidden */
329 True, /* bMap_archive */
331 True, /* bStrictLocking */
332 True, /* bPosixLocking */
334 True, /* bLevel2OpLocks */
335 False, /* bOnlyUser */
336 False, /* bGuest_only */
337 False, /* bGuest_ok */
339 False, /* bMSDfsRoot */
340 True, /* bShareModes */
341 NULL, /* Parametric options */
346 /* local variables */
347 static service **ServicePtrs = NULL;
348 static int iNumServices = 0;
349 static int iServiceIndex = 0;
350 static BOOL bInGlobalSection = True;
351 static BOOL bGlobalOnly = False;
352 static int server_role;
353 static int default_server_announce;
355 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
357 /* prototypes for the special type handlers */
358 static BOOL handle_include(const char *pszParmValue, char **ptr);
359 static BOOL handle_copy(const char *pszParmValue, char **ptr);
360 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
361 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
362 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
364 static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr );
365 static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr );
366 static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
368 static void set_server_role(void);
369 static void set_default_server_announce_type(void);
371 static const struct enum_list enum_protocol[] = {
372 {PROTOCOL_NT1, "NT1"},
373 {PROTOCOL_LANMAN2, "LANMAN2"},
374 {PROTOCOL_LANMAN1, "LANMAN1"},
375 {PROTOCOL_CORE, "CORE"},
376 {PROTOCOL_COREPLUS, "COREPLUS"},
377 {PROTOCOL_COREPLUS, "CORE+"},
381 static const struct enum_list enum_security[] = {
382 {SEC_SHARE, "SHARE"},
384 {SEC_SERVER, "SERVER"},
385 {SEC_DOMAIN, "DOMAIN"},
392 static const struct enum_list enum_printing[] = {
393 {PRINT_SYSV, "sysv"},
395 {PRINT_HPUX, "hpux"},
399 {PRINT_LPRNG, "lprng"},
400 {PRINT_SOFTQ, "softq"},
401 {PRINT_CUPS, "cups"},
403 {PRINT_LPROS2, "os2"},
405 {PRINT_TEST, "test"},
407 #endif /* DEVELOPER */
411 static const struct enum_list enum_ldap_ssl[] = {
412 #ifdef WITH_LDAP_SAMCONFIG
413 {LDAP_SSL_ON, "Yes"},
414 {LDAP_SSL_ON, "yes"},
418 {LDAP_SSL_OFF, "no"},
419 {LDAP_SSL_OFF, "No"},
420 {LDAP_SSL_OFF, "off"},
421 {LDAP_SSL_OFF, "Off"},
422 {LDAP_SSL_START_TLS, "start tls"},
423 {LDAP_SSL_START_TLS, "Start_tls"},
427 static const struct enum_list enum_ldap_passwd_sync[] = {
428 {LDAP_PASSWD_SYNC_ON, "Yes"},
429 {LDAP_PASSWD_SYNC_ON, "yes"},
430 {LDAP_PASSWD_SYNC_ON, "on"},
431 {LDAP_PASSWD_SYNC_ON, "On"},
432 {LDAP_PASSWD_SYNC_OFF, "no"},
433 {LDAP_PASSWD_SYNC_OFF, "No"},
434 {LDAP_PASSWD_SYNC_OFF, "off"},
435 {LDAP_PASSWD_SYNC_OFF, "Off"},
436 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
437 {LDAP_PASSWD_SYNC_ONLY, "Only"},
438 {LDAP_PASSWD_SYNC_ONLY, "only"},
439 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
443 /* Types of machine we can announce as. */
444 #define ANNOUNCE_AS_NT_SERVER 1
445 #define ANNOUNCE_AS_WIN95 2
446 #define ANNOUNCE_AS_WFW 3
447 #define ANNOUNCE_AS_NT_WORKSTATION 4
449 static const struct enum_list enum_announce_as[] = {
450 {ANNOUNCE_AS_NT_SERVER, "NT"},
451 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
452 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
453 {ANNOUNCE_AS_WIN95, "win95"},
454 {ANNOUNCE_AS_WFW, "WfW"},
458 static const struct enum_list enum_case[] = {
459 {CASE_LOWER, "lower"},
460 {CASE_UPPER, "upper"},
464 static const struct enum_list enum_bool_auto[] = {
475 /* Client-side offline caching policy types */
476 #define CSC_POLICY_MANUAL 0
477 #define CSC_POLICY_DOCUMENTS 1
478 #define CSC_POLICY_PROGRAMS 2
479 #define CSC_POLICY_DISABLE 3
481 static const struct enum_list enum_csc_policy[] = {
482 {CSC_POLICY_MANUAL, "manual"},
483 {CSC_POLICY_DOCUMENTS, "documents"},
484 {CSC_POLICY_PROGRAMS, "programs"},
485 {CSC_POLICY_DISABLE, "disable"},
490 Do you want session setups at user level security with a invalid
491 password to be rejected or allowed in as guest? WinNT rejects them
492 but it can be a pain as it means "net view" needs to use a password
494 You have 3 choices in the setting of map_to_guest:
496 "Never" means session setups with an invalid password
497 are rejected. This is the default.
499 "Bad User" means session setups with an invalid password
500 are rejected, unless the username does not exist, in which case it
501 is treated as a guest login
503 "Bad Password" means session setups with an invalid password
504 are treated as a guest login
506 Note that map_to_guest only has an effect in user or server
510 static const struct enum_list enum_map_to_guest[] = {
511 {NEVER_MAP_TO_GUEST, "Never"},
512 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
513 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
517 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
519 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
520 * is implied in current control logic. This may change at some later time. A
521 * flag value of 0 means - show as development option only.
523 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
524 * screen in SWAT. This is used to exclude parameters as well as to squash all
525 * parameters that have been duplicated by pseudonyms.
527 static struct parm_struct parm_table[] = {
528 {"Base Options", P_SEP, P_SEPARATOR},
530 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
531 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
532 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
533 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
534 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
535 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
536 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
537 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
538 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
539 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
540 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
541 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
544 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"ntvfs handler", P_STRING, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
546 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
548 {"Security Options", P_SEP, P_SEPARATOR},
550 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
551 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
552 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
553 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
554 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
555 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
558 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
560 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
568 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
572 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
573 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
583 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
584 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
586 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
587 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
588 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
590 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
592 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
594 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
596 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
597 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
598 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
599 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
601 {"Logging Options", P_SEP, P_SEPARATOR},
603 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
605 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"Protocol Options", P_SEP, P_SEPARATOR},
609 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
611 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
612 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
613 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
614 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
615 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
616 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
618 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
620 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
621 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
622 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
625 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
626 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
627 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
629 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
632 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
634 {"Tuning Options", P_SEP, P_SEPARATOR},
636 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
637 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
638 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
639 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
641 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
642 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
643 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
645 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
647 {"Printing Options", P_SEP, P_SEPARATOR},
649 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
650 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
651 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
652 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
653 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
654 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
655 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
656 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
657 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
658 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
659 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
660 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
661 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
662 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
663 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
666 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
668 {"Filename Handling", P_SEP, P_SEPARATOR},
670 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
671 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
672 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
673 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
675 {"Domain Options", P_SEP, P_SEPARATOR},
677 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
679 {"Logon Options", P_SEP, P_SEPARATOR},
681 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
682 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
684 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
685 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
686 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
687 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
688 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
690 {"Browse Options", P_SEP, P_SEPARATOR},
692 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
697 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
700 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
701 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
703 {"WINS Options", P_SEP, P_SEPARATOR},
704 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
707 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
708 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
709 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
710 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
712 {"Locking Options", P_SEP, P_SEPARATOR},
714 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
715 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
716 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
717 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
719 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
720 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
721 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
722 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
723 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
725 {"Ldap Options", P_SEP, P_SEPARATOR},
727 #ifdef WITH_LDAP_SAMCONFIG
728 {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
729 {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
731 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
732 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
733 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734 {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
737 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
742 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
743 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
746 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
747 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
750 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
751 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
752 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
753 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
754 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
757 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
758 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
760 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
761 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
762 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
764 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
768 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
769 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"Winbind options", P_SEP, P_SEPARATOR},
772 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
782 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
785 /***************************************************************************
786 Initialise the sDefault parameter structure for the printer values.
787 ***************************************************************************/
789 static void init_printer_values(void)
791 /* choose defaults depending on the type of printing */
792 switch (sDefault.iPrinting) {
797 string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
798 string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
799 string_set(&sDefault.szPrintcommand,
805 string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
806 string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
807 string_set(&sDefault.szPrintcommand,
809 string_set(&sDefault.szQueuepausecommand,
811 string_set(&sDefault.szQueueresumecommand,
813 string_set(&sDefault.szLppausecommand,
815 string_set(&sDefault.szLpresumecommand,
816 "lpc release '%p' %j");
821 string_set(&sDefault.szLpqcommand, "");
822 string_set(&sDefault.szLprmcommand, "");
823 string_set(&sDefault.szPrintcommand, "");
824 string_set(&sDefault.szLppausecommand, "");
825 string_set(&sDefault.szLpresumecommand, "");
826 string_set(&sDefault.szQueuepausecommand, "");
827 string_set(&sDefault.szQueueresumecommand, "");
829 string_set(&Globals.szPrintcapname, "cups");
831 string_set(&sDefault.szLpqcommand,
832 "/usr/bin/lpstat -o '%p'");
833 string_set(&sDefault.szLprmcommand,
834 "/usr/bin/cancel '%p-%j'");
835 string_set(&sDefault.szPrintcommand,
836 "/usr/bin/lp -d '%p' %s; rm %s");
837 string_set(&sDefault.szLppausecommand,
838 "lp -i '%p-%j' -H hold");
839 string_set(&sDefault.szLpresumecommand,
840 "lp -i '%p-%j' -H resume");
841 string_set(&sDefault.szQueuepausecommand,
842 "/usr/bin/disable '%p'");
843 string_set(&sDefault.szQueueresumecommand,
844 "/usr/bin/enable '%p'");
845 string_set(&Globals.szPrintcapname, "lpstat");
846 #endif /* HAVE_CUPS */
851 string_set(&sDefault.szLpqcommand, "lpstat -o%p");
852 string_set(&sDefault.szLprmcommand, "cancel %p-%j");
853 string_set(&sDefault.szPrintcommand,
854 "lp -c -d%p %s; rm %s");
855 string_set(&sDefault.szQueuepausecommand,
857 string_set(&sDefault.szQueueresumecommand,
860 string_set(&sDefault.szLppausecommand,
861 "lp -i %p-%j -H hold");
862 string_set(&sDefault.szLpresumecommand,
863 "lp -i %p-%j -H resume");
868 string_set(&sDefault.szLpqcommand, "lpq -P%p");
869 string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
870 string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
874 string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
875 string_set(&sDefault.szLprmcommand,
877 string_set(&sDefault.szPrintcommand,
878 "lp -d%p -s %s; rm %s");
879 string_set(&sDefault.szLppausecommand,
881 string_set(&sDefault.szLpresumecommand,
887 string_set(&sDefault.szPrintcommand, "vlp print %p %s");
888 string_set(&sDefault.szLpqcommand, "vlp lpq %p");
889 string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
890 string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
891 string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
892 string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
893 string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
895 #endif /* DEVELOPER */
901 /***************************************************************************
902 Initialise the global parameter structure.
903 ***************************************************************************/
904 static void init_globals(void)
909 DEBUG(3, ("Initialising global parameters\n"));
911 for (i = 0; parm_table[i].label; i++) {
912 if ((parm_table[i].type == P_STRING ||
913 parm_table[i].type == P_USTRING) &&
915 !(parm_table[i].flags & FLAG_CMDLINE)) {
916 string_set(parm_table[i].ptr, "");
920 /* options that can be set on the command line must be initialised via
921 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
922 do_parameter("socket options", DEFAULT_SOCKET_OPTIONS);
923 do_parameter("workgroup", DEFAULT_WORKGROUP);
924 do_parameter("netbios name", get_myname());
925 do_parameter("max protocol", "NT1");
926 do_parameter("name resolve order", "lmhosts wins host bcast");
928 init_printer_values();
930 string_set(&sDefault.fstype, FSTYPE_STRING);
931 string_set(&sDefault.ntvfs_handler, "default");
933 Globals.dcerpc_ep_servers = str_list_make("epmapper rpcecho", NULL);
935 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
936 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
938 /* use the new 'hash2' method by default, with a prefix of 1 */
940 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
942 /* using UTF8 by default allows us to support all chars */
943 string_set(&Globals.unix_charset, "UTF8");
945 /* Use codepage 850 as a default for the dos character set */
946 string_set(&Globals.dos_charset, "CP850");
949 * Allow the default PASSWD_CHAT to be overridden in local.h.
951 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
953 string_set(&Globals.szPasswdProgram, "");
954 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
955 string_set(&Globals.szPidDir, dyn_PIDDIR);
956 string_set(&Globals.szLockDir, dyn_LOCKDIR);
957 string_set(&Globals.szSocketAddress, "0.0.0.0");
958 pstrcpy(s, "Samba ");
959 pstrcat(s, SAMBA_VERSION_STRING);
960 string_set(&Globals.szServerString, s);
961 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
962 DEFAULT_MINOR_VERSION);
963 string_set(&Globals.szAnnounceVersion, s);
965 string_set(&Globals.szLogonDrive, "");
966 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
967 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
968 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
970 string_set(&Globals.szPasswordServer, "*");
972 Globals.AlgorithmicRidBase = BASE_RID;
974 Globals.bLoadPrinters = True;
975 Globals.mangled_stack = 50;
976 Globals.max_mux = 50; /* This is *needed* for profile support. */
977 Globals.max_xmit = 4356; /* the value w2k3 chooses */
978 Globals.lpqcachetime = 10;
979 Globals.bDisableSpoolss = False;
980 Globals.pwordlevel = 0;
981 Globals.unamelevel = 0;
982 Globals.bLargeReadwrite = True;
983 Globals.minprotocol = PROTOCOL_CORE;
984 Globals.security = SEC_USER;
985 Globals.paranoid_server_security = True;
986 Globals.bEncryptPasswords = True;
987 Globals.bUpdateEncrypt = False;
988 Globals.bReadRaw = True;
989 Globals.bWriteRaw = True;
990 Globals.bNullPasswords = False;
991 Globals.bObeyPamRestrictions = False;
992 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
993 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
994 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
995 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
996 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
997 Globals.lm_interval = 60;
998 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1000 Globals.bTimeServer = False;
1001 Globals.bBindInterfacesOnly = False;
1002 Globals.bUnixPasswdSync = False;
1003 Globals.bPamPasswordChange = False;
1004 Globals.bUnicode = True; /* Do unicode on the wire by default */
1005 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1006 Globals.restrict_anonymous = 0;
1007 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1008 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1009 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1011 Globals.enhanced_browsing = True;
1012 Globals.iLockSpinCount = 3; /* Try 2 times. */
1013 Globals.iLockSpinTime = 10; /* usec. */
1014 #ifdef MMAP_BLACKLIST
1015 Globals.bUseMmap = False;
1017 Globals.bUseMmap = True;
1019 Globals.bUnixExtensions = False;
1021 /* hostname lookups can be very expensive and are broken on
1022 a large number of sites (tridge) */
1023 Globals.bHostnameLookups = False;
1025 #ifdef WITH_LDAP_SAMCONFIG
1026 string_set(&Globals.szLdapServer, "localhost");
1027 Globals.ldap_port = 636;
1028 Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1030 Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1031 #endif /* WITH_LDAP_SAMCONFIG */
1033 string_set(&Globals.szLdapSuffix, "");
1034 string_set(&Globals.szLdapMachineSuffix, "");
1035 string_set(&Globals.szLdapUserSuffix, "");
1037 string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
1038 string_set(&Globals.szLdapAdminDn, "");
1039 Globals.ldap_ssl = LDAP_SSL_ON;
1040 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1042 /* these parameters are set to defaults that are more appropriate
1043 for the increasing samba install base:
1045 as a member of the workgroup, that will possibly become a
1046 _local_ master browser (lm = True). this is opposed to a forced
1047 local master browser startup (pm = True).
1049 doesn't provide WINS server service by default (wsupp = False),
1050 and doesn't provide domain master browser services by default, either.
1054 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1055 Globals.os_level = 20;
1056 Globals.bLocalMaster = True;
1057 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1058 Globals.bDomainLogons = False;
1059 Globals.bWINSsupport = False;
1060 Globals.bWINSproxy = False;
1062 Globals.bDNSproxy = True;
1064 Globals.bAllowTrustedDomains = True;
1066 string_set(&Globals.szTemplateShell, "/bin/false");
1067 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1068 string_set(&Globals.szWinbindSeparator, "\\");
1070 Globals.winbind_cache_time = 15;
1071 Globals.bWinbindEnumUsers = True;
1072 Globals.bWinbindEnumGroups = True;
1073 Globals.bWinbindUseDefaultDomain = False;
1075 string_set(&Globals.szIDMapBackend, "tdb");
1077 Globals.name_cache_timeout = 660; /* In seconds */
1079 Globals.bUseSpnego = True;
1081 string_set(&Globals.smb_ports, SMB_PORTS);
1084 static TALLOC_CTX *lp_talloc;
1086 /******************************************************************* a
1087 Free up temporary memory - called from the main loop.
1088 ********************************************************************/
1090 void lp_talloc_free(void)
1094 talloc_destroy(lp_talloc);
1098 /*******************************************************************
1099 Convenience routine to grab string parameters into temporary memory
1100 and run standard_sub_basic on them. The buffers can be written to by
1101 callers without affecting the source string.
1102 ********************************************************************/
1104 static char *lp_string(const char *s)
1106 #if 0 /* until REWRITE done to make thread-safe */
1107 size_t len = s ? strlen(s) : 0;
1111 /* The follow debug is useful for tracking down memory problems
1112 especially if you have an inner loop that is calling a lp_*()
1113 function that returns a string. Perhaps this debug should be
1114 present all the time? */
1117 DEBUG(10, ("lp_string(%s)\n", s));
1120 #if 0 /* until REWRITE done to make thread-safe */
1122 lp_talloc = talloc_init("lp_talloc");
1124 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1132 StrnCpy(ret, s, len);
1134 if (trim_string(ret, "\"", "\"")) {
1135 if (strchr(ret,'"') != NULL)
1136 StrnCpy(ret, s, len);
1139 standard_sub_basic(ret,len+100);
1146 In this section all the functions that are used to access the
1147 parameters from the rest of the program are defined
1150 #define FN_GLOBAL_STRING(fn_name,ptr) \
1151 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1152 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1153 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1154 #define FN_GLOBAL_LIST(fn_name,ptr) \
1155 const char **fn_name(void) {return(*(const char ***)(ptr));}
1156 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1157 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1158 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1159 char fn_name(void) {return(*(char *)(ptr));}
1160 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1161 int fn_name(void) {return(*(int *)(ptr));}
1163 #define FN_LOCAL_STRING(fn_name,val) \
1164 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1165 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1166 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1167 #define FN_LOCAL_LIST(fn_name,val) \
1168 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1169 #define FN_LOCAL_BOOL(fn_name,val) \
1170 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1171 #define FN_LOCAL_CHAR(fn_name,val) \
1172 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1173 #define FN_LOCAL_INTEGER(fn_name,val) \
1174 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1176 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1177 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1178 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1179 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1180 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1181 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1182 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1183 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1184 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1185 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1186 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1187 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1188 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1189 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1190 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1191 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1192 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1193 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1194 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1195 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1196 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1197 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1198 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1199 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1200 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1201 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1202 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1203 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1204 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1205 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1206 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1207 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1208 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1209 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1210 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1211 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1212 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1213 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1214 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1215 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1216 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1217 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1219 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1221 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1223 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1224 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1225 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1226 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1227 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1228 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1229 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1230 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1231 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1233 #ifdef WITH_LDAP_SAMCONFIG
1234 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1235 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1237 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1238 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1239 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1240 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1241 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1242 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1243 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1244 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1246 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1247 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1248 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1249 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1250 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1251 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1252 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1253 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1254 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1255 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1256 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1257 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1258 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1259 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1260 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1261 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1262 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1263 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1264 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1265 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1266 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1267 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1268 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1269 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1270 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1271 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1272 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1273 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1274 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1275 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1276 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1277 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1278 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1279 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1280 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1281 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1282 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1283 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1284 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1285 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1286 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1287 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1288 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1289 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1290 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1291 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1292 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1293 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1294 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1295 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1296 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1297 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1298 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1299 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1300 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1301 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1302 FN_LOCAL_STRING(lp_servicename, szService)
1303 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1304 FN_LOCAL_STRING(lp_pathname, szPath)
1305 FN_LOCAL_STRING(lp_username, szUsername)
1306 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1307 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1308 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1309 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1310 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1311 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1312 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1313 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1314 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1315 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1316 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1317 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1318 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1319 FN_LOCAL_STRING(lp_comment, comment)
1320 FN_LOCAL_STRING(lp_fstype, fstype)
1321 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1322 static FN_LOCAL_STRING(lp_volume, volume)
1323 FN_LOCAL_STRING(lp_ntvfs_handler, ntvfs_handler)
1324 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1325 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1326 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1327 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1328 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1329 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1330 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1331 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1332 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1333 FN_LOCAL_BOOL(lp_locking, bLocking)
1334 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1335 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1336 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1337 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1338 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1339 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1340 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1341 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1342 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1343 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1344 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1345 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1346 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1347 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
1348 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1350 /* local prototypes */
1352 static int map_parameter(const char *pszParmName);
1353 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1354 static int getservicebyname(const char *pszServiceName,
1355 service * pserviceDest);
1356 static void copy_service(service * pserviceDest,
1357 service * pserviceSource, BOOL *pcopymapDest);
1358 static BOOL service_ok(int iService);
1359 static BOOL do_section(const char *pszSectionName);
1360 static void init_copymap(service * pservice);
1362 /* This is a helper function for parametrical options support. */
1363 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1364 /* Actual parametrical functions are quite simple */
1365 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1368 struct param_opt *data;
1370 if (lookup_service >= iNumServices) return NULL;
1372 data = (lookup_service < 0) ?
1373 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1375 asprintf(&vfskey, "%s:%s", type, option);
1379 if (strcmp(data->key, vfskey) == 0) {
1386 if (lookup_service >= 0) {
1387 /* Try to fetch the same option but from globals */
1388 /* but only if we are not already working with Globals */
1389 data = Globals.param_opt;
1391 if (strcmp(data->key, vfskey) == 0) {
1405 /*******************************************************************
1406 convenience routine to return int parameters.
1407 ********************************************************************/
1408 static int lp_int(const char *s)
1412 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1419 /*******************************************************************
1420 convenience routine to return unsigned long parameters.
1421 ********************************************************************/
1422 static int lp_ulong(const char *s)
1426 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1430 return strtoul(s, NULL, 10);
1433 /*******************************************************************
1434 convenience routine to return boolean parameters.
1435 ********************************************************************/
1436 static BOOL lp_bool(const char *s)
1441 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1445 if (!set_boolean(&ret,s)) {
1446 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1453 /*******************************************************************
1454 convenience routine to return enum parameters.
1455 ********************************************************************/
1456 static int lp_enum(const char *s,const struct enum_list *_enum)
1461 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1465 for (i=0; _enum[i].name; i++) {
1466 if (strcasecmp(_enum[i].name,s)==0)
1467 return _enum[i].value;
1470 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1474 /* Return parametric option from a given service. Type is a part of option before ':' */
1475 /* Parametric option has following syntax: 'Type: option = value' */
1476 /* Returned value is allocated in 'lp_talloc' context */
1478 char *lp_parm_string(int lookup_service, const char *type, const char *option)
1480 const char *value = get_parametrics(lookup_service, type, option);
1483 return lp_string(value);
1488 /* Return parametric option from a given service. Type is a part of option before ':' */
1489 /* Parametric option has following syntax: 'Type: option = value' */
1490 /* Returned value is allocated in 'lp_talloc' context */
1492 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1493 const char *separator)
1495 const char *value = get_parametrics(lookup_service, type, option);
1498 return str_list_make(value, separator);
1503 /* Return parametric option from a given service. Type is a part of option before ':' */
1504 /* Parametric option has following syntax: 'Type: option = value' */
1506 int lp_parm_int(int lookup_service, const char *type, const char *option)
1508 const char *value = get_parametrics(lookup_service, type, option);
1511 return lp_int(value);
1516 /* Return parametric option from a given service. Type is a part of option before ':' */
1517 /* Parametric option has following syntax: 'Type: option = value' */
1519 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1521 const char *value = get_parametrics(lookup_service, type, option);
1524 return lp_ulong(value);
1529 /* Return parametric option from a given service. Type is a part of option before ':' */
1530 /* Parametric option has following syntax: 'Type: option = value' */
1532 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1534 const char *value = get_parametrics(lookup_service, type, option);
1537 return lp_bool(value);
1542 /* Return parametric option from a given service. Type is a part of option before ':' */
1543 /* Parametric option has following syntax: 'Type: option = value' */
1545 int lp_parm_enum(int lookup_service, const char *type, const char *option,
1546 const struct enum_list *_enum)
1548 const char *value = get_parametrics(lookup_service, type, option);
1551 return lp_enum(value, _enum);
1557 /***************************************************************************
1558 Initialise a service to the defaults.
1559 ***************************************************************************/
1561 static void init_service(service * pservice)
1563 memset((char *)pservice, '\0', sizeof(service));
1564 copy_service(pservice, &sDefault, NULL);
1567 /***************************************************************************
1568 Free the dynamically allocated parts of a service struct.
1569 ***************************************************************************/
1571 static void free_service(service *pservice)
1574 struct param_opt *data, *pdata;
1578 if (pservice->szService)
1579 DEBUG(5, ("free_service: Freeing service %s\n",
1580 pservice->szService));
1582 string_free(&pservice->szService);
1583 SAFE_FREE(pservice->copymap);
1585 for (i = 0; parm_table[i].label; i++) {
1586 if ((parm_table[i].type == P_STRING ||
1587 parm_table[i].type == P_USTRING) &&
1588 parm_table[i].class == P_LOCAL)
1589 string_free((char **)
1590 (((char *)pservice) +
1591 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1592 else if (parm_table[i].type == P_LIST &&
1593 parm_table[i].class == P_LOCAL)
1594 str_list_free((char ***)
1595 (((char *)pservice) +
1596 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1599 DEBUG(5,("Freeing parametrics:\n"));
1600 data = pservice->param_opt;
1602 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1603 string_free(&data->key);
1604 string_free(&data->value);
1610 ZERO_STRUCTP(pservice);
1613 /***************************************************************************
1614 Add a new service to the services array initialising it with the given
1616 ***************************************************************************/
1618 static int add_a_service(const service *pservice, const char *name)
1622 int num_to_alloc = iNumServices + 1;
1623 struct param_opt *data, *pdata;
1625 tservice = *pservice;
1627 /* it might already exist */
1629 i = getservicebyname(name, NULL);
1631 /* Clean all parametric options for service */
1632 /* They will be added during parsing again */
1633 data = ServicePtrs[i]->param_opt;
1635 string_free(&data->key);
1636 string_free(&data->value);
1641 ServicePtrs[i]->param_opt = NULL;
1646 /* find an invalid one */
1647 for (i = 0; i < iNumServices; i++)
1648 if (!ServicePtrs[i]->valid)
1651 /* if not, then create one */
1652 if (i == iNumServices) {
1655 tsp = (service **) Realloc(ServicePtrs,
1660 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1665 ServicePtrs[iNumServices] =
1666 (service *) malloc(sizeof(service));
1668 if (!ServicePtrs[iNumServices]) {
1669 DEBUG(0,("add_a_service: out of memory!\n"));
1675 free_service(ServicePtrs[i]);
1677 ServicePtrs[i]->valid = True;
1679 init_service(ServicePtrs[i]);
1680 copy_service(ServicePtrs[i], &tservice, NULL);
1682 string_set(&ServicePtrs[i]->szService, name);
1686 /***************************************************************************
1687 Add a new home service, with the specified home directory, defaults coming
1689 ***************************************************************************/
1691 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1692 const char *user, const char *pszHomedir)
1697 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1702 if (!(*(ServicePtrs[iDefaultService]->szPath))
1703 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1704 pstrcpy(newHomedir, pszHomedir);
1706 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1707 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1710 string_set(&ServicePtrs[i]->szPath, newHomedir);
1712 if (!(*(ServicePtrs[i]->comment))) {
1714 slprintf(comment, sizeof(comment) - 1,
1715 "Home directory of %s", user);
1716 string_set(&ServicePtrs[i]->comment, comment);
1718 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1719 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1721 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1727 /***************************************************************************
1728 Add a new service, based on an old one.
1729 ***************************************************************************/
1731 int lp_add_service(const char *pszService, int iDefaultService)
1733 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1736 /***************************************************************************
1737 Add the IPC service.
1738 ***************************************************************************/
1740 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1743 int i = add_a_service(&sDefault, ipc_name);
1748 slprintf(comment, sizeof(comment) - 1,
1749 "IPC Service (%s)", Globals.szServerString);
1751 string_set(&ServicePtrs[i]->szPath, tmpdir());
1752 string_set(&ServicePtrs[i]->szUsername, "");
1753 string_set(&ServicePtrs[i]->comment, comment);
1754 string_set(&ServicePtrs[i]->fstype, "IPC");
1755 ServicePtrs[i]->iMaxConnections = 0;
1756 ServicePtrs[i]->bAvailable = True;
1757 ServicePtrs[i]->bRead_only = True;
1758 ServicePtrs[i]->bGuest_only = False;
1759 ServicePtrs[i]->bGuest_ok = guest_ok;
1760 ServicePtrs[i]->bPrint_ok = False;
1761 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1763 DEBUG(3, ("adding IPC service\n"));
1768 /***************************************************************************
1769 Add a new printer service, with defaults coming from service iFrom.
1770 ***************************************************************************/
1772 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1774 const char *comment = "From Printcap";
1775 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1780 /* note that we do NOT default the availability flag to True - */
1781 /* we take it from the default service passed. This allows all */
1782 /* dynamic printers to be disabled by disabling the [printers] */
1783 /* entry (if/when the 'available' keyword is implemented!). */
1785 /* the printer name is set to the service name. */
1786 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1787 string_set(&ServicePtrs[i]->comment, comment);
1788 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1789 /* Printers cannot be read_only. */
1790 ServicePtrs[i]->bRead_only = False;
1791 /* No share modes on printer services. */
1792 ServicePtrs[i]->bShareModes = False;
1793 /* No oplocks on printer services. */
1794 ServicePtrs[i]->bOpLocks = False;
1795 /* Printer services must be printable. */
1796 ServicePtrs[i]->bPrint_ok = True;
1798 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1800 update_server_announce_as_printserver();
1805 /***************************************************************************
1806 Map a parameter's string representation to something we can use.
1807 Returns False if the parameter string is not recognised, else TRUE.
1808 ***************************************************************************/
1810 static int map_parameter(const char *pszParmName)
1814 if (*pszParmName == '-')
1817 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1818 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1821 /* Warn only if it isn't parametric option */
1822 if (strchr(pszParmName, ':') == NULL)
1823 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1824 /* We do return 'fail' for parametric options as well because they are
1825 stored in different storage
1830 /***************************************************************************
1831 Set a boolean variable from the text value stored in the passed string.
1832 Returns True in success, False if the passed string does not correctly
1833 represent a boolean.
1834 ***************************************************************************/
1836 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1841 if (strwicmp(pszParmValue, "yes") == 0 ||
1842 strwicmp(pszParmValue, "true") == 0 ||
1843 strwicmp(pszParmValue, "1") == 0)
1845 else if (strwicmp(pszParmValue, "no") == 0 ||
1846 strwicmp(pszParmValue, "False") == 0 ||
1847 strwicmp(pszParmValue, "0") == 0)
1851 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1858 /***************************************************************************
1859 Find a service by name. Otherwise works like get_service.
1860 ***************************************************************************/
1862 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1866 for (iService = iNumServices - 1; iService >= 0; iService--)
1867 if (VALID(iService) &&
1868 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1869 if (pserviceDest != NULL)
1870 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1877 /***************************************************************************
1878 Copy a service structure to another.
1879 If pcopymapDest is NULL then copy all fields
1880 ***************************************************************************/
1882 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1885 BOOL bcopyall = (pcopymapDest == NULL);
1886 struct param_opt *data, *pdata, *paramo;
1889 for (i = 0; parm_table[i].label; i++)
1890 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1891 (bcopyall || pcopymapDest[i])) {
1892 void *def_ptr = parm_table[i].ptr;
1894 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1897 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1900 switch (parm_table[i].type) {
1903 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1909 *(int *)dest_ptr = *(int *)src_ptr;
1913 *(char *)dest_ptr = *(char *)src_ptr;
1917 string_set(dest_ptr,
1922 string_set(dest_ptr,
1924 strupper(*(char **)dest_ptr);
1927 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1935 init_copymap(pserviceDest);
1936 if (pserviceSource->copymap)
1937 memcpy((void *)pserviceDest->copymap,
1938 (void *)pserviceSource->copymap,
1939 sizeof(BOOL) * NUMPARAMETERS);
1942 data = pserviceSource->param_opt;
1945 pdata = pserviceDest->param_opt;
1946 /* Traverse destination */
1948 /* If we already have same option, override it */
1949 if (strcmp(pdata->key, data->key) == 0) {
1950 string_free(&pdata->value);
1951 pdata->value = strdup(data->value);
1955 pdata = pdata->next;
1958 paramo = smb_xmalloc(sizeof(*paramo));
1959 paramo->key = strdup(data->key);
1960 paramo->value = strdup(data->value);
1961 DLIST_ADD(pserviceDest->param_opt, paramo);
1967 /***************************************************************************
1968 Check a service for consistency. Return False if the service is in any way
1969 incomplete or faulty, else True.
1970 ***************************************************************************/
1972 static BOOL service_ok(int iService)
1977 if (ServicePtrs[iService]->szService[0] == '\0') {
1978 DEBUG(0, ("The following message indicates an internal error:\n"));
1979 DEBUG(0, ("No service name in service entry.\n"));
1983 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1984 /* I can't see why you'd want a non-printable printer service... */
1985 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1986 if (!ServicePtrs[iService]->bPrint_ok) {
1987 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1988 ServicePtrs[iService]->szService));
1989 ServicePtrs[iService]->bPrint_ok = True;
1991 /* [printers] service must also be non-browsable. */
1992 if (ServicePtrs[iService]->bBrowseable)
1993 ServicePtrs[iService]->bBrowseable = False;
1996 if (ServicePtrs[iService]->szPath[0] == '\0' &&
1997 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
1998 DEBUG(0, ("No path in service %s - using %s\n",
1999 ServicePtrs[iService]->szService, tmpdir()));
2000 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2003 /* If a service is flagged unavailable, log the fact at level 0. */
2004 if (!ServicePtrs[iService]->bAvailable)
2005 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2006 ServicePtrs[iService]->szService));
2011 static struct file_lists {
2012 struct file_lists *next;
2016 } *file_lists = NULL;
2018 /*******************************************************************
2019 Keep a linked list of all config files so we know when one has changed
2020 it's date and needs to be reloaded.
2021 ********************************************************************/
2023 static void add_to_file_list(const char *fname, const char *subfname)
2025 struct file_lists *f = file_lists;
2028 if (f->name && !strcmp(f->name, fname))
2034 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2037 f->next = file_lists;
2038 f->name = strdup(fname);
2043 f->subfname = strdup(subfname);
2049 f->modtime = file_modtime(subfname);
2051 time_t t = file_modtime(subfname);
2057 /*******************************************************************
2058 Check if a config file has changed date.
2059 ********************************************************************/
2061 BOOL lp_file_list_changed(void)
2063 struct file_lists *f = file_lists;
2064 DEBUG(6, ("lp_file_list_changed()\n"));
2070 pstrcpy(n2, f->name);
2071 standard_sub_basic(n2,sizeof(n2));
2073 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2074 f->name, n2, ctime(&f->modtime)));
2076 mod_time = file_modtime(n2);
2078 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2080 ("file %s modified: %s\n", n2,
2082 f->modtime = mod_time;
2083 SAFE_FREE(f->subfname);
2084 f->subfname = strdup(n2);
2092 /***************************************************************************
2093 Handle the include operation.
2094 ***************************************************************************/
2096 static BOOL handle_include(const char *pszParmValue, char **ptr)
2099 pstrcpy(fname, pszParmValue);
2101 standard_sub_basic(fname,sizeof(fname));
2103 add_to_file_list(pszParmValue, fname);
2105 string_set(ptr, fname);
2107 if (file_exist(fname, NULL))
2108 return (pm_process(fname, do_section, do_parameter));
2110 DEBUG(2, ("Can't find include file %s\n", fname));
2115 /***************************************************************************
2116 Handle the interpretation of the copy parameter.
2117 ***************************************************************************/
2119 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2123 service serviceTemp;
2125 string_set(ptr, pszParmValue);
2127 init_service(&serviceTemp);
2131 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2133 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2134 if (iTemp == iServiceIndex) {
2135 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2137 copy_service(ServicePtrs[iServiceIndex],
2139 ServicePtrs[iServiceIndex]->copymap);
2143 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2147 free_service(&serviceTemp);
2151 /***************************************************************************
2152 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2157 winbind uid = 1000-1999
2158 winbind gid = 700-899
2160 We only do simple parsing checks here. The strings are parsed into useful
2161 structures in the winbind daemon code.
2163 ***************************************************************************/
2165 /* Some lp_ routines to return winbind [ug]id information */
2167 static uid_t winbind_uid_low, winbind_uid_high;
2168 static gid_t winbind_gid_low, winbind_gid_high;
2169 static uint32 non_unix_account_low, non_unix_account_high;
2171 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2173 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2177 *low = winbind_uid_low;
2180 *high = winbind_uid_high;
2185 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2187 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2191 *low = winbind_gid_low;
2194 *high = winbind_gid_high;
2199 BOOL lp_non_unix_account_range(uint32 *low, uint32 *high)
2201 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2205 *low = non_unix_account_low;
2208 *high = non_unix_account_high;
2213 /* Do some simple checks on "winbind [ug]id" parameter values */
2215 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2219 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2224 string_set(ptr, pszParmValue);
2226 winbind_uid_low = low;
2227 winbind_uid_high = high;
2232 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2236 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2241 string_set(ptr, pszParmValue);
2243 winbind_gid_low = low;
2244 winbind_gid_high = high;
2249 /***************************************************************************
2250 Do some simple checks on "non unix account range" parameter values.
2251 ***************************************************************************/
2253 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2257 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2262 string_set(ptr, pszParmValue);
2264 non_unix_account_low = low;
2265 non_unix_account_high = high;
2270 /***************************************************************************
2271 Handle the ldap machine suffix option.
2272 ***************************************************************************/
2274 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2278 pstrcpy(suffix, pszParmValue);
2280 if (! *Globals.szLdapSuffix ) {
2281 string_set( ptr, suffix );
2285 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2286 if ( *pszParmValue )
2287 pstrcat(suffix, ",");
2288 pstrcat(suffix, Globals.szLdapSuffix);
2290 string_set( ptr, suffix );
2294 /***************************************************************************
2295 Handle the ldap user suffix option.
2296 ***************************************************************************/
2298 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2302 pstrcpy(suffix, pszParmValue);
2304 if (! *Globals.szLdapSuffix ) {
2305 string_set( ptr, suffix );
2309 if (! strstr(suffix, Globals.szLdapSuffix) ) {
2310 if ( *pszParmValue )
2311 pstrcat(suffix, ",");
2312 pstrcat(suffix, Globals.szLdapSuffix);
2314 string_set( ptr, suffix );
2318 /***************************************************************************
2319 Handle setting ldap suffix and determines whether ldap machine suffix needs
2321 ***************************************************************************/
2323 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
2326 pstring user_suffix;
2327 pstring machine_suffix;
2329 pstrcpy(suffix, pszParmValue);
2331 if (! *Globals.szLdapMachineSuffix )
2332 string_set(&Globals.szLdapMachineSuffix, suffix);
2333 if (! *Globals.szLdapUserSuffix )
2334 string_set(&Globals.szLdapUserSuffix, suffix);
2336 if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
2337 pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
2338 if ( *Globals.szLdapMachineSuffix )
2339 pstrcat(machine_suffix, ",");
2340 pstrcat(machine_suffix, suffix);
2341 string_set(&Globals.szLdapMachineSuffix, machine_suffix);
2344 if (! strstr(Globals.szLdapUserSuffix, suffix)) {
2345 pstrcpy(user_suffix, Globals.szLdapUserSuffix);
2346 if ( *Globals.szLdapUserSuffix )
2347 pstrcat(user_suffix, ",");
2348 pstrcat(user_suffix, suffix);
2349 string_set(&Globals.szLdapUserSuffix, user_suffix);
2352 string_set(ptr, suffix);
2357 /***************************************************************************
2358 Initialise a copymap.
2359 ***************************************************************************/
2361 static void init_copymap(service * pservice)
2364 SAFE_FREE(pservice->copymap);
2365 pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
2366 if (!pservice->copymap)
2368 ("Couldn't allocate copymap!! (size %d)\n",
2369 (int)NUMPARAMETERS));
2371 for (i = 0; i < NUMPARAMETERS; i++)
2372 pservice->copymap[i] = True;
2375 /***************************************************************************
2376 Return the local pointer to a parameter given the service number and the
2377 pointer into the default structure.
2378 ***************************************************************************/
2380 void *lp_local_ptr(int snum, void *ptr)
2382 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2386 /***************************************************************************
2387 Process a parametric option
2388 ***************************************************************************/
2389 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2391 struct param_opt *paramo, *data;
2394 while (isspace(*pszParmName)) {
2398 name = strdup(pszParmName);
2399 if (!name) return False;
2404 data = Globals.param_opt;
2406 data = ServicePtrs[snum]->param_opt;
2409 /* Traverse destination */
2410 for (paramo=data; paramo; paramo=paramo->next) {
2411 /* If we already have the option set, override it unless
2412 it was a command line option and the new one isn't */
2413 if (strcmp(paramo->key, name) == 0) {
2414 if ((paramo->flags & FLAG_CMDLINE) &&
2415 !(flags & FLAG_CMDLINE)) {
2419 free(paramo->value);
2420 paramo->value = strdup(pszParmValue);
2421 paramo->flags = flags;
2427 paramo = smb_xmalloc(sizeof(*paramo));
2428 paramo->key = strdup(name);
2429 paramo->value = strdup(pszParmValue);
2430 paramo->flags = flags;
2432 DLIST_ADD(Globals.param_opt, paramo);
2434 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2442 /***************************************************************************
2443 Process a parameter for a particular service number. If snum < 0
2444 then assume we are in the globals.
2445 ***************************************************************************/
2446 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2449 void *parm_ptr = NULL; /* where we are going to store the result */
2450 void *def_ptr = NULL;
2452 parmnum = map_parameter(pszParmName);
2455 if (strchr(pszParmName, ':')) {
2456 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2458 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2462 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2463 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2467 /* if the flag has been set on the command line, then don't allow override,
2468 but don't report an error */
2469 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2473 def_ptr = parm_table[parmnum].ptr;
2475 /* we might point at a service, the default service or a global */
2479 if (parm_table[parmnum].class == P_GLOBAL) {
2481 ("Global parameter %s found in service section!\n",
2486 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2491 if (!ServicePtrs[snum]->copymap)
2492 init_copymap(ServicePtrs[snum]);
2494 /* this handles the aliases - set the copymap for other entries with
2495 the same data pointer */
2496 for (i = 0; parm_table[i].label; i++)
2497 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2498 ServicePtrs[snum]->copymap[i] = False;
2501 /* if it is a special case then go ahead */
2502 if (parm_table[parmnum].special) {
2503 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2507 /* now switch on the type of variable it is */
2508 switch (parm_table[parmnum].type)
2511 set_boolean(parm_ptr, pszParmValue);
2515 set_boolean(parm_ptr, pszParmValue);
2516 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2520 *(int *)parm_ptr = atoi(pszParmValue);
2524 *(char *)parm_ptr = *pszParmValue;
2528 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2532 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2536 string_set(parm_ptr, pszParmValue);
2540 string_set(parm_ptr, pszParmValue);
2541 strupper(*(char **)parm_ptr);
2545 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2548 parm_table[parmnum].enum_list[i].name)) {
2550 parm_table[parmnum].
2563 /***************************************************************************
2564 Process a parameter.
2565 ***************************************************************************/
2567 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2569 if (!bInGlobalSection && bGlobalOnly)
2572 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2574 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2575 pszParmName, pszParmValue));
2580 set a parameter from the commandline - this is called from command line parameter
2581 parsing code. It sets the parameter then marks the parameter as unable to be modified
2582 by smb.conf processing
2584 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2586 int parmnum = map_parameter(pszParmName);
2588 if (parmnum < 0 && strchr(pszParmName, ':')) {
2589 /* set a parametric option */
2590 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2593 /* reset the CMDLINE flag in case this has been called before */
2594 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2596 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2600 parm_table[parmnum].flags |= FLAG_CMDLINE;
2604 /***************************************************************************
2605 Print a parameter of the specified type.
2606 ***************************************************************************/
2608 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2614 for (i = 0; p->enum_list[i].name; i++) {
2615 if (*(int *)ptr == p->enum_list[i].value) {
2617 p->enum_list[i].name);
2624 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2628 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2632 fprintf(f, "%d", *(int *)ptr);
2636 fprintf(f, "%c", *(char *)ptr);
2640 fprintf(f, "%s", octal_string(*(int *)ptr));
2644 if ((char ***)ptr && *(char ***)ptr) {
2645 char **list = *(char ***)ptr;
2647 for (; *list; list++)
2648 fprintf(f, "%s%s", *list,
2649 ((*(list+1))?", ":""));
2655 if (*(char **)ptr) {
2656 fprintf(f, "%s", *(char **)ptr);
2664 /***************************************************************************
2665 Check if two parameters are equal.
2666 ***************************************************************************/
2668 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2673 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2678 return (*((int *)ptr1) == *((int *)ptr2));
2681 return (*((char *)ptr1) == *((char *)ptr2));
2684 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2689 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2694 return (p1 == p2 || strequal(p1, p2));
2702 /***************************************************************************
2703 Process a new section (service). At this stage all sections are services.
2704 Later we'll have special sections that permit server parameters to be set.
2705 Returns True on success, False on failure.
2706 ***************************************************************************/
2708 static BOOL do_section(const char *pszSectionName)
2711 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2712 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2715 /* if we've just struck a global section, note the fact. */
2716 bInGlobalSection = isglobal;
2718 /* check for multiple global sections */
2719 if (bInGlobalSection) {
2720 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2724 if (!bInGlobalSection && bGlobalOnly)
2727 /* if we have a current service, tidy it up before moving on */
2730 if (iServiceIndex >= 0)
2731 bRetval = service_ok(iServiceIndex);
2733 /* if all is still well, move to the next record in the services array */
2735 /* We put this here to avoid an odd message order if messages are */
2736 /* issued by the post-processing of a previous section. */
2737 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2739 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2741 DEBUG(0, ("Failed to add a new service\n"));
2750 /***************************************************************************
2751 Determine if a partcular base parameter is currentl set to the default value.
2752 ***************************************************************************/
2754 static BOOL is_default(int i)
2756 if (!defaults_saved)
2758 switch (parm_table[i].type) {
2760 return str_list_compare (parm_table[i].def.lvalue,
2761 *(char ***)parm_table[i].ptr);
2764 return strequal(parm_table[i].def.svalue,
2765 *(char **)parm_table[i].ptr);
2768 return parm_table[i].def.bvalue ==
2769 *(BOOL *)parm_table[i].ptr;
2771 return parm_table[i].def.cvalue ==
2772 *(char *)parm_table[i].ptr;
2776 return parm_table[i].def.ivalue ==
2777 *(int *)parm_table[i].ptr;
2784 /***************************************************************************
2785 Display the contents of the global structure.
2786 ***************************************************************************/
2788 static void dump_globals(FILE *f)
2791 struct param_opt *data;
2793 fprintf(f, "# Global parameters\n[global]\n");
2795 for (i = 0; parm_table[i].label; i++)
2796 if (parm_table[i].class == P_GLOBAL &&
2797 parm_table[i].ptr &&
2798 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2799 if (defaults_saved && is_default(i))
2801 fprintf(f, "\t%s = ", parm_table[i].label);
2802 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2805 if (Globals.param_opt != NULL) {
2806 data = Globals.param_opt;
2808 fprintf(f, "\t%s = %s\n", data->key, data->value);
2815 /***************************************************************************
2816 Return True if a local parameter is currently set to the global default.
2817 ***************************************************************************/
2819 BOOL lp_is_default(int snum, struct parm_struct *parm)
2821 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
2823 return equal_parameter(parm->type,
2824 ((char *)ServicePtrs[snum]) + pdiff,
2825 ((char *)&sDefault) + pdiff);
2828 /***************************************************************************
2829 Display the contents of a single services record.
2830 ***************************************************************************/
2832 static void dump_a_service(service * pService, FILE * f)
2835 struct param_opt *data;
2837 if (pService != &sDefault)
2838 fprintf(f, "\n[%s]\n", pService->szService);
2840 for (i = 0; parm_table[i].label; i++)
2841 if (parm_table[i].class == P_LOCAL &&
2842 parm_table[i].ptr &&
2843 (*parm_table[i].label != '-') &&
2844 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2845 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2847 if (pService == &sDefault) {
2848 if (defaults_saved && is_default(i))
2851 if (equal_parameter(parm_table[i].type,
2852 ((char *)pService) +
2854 ((char *)&sDefault) +
2859 fprintf(f, "\t%s = ", parm_table[i].label);
2860 print_parameter(&parm_table[i],
2861 ((char *)pService) + pdiff, f);
2864 if (pService->param_opt != NULL) {
2865 data = pService->param_opt;
2867 fprintf(f, "\t%s = %s\n", data->key, data->value);
2874 /***************************************************************************
2875 Return info about the next service in a service. snum==-1 gives the globals.
2876 Return NULL when out of parameters.
2877 ***************************************************************************/
2879 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2882 /* do the globals */
2883 for (; parm_table[*i].label; (*i)++) {
2884 if (parm_table[*i].class == P_SEPARATOR)
2885 return &parm_table[(*i)++];
2887 if (!parm_table[*i].ptr
2888 || (*parm_table[*i].label == '-'))
2892 && (parm_table[*i].ptr ==
2893 parm_table[(*i) - 1].ptr))
2896 return &parm_table[(*i)++];
2899 service *pService = ServicePtrs[snum];
2901 for (; parm_table[*i].label; (*i)++) {
2902 if (parm_table[*i].class == P_SEPARATOR)
2903 return &parm_table[(*i)++];
2905 if (parm_table[*i].class == P_LOCAL &&
2906 parm_table[*i].ptr &&
2907 (*parm_table[*i].label != '-') &&
2909 (parm_table[*i].ptr !=
2910 parm_table[(*i) - 1].ptr)))
2913 PTR_DIFF(parm_table[*i].ptr,
2916 if (allparameters ||
2917 !equal_parameter(parm_table[*i].type,
2918 ((char *)pService) +
2920 ((char *)&sDefault) +
2923 return &parm_table[(*i)++];
2934 /***************************************************************************
2935 Display the contents of a single copy structure.
2936 ***************************************************************************/
2937 static void dump_copy_map(BOOL *pcopymap)
2943 printf("\n\tNon-Copied parameters:\n");
2945 for (i = 0; parm_table[i].label; i++)
2946 if (parm_table[i].class == P_LOCAL &&
2947 parm_table[i].ptr && !pcopymap[i] &&
2948 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2950 printf("\t\t%s\n", parm_table[i].label);
2955 /***************************************************************************
2956 Return TRUE if the passed service number is within range.
2957 ***************************************************************************/
2959 BOOL lp_snum_ok(int iService)
2961 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2964 /***************************************************************************
2965 Auto-load some home services.
2966 ***************************************************************************/
2968 static void lp_add_auto_services(char *str)
2981 homes = lp_servicenumber(HOMES_NAME);
2983 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
2984 char *home = get_user_home_dir(p);
2986 if (lp_servicenumber(p) >= 0)
2989 if (home && homes >= 0)
2990 lp_add_home(p, homes, p, home);
2995 /***************************************************************************
2996 Auto-load one printer.
2997 ***************************************************************************/
2999 void lp_add_one_printer(char *name, char *comment)
3001 int printers = lp_servicenumber(PRINTERS_NAME);
3004 if (lp_servicenumber(name) < 0) {
3005 lp_add_printer(name, printers);
3006 if ((i = lp_servicenumber(name)) >= 0) {
3007 string_set(&ServicePtrs[i]->comment, comment);
3008 ServicePtrs[i]->autoloaded = True;
3013 /***************************************************************************
3014 Announce ourselves as a print server.
3015 ***************************************************************************/
3017 void update_server_announce_as_printserver(void)
3019 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3022 /***************************************************************************
3023 Have we loaded a services file yet?
3024 ***************************************************************************/
3026 BOOL lp_loaded(void)
3031 /***************************************************************************
3032 Unload unused services.
3033 ***************************************************************************/
3035 void lp_killunused(struct server_context *smb, BOOL (*snumused) (struct server_context *, int))
3038 for (i = 0; i < iNumServices; i++) {
3042 if (!snumused || !snumused(smb, i)) {
3043 ServicePtrs[i]->valid = False;
3044 free_service(ServicePtrs[i]);
3049 /***************************************************************************
3051 ***************************************************************************/
3053 void lp_killservice(int iServiceIn)
3055 if (VALID(iServiceIn)) {
3056 ServicePtrs[iServiceIn]->valid = False;
3057 free_service(ServicePtrs[iServiceIn]);
3061 /***************************************************************************
3062 Save the curent values of all global and sDefault parameters into the
3063 defaults union. This allows swat and testparm to show only the
3064 changed (ie. non-default) parameters.
3065 ***************************************************************************/
3067 static void lp_save_defaults(void)
3070 for (i = 0; parm_table[i].label; i++) {
3071 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3073 switch (parm_table[i].type) {
3075 str_list_copy(&(parm_table[i].def.lvalue),
3076 *(const char ***)parm_table[i].ptr);
3080 if (parm_table[i].ptr) {
3081 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
3083 parm_table[i].def.svalue = NULL;
3088 parm_table[i].def.bvalue =
3089 *(BOOL *)parm_table[i].ptr;
3092 parm_table[i].def.cvalue =
3093 *(char *)parm_table[i].ptr;
3098 parm_table[i].def.ivalue =
3099 *(int *)parm_table[i].ptr;
3105 defaults_saved = True;
3108 /*******************************************************************
3109 Set the server type we will announce as via nmbd.
3110 ********************************************************************/
3112 static void set_server_role(void)
3114 server_role = ROLE_STANDALONE;
3116 switch (lp_security()) {
3118 if (lp_domain_logons())
3119 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3124 if (lp_domain_logons()) {
3125 server_role = ROLE_DOMAIN_PDC;
3128 server_role = ROLE_DOMAIN_MEMBER;
3131 if (lp_domain_logons()) {
3133 if (Globals.bDomainMaster) /* auto or yes */
3134 server_role = ROLE_DOMAIN_PDC;
3136 server_role = ROLE_DOMAIN_BDC;
3140 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3144 DEBUG(10, ("set_server_role: role = "));
3146 switch(server_role) {
3147 case ROLE_STANDALONE:
3148 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3150 case ROLE_DOMAIN_MEMBER:
3151 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3153 case ROLE_DOMAIN_BDC:
3154 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3156 case ROLE_DOMAIN_PDC:
3157 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3162 /***************************************************************************
3163 Load the services array from the services file. Return True on success,
3165 ***************************************************************************/
3167 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3172 struct param_opt *data;
3174 pstrcpy(n2, pszFname);
3175 standard_sub_basic(n2,sizeof(n2));
3177 add_to_file_list(pszFname, n2);
3181 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3183 bInGlobalSection = True;
3184 bGlobalOnly = global_only;
3193 if (Globals.param_opt != NULL) {
3194 struct param_opt *next;
3195 for (data=Globals.param_opt; data; data=next) {
3197 if (data->flags & FLAG_CMDLINE) continue;
3200 DLIST_REMOVE(Globals.param_opt, data);
3205 /* We get sections first, so have to start 'behind' to make up */
3207 bRetval = pm_process(n2, do_section, do_parameter);
3209 /* finish up the last section */
3210 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3212 if (iServiceIndex >= 0)
3213 bRetval = service_ok(iServiceIndex);
3215 lp_add_auto_services(lp_auto_services());
3218 /* When 'restrict anonymous = 2' guest connections to ipc$
3220 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3221 lp_add_ipc("ADMIN$", False);
3225 set_default_server_announce_type();
3229 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3230 /* if bWINSsupport is true and we are in the client */
3231 if (in_client && Globals.bWINSsupport) {
3232 lp_do_parameter(-1, "wins server", "127.0.0.1");
3240 /***************************************************************************
3241 Reset the max number of services.
3242 ***************************************************************************/
3244 void lp_resetnumservices(void)
3249 /***************************************************************************
3250 Return the max number of services.
3251 ***************************************************************************/
3253 int lp_numservices(void)
3255 return (iNumServices);
3258 /***************************************************************************
3259 Display the contents of the services array in human-readable form.
3260 ***************************************************************************/
3262 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3267 defaults_saved = False;
3271 dump_a_service(&sDefault, f);
3273 for (iService = 0; iService < maxtoprint; iService++)
3274 lp_dump_one(f, show_defaults, iService);
3277 /***************************************************************************
3278 Display the contents of one service in human-readable form.
3279 ***************************************************************************/
3281 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3284 if (ServicePtrs[snum]->szService[0] == '\0')
3286 dump_a_service(ServicePtrs[snum], f);
3290 /***************************************************************************
3291 Return the number of the service with the given name, or -1 if it doesn't
3292 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3293 getservicebyname()! This works ONLY if all services have been loaded, and
3294 does not copy the found service.
3295 ***************************************************************************/
3297 int lp_servicenumber(const char *pszServiceName)
3300 fstring serviceName;
3303 for (iService = iNumServices - 1; iService >= 0; iService--) {
3304 if (VALID(iService) && ServicePtrs[iService]->szService) {
3306 * The substitution here is used to support %U is
3309 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3310 standard_sub_basic(serviceName,sizeof(serviceName));
3311 if (strequal(serviceName, pszServiceName))
3317 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3322 /*******************************************************************
3323 A useful volume label function.
3324 ********************************************************************/
3325 char *volume_label(int snum)
3327 char *ret = lp_volume(snum);
3329 return lp_servicename(snum);
3334 /*******************************************************************
3335 Set the server type we will announce as via nmbd.
3336 ********************************************************************/
3338 static void set_default_server_announce_type(void)
3340 default_server_announce = 0;
3341 default_server_announce |= SV_TYPE_WORKSTATION;
3342 default_server_announce |= SV_TYPE_SERVER;
3343 default_server_announce |= SV_TYPE_SERVER_UNIX;
3345 switch (lp_announce_as()) {
3346 case ANNOUNCE_AS_NT_SERVER:
3347 default_server_announce |= SV_TYPE_SERVER_NT;
3348 /* fall through... */
3349 case ANNOUNCE_AS_NT_WORKSTATION:
3350 default_server_announce |= SV_TYPE_NT;
3352 case ANNOUNCE_AS_WIN95:
3353 default_server_announce |= SV_TYPE_WIN95_PLUS;
3355 case ANNOUNCE_AS_WFW:
3356 default_server_announce |= SV_TYPE_WFW;
3362 switch (lp_server_role()) {
3363 case ROLE_DOMAIN_MEMBER:
3364 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3366 case ROLE_DOMAIN_PDC:
3367 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3369 case ROLE_DOMAIN_BDC:
3370 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3372 case ROLE_STANDALONE:
3376 if (lp_time_server())
3377 default_server_announce |= SV_TYPE_TIME_SOURCE;
3379 if (lp_host_msdfs())
3380 default_server_announce |= SV_TYPE_DFS_SERVER;
3383 /***********************************************************
3384 returns role of Samba server
3385 ************************************************************/
3387 int lp_server_role(void)
3392 /***********************************************************
3393 If we are PDC then prefer us as DMB
3394 ************************************************************/
3396 BOOL lp_domain_master(void)
3398 if (Globals.bDomainMaster == Auto)
3399 return (lp_server_role() == ROLE_DOMAIN_PDC);
3401 return Globals.bDomainMaster;
3404 /***********************************************************
3405 If we are DMB then prefer us as LMB
3406 ************************************************************/
3408 BOOL lp_preferred_master(void)
3410 if (Globals.bPreferredMaster == Auto)
3411 return (lp_local_master() && lp_domain_master());
3413 return Globals.bPreferredMaster;
3416 /*******************************************************************
3418 ********************************************************************/
3420 void lp_remove_service(int snum)
3422 ServicePtrs[snum]->valid = False;
3425 /*******************************************************************
3427 ********************************************************************/
3429 void lp_copy_service(int snum, const char *new_name)
3431 char *oldname = lp_servicename(snum);
3432 do_section(new_name);
3434 snum = lp_servicenumber(new_name);
3436 lp_do_parameter(snum, "copy", oldname);
3441 /*******************************************************************
3442 Get the default server type we will announce as via nmbd.
3443 ********************************************************************/
3445 int lp_default_server_announce(void)
3447 return default_server_announce;
3450 /*******************************************************************
3451 Split the announce version into major and minor numbers.
3452 ********************************************************************/
3454 int lp_major_announce_version(void)
3456 static BOOL got_major = False;
3457 static int major_version = DEFAULT_MAJOR_VERSION;
3462 return major_version;
3465 if ((vers = lp_announce_version()) == NULL)
3466 return major_version;
3468 if ((p = strchr_m(vers, '.')) == 0)
3469 return major_version;
3472 major_version = atoi(vers);
3473 return major_version;
3476 int lp_minor_announce_version(void)
3478 static BOOL got_minor = False;
3479 static int minor_version = DEFAULT_MINOR_VERSION;
3484 return minor_version;
3487 if ((vers = lp_announce_version()) == NULL)
3488 return minor_version;
3490 if ((p = strchr_m(vers, '.')) == 0)
3491 return minor_version;
3494 minor_version = atoi(p);
3495 return minor_version;
3498 const char *lp_printername(int snum)
3500 const char *ret = _lp_printername(snum);
3501 if (ret == NULL || (ret != NULL && *ret == '\0'))
3502 ret = lp_const_servicename(snum);
3508 /*******************************************************************
3509 Return the max print jobs per queue.
3510 ********************************************************************/
3512 int lp_maxprintjobs(int snum)
3514 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3515 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3516 maxjobs = PRINT_MAX_JOBID - 1;