2 Unix SMB/Netbios implementation.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993-1998
7 Largely re-written by Andrew Tridgell, September 1994
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * This module provides suitable callback functions for the params
28 * module. It builds the internal table of service details which is
29 * then used by the rest of the server.
33 * 1) add it to the global or service structure definition
34 * 2) add it to the parm_table
35 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
36 * 4) If it's a global then initialise it in init_globals. If a local
37 * (ie. service) parameter then initialise it in the sDefault structure
41 * The configuration file is processed sequentially for speed. It is NOT
42 * accessed randomly as happens in 'real' Windows. For this reason, there
43 * is a fair bit of sequence-dependent code here - ie., code which assumes
44 * that certain things happen before others. In particular, the code which
45 * happens at the boundary between sections is delicately poised, so be
52 /* Set default coding system for KANJI if none specified in Makefile. */
54 * We treat KANJI specially due to historical precedent (it was the
55 * first non-english codepage added to Samba). With the new dynamic
56 * codepage support this is not needed anymore.
58 * The define 'KANJI' is being overloaded to mean 'use kanji codepage
59 * by default' and also 'this is the filename-to-disk conversion
60 * method to use'. This really should be removed and all control
61 * over this left in the smb.conf parameters 'client codepage'
62 * and 'coding system'.
70 extern int DEBUGLEVEL;
71 extern pstring user_socket_options;
72 extern pstring global_myname;
75 #define GLOBAL_NAME "global"
79 #define PRINTERS_NAME "printers"
83 #define HOMES_NAME "homes"
86 /* some helpful bits */
87 #define pSERVICE(i) ServicePtrs[i]
88 #define iSERVICE(i) (*pSERVICE(i))
89 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
90 #define VALID(i) iSERVICE(i).valid
92 int keepalive=DEFAULT_KEEPALIVE;
93 extern BOOL use_getwd_cache;
95 extern int extra_time_offset;
97 static BOOL defaults_saved=False;
100 * This structure describes global (ie., server-wide) parameters.
104 char *szPrintcapname;
107 char *szDefaultService;
111 char *szServerString;
112 char *szAutoServices;
113 char *szPasswdProgram;
117 char *szSMBPasswdFile;
118 char *szPasswordServer;
119 char *szSocketOptions;
122 char *szDomainAdminUsers;
123 char *szDomainGuestUsers;
124 char *szDomainHostsallow;
125 char *szDomainHostsdeny;
127 char *szCharacterSet;
134 char *szCodingSystem;
136 char *szRemoteAnnounce;
137 char *szRemoteBrowseSync;
138 char *szSocketAddress;
139 char *szNISHomeMapName;
140 char *szAnnounceVersion; /* This is initialised in init_globals */
141 char *szNetbiosAliases;
143 char *szDomainOtherSIDs;
144 char *szDomainGroups;
146 char *szNameResolveOrder;
168 int client_code_page;
169 int announce_as; /* This is initialised in init_globals */
174 BOOL bPreferredMaster;
175 BOOL bDomainController;
178 BOOL bEncryptPasswords;
185 BOOL bReadPrediction;
192 BOOL bBindInterfacesOnly;
193 BOOL bNetWkstaUserLogon;
194 BOOL bUnixPasswdSync;
195 BOOL bPasswdChatDebug;
198 static global Globals;
203 * This structure describes a single service.
211 char *szGuestaccount;
212 char *szInvalidUsers;
220 char *szRootPostExec;
221 char *szPrintcommand;
224 char *szLppausecommand;
225 char *szLpresumecommand;
227 char *szPrinterDriver;
228 char *szPrinterDriverLocation;
237 char *szVetoOplockFiles;
246 int iCreate_force_mode;
256 BOOL bShortCasePreserve;
282 BOOL bDeleteReadonly;
284 BOOL bDeleteVetoFiles;
286 BOOL bDosFiletimeResolution;
287 BOOL bFakeDirCreateTimes;
288 char dummy[3]; /* for alignment */
292 /* This is a default service used to prime a services structure */
293 static service sDefault =
296 NULL, /* szService */
298 NULL, /* szUsername */
299 NULL, /* szGuestAccount - this is set in init_globals() */
300 NULL, /* szInvalidUsers */
301 NULL, /* szValidUsers */
302 NULL, /* szAdminUsers */
304 NULL, /* szInclude */
305 NULL, /* szPreExec */
306 NULL, /* szPostExec */
307 NULL, /* szRootPreExec */
308 NULL, /* szRootPostExec */
309 NULL, /* szPrintcommand */
310 NULL, /* szLpqcommand */
311 NULL, /* szLprmcommand */
312 NULL, /* szLppausecommand */
313 NULL, /* szLpresumecommand */
314 NULL, /* szPrintername */
315 NULL, /* szPrinterDriver - this is set in init_globals() */
316 NULL, /* szPrinterDriverLocation */
317 NULL, /* szDontdescend */
318 NULL, /* szHostsallow */
319 NULL, /* szHostsdeny */
320 NULL, /* szMagicScript */
321 NULL, /* szMagicOutput */
322 NULL, /* szMangledMap */
323 NULL, /* szVetoFiles */
324 NULL, /* szHideFiles */
325 NULL, /* szVetoOplockFiles */
327 NULL, /* force user */
328 NULL, /* force group */
330 NULL, /* writelist */
332 0, /* iMinPrintSpace */
333 0744, /* iCreate_mask */
334 0000, /* iCreate_force_mode */
335 0755, /* iDir_mask */
336 0000, /* iDir_force_mode */
337 0, /* iMaxConnections */
338 CASE_LOWER, /* iDefaultCase */
339 DEFAULT_PRINTING, /* iPrinting */
340 False, /* bAlternatePerm */
341 False, /* revalidate */
342 False, /* case sensitive */
343 False, /* case preserve */
344 False, /* short case preserve */
345 False, /* case mangle */
347 True, /* bHideDotFiles */
348 True, /* bBrowseable */
349 True, /* bAvailable */
350 True, /* bRead_only */
351 True, /* bNo_set_dir */
352 False, /* bGuest_only */
353 False, /* bGuest_ok */
354 False, /* bPrint_ok */
355 False, /* bPostscript */
356 False, /* bMap_system */
357 False, /* bMap_hidden */
358 True, /* bMap_archive */
360 False, /* bStrictLocking */
361 True, /* bShareModes */
363 False, /* bOnlyUser */
364 True, /* bMangledNames */
365 True, /* bWidelinks */
366 True, /* bSymlinks */
367 False, /* bSyncAlways */
368 '~', /* magic char */
370 False, /* bDeleteReadonly */
371 False, /* bFakeOplocks */
372 False, /* bDeleteVetoFiles */
373 False, /* bDosFiletimes */
374 False, /* bDosFiletimeResolution */
375 False, /* bFakeDirCreateTimes */
381 /* local variables */
382 static service **ServicePtrs = NULL;
383 static int iNumServices = 0;
384 static int iServiceIndex = 0;
385 static BOOL bInGlobalSection = True;
386 static BOOL bGlobalOnly = False;
387 static int default_server_announce;
389 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
391 /* prototypes for the special type handlers */
392 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
393 static BOOL handle_include(char *pszParmValue, char **ptr);
394 static BOOL handle_copy(char *pszParmValue, char **ptr);
395 static BOOL handle_character_set(char *pszParmValue,char **ptr);
396 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
398 static void set_default_server_announce_type(void);
400 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
401 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
402 {PROTOCOL_COREPLUS, "COREPLUS"},
403 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
405 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
406 {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
409 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
410 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
411 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
412 {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
415 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
416 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
418 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
420 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
422 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
423 static struct parm_struct parm_table[] =
425 {"Base Options", P_SEP, P_SEPARATOR},
426 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
427 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
428 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
429 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
430 {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC},
431 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
432 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
433 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
434 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
436 {"Security Options", P_SEP, P_SEPARATOR},
437 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
438 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
439 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
440 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
441 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
442 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
443 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
444 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
445 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
446 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
447 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
448 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
449 {"passwd chat debug",P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0},
450 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
451 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
452 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
453 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
454 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL},
455 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
456 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
457 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
458 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
459 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
460 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
461 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
462 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
463 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
464 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
465 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
466 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
467 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
468 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
469 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
470 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
471 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
472 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
473 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
474 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
475 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
476 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
477 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
478 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
479 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
480 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
481 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
482 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
483 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
484 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
485 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
486 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
488 {"Logging Options", P_SEP, P_SEPARATOR},
489 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
490 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
491 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
492 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
493 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
494 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
495 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
497 {"Protocol Options", P_SEP, P_SEPARATOR},
498 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
499 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
500 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
501 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
502 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
503 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
504 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
505 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
506 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
507 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
508 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
509 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
510 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
511 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
512 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
513 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
515 {"Tuning Options", P_SEP, P_SEPARATOR},
516 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
517 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
518 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
519 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
520 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
521 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
522 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
523 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
524 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
525 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
526 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
527 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
529 {"Printing Options", P_SEP, P_SEPARATOR},
530 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
531 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
532 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
533 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
534 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
535 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
536 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
537 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
538 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
539 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
540 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
541 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
542 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
543 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
544 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
545 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
546 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
549 {"Filename Handling", P_SEP, P_SEPARATOR},
550 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
551 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
552 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
553 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
554 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
555 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
556 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
557 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
558 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
559 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
560 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
561 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
562 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
563 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
564 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
565 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
566 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
567 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
568 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
569 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
570 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
571 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
573 {"Domain Options", P_SEP, P_SEPARATOR},
574 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
575 {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL, 0},
576 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
577 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
578 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
579 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
580 {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
581 {"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
582 {"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
583 {"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
585 {"Logon Options", P_SEP, P_SEPARATOR},
586 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
587 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
588 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
589 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
590 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
592 {"Browse Options", P_SEP, P_SEPARATOR},
593 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, 0},
594 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
595 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
596 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
597 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
598 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, 0},
599 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, 0},
600 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
601 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
602 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
604 {"WINS Options", P_SEP, P_SEPARATOR},
605 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
606 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
607 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
608 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
610 {"Locking Options", P_SEP, P_SEPARATOR},
611 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
612 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
613 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
614 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
615 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
617 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
618 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
619 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
620 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
621 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
622 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
623 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
624 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
625 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
626 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
627 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
628 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
629 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
630 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
631 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
632 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
633 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
634 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
635 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
636 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
637 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
638 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
639 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
640 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
641 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
642 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
643 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
644 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
645 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
646 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
647 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
648 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
649 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
650 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
651 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
652 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
653 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
654 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
656 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
657 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
662 /***************************************************************************
663 Initialise the global parameter structure.
664 ***************************************************************************/
665 static void init_globals(void)
667 static BOOL done_init = False;
673 bzero((void *)&Globals,sizeof(Globals));
675 for (i = 0; parm_table[i].label; i++)
676 if ((parm_table[i].type == P_STRING ||
677 parm_table[i].type == P_USTRING) &&
679 string_init(parm_table[i].ptr,"");
681 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
682 string_set(&sDefault.szPrinterDriver, "NULL");
688 DEBUG(3,("Initialising global parameters\n"));
690 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
691 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
692 string_set(&Globals.szWorkGroup, WORKGROUP);
693 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
694 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
695 string_set(&Globals.szDriverFile, DRIVERFILE);
696 string_set(&Globals.szLockDir, LOCKDIR);
697 string_set(&Globals.szRootdir, "/");
698 string_set(&Globals.szSmbrun, SMBRUN);
699 string_set(&Globals.szSocketAddress, "0.0.0.0");
700 sprintf(s,"Samba %s",VERSION);
701 string_set(&Globals.szServerString,s);
702 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
703 string_set(&Globals.szAnnounceVersion,s);
705 string_set(&Globals.szLogonDrive, "");
706 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
707 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
708 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
710 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
712 Globals.bLoadPrinters = True;
713 Globals.bUseRhosts = False;
714 Globals.max_packet = 65535;
715 Globals.mangled_stack = 50;
716 Globals.max_xmit = 65535;
717 Globals.max_mux = 50; /* This is *needed* for profile support. */
718 Globals.lpqcachetime = 10;
719 Globals.pwordlevel = 0;
720 Globals.unamelevel = 0;
721 Globals.deadtime = 0;
722 Globals.max_log_size = 5000;
723 Globals.maxprotocol = PROTOCOL_NT1;
724 Globals.security = SEC_SHARE;
725 Globals.bEncryptPasswords = False;
726 Globals.bReadRaw = True;
727 Globals.bWriteRaw = True;
728 Globals.bReadPrediction = False;
729 Globals.bReadbmpx = True;
730 Globals.bNullPasswords = False;
731 Globals.bStripDot = False;
733 Globals.bSyslogOnly = False;
734 Globals.os_level = 0;
735 Globals.max_ttl = 60*60*4; /* 4 hours default */
736 Globals.max_wins_ttl = 60*60*24*3; /* 3 days default */
737 Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
738 Globals.ReadSize = 16*1024;
739 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
740 Globals.lm_interval = 60;
741 Globals.shmem_size = SHMEM_SIZE;
742 Globals.announce_as = ANNOUNCE_AS_NT;
743 Globals.bUnixRealname = False;
744 #if (defined(NETGROUP) && defined(AUTOMOUNT))
745 Globals.bNISHomeMap = False;
747 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
749 string_set(&Globals.szNISHomeMapName, "auto.home");
752 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
753 Globals.bTimeServer = False;
754 Globals.bBindInterfacesOnly = False;
755 Globals.bNetWkstaUserLogon = True;
756 Globals.bUnixPasswdSync = False;
757 Globals.bPasswdChatDebug = False;
759 /* these parameters are set to defaults that are more appropriate
760 for the increasing samba install base:
762 as a member of the workgroup, that will possibly become a
763 _local_ master browser (lm = True). this is opposed to a forced
764 local master browser startup (pm = True).
766 doesn't provide WINS server service by default (wsupp = False),
767 and doesn't provide domain master browser services by default, either.
771 Globals.bPreferredMaster = False;
772 Globals.bLocalMaster = True;
773 Globals.bDomainMaster = False;
774 Globals.bDomainLogons = False;
775 Globals.bBrowseList = True;
776 Globals.bWINSsupport = False;
777 Globals.bWINSproxy = False;
779 Globals.bDNSproxy = True;
782 * This must be done last as it checks the value in
786 interpret_coding_system(KANJI);
789 /***************************************************************************
790 check if a string is initialised and if not then initialise it
791 ***************************************************************************/
792 static void string_initial(char **s,char *v)
799 /***************************************************************************
800 Initialise the sDefault parameter structure.
801 ***************************************************************************/
802 static void init_locals(void)
804 /* choose defaults depending on the type of printing */
805 switch (sDefault.iPrinting)
811 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
812 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
813 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
818 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
819 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
820 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
822 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
823 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
828 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
829 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
830 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
834 string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
835 string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
836 string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
837 string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
838 string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
845 /******************************************************************* a
846 convenience routine to grab string parameters into a rotating buffer,
847 and run standard_sub_basic on them. The buffers can be written to by
848 callers without affecting the source string.
849 ********************************************************************/
850 char *lp_string(char *s)
852 static char *bufs[10];
853 static int buflen[10];
854 static int next = -1;
857 int len = s?strlen(s):0;
868 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
871 if (buflen[next] != len) {
873 if (bufs[next]) free(bufs[next]);
874 bufs[next] = (char *)malloc(len);
876 DEBUG(0,("out of memory in lp_string()"));
881 ret = &bufs[next][0];
889 trim_string(ret, "\"", "\"");
891 standard_sub_basic(ret);
897 In this section all the functions that are used to access the
898 parameters from the rest of the program are defined
901 #define FN_GLOBAL_STRING(fn_name,ptr) \
902 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
903 #define FN_GLOBAL_BOOL(fn_name,ptr) \
904 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
905 #define FN_GLOBAL_CHAR(fn_name,ptr) \
906 char fn_name(void) {return(*(char *)(ptr));}
907 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
908 int fn_name(void) {return(*(int *)(ptr));}
910 #define FN_LOCAL_STRING(fn_name,val) \
911 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
912 #define FN_LOCAL_BOOL(fn_name,val) \
913 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
914 #define FN_LOCAL_CHAR(fn_name,val) \
915 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
916 #define FN_LOCAL_INTEGER(fn_name,val) \
917 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
919 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
920 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
921 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
922 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
923 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
924 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
925 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
926 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
927 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
928 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
929 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
930 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
931 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
932 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
933 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
934 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
935 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
936 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
937 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
938 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
939 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
940 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
941 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
942 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
943 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
944 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
945 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
946 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
947 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
948 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
949 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
950 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
951 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
953 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
954 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
955 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
956 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
957 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
958 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
959 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
961 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
962 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
963 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
964 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
965 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
966 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
967 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
968 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
969 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
970 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
971 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
972 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
973 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
974 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
975 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
976 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
977 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
978 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
979 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
980 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
981 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
982 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
983 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
984 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
985 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
986 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
987 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
988 FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
990 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
991 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
992 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
993 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
994 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
995 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
996 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
997 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
998 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
999 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
1000 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
1001 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
1002 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
1003 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
1004 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
1005 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
1006 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
1007 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
1008 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
1009 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
1010 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
1011 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
1012 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
1013 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
1015 FN_LOCAL_STRING(lp_preexec,szPreExec)
1016 FN_LOCAL_STRING(lp_postexec,szPostExec)
1017 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
1018 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
1019 FN_LOCAL_STRING(lp_servicename,szService)
1020 FN_LOCAL_STRING(lp_pathname,szPath)
1021 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1022 FN_LOCAL_STRING(lp_username,szUsername)
1023 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1024 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1025 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1026 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1027 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1028 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1029 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1030 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1031 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1032 FN_LOCAL_STRING(lp_printername,szPrintername)
1033 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1034 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1035 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1036 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1037 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1038 FN_LOCAL_STRING(lp_comment,comment)
1039 FN_LOCAL_STRING(lp_force_user,force_user)
1040 FN_LOCAL_STRING(lp_force_group,force_group)
1041 FN_LOCAL_STRING(lp_readlist,readlist)
1042 FN_LOCAL_STRING(lp_writelist,writelist)
1043 FN_LOCAL_STRING(lp_volume,volume)
1044 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1045 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1046 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1047 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1048 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1050 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
1051 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1052 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1053 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1054 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1055 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1056 FN_LOCAL_BOOL(lp_status,status)
1057 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1058 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1059 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1060 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1061 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1062 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1063 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1064 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1065 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1066 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1067 FN_LOCAL_BOOL(lp_locking,bLocking)
1068 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1069 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1070 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1071 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1072 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1073 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1074 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1075 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1076 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1077 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1078 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1079 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1080 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1081 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1082 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1084 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1085 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1086 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1087 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1088 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1089 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1090 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1091 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1093 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1097 /* local prototypes */
1098 static int strwicmp( char *psz1, char *psz2 );
1099 static int map_parameter( char *pszParmName);
1100 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1101 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1102 static void copy_service( service *pserviceDest,
1103 service *pserviceSource,
1104 BOOL *pcopymapDest );
1105 static BOOL service_ok(int iService);
1106 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1107 static BOOL do_section(char *pszSectionName);
1108 static void init_copymap(service *pservice);
1111 /***************************************************************************
1112 initialise a service to the defaults
1113 ***************************************************************************/
1114 static void init_service(service *pservice)
1116 bzero((char *)pservice,sizeof(service));
1117 copy_service(pservice,&sDefault,NULL);
1121 /***************************************************************************
1122 free the dynamically allocated parts of a service struct
1123 ***************************************************************************/
1124 static void free_service(service *pservice)
1130 if(pservice->szService)
1131 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1133 string_free(&pservice->szService);
1134 if (pservice->copymap)
1136 free(pservice->copymap);
1137 pservice->copymap = NULL;
1140 for (i=0;parm_table[i].label;i++)
1141 if ((parm_table[i].type == P_STRING ||
1142 parm_table[i].type == P_USTRING) &&
1143 parm_table[i].class == P_LOCAL)
1144 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1147 /***************************************************************************
1148 add a new service to the services array initialising it with the given
1150 ***************************************************************************/
1151 static int add_a_service(service *pservice, char *name)
1155 int num_to_alloc = iNumServices+1;
1157 tservice = *pservice;
1159 /* it might already exist */
1162 i = getservicebyname(name,NULL);
1167 /* find an invalid one */
1168 for (i=0;i<iNumServices;i++)
1169 if (!pSERVICE(i)->valid)
1172 /* if not, then create one */
1173 if (i == iNumServices)
1175 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1177 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1179 if (!ServicePtrs || !pSERVICE(iNumServices))
1185 free_service(pSERVICE(i));
1187 pSERVICE(i)->valid = True;
1189 init_service(pSERVICE(i));
1190 copy_service(pSERVICE(i),&tservice,NULL);
1192 string_set(&iSERVICE(i).szService,name);
1197 /***************************************************************************
1198 add a new home service, with the specified home directory, defaults coming
1200 ***************************************************************************/
1201 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1203 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1208 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1209 string_set(&iSERVICE(i).szPath,pszHomedir);
1210 if (!(*(iSERVICE(i).comment)))
1213 sprintf(comment,"Home directory of %s",pszHomename);
1214 string_set(&iSERVICE(i).comment,comment);
1216 iSERVICE(i).bAvailable = sDefault.bAvailable;
1217 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1219 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1224 /***************************************************************************
1225 add a new service, based on an old one
1226 ***************************************************************************/
1227 int lp_add_service(char *pszService, int iDefaultService)
1229 return(add_a_service(pSERVICE(iDefaultService),pszService));
1233 /***************************************************************************
1235 ***************************************************************************/
1236 static BOOL lp_add_ipc(void)
1239 int i = add_a_service(&sDefault,"IPC$");
1244 sprintf(comment,"IPC Service (%s)", Globals.szServerString );
1246 string_set(&iSERVICE(i).szPath,tmpdir());
1247 string_set(&iSERVICE(i).szUsername,"");
1248 string_set(&iSERVICE(i).comment,comment);
1249 iSERVICE(i).status = False;
1250 iSERVICE(i).iMaxConnections = 0;
1251 iSERVICE(i).bAvailable = True;
1252 iSERVICE(i).bRead_only = True;
1253 iSERVICE(i).bGuest_only = False;
1254 iSERVICE(i).bGuest_ok = True;
1255 iSERVICE(i).bPrint_ok = False;
1256 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1258 DEBUG(3,("adding IPC service\n"));
1264 /***************************************************************************
1265 add a new printer service, with defaults coming from service iFrom
1266 ***************************************************************************/
1267 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1269 char *comment = "From Printcap";
1270 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1275 /* note that we do NOT default the availability flag to True - */
1276 /* we take it from the default service passed. This allows all */
1277 /* dynamic printers to be disabled by disabling the [printers] */
1278 /* entry (if/when the 'available' keyword is implemented!). */
1280 /* the printer name is set to the service name. */
1281 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1282 string_set(&iSERVICE(i).comment,comment);
1283 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1284 /* Printers cannot be read_only. */
1285 iSERVICE(i).bRead_only = False;
1286 /* No share modes on printer services. */
1287 iSERVICE(i).bShareModes = False;
1288 /* No oplocks on printer services. */
1289 iSERVICE(i).bOpLocks = False;
1290 /* Printer services must be printable. */
1291 iSERVICE(i).bPrint_ok = True;
1293 DEBUG(3,("adding printer service %s\n",pszPrintername));
1299 /***************************************************************************
1300 Do a case-insensitive, whitespace-ignoring string compare.
1301 ***************************************************************************/
1302 static int strwicmp(char *psz1, char *psz2)
1304 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1305 /* appropriate value. */
1315 /* sync the strings on first non-whitespace */
1318 while (isspace(*psz1))
1320 while (isspace(*psz2))
1322 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1327 return (*psz1 - *psz2);
1330 /***************************************************************************
1331 Map a parameter's string representation to something we can use.
1332 Returns False if the parameter string is not recognised, else TRUE.
1333 ***************************************************************************/
1334 static int map_parameter(char *pszParmName)
1338 if (*pszParmName == '-')
1341 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1342 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1345 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1350 /***************************************************************************
1351 Set a boolean variable from the text value stored in the passed string.
1352 Returns True in success, False if the passed string does not correctly
1353 represent a boolean.
1354 ***************************************************************************/
1355 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1360 if (strwicmp(pszParmValue, "yes") == 0 ||
1361 strwicmp(pszParmValue, "true") == 0 ||
1362 strwicmp(pszParmValue, "1") == 0)
1365 if (strwicmp(pszParmValue, "no") == 0 ||
1366 strwicmp(pszParmValue, "False") == 0 ||
1367 strwicmp(pszParmValue, "0") == 0)
1371 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1378 /***************************************************************************
1379 Find a service by name. Otherwise works like get_service.
1380 ***************************************************************************/
1381 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1385 for (iService = iNumServices - 1; iService >= 0; iService--)
1386 if (VALID(iService) &&
1387 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1389 if (pserviceDest != NULL)
1390 copy_service(pserviceDest, pSERVICE(iService), NULL);
1399 /***************************************************************************
1400 Copy a service structure to another
1402 If pcopymapDest is NULL then copy all fields
1403 ***************************************************************************/
1404 static void copy_service(service *pserviceDest,
1405 service *pserviceSource,
1409 BOOL bcopyall = (pcopymapDest == NULL);
1411 for (i=0;parm_table[i].label;i++)
1412 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1413 (bcopyall || pcopymapDest[i]))
1415 void *def_ptr = parm_table[i].ptr;
1417 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1419 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1421 switch (parm_table[i].type)
1425 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1431 *(int *)dest_ptr = *(int *)src_ptr;
1435 *(char *)dest_ptr = *(char *)src_ptr;
1439 string_set(dest_ptr,*(char **)src_ptr);
1443 string_set(dest_ptr,*(char **)src_ptr);
1444 strupper(*(char **)dest_ptr);
1453 init_copymap(pserviceDest);
1454 if (pserviceSource->copymap)
1455 memcpy((void *)pserviceDest->copymap,
1456 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1460 /***************************************************************************
1461 Check a service for consistency. Return False if the service is in any way
1462 incomplete or faulty, else True.
1463 ***************************************************************************/
1464 static BOOL service_ok(int iService)
1469 if (iSERVICE(iService).szService[0] == '\0')
1471 DEBUG(0,( "The following message indicates an internal error:\n"));
1472 DEBUG(0,( "No service name in service entry.\n"));
1476 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1477 /* I can't see why you'd want a non-printable printer service... */
1478 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1479 if (!iSERVICE(iService).bPrint_ok)
1481 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1482 iSERVICE(iService).szService));
1483 iSERVICE(iService).bPrint_ok = True;
1486 if (iSERVICE(iService).szPath[0] == '\0' &&
1487 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1489 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1490 string_set(&iSERVICE(iService).szPath,tmpdir());
1493 /* If a service is flagged unavailable, log the fact at level 0. */
1494 if (!iSERVICE(iService).bAvailable)
1495 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1496 iSERVICE(iService).szService));
1501 static struct file_lists {
1502 struct file_lists *next;
1505 } *file_lists = NULL;
1507 /*******************************************************************
1508 keep a linked list of all config files so we know when one has changed
1509 it's date and needs to be reloaded
1510 ********************************************************************/
1511 static void add_to_file_list(char *fname)
1513 struct file_lists *f=file_lists;
1516 if (f->name && !strcmp(f->name,fname)) break;
1521 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1523 f->next = file_lists;
1524 f->name = strdup(fname);
1535 standard_sub_basic(n2);
1536 f->modtime = file_modtime(n2);
1541 /*******************************************************************
1542 check if a config file has changed date
1543 ********************************************************************/
1544 BOOL lp_file_list_changed(void)
1546 struct file_lists *f = file_lists;
1547 DEBUG(6,("lp_file_list_changed()\n"));
1554 pstrcpy(n2,f->name);
1555 standard_sub_basic(n2);
1557 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1558 f->name, n2, ctime(&f->modtime)));
1560 mod_time = file_modtime(n2);
1562 if (f->modtime != mod_time) {
1563 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1564 f->modtime = mod_time;
1572 /***************************************************************************
1573 handle the interpretation of the coding system parameter
1574 *************************************************************************/
1575 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1577 string_set(ptr,pszParmValue);
1578 interpret_coding_system(pszParmValue);
1582 /***************************************************************************
1583 handle the interpretation of the character set system parameter
1584 ***************************************************************************/
1585 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1587 string_set(ptr,pszParmValue);
1588 interpret_character_set(pszParmValue);
1593 /***************************************************************************
1594 handle the valid chars lines
1595 ***************************************************************************/
1596 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1598 string_set(ptr,pszParmValue);
1600 /* A dependency here is that the parameter client code page must be
1601 set before this is called - as calling codepage_initialise()
1602 would overwrite the valid char lines.
1604 codepage_initialise(lp_client_code_page());
1606 add_char_string(pszParmValue);
1611 /***************************************************************************
1612 handle the include operation
1613 ***************************************************************************/
1614 static BOOL handle_include(char *pszParmValue,char **ptr)
1617 pstrcpy(fname,pszParmValue);
1619 add_to_file_list(fname);
1621 standard_sub_basic(fname);
1623 string_set(ptr,fname);
1625 if (file_exist(fname,NULL))
1626 return(pm_process(fname, do_section, do_parameter));
1628 DEBUG(2,("Can't find include file %s\n",fname));
1634 /***************************************************************************
1635 handle the interpretation of the copy parameter
1636 ***************************************************************************/
1637 static BOOL handle_copy(char *pszParmValue,char **ptr)
1641 service serviceTemp;
1643 string_set(ptr,pszParmValue);
1645 init_service(&serviceTemp);
1649 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1651 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1653 if (iTemp == iServiceIndex)
1655 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1660 copy_service(pSERVICE(iServiceIndex),
1662 iSERVICE(iServiceIndex).copymap);
1668 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1673 free_service(&serviceTemp);
1678 /***************************************************************************
1679 initialise a copymap
1680 ***************************************************************************/
1681 static void init_copymap(service *pservice)
1684 if (pservice->copymap) free(pservice->copymap);
1685 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1686 if (!pservice->copymap)
1687 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1689 for (i=0;i<NUMPARAMETERS;i++)
1690 pservice->copymap[i] = True;
1694 /***************************************************************************
1695 return the local pointer to a parameter given the service number and the
1696 pointer into the default structure
1697 ***************************************************************************/
1698 void *lp_local_ptr(int snum, void *ptr)
1700 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1703 /***************************************************************************
1704 Process a parameter for a particular service number. If snum < 0
1705 then assume we are in the globals
1706 ***************************************************************************/
1707 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1710 void *parm_ptr=NULL; /* where we are going to store the result */
1713 parmnum = map_parameter(pszParmName);
1717 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1721 def_ptr = parm_table[parmnum].ptr;
1723 /* we might point at a service, the default service or a global */
1727 if (parm_table[parmnum].class == P_GLOBAL) {
1728 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1731 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1735 if (!iSERVICE(snum).copymap)
1736 init_copymap(pSERVICE(snum));
1738 /* this handles the aliases - set the copymap for other entries with
1739 the same data pointer */
1740 for (i=0;parm_table[i].label;i++)
1741 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1742 iSERVICE(snum).copymap[i] = False;
1745 /* if it is a special case then go ahead */
1746 if (parm_table[parmnum].special) {
1747 parm_table[parmnum].special(pszParmValue,(char **)parm_ptr);
1751 /* now switch on the type of variable it is */
1752 switch (parm_table[parmnum].type)
1755 set_boolean(parm_ptr,pszParmValue);
1759 set_boolean(parm_ptr,pszParmValue);
1760 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1764 *(int *)parm_ptr = atoi(pszParmValue);
1768 *(char *)parm_ptr = *pszParmValue;
1772 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1776 string_set(parm_ptr,pszParmValue);
1780 string_set(parm_ptr,pszParmValue);
1781 strupper(*(char **)parm_ptr);
1785 strcpy((char *)parm_ptr,pszParmValue);
1789 strcpy((char *)parm_ptr,pszParmValue);
1790 strupper((char *)parm_ptr);
1794 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1795 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1796 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1808 /***************************************************************************
1809 Process a parameter.
1810 ***************************************************************************/
1811 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1813 if (!bInGlobalSection && bGlobalOnly) return(True);
1815 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1817 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1821 /***************************************************************************
1822 print a parameter of the specified type
1823 ***************************************************************************/
1824 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1829 for (i=0;p->enum_list[i].name;i++) {
1830 if (*(int *)ptr == p->enum_list[i].value) {
1831 fprintf(f,"%s",p->enum_list[i].name);
1838 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1842 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1846 fprintf(f,"%d",*(int *)ptr);
1850 fprintf(f,"%c",*(char *)ptr);
1854 fprintf(f,"0%o",*(int *)ptr);
1860 fprintf(f,"%s",(char *)ptr);
1866 fprintf(f,"%s",*(char **)ptr);
1874 /***************************************************************************
1875 check if two parameters are equal
1876 ***************************************************************************/
1877 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1883 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1888 return(*((int *)ptr1) == *((int *)ptr2));
1891 return(*((char *)ptr1) == *((char *)ptr2));
1896 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1897 if (p1 && !*p1) p1 = NULL;
1898 if (p2 && !*p2) p2 = NULL;
1899 return(p1==p2 || strequal(p1,p2));
1904 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1905 if (p1 && !*p1) p1 = NULL;
1906 if (p2 && !*p2) p2 = NULL;
1907 return(p1==p2 || strequal(p1,p2));
1915 /***************************************************************************
1916 Process a new section (service). At this stage all sections are services.
1917 Later we'll have special sections that permit server parameters to be set.
1918 Returns True on success, False on failure.
1919 ***************************************************************************/
1920 static BOOL do_section(char *pszSectionName)
1923 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1924 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1927 /* if we were in a global section then do the local inits */
1928 if (bInGlobalSection && !isglobal)
1931 /* if we've just struck a global section, note the fact. */
1932 bInGlobalSection = isglobal;
1934 /* check for multiple global sections */
1935 if (bInGlobalSection)
1937 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1941 if (!bInGlobalSection && bGlobalOnly) return(True);
1943 /* if we have a current service, tidy it up before moving on */
1946 if (iServiceIndex >= 0)
1947 bRetval = service_ok(iServiceIndex);
1949 /* if all is still well, move to the next record in the services array */
1952 /* We put this here to avoid an odd message order if messages are */
1953 /* issued by the post-processing of a previous section. */
1954 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1956 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1958 DEBUG(0,("Failed to add a new service\n"));
1967 /***************************************************************************
1968 determine if a partcular base parameter is currently set to the default value.
1969 ***************************************************************************/
1970 static BOOL is_default(int i)
1972 if (!defaults_saved) return False;
1973 switch (parm_table[i].type) {
1976 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
1979 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
1982 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
1984 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
1988 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
1996 /***************************************************************************
1997 Display the contents of the global structure.
1998 ***************************************************************************/
1999 static void dump_globals(FILE *f)
2002 fprintf(f, "# Global parameters\n");
2004 for (i=0;parm_table[i].label;i++)
2005 if (parm_table[i].class == P_GLOBAL &&
2006 parm_table[i].ptr &&
2007 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2008 if (defaults_saved && is_default(i)) continue;
2009 fprintf(f,"\t%s = ",parm_table[i].label);
2010 print_parameter(&parm_table[i],parm_table[i].ptr, f);
2015 /***************************************************************************
2016 return True if a local parameter is currently set to the global default
2017 ***************************************************************************/
2018 BOOL lp_is_default(int snum, struct parm_struct *parm)
2020 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2022 return equal_parameter(parm->type,
2023 ((char *)pSERVICE(snum)) + pdiff,
2024 ((char *)&sDefault) + pdiff);
2028 /***************************************************************************
2029 Display the contents of a single services record.
2030 ***************************************************************************/
2031 static void dump_a_service(service *pService, FILE *f)
2034 if (pService != &sDefault)
2035 fprintf(f,"\n[%s]\n",pService->szService);
2037 for (i=0;parm_table[i].label;i++)
2038 if (parm_table[i].class == P_LOCAL &&
2039 parm_table[i].ptr &&
2040 (*parm_table[i].label != '-') &&
2041 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2042 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2044 if (pService == &sDefault) {
2045 if (defaults_saved && is_default(i)) continue;
2047 if (equal_parameter(parm_table[i].type,
2048 ((char *)pService) + pdiff,
2049 ((char *)&sDefault) + pdiff))
2053 fprintf(f,"\t%s = ",parm_table[i].label);
2054 print_parameter(&parm_table[i],
2055 ((char *)pService) + pdiff, f);
2061 /***************************************************************************
2062 return info about the next service in a service. snum==-1 gives the globals
2064 return NULL when out of parameters
2065 ***************************************************************************/
2066 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2069 /* do the globals */
2070 for (;parm_table[*i].label;(*i)++) {
2071 if (parm_table[*i].class == P_SEPARATOR)
2072 return &parm_table[(*i)++];
2074 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2077 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2080 return &parm_table[(*i)++];
2083 service *pService = pSERVICE(snum);
2085 for (;parm_table[*i].label;(*i)++) {
2086 if (parm_table[*i].class == P_SEPARATOR)
2087 return &parm_table[(*i)++];
2089 if (parm_table[*i].class == P_LOCAL &&
2090 parm_table[*i].ptr &&
2091 (*parm_table[*i].label != '-') &&
2093 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2094 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2096 if (allparameters ||
2097 !equal_parameter(parm_table[*i].type,
2098 ((char *)pService) + pdiff,
2099 ((char *)&sDefault) + pdiff)) {
2100 return &parm_table[(*i)++];
2111 /***************************************************************************
2112 Display the contents of a single copy structure.
2113 ***************************************************************************/
2114 static void dump_copy_map(BOOL *pcopymap)
2117 if (!pcopymap) return;
2119 printf("\n\tNon-Copied parameters:\n");
2121 for (i=0;parm_table[i].label;i++)
2122 if (parm_table[i].class == P_LOCAL &&
2123 parm_table[i].ptr && !pcopymap[i] &&
2124 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2126 printf("\t\t%s\n",parm_table[i].label);
2131 /***************************************************************************
2132 Return TRUE if the passed service number is within range.
2133 ***************************************************************************/
2134 BOOL lp_snum_ok(int iService)
2136 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2140 /***************************************************************************
2141 auto-load some homes and printer services
2142 ***************************************************************************/
2143 static void lp_add_auto_services(char *str)
2147 int homes, printers;
2155 homes = lp_servicenumber(HOMES_NAME);
2156 printers = lp_servicenumber(PRINTERS_NAME);
2158 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2160 char *home = get_home_dir(p);
2162 if (lp_servicenumber(p) >= 0) continue;
2164 if (home && homes >= 0)
2166 lp_add_home(p,homes,home);
2170 if (printers >= 0 && pcap_printername_ok(p,NULL))
2171 lp_add_printer(p,printers);
2176 /***************************************************************************
2177 auto-load one printer
2178 ***************************************************************************/
2179 static void lp_add_one_printer(char *name,char *comment)
2181 int printers = lp_servicenumber(PRINTERS_NAME);
2184 if (lp_servicenumber(name) < 0)
2186 lp_add_printer(name,printers);
2187 if ((i=lp_servicenumber(name)) >= 0)
2188 string_set(&iSERVICE(i).comment,comment);
2193 /***************************************************************************
2194 auto-load printer services
2195 ***************************************************************************/
2196 static void lp_add_all_printers(void)
2198 int printers = lp_servicenumber(PRINTERS_NAME);
2200 if (printers < 0) return;
2202 pcap_printer_fn(lp_add_one_printer);
2205 /***************************************************************************
2206 have we loaded a services file yet?
2207 ***************************************************************************/
2208 BOOL lp_loaded(void)
2213 /***************************************************************************
2214 unload unused services
2215 ***************************************************************************/
2216 void lp_killunused(BOOL (*snumused)(int ))
2219 for (i=0;i<iNumServices;i++)
2220 if (VALID(i) && (!snumused || !snumused(i)))
2222 iSERVICE(i).valid = False;
2223 free_service(pSERVICE(i));
2228 /***************************************************************************
2229 save the curent values of all global and sDefault parameters into the
2230 defaults union. This allows swat and testparm to show only the
2231 changed (ie. non-default) parameters.
2232 ***************************************************************************/
2233 static void lp_save_defaults(void)
2236 for (i = 0; parm_table[i].label; i++) {
2237 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2238 switch (parm_table[i].type) {
2241 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2245 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2249 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2252 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2257 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2263 defaults_saved = True;
2267 /***************************************************************************
2268 Load the services array from the services file. Return True on success,
2270 ***************************************************************************/
2271 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2276 add_to_file_list(pszFname);
2280 bInGlobalSection = True;
2281 bGlobalOnly = global_only;
2285 if (save_defaults) {
2290 pstrcpy(n2,pszFname);
2291 standard_sub_basic(n2);
2293 /* We get sections first, so have to start 'behind' to make up */
2295 bRetval = pm_process(n2, do_section, do_parameter);
2297 /* finish up the last section */
2298 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2300 if (iServiceIndex >= 0)
2301 bRetval = service_ok(iServiceIndex);
2303 lp_add_auto_services(lp_auto_services());
2304 if (lp_load_printers())
2305 lp_add_all_printers();
2310 set_default_server_announce_type();
2318 /***************************************************************************
2319 return the max number of services
2320 ***************************************************************************/
2321 int lp_numservices(void)
2323 return(iNumServices);
2326 /***************************************************************************
2327 Display the contents of the services array in human-readable form.
2328 ***************************************************************************/
2329 void lp_dump(FILE *f, BOOL show_defaults)
2333 if (show_defaults) {
2334 defaults_saved = False;
2339 dump_a_service(&sDefault, f);
2341 for (iService = 0; iService < iNumServices; iService++)
2343 if (VALID(iService))
2345 if (iSERVICE(iService).szService[0] == '\0')
2347 dump_a_service(pSERVICE(iService), f);
2353 /***************************************************************************
2354 Return the number of the service with the given name, or -1 if it doesn't
2355 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2356 getservicebyname()! This works ONLY if all services have been loaded, and
2357 does not copy the found service.
2358 ***************************************************************************/
2359 int lp_servicenumber(char *pszServiceName)
2363 for (iService = iNumServices - 1; iService >= 0; iService--)
2364 if (VALID(iService) &&
2365 strequal(lp_servicename(iService), pszServiceName))
2369 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2374 /*******************************************************************
2375 a useful volume label function
2376 ******************************************************************/
2377 char *volume_label(int snum)
2379 char *ret = lp_volume(snum);
2380 if (!*ret) return(lp_servicename(snum));
2386 * nmbd only loads the global section. There seems to be no way to
2387 * determine exactly is a service is printable by only looking at the
2388 * [global] section so for now always announce as a print server. This
2389 * will need looking at in the future. Jeremy (jallison@whistle.com).
2391 /*******************************************************************
2392 Return true if any printer services are defined.
2393 ******************************************************************/
2394 static BOOL lp_printer_services(void)
2398 for (iService = iNumServices - 1; iService >= 0; iService--)
2399 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2405 /*******************************************************************
2406 Set the server type we will announce as via nmbd.
2407 ********************************************************************/
2408 static void set_default_server_announce_type()
2410 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2411 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2412 if(lp_announce_as() == ANNOUNCE_AS_NT)
2413 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2414 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2415 default_server_announce |= SV_TYPE_WIN95_PLUS;
2416 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2417 default_server_announce |= SV_TYPE_WFW;
2418 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2420 * nmbd only loads the [global] section. There seems to be no way to
2421 * determine exactly if any service is printable by only looking at the
2422 * [global] section so for now always announce as a print server. This
2423 * will need looking at in the future. Jeremy (jallison@whistle.com).
2426 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2431 /*******************************************************************
2433 ********************************************************************/
2434 void lp_rename_service(int snum, char *new_name)
2436 string_set(&pSERVICE(snum)->szService, new_name);
2439 /*******************************************************************
2441 ********************************************************************/
2442 void lp_remove_service(int snum)
2444 pSERVICE(snum)->valid = False;
2447 /*******************************************************************
2449 ********************************************************************/
2450 void lp_copy_service(int snum, char *new_name)
2452 char *oldname = lp_servicename(snum);
2453 do_section(new_name);
2455 snum = lp_servicenumber(new_name);
2457 lp_do_parameter(snum, "copy", oldname);
2462 /*******************************************************************
2463 Get the default server type we will announce as via nmbd.
2464 ********************************************************************/
2465 int lp_default_server_announce(void)
2467 return default_server_announce;
2470 /*******************************************************************
2471 Split the announce version into major and minor numbers.
2472 ********************************************************************/
2473 int lp_major_announce_version(void)
2475 static BOOL got_major = False;
2476 static int major_version = DEFAULT_MAJOR_VERSION;
2481 return major_version;
2484 if((vers = lp_announce_version()) == NULL)
2485 return major_version;
2487 if((p = strchr(vers, '.')) == 0)
2488 return major_version;
2491 major_version = atoi(vers);
2492 return major_version;
2495 int lp_minor_announce_version(void)
2497 static BOOL got_minor = False;
2498 static int minor_version = DEFAULT_MINOR_VERSION;
2503 return minor_version;
2506 if((vers = lp_announce_version()) == NULL)
2507 return minor_version;
2509 if((p = strchr(vers, '.')) == 0)
2510 return minor_version;
2513 minor_version = atoi(p);
2514 return minor_version;
2517 /***********************************************************
2518 Set the global name resolution order (used in smbclient).
2519 ************************************************************/
2521 void lp_set_name_resolve_order(char *new_order)
2523 Globals.szNameResolveOrder = new_order;