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 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;
167 int client_code_page;
168 int announce_as; /* This is initialised in init_globals */
173 BOOL bPreferredMaster;
174 BOOL bDomainController;
177 BOOL bEncryptPasswords;
184 BOOL bReadPrediction;
191 BOOL bBindInterfacesOnly;
192 BOOL bNetWkstaUserLogon;
195 static global Globals;
200 * This structure describes a single service.
208 char *szGuestaccount;
209 char *szInvalidUsers;
217 char *szRootPostExec;
218 char *szPrintcommand;
221 char *szLppausecommand;
222 char *szLpresumecommand;
224 char *szPrinterDriver;
225 char *szPrinterDriverLocation;
234 char *szVetoOplockFiles;
243 int iCreate_force_mode;
253 BOOL bShortCasePreserve;
279 BOOL bDeleteReadonly;
281 BOOL bDeleteVetoFiles;
283 BOOL bDosFiletimeResolution;
284 char dummy[3]; /* for alignment */
288 /* This is a default service used to prime a services structure */
289 static service sDefault =
292 NULL, /* szService */
294 NULL, /* szUsername */
295 NULL, /* szGuestAccount - this is set in init_globals() */
296 NULL, /* szInvalidUsers */
297 NULL, /* szValidUsers */
298 NULL, /* szAdminUsers */
300 NULL, /* szInclude */
301 NULL, /* szPreExec */
302 NULL, /* szPostExec */
303 NULL, /* szRootPreExec */
304 NULL, /* szRootPostExec */
305 NULL, /* szPrintcommand */
306 NULL, /* szLpqcommand */
307 NULL, /* szLprmcommand */
308 NULL, /* szLppausecommand */
309 NULL, /* szLpresumecommand */
310 NULL, /* szPrintername */
311 NULL, /* szPrinterDriver - this is set in init_globals() */
312 NULL, /* szPrinterDriverLocation */
313 NULL, /* szDontdescend */
314 NULL, /* szHostsallow */
315 NULL, /* szHostsdeny */
316 NULL, /* szMagicScript */
317 NULL, /* szMagicOutput */
318 NULL, /* szMangledMap */
319 NULL, /* szVetoFiles */
320 NULL, /* szHideFiles */
321 NULL, /* szVetoOplockFiles */
323 NULL, /* force user */
324 NULL, /* force group */
326 NULL, /* writelist */
328 0, /* iMinPrintSpace */
329 0744, /* iCreate_mask */
330 0000, /* iCreate_force_mode */
331 0755, /* iDir_mask */
332 0000, /* iDir_force_mode */
333 0, /* iMaxConnections */
334 CASE_LOWER, /* iDefaultCase */
335 DEFAULT_PRINTING, /* iPrinting */
336 False, /* bAlternatePerm */
337 False, /* revalidate */
338 False, /* case sensitive */
339 False, /* case preserve */
340 False, /* short case preserve */
341 False, /* case mangle */
343 True, /* bHideDotFiles */
344 True, /* bBrowseable */
345 True, /* bAvailable */
346 True, /* bRead_only */
347 True, /* bNo_set_dir */
348 False, /* bGuest_only */
349 False, /* bGuest_ok */
350 False, /* bPrint_ok */
351 False, /* bPostscript */
352 False, /* bMap_system */
353 False, /* bMap_hidden */
354 True, /* bMap_archive */
356 False, /* bStrictLocking */
357 True, /* bShareModes */
359 False, /* bOnlyUser */
360 True, /* bMangledNames */
361 True, /* bWidelinks */
362 True, /* bSymlinks */
363 False, /* bSyncAlways */
364 '~', /* magic char */
366 False, /* bDeleteReadonly */
367 False, /* bFakeOplocks */
368 False, /* bDeleteVetoFiles */
369 False, /* bDosFiletimes */
370 False, /* bDosFiletimeResolution */
376 /* local variables */
377 static service **ServicePtrs = NULL;
378 static int iNumServices = 0;
379 static int iServiceIndex = 0;
380 static BOOL bInGlobalSection = True;
381 static BOOL bGlobalOnly = False;
382 static int default_server_announce;
384 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
386 /* prototypes for the special type handlers */
387 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
388 static BOOL handle_include(char *pszParmValue, char **ptr);
389 static BOOL handle_copy(char *pszParmValue, char **ptr);
390 static BOOL handle_character_set(char *pszParmValue,char **ptr);
391 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
393 static void set_default_server_announce_type(void);
395 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
396 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
397 {PROTOCOL_COREPLUS, "COREPLUS"},
398 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
400 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
401 {SEC_SERVER, "SERVER"}, {-1, NULL}};
403 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
404 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
405 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
406 {PRINT_LPRNG, "lprng"}, {-1, NULL}};
408 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
409 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
411 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
413 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
415 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
416 static struct parm_struct parm_table[] =
418 {"Base Options", P_SEP, P_SEPARATOR},
419 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
420 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
421 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
422 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
423 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL, NULL, FLAG_BASIC},
424 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
425 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
426 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
427 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
429 {"Security Options", P_SEP, P_SEPARATOR},
430 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
431 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
432 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
433 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
434 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
435 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
436 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
437 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
438 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
439 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
440 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
441 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
442 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
443 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
444 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
445 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL},
446 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
447 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
448 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
449 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
450 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
451 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
452 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
453 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
454 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
455 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
456 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
457 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
458 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
459 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
460 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
461 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
462 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
463 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
464 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
465 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
466 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
467 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
468 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
469 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
470 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
471 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
472 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
473 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
474 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
475 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
476 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
477 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
479 {"Logging Options", P_SEP, P_SEPARATOR},
480 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
481 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
482 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
483 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
484 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
485 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
486 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
488 {"Protocol Options", P_SEP, P_SEPARATOR},
489 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
490 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
491 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
492 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
493 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
494 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
495 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
496 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
497 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
498 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
499 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
500 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
501 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
502 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
503 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
505 {"Tuning Options", P_SEP, P_SEPARATOR},
506 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
507 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
508 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
509 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
510 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
511 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
512 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
513 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
514 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
515 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
516 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
517 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
519 {"Printing Options", P_SEP, P_SEPARATOR},
520 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
521 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
522 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
523 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
524 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
525 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
526 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
527 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
528 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
529 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
530 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
531 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
532 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
533 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
534 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
535 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
536 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
539 {"Filename Handling", P_SEP, P_SEPARATOR},
540 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
541 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
542 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
543 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
544 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
545 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
546 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
547 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
548 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
549 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
550 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
551 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
552 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
553 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
554 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
555 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
556 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
557 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
558 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
559 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
560 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
561 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
563 {"Domain Options", P_SEP, P_SEPARATOR},
564 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
565 {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL, 0},
566 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
567 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
568 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
569 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
570 {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
571 {"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
572 {"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
573 {"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
575 {"Logon Options", P_SEP, P_SEPARATOR},
576 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
577 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
578 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
579 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
580 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
582 {"Browse Options", P_SEP, P_SEPARATOR},
583 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, 0},
584 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
585 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
586 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
587 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
588 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, 0},
589 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, 0},
590 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
591 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
592 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
594 {"WINS Options", P_SEP, P_SEPARATOR},
595 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
596 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
597 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
598 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
600 {"Locking Options", P_SEP, P_SEPARATOR},
601 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
602 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
603 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
604 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
605 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
607 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
608 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
609 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
610 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
611 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
612 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
613 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
614 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
615 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
616 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
617 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
618 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
619 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
620 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
621 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
622 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
623 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
624 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
625 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
626 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
627 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
628 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
629 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
630 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
631 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
632 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
633 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
634 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
635 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
636 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
637 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
638 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
639 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
640 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
641 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
642 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
643 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
644 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
646 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
651 /***************************************************************************
652 Initialise the global parameter structure.
653 ***************************************************************************/
654 static void init_globals(void)
656 static BOOL done_init = False;
662 bzero((void *)&Globals,sizeof(Globals));
664 for (i = 0; parm_table[i].label; i++)
665 if ((parm_table[i].type == P_STRING ||
666 parm_table[i].type == P_USTRING) &&
668 string_init(parm_table[i].ptr,"");
670 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
671 string_set(&sDefault.szPrinterDriver, "NULL");
677 DEBUG(3,("Initialising global parameters\n"));
679 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
680 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
681 string_set(&Globals.szWorkGroup, WORKGROUP);
682 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
683 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
684 string_set(&Globals.szDriverFile, DRIVERFILE);
685 string_set(&Globals.szLockDir, LOCKDIR);
686 string_set(&Globals.szRootdir, "/");
687 string_set(&Globals.szSmbrun, SMBRUN);
688 string_set(&Globals.szSocketAddress, "0.0.0.0");
689 sprintf(s,"Samba %s",VERSION);
690 string_set(&Globals.szServerString,s);
691 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
692 string_set(&Globals.szAnnounceVersion,s);
694 string_set(&Globals.szLogonDrive, "");
695 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
696 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
697 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
699 Globals.bLoadPrinters = True;
700 Globals.bUseRhosts = False;
701 Globals.max_packet = 65535;
702 Globals.mangled_stack = 50;
703 Globals.max_xmit = 65535;
704 Globals.max_mux = 50; /* This is *needed* for profile support. */
705 Globals.lpqcachetime = 10;
706 Globals.pwordlevel = 0;
707 Globals.unamelevel = 0;
708 Globals.deadtime = 0;
709 Globals.max_log_size = 5000;
710 Globals.maxprotocol = PROTOCOL_NT1;
711 Globals.security = SEC_SHARE;
712 Globals.bEncryptPasswords = False;
713 Globals.bReadRaw = True;
714 Globals.bWriteRaw = True;
715 Globals.bReadPrediction = False;
716 Globals.bReadbmpx = True;
717 Globals.bNullPasswords = False;
718 Globals.bStripDot = False;
720 Globals.bSyslogOnly = False;
721 Globals.os_level = 0;
722 Globals.max_ttl = 60*60*4; /* 4 hours default */
723 Globals.max_wins_ttl = 60*60*24*3; /* 3 days default */
724 Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
725 Globals.ReadSize = 16*1024;
726 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
727 Globals.lm_interval = 60;
728 Globals.shmem_size = SHMEM_SIZE;
729 Globals.announce_as = ANNOUNCE_AS_NT;
730 Globals.bUnixRealname = False;
731 #if (defined(NETGROUP) && defined(AUTOMOUNT))
732 Globals.bNISHomeMap = False;
733 string_set(&Globals.szNISHomeMapName, "auto.home");
735 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
736 Globals.bTimeServer = False;
737 Globals.bBindInterfacesOnly = False;
738 Globals.bNetWkstaUserLogon = True;
740 /* these parameters are set to defaults that are more appropriate
741 for the increasing samba install base:
743 as a member of the workgroup, that will possibly become a
744 _local_ master browser (lm = True). this is opposed to a forced
745 local master browser startup (pm = True).
747 doesn't provide WINS server service by default (wsupp = False),
748 and doesn't provide domain master browser services by default, either.
752 Globals.bPreferredMaster = False;
753 Globals.bLocalMaster = True;
754 Globals.bDomainMaster = False;
755 Globals.bDomainLogons = False;
756 Globals.bBrowseList = True;
757 Globals.bWINSsupport = False;
758 Globals.bWINSproxy = False;
760 Globals.bDNSproxy = True;
763 * This must be done last as it checks the value in
767 interpret_coding_system(KANJI);
770 /***************************************************************************
771 check if a string is initialised and if not then initialise it
772 ***************************************************************************/
773 static void string_initial(char **s,char *v)
780 /***************************************************************************
781 Initialise the sDefault parameter structure.
782 ***************************************************************************/
783 static void init_locals(void)
785 /* choose defaults depending on the type of printing */
786 switch (sDefault.iPrinting)
792 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
793 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
794 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
799 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
800 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
801 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
803 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
804 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
809 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
810 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
811 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
819 /******************************************************************* a
820 convenience routine to grab string parameters into a rotating buffer,
821 and run standard_sub_basic on them. The buffers can be written to by
822 callers without affecting the source string.
823 ********************************************************************/
824 char *lp_string(char *s)
826 static char *bufs[10];
827 static int buflen[10];
828 static int next = -1;
831 int len = s?strlen(s):0;
842 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
845 if (buflen[next] != len) {
847 if (bufs[next]) free(bufs[next]);
848 bufs[next] = (char *)malloc(len);
850 DEBUG(0,("out of memory in lp_string()"));
855 ret = &bufs[next][0];
863 trim_string(ret, "\"", "\"");
865 standard_sub_basic(ret);
871 In this section all the functions that are used to access the
872 parameters from the rest of the program are defined
875 #define FN_GLOBAL_STRING(fn_name,ptr) \
876 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
877 #define FN_GLOBAL_BOOL(fn_name,ptr) \
878 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
879 #define FN_GLOBAL_CHAR(fn_name,ptr) \
880 char fn_name(void) {return(*(char *)(ptr));}
881 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
882 int fn_name(void) {return(*(int *)(ptr));}
884 #define FN_LOCAL_STRING(fn_name,val) \
885 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
886 #define FN_LOCAL_BOOL(fn_name,val) \
887 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
888 #define FN_LOCAL_CHAR(fn_name,val) \
889 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
890 #define FN_LOCAL_INTEGER(fn_name,val) \
891 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
893 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
894 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
895 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
896 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
897 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
898 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
899 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
900 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
901 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
902 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
903 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
904 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
905 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
906 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
907 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
908 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
909 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
910 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
911 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
912 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
913 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
914 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
915 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
916 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
917 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
918 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
919 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
920 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
921 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
922 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
923 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
924 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
926 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
927 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
928 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
929 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
930 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
931 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
932 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
934 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
935 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
936 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
937 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
938 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
939 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
940 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
941 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
942 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
943 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
944 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
945 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
946 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
947 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
948 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
949 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
950 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
951 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
952 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
953 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
954 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
955 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
956 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
957 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
958 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
959 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
961 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
962 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
963 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
964 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
965 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
966 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
967 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
968 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
969 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
970 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
971 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
972 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
973 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
974 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
975 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
976 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
977 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
978 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
979 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
980 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
981 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
982 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
983 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
984 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
986 FN_LOCAL_STRING(lp_preexec,szPreExec)
987 FN_LOCAL_STRING(lp_postexec,szPostExec)
988 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
989 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
990 FN_LOCAL_STRING(lp_servicename,szService)
991 FN_LOCAL_STRING(lp_pathname,szPath)
992 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
993 FN_LOCAL_STRING(lp_username,szUsername)
994 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
995 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
996 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
997 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
998 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
999 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1000 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1001 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1002 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1003 FN_LOCAL_STRING(lp_printername,szPrintername)
1004 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1005 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1006 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1007 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1008 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1009 FN_LOCAL_STRING(lp_comment,comment)
1010 FN_LOCAL_STRING(lp_force_user,force_user)
1011 FN_LOCAL_STRING(lp_force_group,force_group)
1012 FN_LOCAL_STRING(lp_readlist,readlist)
1013 FN_LOCAL_STRING(lp_writelist,writelist)
1014 FN_LOCAL_STRING(lp_volume,volume)
1015 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1016 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1017 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1018 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1019 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1021 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
1022 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1023 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1024 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1025 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1026 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1027 FN_LOCAL_BOOL(lp_status,status)
1028 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1029 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1030 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1031 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1032 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1033 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1034 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1035 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1036 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1037 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1038 FN_LOCAL_BOOL(lp_locking,bLocking)
1039 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1040 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1041 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1042 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1043 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1044 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1045 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1046 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1047 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1048 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1049 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1050 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1051 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1052 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1054 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1055 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1056 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1057 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1058 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1059 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1060 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1061 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1063 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1067 /* local prototypes */
1068 static int strwicmp( char *psz1, char *psz2 );
1069 static int map_parameter( char *pszParmName);
1070 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1071 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1072 static void copy_service( service *pserviceDest,
1073 service *pserviceSource,
1074 BOOL *pcopymapDest );
1075 static BOOL service_ok(int iService);
1076 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1077 static BOOL do_section(char *pszSectionName);
1078 static void init_copymap(service *pservice);
1081 /***************************************************************************
1082 initialise a service to the defaults
1083 ***************************************************************************/
1084 static void init_service(service *pservice)
1086 bzero((char *)pservice,sizeof(service));
1087 copy_service(pservice,&sDefault,NULL);
1091 /***************************************************************************
1092 free the dynamically allocated parts of a service struct
1093 ***************************************************************************/
1094 static void free_service(service *pservice)
1100 if(pservice->szService)
1101 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1103 string_free(&pservice->szService);
1104 if (pservice->copymap)
1106 free(pservice->copymap);
1107 pservice->copymap = NULL;
1110 for (i=0;parm_table[i].label;i++)
1111 if ((parm_table[i].type == P_STRING ||
1112 parm_table[i].type == P_USTRING) &&
1113 parm_table[i].class == P_LOCAL)
1114 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1117 /***************************************************************************
1118 add a new service to the services array initialising it with the given
1120 ***************************************************************************/
1121 static int add_a_service(service *pservice, char *name)
1125 int num_to_alloc = iNumServices+1;
1127 tservice = *pservice;
1129 /* it might already exist */
1132 i = getservicebyname(name,NULL);
1137 /* find an invalid one */
1138 for (i=0;i<iNumServices;i++)
1139 if (!pSERVICE(i)->valid)
1142 /* if not, then create one */
1143 if (i == iNumServices)
1145 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1147 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1149 if (!ServicePtrs || !pSERVICE(iNumServices))
1155 free_service(pSERVICE(i));
1157 pSERVICE(i)->valid = True;
1159 init_service(pSERVICE(i));
1160 copy_service(pSERVICE(i),&tservice,NULL);
1162 string_set(&iSERVICE(i).szService,name);
1167 /***************************************************************************
1168 add a new home service, with the specified home directory, defaults coming
1170 ***************************************************************************/
1171 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1173 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1178 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1179 string_set(&iSERVICE(i).szPath,pszHomedir);
1180 if (!(*(iSERVICE(i).comment)))
1183 sprintf(comment,"Home directory of %s",pszHomename);
1184 string_set(&iSERVICE(i).comment,comment);
1186 iSERVICE(i).bAvailable = sDefault.bAvailable;
1187 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1189 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1194 /***************************************************************************
1195 add a new service, based on an old one
1196 ***************************************************************************/
1197 int lp_add_service(char *pszService, int iDefaultService)
1199 return(add_a_service(pSERVICE(iDefaultService),pszService));
1203 /***************************************************************************
1205 ***************************************************************************/
1206 static BOOL lp_add_ipc(void)
1209 int i = add_a_service(&sDefault,"IPC$");
1214 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1216 string_set(&iSERVICE(i).szPath,tmpdir());
1217 string_set(&iSERVICE(i).szUsername,"");
1218 string_set(&iSERVICE(i).comment,comment);
1219 iSERVICE(i).status = False;
1220 iSERVICE(i).iMaxConnections = 0;
1221 iSERVICE(i).bAvailable = True;
1222 iSERVICE(i).bRead_only = True;
1223 iSERVICE(i).bGuest_only = False;
1224 iSERVICE(i).bGuest_ok = True;
1225 iSERVICE(i).bPrint_ok = False;
1226 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1228 DEBUG(3,("adding IPC service\n"));
1234 /***************************************************************************
1235 add a new printer service, with defaults coming from service iFrom
1236 ***************************************************************************/
1237 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1239 char *comment = "From Printcap";
1240 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1245 /* note that we do NOT default the availability flag to True - */
1246 /* we take it from the default service passed. This allows all */
1247 /* dynamic printers to be disabled by disabling the [printers] */
1248 /* entry (if/when the 'available' keyword is implemented!). */
1250 /* the printer name is set to the service name. */
1251 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1252 string_set(&iSERVICE(i).comment,comment);
1253 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1254 /* Printers cannot be read_only. */
1255 iSERVICE(i).bRead_only = False;
1256 /* No share modes on printer services. */
1257 iSERVICE(i).bShareModes = False;
1258 /* No oplocks on printer services. */
1259 iSERVICE(i).bOpLocks = False;
1260 /* Printer services must be printable. */
1261 iSERVICE(i).bPrint_ok = True;
1263 DEBUG(3,("adding printer service %s\n",pszPrintername));
1269 /***************************************************************************
1270 Do a case-insensitive, whitespace-ignoring string compare.
1271 ***************************************************************************/
1272 static int strwicmp(char *psz1, char *psz2)
1274 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1275 /* appropriate value. */
1285 /* sync the strings on first non-whitespace */
1288 while (isspace(*psz1))
1290 while (isspace(*psz2))
1292 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1297 return (*psz1 - *psz2);
1300 /***************************************************************************
1301 Map a parameter's string representation to something we can use.
1302 Returns False if the parameter string is not recognised, else TRUE.
1303 ***************************************************************************/
1304 static int map_parameter(char *pszParmName)
1308 if (*pszParmName == '-')
1311 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1312 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1315 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1320 /***************************************************************************
1321 Set a boolean variable from the text value stored in the passed string.
1322 Returns True in success, False if the passed string does not correctly
1323 represent a boolean.
1324 ***************************************************************************/
1325 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1330 if (strwicmp(pszParmValue, "yes") == 0 ||
1331 strwicmp(pszParmValue, "true") == 0 ||
1332 strwicmp(pszParmValue, "1") == 0)
1335 if (strwicmp(pszParmValue, "no") == 0 ||
1336 strwicmp(pszParmValue, "False") == 0 ||
1337 strwicmp(pszParmValue, "0") == 0)
1341 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1348 /***************************************************************************
1349 Find a service by name. Otherwise works like get_service.
1350 ***************************************************************************/
1351 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1355 for (iService = iNumServices - 1; iService >= 0; iService--)
1356 if (VALID(iService) &&
1357 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1359 if (pserviceDest != NULL)
1360 copy_service(pserviceDest, pSERVICE(iService), NULL);
1369 /***************************************************************************
1370 Copy a service structure to another
1372 If pcopymapDest is NULL then copy all fields
1373 ***************************************************************************/
1374 static void copy_service(service *pserviceDest,
1375 service *pserviceSource,
1379 BOOL bcopyall = (pcopymapDest == NULL);
1381 for (i=0;parm_table[i].label;i++)
1382 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1383 (bcopyall || pcopymapDest[i]))
1385 void *def_ptr = parm_table[i].ptr;
1387 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1389 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1391 switch (parm_table[i].type)
1395 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1401 *(int *)dest_ptr = *(int *)src_ptr;
1405 *(char *)dest_ptr = *(char *)src_ptr;
1409 string_set(dest_ptr,*(char **)src_ptr);
1413 string_set(dest_ptr,*(char **)src_ptr);
1414 strupper(*(char **)dest_ptr);
1423 init_copymap(pserviceDest);
1424 if (pserviceSource->copymap)
1425 memcpy((void *)pserviceDest->copymap,
1426 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1430 /***************************************************************************
1431 Check a service for consistency. Return False if the service is in any way
1432 incomplete or faulty, else True.
1433 ***************************************************************************/
1434 static BOOL service_ok(int iService)
1439 if (iSERVICE(iService).szService[0] == '\0')
1441 DEBUG(0,( "The following message indicates an internal error:\n"));
1442 DEBUG(0,( "No service name in service entry.\n"));
1446 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1447 /* I can't see why you'd want a non-printable printer service... */
1448 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1449 if (!iSERVICE(iService).bPrint_ok)
1451 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1452 iSERVICE(iService).szService));
1453 iSERVICE(iService).bPrint_ok = True;
1456 if (iSERVICE(iService).szPath[0] == '\0' &&
1457 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1459 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1460 string_set(&iSERVICE(iService).szPath,tmpdir());
1463 /* If a service is flagged unavailable, log the fact at level 0. */
1464 if (!iSERVICE(iService).bAvailable)
1465 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1466 iSERVICE(iService).szService));
1471 static struct file_lists {
1472 struct file_lists *next;
1475 } *file_lists = NULL;
1477 /*******************************************************************
1478 keep a linked list of all config files so we know when one has changed
1479 it's date and needs to be reloaded
1480 ********************************************************************/
1481 static void add_to_file_list(char *fname)
1483 struct file_lists *f=file_lists;
1486 if (f->name && !strcmp(f->name,fname)) break;
1491 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1493 f->next = file_lists;
1494 f->name = strdup(fname);
1505 standard_sub_basic(n2);
1506 f->modtime = file_modtime(n2);
1511 /*******************************************************************
1512 check if a config file has changed date
1513 ********************************************************************/
1514 BOOL lp_file_list_changed(void)
1516 struct file_lists *f = file_lists;
1517 DEBUG(6,("lp_file_list_changed()\n"));
1524 pstrcpy(n2,f->name);
1525 standard_sub_basic(n2);
1527 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1528 f->name, n2, ctime(&f->modtime)));
1530 mod_time = file_modtime(n2);
1532 if (f->modtime != mod_time) {
1533 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1534 f->modtime = mod_time;
1542 /***************************************************************************
1543 handle the interpretation of the coding system parameter
1544 *************************************************************************/
1545 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1547 string_set(ptr,pszParmValue);
1548 interpret_coding_system(pszParmValue);
1552 /***************************************************************************
1553 handle the interpretation of the character set system parameter
1554 ***************************************************************************/
1555 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1557 string_set(ptr,pszParmValue);
1558 interpret_character_set(pszParmValue);
1563 /***************************************************************************
1564 handle the valid chars lines
1565 ***************************************************************************/
1566 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1568 string_set(ptr,pszParmValue);
1570 /* A dependency here is that the parameter client code page must be
1571 set before this is called - as calling codepage_initialise()
1572 would overwrite the valid char lines.
1574 codepage_initialise(lp_client_code_page());
1576 add_char_string(pszParmValue);
1581 /***************************************************************************
1582 handle the include operation
1583 ***************************************************************************/
1584 static BOOL handle_include(char *pszParmValue,char **ptr)
1587 pstrcpy(fname,pszParmValue);
1589 add_to_file_list(fname);
1591 standard_sub_basic(fname);
1593 string_set(ptr,fname);
1595 if (file_exist(fname,NULL))
1596 return(pm_process(fname, do_section, do_parameter));
1598 DEBUG(2,("Can't find include file %s\n",fname));
1604 /***************************************************************************
1605 handle the interpretation of the copy parameter
1606 ***************************************************************************/
1607 static BOOL handle_copy(char *pszParmValue,char **ptr)
1611 service serviceTemp;
1613 string_set(ptr,pszParmValue);
1615 init_service(&serviceTemp);
1619 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1621 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1623 if (iTemp == iServiceIndex)
1625 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1630 copy_service(pSERVICE(iServiceIndex),
1632 iSERVICE(iServiceIndex).copymap);
1638 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1643 free_service(&serviceTemp);
1648 /***************************************************************************
1649 initialise a copymap
1650 ***************************************************************************/
1651 static void init_copymap(service *pservice)
1654 if (pservice->copymap) free(pservice->copymap);
1655 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1656 if (!pservice->copymap)
1657 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1659 for (i=0;i<NUMPARAMETERS;i++)
1660 pservice->copymap[i] = True;
1664 /***************************************************************************
1665 return the local pointer to a parameter given the service number and the
1666 pointer into the default structure
1667 ***************************************************************************/
1668 void *lp_local_ptr(int snum, void *ptr)
1670 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1673 /***************************************************************************
1674 Process a parameter for a particular service number. If snum < 0
1675 then assume we are in the globals
1676 ***************************************************************************/
1677 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1680 void *parm_ptr=NULL; /* where we are going to store the result */
1683 parmnum = map_parameter(pszParmName);
1687 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1691 def_ptr = parm_table[parmnum].ptr;
1693 /* we might point at a service, the default service or a global */
1697 if (parm_table[parmnum].class == P_GLOBAL) {
1698 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1701 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1705 if (!iSERVICE(snum).copymap)
1706 init_copymap(pSERVICE(snum));
1708 /* this handles the aliases - set the copymap for other entries with
1709 the same data pointer */
1710 for (i=0;parm_table[i].label;i++)
1711 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1712 iSERVICE(snum).copymap[i] = False;
1715 /* if it is a special case then go ahead */
1716 if (parm_table[parmnum].special) {
1717 parm_table[parmnum].special(pszParmValue,parm_ptr);
1721 /* now switch on the type of variable it is */
1722 switch (parm_table[parmnum].type)
1725 set_boolean(parm_ptr,pszParmValue);
1729 set_boolean(parm_ptr,pszParmValue);
1730 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1734 *(int *)parm_ptr = atoi(pszParmValue);
1738 *(char *)parm_ptr = *pszParmValue;
1742 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1746 string_set(parm_ptr,pszParmValue);
1750 string_set(parm_ptr,pszParmValue);
1751 strupper(*(char **)parm_ptr);
1755 strcpy((char *)parm_ptr,pszParmValue);
1759 strcpy((char *)parm_ptr,pszParmValue);
1760 strupper((char *)parm_ptr);
1764 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1765 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1766 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1778 /***************************************************************************
1779 Process a parameter.
1780 ***************************************************************************/
1781 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1783 if (!bInGlobalSection && bGlobalOnly) return(True);
1785 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1787 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1791 /***************************************************************************
1792 print a parameter of the specified type
1793 ***************************************************************************/
1794 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1799 for (i=0;p->enum_list[i].name;i++) {
1800 if (*(int *)ptr == p->enum_list[i].value) {
1801 fprintf(f,"%s",p->enum_list[i].name);
1808 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1812 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1816 fprintf(f,"%d",*(int *)ptr);
1820 fprintf(f,"%c",*(char *)ptr);
1824 fprintf(f,"0%o",*(int *)ptr);
1830 fprintf(f,"%s",(char *)ptr);
1836 fprintf(f,"%s",*(char **)ptr);
1844 /***************************************************************************
1845 check if two parameters are equal
1846 ***************************************************************************/
1847 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1853 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1858 return(*((int *)ptr1) == *((int *)ptr2));
1861 return(*((char *)ptr1) == *((char *)ptr2));
1866 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1867 if (p1 && !*p1) p1 = NULL;
1868 if (p2 && !*p2) p2 = NULL;
1869 return(p1==p2 || strequal(p1,p2));
1874 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1875 if (p1 && !*p1) p1 = NULL;
1876 if (p2 && !*p2) p2 = NULL;
1877 return(p1==p2 || strequal(p1,p2));
1885 /***************************************************************************
1886 Process a new section (service). At this stage all sections are services.
1887 Later we'll have special sections that permit server parameters to be set.
1888 Returns True on success, False on failure.
1889 ***************************************************************************/
1890 static BOOL do_section(char *pszSectionName)
1893 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1894 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1897 /* if we were in a global section then do the local inits */
1898 if (bInGlobalSection && !isglobal)
1901 /* if we've just struck a global section, note the fact. */
1902 bInGlobalSection = isglobal;
1904 /* check for multiple global sections */
1905 if (bInGlobalSection)
1907 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1911 if (!bInGlobalSection && bGlobalOnly) return(True);
1913 /* if we have a current service, tidy it up before moving on */
1916 if (iServiceIndex >= 0)
1917 bRetval = service_ok(iServiceIndex);
1919 /* if all is still well, move to the next record in the services array */
1922 /* We put this here to avoid an odd message order if messages are */
1923 /* issued by the post-processing of a previous section. */
1924 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1926 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1928 DEBUG(0,("Failed to add a new service\n"));
1937 /***************************************************************************
1938 determine if a partcular base parameter is currently set to the default value.
1939 ***************************************************************************/
1940 static BOOL is_default(int i)
1942 if (!defaults_saved) return False;
1943 switch (parm_table[i].type) {
1946 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
1949 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
1952 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
1954 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
1958 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
1966 /***************************************************************************
1967 Display the contents of the global structure.
1968 ***************************************************************************/
1969 static void dump_globals(FILE *f)
1972 fprintf(f, "# Global parameters\n");
1974 for (i=0;parm_table[i].label;i++)
1975 if (parm_table[i].class == P_GLOBAL &&
1976 parm_table[i].ptr &&
1977 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
1978 if (defaults_saved && is_default(i)) continue;
1979 fprintf(f,"\t%s = ",parm_table[i].label);
1980 print_parameter(&parm_table[i],parm_table[i].ptr, f);
1985 /***************************************************************************
1986 return True if a local parameter is currently set to the global default
1987 ***************************************************************************/
1988 BOOL lp_is_default(int snum, struct parm_struct *parm)
1990 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
1992 return equal_parameter(parm->type,
1993 ((char *)pSERVICE(snum)) + pdiff,
1994 ((char *)&sDefault) + pdiff);
1998 /***************************************************************************
1999 Display the contents of a single services record.
2000 ***************************************************************************/
2001 static void dump_a_service(service *pService, FILE *f)
2004 if (pService != &sDefault)
2005 fprintf(f,"\n[%s]\n",pService->szService);
2007 for (i=0;parm_table[i].label;i++)
2008 if (parm_table[i].class == P_LOCAL &&
2009 parm_table[i].ptr &&
2010 (*parm_table[i].label != '-') &&
2011 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2012 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2014 if (pService == &sDefault) {
2015 if (defaults_saved && is_default(i)) continue;
2017 if (equal_parameter(parm_table[i].type,
2018 ((char *)pService) + pdiff,
2019 ((char *)&sDefault) + pdiff))
2023 fprintf(f,"\t%s = ",parm_table[i].label);
2024 print_parameter(&parm_table[i],
2025 ((char *)pService) + pdiff, f);
2031 /***************************************************************************
2032 return info about the next service in a service. snum==-1 gives the globals
2034 return NULL when out of parameters
2035 ***************************************************************************/
2036 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2039 /* do the globals */
2040 for (;parm_table[*i].label;(*i)++) {
2041 if (parm_table[*i].class == P_SEPARATOR)
2042 return &parm_table[(*i)++];
2044 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2047 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2050 return &parm_table[(*i)++];
2053 service *pService = pSERVICE(snum);
2055 for (;parm_table[*i].label;(*i)++) {
2056 if (parm_table[*i].class == P_SEPARATOR)
2057 return &parm_table[(*i)++];
2059 if (parm_table[*i].class == P_LOCAL &&
2060 parm_table[*i].ptr &&
2061 (*parm_table[*i].label != '-') &&
2063 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2064 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2066 if (allparameters ||
2067 !equal_parameter(parm_table[*i].type,
2068 ((char *)pService) + pdiff,
2069 ((char *)&sDefault) + pdiff)) {
2070 return &parm_table[(*i)++];
2081 /***************************************************************************
2082 Display the contents of a single copy structure.
2083 ***************************************************************************/
2084 static void dump_copy_map(BOOL *pcopymap)
2087 if (!pcopymap) return;
2089 printf("\n\tNon-Copied parameters:\n");
2091 for (i=0;parm_table[i].label;i++)
2092 if (parm_table[i].class == P_LOCAL &&
2093 parm_table[i].ptr && !pcopymap[i] &&
2094 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2096 printf("\t\t%s\n",parm_table[i].label);
2101 /***************************************************************************
2102 Return TRUE if the passed service number is within range.
2103 ***************************************************************************/
2104 BOOL lp_snum_ok(int iService)
2106 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2110 /***************************************************************************
2111 auto-load some homes and printer services
2112 ***************************************************************************/
2113 static void lp_add_auto_services(char *str)
2117 int homes = lp_servicenumber(HOMES_NAME);
2118 int printers = lp_servicenumber(PRINTERS_NAME);
2126 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2128 char *home = get_home_dir(p);
2130 if (lp_servicenumber(p) >= 0) continue;
2132 if (home && homes >= 0)
2134 lp_add_home(p,homes,home);
2138 if (printers >= 0 && pcap_printername_ok(p,NULL))
2139 lp_add_printer(p,printers);
2144 /***************************************************************************
2145 auto-load one printer
2146 ***************************************************************************/
2147 static void lp_add_one_printer(char *name,char *comment)
2149 int printers = lp_servicenumber(PRINTERS_NAME);
2152 if (lp_servicenumber(name) < 0)
2154 lp_add_printer(name,printers);
2155 if ((i=lp_servicenumber(name)) >= 0)
2156 string_set(&iSERVICE(i).comment,comment);
2161 /***************************************************************************
2162 auto-load printer services
2163 ***************************************************************************/
2164 static void lp_add_all_printers(void)
2166 int printers = lp_servicenumber(PRINTERS_NAME);
2168 if (printers < 0) return;
2170 pcap_printer_fn(lp_add_one_printer);
2173 /***************************************************************************
2174 have we loaded a services file yet?
2175 ***************************************************************************/
2176 BOOL lp_loaded(void)
2181 /***************************************************************************
2182 unload unused services
2183 ***************************************************************************/
2184 void lp_killunused(BOOL (*snumused)(int ))
2187 for (i=0;i<iNumServices;i++)
2188 if (VALID(i) && (!snumused || !snumused(i)))
2190 iSERVICE(i).valid = False;
2191 free_service(pSERVICE(i));
2196 /***************************************************************************
2197 save the curent values of all global and sDefault parameters into the
2198 defaults union. This allows swat and testparm to show only the
2199 changed (ie. non-default) parameters.
2200 ***************************************************************************/
2201 static void lp_save_defaults(void)
2204 for (i = 0; parm_table[i].label; i++) {
2205 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2206 switch (parm_table[i].type) {
2209 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2213 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2217 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2220 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2225 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2231 defaults_saved = True;
2235 /***************************************************************************
2236 Load the services array from the services file. Return True on success,
2238 ***************************************************************************/
2239 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2244 add_to_file_list(pszFname);
2248 bInGlobalSection = True;
2249 bGlobalOnly = global_only;
2253 if (save_defaults) {
2258 pstrcpy(n2,pszFname);
2259 standard_sub_basic(n2);
2261 /* We get sections first, so have to start 'behind' to make up */
2263 bRetval = pm_process(n2, do_section, do_parameter);
2265 /* finish up the last section */
2266 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2268 if (iServiceIndex >= 0)
2269 bRetval = service_ok(iServiceIndex);
2271 lp_add_auto_services(lp_auto_services());
2272 if (lp_load_printers())
2273 lp_add_all_printers();
2278 set_default_server_announce_type();
2286 /***************************************************************************
2287 return the max number of services
2288 ***************************************************************************/
2289 int lp_numservices(void)
2291 return(iNumServices);
2294 /***************************************************************************
2295 Display the contents of the services array in human-readable form.
2296 ***************************************************************************/
2297 void lp_dump(FILE *f)
2303 dump_a_service(&sDefault, f);
2305 for (iService = 0; iService < iNumServices; iService++)
2307 if (VALID(iService))
2309 if (iSERVICE(iService).szService[0] == '\0')
2311 dump_a_service(pSERVICE(iService), f);
2317 /***************************************************************************
2318 Return the number of the service with the given name, or -1 if it doesn't
2319 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2320 getservicebyname()! This works ONLY if all services have been loaded, and
2321 does not copy the found service.
2322 ***************************************************************************/
2323 int lp_servicenumber(char *pszServiceName)
2327 for (iService = iNumServices - 1; iService >= 0; iService--)
2328 if (VALID(iService) &&
2329 strequal(lp_servicename(iService), pszServiceName))
2333 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2338 /*******************************************************************
2339 a useful volume label function
2340 ******************************************************************/
2341 char *volume_label(int snum)
2343 char *ret = lp_volume(snum);
2344 if (!*ret) return(lp_servicename(snum));
2350 * nmbd only loads the global section. There seems to be no way to
2351 * determine exactly is a service is printable by only looking at the
2352 * [global] section so for now always announce as a print server. This
2353 * will need looking at in the future. Jeremy (jallison@whistle.com).
2355 /*******************************************************************
2356 Return true if any printer services are defined.
2357 ******************************************************************/
2358 static BOOL lp_printer_services(void)
2362 for (iService = iNumServices - 1; iService >= 0; iService--)
2363 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2369 /*******************************************************************
2370 Set the server type we will announce as via nmbd.
2371 ********************************************************************/
2372 static void set_default_server_announce_type()
2374 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2375 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2376 if(lp_announce_as() == ANNOUNCE_AS_NT)
2377 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2378 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2379 default_server_announce |= SV_TYPE_WIN95_PLUS;
2380 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2381 default_server_announce |= SV_TYPE_WFW;
2382 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2384 * nmbd only loads the [global] section. There seems to be no way to
2385 * determine exactly if any service is printable by only looking at the
2386 * [global] section so for now always announce as a print server. This
2387 * will need looking at in the future. Jeremy (jallison@whistle.com).
2390 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2395 /*******************************************************************
2397 ********************************************************************/
2398 void lp_rename_service(int snum, char *new_name)
2400 string_set(&pSERVICE(snum)->szService, new_name);
2403 /*******************************************************************
2405 ********************************************************************/
2406 void lp_remove_service(int snum)
2408 pSERVICE(snum)->valid = False;
2411 /*******************************************************************
2413 ********************************************************************/
2414 void lp_copy_service(int snum, char *new_name)
2416 char *oldname = lp_servicename(snum);
2417 do_section(new_name);
2419 snum = lp_servicenumber(new_name);
2421 lp_do_parameter(snum, "copy", oldname);
2426 /*******************************************************************
2427 Get the default server type we will announce as via nmbd.
2428 ********************************************************************/
2429 int lp_default_server_announce(void)
2431 return default_server_announce;
2434 /*******************************************************************
2435 Split the announce version into major and minor numbers.
2436 ********************************************************************/
2437 int lp_major_announce_version(void)
2439 static BOOL got_major = False;
2440 static int major_version = DEFAULT_MAJOR_VERSION;
2445 return major_version;
2448 if((vers = lp_announce_version()) == NULL)
2449 return major_version;
2451 if((p = strchr(vers, '.')) == 0)
2452 return major_version;
2455 major_version = atoi(vers);
2456 return major_version;
2459 int lp_minor_announce_version(void)
2461 static BOOL got_minor = False;
2462 static int minor_version = DEFAULT_MINOR_VERSION;
2467 return minor_version;
2470 if((vers = lp_announce_version()) == NULL)
2471 return minor_version;
2473 if((p = strchr(vers, '.')) == 0)
2474 return minor_version;
2477 minor_version = atoi(p);
2478 return minor_version;