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;
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;
196 static global Globals;
201 * This structure describes a single service.
209 char *szGuestaccount;
210 char *szInvalidUsers;
218 char *szRootPostExec;
219 char *szPrintcommand;
222 char *szLppausecommand;
223 char *szLpresumecommand;
225 char *szPrinterDriver;
226 char *szPrinterDriverLocation;
235 char *szVetoOplockFiles;
244 int iCreate_force_mode;
254 BOOL bShortCasePreserve;
280 BOOL bDeleteReadonly;
282 BOOL bDeleteVetoFiles;
284 BOOL bDosFiletimeResolution;
285 BOOL bFakeDirCreateTimes;
286 char dummy[3]; /* for alignment */
290 /* This is a default service used to prime a services structure */
291 static service sDefault =
294 NULL, /* szService */
296 NULL, /* szUsername */
297 NULL, /* szGuestAccount - this is set in init_globals() */
298 NULL, /* szInvalidUsers */
299 NULL, /* szValidUsers */
300 NULL, /* szAdminUsers */
302 NULL, /* szInclude */
303 NULL, /* szPreExec */
304 NULL, /* szPostExec */
305 NULL, /* szRootPreExec */
306 NULL, /* szRootPostExec */
307 NULL, /* szPrintcommand */
308 NULL, /* szLpqcommand */
309 NULL, /* szLprmcommand */
310 NULL, /* szLppausecommand */
311 NULL, /* szLpresumecommand */
312 NULL, /* szPrintername */
313 NULL, /* szPrinterDriver - this is set in init_globals() */
314 NULL, /* szPrinterDriverLocation */
315 NULL, /* szDontdescend */
316 NULL, /* szHostsallow */
317 NULL, /* szHostsdeny */
318 NULL, /* szMagicScript */
319 NULL, /* szMagicOutput */
320 NULL, /* szMangledMap */
321 NULL, /* szVetoFiles */
322 NULL, /* szHideFiles */
323 NULL, /* szVetoOplockFiles */
325 NULL, /* force user */
326 NULL, /* force group */
328 NULL, /* writelist */
330 0, /* iMinPrintSpace */
331 0744, /* iCreate_mask */
332 0000, /* iCreate_force_mode */
333 0755, /* iDir_mask */
334 0000, /* iDir_force_mode */
335 0, /* iMaxConnections */
336 CASE_LOWER, /* iDefaultCase */
337 DEFAULT_PRINTING, /* iPrinting */
338 False, /* bAlternatePerm */
339 False, /* revalidate */
340 False, /* case sensitive */
341 False, /* case preserve */
342 False, /* short case preserve */
343 False, /* case mangle */
345 True, /* bHideDotFiles */
346 True, /* bBrowseable */
347 True, /* bAvailable */
348 True, /* bRead_only */
349 True, /* bNo_set_dir */
350 False, /* bGuest_only */
351 False, /* bGuest_ok */
352 False, /* bPrint_ok */
353 False, /* bPostscript */
354 False, /* bMap_system */
355 False, /* bMap_hidden */
356 True, /* bMap_archive */
358 False, /* bStrictLocking */
359 True, /* bShareModes */
361 False, /* bOnlyUser */
362 True, /* bMangledNames */
363 True, /* bWidelinks */
364 True, /* bSymlinks */
365 False, /* bSyncAlways */
366 '~', /* magic char */
368 False, /* bDeleteReadonly */
369 False, /* bFakeOplocks */
370 False, /* bDeleteVetoFiles */
371 False, /* bDosFiletimes */
372 False, /* bDosFiletimeResolution */
373 False, /* bFakeDirCreateTimes */
379 /* local variables */
380 static service **ServicePtrs = NULL;
381 static int iNumServices = 0;
382 static int iServiceIndex = 0;
383 static BOOL bInGlobalSection = True;
384 static BOOL bGlobalOnly = False;
385 static int default_server_announce;
387 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
389 /* prototypes for the special type handlers */
390 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
391 static BOOL handle_include(char *pszParmValue, char **ptr);
392 static BOOL handle_copy(char *pszParmValue, char **ptr);
393 static BOOL handle_character_set(char *pszParmValue,char **ptr);
394 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
396 static void set_default_server_announce_type(void);
398 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
399 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
400 {PROTOCOL_COREPLUS, "COREPLUS"},
401 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
403 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
404 {SEC_SERVER, "SERVER"}, {-1, NULL}};
406 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
407 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
408 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
409 {PRINT_LPRNG, "lprng"}, {-1, NULL}};
411 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
412 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
414 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
416 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
418 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
419 static struct parm_struct parm_table[] =
421 {"Base Options", P_SEP, P_SEPARATOR},
422 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
423 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
424 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
425 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
426 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL, NULL, FLAG_BASIC},
427 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
428 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
429 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
430 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
432 {"Security Options", P_SEP, P_SEPARATOR},
433 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
434 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
435 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
436 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
437 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
438 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
439 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
440 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
441 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
442 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
443 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
444 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
445 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
446 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
447 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
448 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL},
449 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
450 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
451 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
452 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
453 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
454 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
455 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
456 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
457 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
458 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
459 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
460 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
461 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
462 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
463 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
464 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
465 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
466 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
467 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
468 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
469 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
470 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
471 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
472 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
473 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
474 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
475 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
476 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
477 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
478 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
479 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
480 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
482 {"Logging Options", P_SEP, P_SEPARATOR},
483 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
484 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
485 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
486 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
487 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
488 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
489 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
491 {"Protocol Options", P_SEP, P_SEPARATOR},
492 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
493 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
494 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
495 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
496 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
497 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
498 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
499 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
500 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
501 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
502 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
503 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
504 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
505 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
506 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
507 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
509 {"Tuning Options", P_SEP, P_SEPARATOR},
510 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
511 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
512 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
513 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
514 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
515 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
516 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
517 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
518 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
519 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
520 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
521 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
523 {"Printing Options", P_SEP, P_SEPARATOR},
524 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
525 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
526 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
527 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
528 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
529 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
530 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
531 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
532 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
533 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
534 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
535 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
536 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
537 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
538 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
539 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
540 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
543 {"Filename Handling", P_SEP, P_SEPARATOR},
544 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
545 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
546 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
547 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
548 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
549 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
550 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
551 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
552 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
553 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
554 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
555 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
556 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
557 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
558 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
559 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
560 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
561 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
562 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
563 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
564 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
565 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
567 {"Domain Options", P_SEP, P_SEPARATOR},
568 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
569 {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL, 0},
570 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
571 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
572 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
573 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
574 {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
575 {"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
576 {"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
577 {"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
579 {"Logon Options", P_SEP, P_SEPARATOR},
580 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
581 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
582 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
583 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
584 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
586 {"Browse Options", P_SEP, P_SEPARATOR},
587 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, 0},
588 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
589 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
590 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
591 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
592 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, 0},
593 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, 0},
594 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
595 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
596 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
598 {"WINS Options", P_SEP, P_SEPARATOR},
599 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
600 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
601 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
602 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
604 {"Locking Options", P_SEP, P_SEPARATOR},
605 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
606 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
607 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
608 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
609 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
611 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
612 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
613 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
614 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
615 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
616 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
617 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
618 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
619 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
620 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
621 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
622 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
623 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
624 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
625 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
626 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
627 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
628 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
629 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
630 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
631 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
632 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
633 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
634 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
635 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
636 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
637 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
638 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
639 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
640 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
641 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
642 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
643 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
644 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
645 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
646 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
647 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
648 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
650 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
651 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
656 /***************************************************************************
657 Initialise the global parameter structure.
658 ***************************************************************************/
659 static void init_globals(void)
661 static BOOL done_init = False;
667 bzero((void *)&Globals,sizeof(Globals));
669 for (i = 0; parm_table[i].label; i++)
670 if ((parm_table[i].type == P_STRING ||
671 parm_table[i].type == P_USTRING) &&
673 string_init(parm_table[i].ptr,"");
675 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
676 string_set(&sDefault.szPrinterDriver, "NULL");
682 DEBUG(3,("Initialising global parameters\n"));
684 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
685 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
686 string_set(&Globals.szWorkGroup, WORKGROUP);
687 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
688 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
689 string_set(&Globals.szDriverFile, DRIVERFILE);
690 string_set(&Globals.szLockDir, LOCKDIR);
691 string_set(&Globals.szRootdir, "/");
692 string_set(&Globals.szSmbrun, SMBRUN);
693 string_set(&Globals.szSocketAddress, "0.0.0.0");
694 sprintf(s,"Samba %s",VERSION);
695 string_set(&Globals.szServerString,s);
696 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
697 string_set(&Globals.szAnnounceVersion,s);
699 string_set(&Globals.szLogonDrive, "");
700 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
701 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
702 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
704 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
706 Globals.bLoadPrinters = True;
707 Globals.bUseRhosts = False;
708 Globals.max_packet = 65535;
709 Globals.mangled_stack = 50;
710 Globals.max_xmit = 65535;
711 Globals.max_mux = 50; /* This is *needed* for profile support. */
712 Globals.lpqcachetime = 10;
713 Globals.pwordlevel = 0;
714 Globals.unamelevel = 0;
715 Globals.deadtime = 0;
716 Globals.max_log_size = 5000;
717 Globals.maxprotocol = PROTOCOL_NT1;
718 Globals.security = SEC_SHARE;
719 Globals.bEncryptPasswords = False;
720 Globals.bReadRaw = True;
721 Globals.bWriteRaw = True;
722 Globals.bReadPrediction = False;
723 Globals.bReadbmpx = True;
724 Globals.bNullPasswords = False;
725 Globals.bStripDot = False;
727 Globals.bSyslogOnly = False;
728 Globals.os_level = 0;
729 Globals.max_ttl = 60*60*4; /* 4 hours default */
730 Globals.max_wins_ttl = 60*60*24*3; /* 3 days default */
731 Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
732 Globals.ReadSize = 16*1024;
733 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
734 Globals.lm_interval = 60;
735 Globals.shmem_size = SHMEM_SIZE;
736 Globals.announce_as = ANNOUNCE_AS_NT;
737 Globals.bUnixRealname = False;
738 #if (defined(NETGROUP) && defined(AUTOMOUNT))
739 Globals.bNISHomeMap = False;
740 string_set(&Globals.szNISHomeMapName, "auto.home");
742 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
743 Globals.bTimeServer = False;
744 Globals.bBindInterfacesOnly = False;
745 Globals.bNetWkstaUserLogon = True;
747 /* these parameters are set to defaults that are more appropriate
748 for the increasing samba install base:
750 as a member of the workgroup, that will possibly become a
751 _local_ master browser (lm = True). this is opposed to a forced
752 local master browser startup (pm = True).
754 doesn't provide WINS server service by default (wsupp = False),
755 and doesn't provide domain master browser services by default, either.
759 Globals.bPreferredMaster = False;
760 Globals.bLocalMaster = True;
761 Globals.bDomainMaster = False;
762 Globals.bDomainLogons = False;
763 Globals.bBrowseList = True;
764 Globals.bWINSsupport = False;
765 Globals.bWINSproxy = False;
767 Globals.bDNSproxy = True;
770 * This must be done last as it checks the value in
774 interpret_coding_system(KANJI);
777 /***************************************************************************
778 check if a string is initialised and if not then initialise it
779 ***************************************************************************/
780 static void string_initial(char **s,char *v)
787 /***************************************************************************
788 Initialise the sDefault parameter structure.
789 ***************************************************************************/
790 static void init_locals(void)
792 /* choose defaults depending on the type of printing */
793 switch (sDefault.iPrinting)
799 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
800 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
801 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
806 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
807 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
808 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
810 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
811 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
816 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
817 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
818 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
826 /******************************************************************* a
827 convenience routine to grab string parameters into a rotating buffer,
828 and run standard_sub_basic on them. The buffers can be written to by
829 callers without affecting the source string.
830 ********************************************************************/
831 char *lp_string(char *s)
833 static char *bufs[10];
834 static int buflen[10];
835 static int next = -1;
838 int len = s?strlen(s):0;
849 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
852 if (buflen[next] != len) {
854 if (bufs[next]) free(bufs[next]);
855 bufs[next] = (char *)malloc(len);
857 DEBUG(0,("out of memory in lp_string()"));
862 ret = &bufs[next][0];
870 trim_string(ret, "\"", "\"");
872 standard_sub_basic(ret);
878 In this section all the functions that are used to access the
879 parameters from the rest of the program are defined
882 #define FN_GLOBAL_STRING(fn_name,ptr) \
883 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
884 #define FN_GLOBAL_BOOL(fn_name,ptr) \
885 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
886 #define FN_GLOBAL_CHAR(fn_name,ptr) \
887 char fn_name(void) {return(*(char *)(ptr));}
888 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
889 int fn_name(void) {return(*(int *)(ptr));}
891 #define FN_LOCAL_STRING(fn_name,val) \
892 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
893 #define FN_LOCAL_BOOL(fn_name,val) \
894 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
895 #define FN_LOCAL_CHAR(fn_name,val) \
896 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
897 #define FN_LOCAL_INTEGER(fn_name,val) \
898 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
900 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
901 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
902 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
903 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
904 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
905 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
906 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
907 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
908 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
909 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
910 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
911 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
912 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
913 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
914 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
915 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
916 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
917 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
918 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
919 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
920 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
921 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
922 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
923 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
924 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
925 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
926 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
927 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
928 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
929 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
930 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
931 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
932 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
934 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
935 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
936 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
937 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
938 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
939 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
940 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
942 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
943 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
944 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
945 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
946 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
947 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
948 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
949 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
950 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
951 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
952 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
953 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
954 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
955 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
956 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
957 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
958 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
959 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
960 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
961 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
962 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
963 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
964 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
965 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
966 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
967 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
969 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
970 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
971 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
972 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
973 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
974 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
975 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
976 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
977 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
978 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
979 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
980 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
981 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
982 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
983 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
984 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
985 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
986 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
987 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
988 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
989 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
990 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
991 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
992 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
994 FN_LOCAL_STRING(lp_preexec,szPreExec)
995 FN_LOCAL_STRING(lp_postexec,szPostExec)
996 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
997 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
998 FN_LOCAL_STRING(lp_servicename,szService)
999 FN_LOCAL_STRING(lp_pathname,szPath)
1000 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1001 FN_LOCAL_STRING(lp_username,szUsername)
1002 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1003 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1004 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1005 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1006 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1007 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1008 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1009 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1010 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1011 FN_LOCAL_STRING(lp_printername,szPrintername)
1012 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1013 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1014 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1015 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1016 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1017 FN_LOCAL_STRING(lp_comment,comment)
1018 FN_LOCAL_STRING(lp_force_user,force_user)
1019 FN_LOCAL_STRING(lp_force_group,force_group)
1020 FN_LOCAL_STRING(lp_readlist,readlist)
1021 FN_LOCAL_STRING(lp_writelist,writelist)
1022 FN_LOCAL_STRING(lp_volume,volume)
1023 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1024 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1025 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1026 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1027 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1029 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
1030 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1031 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1032 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1033 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1034 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1035 FN_LOCAL_BOOL(lp_status,status)
1036 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1037 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1038 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1039 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1040 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1041 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1042 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1043 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1044 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1045 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1046 FN_LOCAL_BOOL(lp_locking,bLocking)
1047 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1048 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1049 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1050 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1051 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1052 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1053 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1054 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1055 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1056 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1057 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1058 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1059 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1060 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1061 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1063 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1064 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1065 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1066 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1067 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1068 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1069 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1070 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1072 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1076 /* local prototypes */
1077 static int strwicmp( char *psz1, char *psz2 );
1078 static int map_parameter( char *pszParmName);
1079 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1080 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1081 static void copy_service( service *pserviceDest,
1082 service *pserviceSource,
1083 BOOL *pcopymapDest );
1084 static BOOL service_ok(int iService);
1085 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1086 static BOOL do_section(char *pszSectionName);
1087 static void init_copymap(service *pservice);
1090 /***************************************************************************
1091 initialise a service to the defaults
1092 ***************************************************************************/
1093 static void init_service(service *pservice)
1095 bzero((char *)pservice,sizeof(service));
1096 copy_service(pservice,&sDefault,NULL);
1100 /***************************************************************************
1101 free the dynamically allocated parts of a service struct
1102 ***************************************************************************/
1103 static void free_service(service *pservice)
1109 if(pservice->szService)
1110 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1112 string_free(&pservice->szService);
1113 if (pservice->copymap)
1115 free(pservice->copymap);
1116 pservice->copymap = NULL;
1119 for (i=0;parm_table[i].label;i++)
1120 if ((parm_table[i].type == P_STRING ||
1121 parm_table[i].type == P_USTRING) &&
1122 parm_table[i].class == P_LOCAL)
1123 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1126 /***************************************************************************
1127 add a new service to the services array initialising it with the given
1129 ***************************************************************************/
1130 static int add_a_service(service *pservice, char *name)
1134 int num_to_alloc = iNumServices+1;
1136 tservice = *pservice;
1138 /* it might already exist */
1141 i = getservicebyname(name,NULL);
1146 /* find an invalid one */
1147 for (i=0;i<iNumServices;i++)
1148 if (!pSERVICE(i)->valid)
1151 /* if not, then create one */
1152 if (i == iNumServices)
1154 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1156 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1158 if (!ServicePtrs || !pSERVICE(iNumServices))
1164 free_service(pSERVICE(i));
1166 pSERVICE(i)->valid = True;
1168 init_service(pSERVICE(i));
1169 copy_service(pSERVICE(i),&tservice,NULL);
1171 string_set(&iSERVICE(i).szService,name);
1176 /***************************************************************************
1177 add a new home service, with the specified home directory, defaults coming
1179 ***************************************************************************/
1180 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1182 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1187 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1188 string_set(&iSERVICE(i).szPath,pszHomedir);
1189 if (!(*(iSERVICE(i).comment)))
1192 sprintf(comment,"Home directory of %s",pszHomename);
1193 string_set(&iSERVICE(i).comment,comment);
1195 iSERVICE(i).bAvailable = sDefault.bAvailable;
1196 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1198 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1203 /***************************************************************************
1204 add a new service, based on an old one
1205 ***************************************************************************/
1206 int lp_add_service(char *pszService, int iDefaultService)
1208 return(add_a_service(pSERVICE(iDefaultService),pszService));
1212 /***************************************************************************
1214 ***************************************************************************/
1215 static BOOL lp_add_ipc(void)
1218 int i = add_a_service(&sDefault,"IPC$");
1223 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1225 string_set(&iSERVICE(i).szPath,tmpdir());
1226 string_set(&iSERVICE(i).szUsername,"");
1227 string_set(&iSERVICE(i).comment,comment);
1228 iSERVICE(i).status = False;
1229 iSERVICE(i).iMaxConnections = 0;
1230 iSERVICE(i).bAvailable = True;
1231 iSERVICE(i).bRead_only = True;
1232 iSERVICE(i).bGuest_only = False;
1233 iSERVICE(i).bGuest_ok = True;
1234 iSERVICE(i).bPrint_ok = False;
1235 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1237 DEBUG(3,("adding IPC service\n"));
1243 /***************************************************************************
1244 add a new printer service, with defaults coming from service iFrom
1245 ***************************************************************************/
1246 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1248 char *comment = "From Printcap";
1249 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1254 /* note that we do NOT default the availability flag to True - */
1255 /* we take it from the default service passed. This allows all */
1256 /* dynamic printers to be disabled by disabling the [printers] */
1257 /* entry (if/when the 'available' keyword is implemented!). */
1259 /* the printer name is set to the service name. */
1260 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1261 string_set(&iSERVICE(i).comment,comment);
1262 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1263 /* Printers cannot be read_only. */
1264 iSERVICE(i).bRead_only = False;
1265 /* No share modes on printer services. */
1266 iSERVICE(i).bShareModes = False;
1267 /* No oplocks on printer services. */
1268 iSERVICE(i).bOpLocks = False;
1269 /* Printer services must be printable. */
1270 iSERVICE(i).bPrint_ok = True;
1272 DEBUG(3,("adding printer service %s\n",pszPrintername));
1278 /***************************************************************************
1279 Do a case-insensitive, whitespace-ignoring string compare.
1280 ***************************************************************************/
1281 static int strwicmp(char *psz1, char *psz2)
1283 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1284 /* appropriate value. */
1294 /* sync the strings on first non-whitespace */
1297 while (isspace(*psz1))
1299 while (isspace(*psz2))
1301 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1306 return (*psz1 - *psz2);
1309 /***************************************************************************
1310 Map a parameter's string representation to something we can use.
1311 Returns False if the parameter string is not recognised, else TRUE.
1312 ***************************************************************************/
1313 static int map_parameter(char *pszParmName)
1317 if (*pszParmName == '-')
1320 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1321 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1324 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1329 /***************************************************************************
1330 Set a boolean variable from the text value stored in the passed string.
1331 Returns True in success, False if the passed string does not correctly
1332 represent a boolean.
1333 ***************************************************************************/
1334 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1339 if (strwicmp(pszParmValue, "yes") == 0 ||
1340 strwicmp(pszParmValue, "true") == 0 ||
1341 strwicmp(pszParmValue, "1") == 0)
1344 if (strwicmp(pszParmValue, "no") == 0 ||
1345 strwicmp(pszParmValue, "False") == 0 ||
1346 strwicmp(pszParmValue, "0") == 0)
1350 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1357 /***************************************************************************
1358 Find a service by name. Otherwise works like get_service.
1359 ***************************************************************************/
1360 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1364 for (iService = iNumServices - 1; iService >= 0; iService--)
1365 if (VALID(iService) &&
1366 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1368 if (pserviceDest != NULL)
1369 copy_service(pserviceDest, pSERVICE(iService), NULL);
1378 /***************************************************************************
1379 Copy a service structure to another
1381 If pcopymapDest is NULL then copy all fields
1382 ***************************************************************************/
1383 static void copy_service(service *pserviceDest,
1384 service *pserviceSource,
1388 BOOL bcopyall = (pcopymapDest == NULL);
1390 for (i=0;parm_table[i].label;i++)
1391 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1392 (bcopyall || pcopymapDest[i]))
1394 void *def_ptr = parm_table[i].ptr;
1396 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1398 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1400 switch (parm_table[i].type)
1404 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1410 *(int *)dest_ptr = *(int *)src_ptr;
1414 *(char *)dest_ptr = *(char *)src_ptr;
1418 string_set(dest_ptr,*(char **)src_ptr);
1422 string_set(dest_ptr,*(char **)src_ptr);
1423 strupper(*(char **)dest_ptr);
1432 init_copymap(pserviceDest);
1433 if (pserviceSource->copymap)
1434 memcpy((void *)pserviceDest->copymap,
1435 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1439 /***************************************************************************
1440 Check a service for consistency. Return False if the service is in any way
1441 incomplete or faulty, else True.
1442 ***************************************************************************/
1443 static BOOL service_ok(int iService)
1448 if (iSERVICE(iService).szService[0] == '\0')
1450 DEBUG(0,( "The following message indicates an internal error:\n"));
1451 DEBUG(0,( "No service name in service entry.\n"));
1455 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1456 /* I can't see why you'd want a non-printable printer service... */
1457 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1458 if (!iSERVICE(iService).bPrint_ok)
1460 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1461 iSERVICE(iService).szService));
1462 iSERVICE(iService).bPrint_ok = True;
1465 if (iSERVICE(iService).szPath[0] == '\0' &&
1466 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1468 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1469 string_set(&iSERVICE(iService).szPath,tmpdir());
1472 /* If a service is flagged unavailable, log the fact at level 0. */
1473 if (!iSERVICE(iService).bAvailable)
1474 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1475 iSERVICE(iService).szService));
1480 static struct file_lists {
1481 struct file_lists *next;
1484 } *file_lists = NULL;
1486 /*******************************************************************
1487 keep a linked list of all config files so we know when one has changed
1488 it's date and needs to be reloaded
1489 ********************************************************************/
1490 static void add_to_file_list(char *fname)
1492 struct file_lists *f=file_lists;
1495 if (f->name && !strcmp(f->name,fname)) break;
1500 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1502 f->next = file_lists;
1503 f->name = strdup(fname);
1514 standard_sub_basic(n2);
1515 f->modtime = file_modtime(n2);
1520 /*******************************************************************
1521 check if a config file has changed date
1522 ********************************************************************/
1523 BOOL lp_file_list_changed(void)
1525 struct file_lists *f = file_lists;
1526 DEBUG(6,("lp_file_list_changed()\n"));
1533 pstrcpy(n2,f->name);
1534 standard_sub_basic(n2);
1536 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1537 f->name, n2, ctime(&f->modtime)));
1539 mod_time = file_modtime(n2);
1541 if (f->modtime != mod_time) {
1542 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1543 f->modtime = mod_time;
1551 /***************************************************************************
1552 handle the interpretation of the coding system parameter
1553 *************************************************************************/
1554 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1556 string_set(ptr,pszParmValue);
1557 interpret_coding_system(pszParmValue);
1561 /***************************************************************************
1562 handle the interpretation of the character set system parameter
1563 ***************************************************************************/
1564 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1566 string_set(ptr,pszParmValue);
1567 interpret_character_set(pszParmValue);
1572 /***************************************************************************
1573 handle the valid chars lines
1574 ***************************************************************************/
1575 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1577 string_set(ptr,pszParmValue);
1579 /* A dependency here is that the parameter client code page must be
1580 set before this is called - as calling codepage_initialise()
1581 would overwrite the valid char lines.
1583 codepage_initialise(lp_client_code_page());
1585 add_char_string(pszParmValue);
1590 /***************************************************************************
1591 handle the include operation
1592 ***************************************************************************/
1593 static BOOL handle_include(char *pszParmValue,char **ptr)
1596 pstrcpy(fname,pszParmValue);
1598 add_to_file_list(fname);
1600 standard_sub_basic(fname);
1602 string_set(ptr,fname);
1604 if (file_exist(fname,NULL))
1605 return(pm_process(fname, do_section, do_parameter));
1607 DEBUG(2,("Can't find include file %s\n",fname));
1613 /***************************************************************************
1614 handle the interpretation of the copy parameter
1615 ***************************************************************************/
1616 static BOOL handle_copy(char *pszParmValue,char **ptr)
1620 service serviceTemp;
1622 string_set(ptr,pszParmValue);
1624 init_service(&serviceTemp);
1628 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1630 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1632 if (iTemp == iServiceIndex)
1634 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1639 copy_service(pSERVICE(iServiceIndex),
1641 iSERVICE(iServiceIndex).copymap);
1647 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1652 free_service(&serviceTemp);
1657 /***************************************************************************
1658 initialise a copymap
1659 ***************************************************************************/
1660 static void init_copymap(service *pservice)
1663 if (pservice->copymap) free(pservice->copymap);
1664 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1665 if (!pservice->copymap)
1666 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1668 for (i=0;i<NUMPARAMETERS;i++)
1669 pservice->copymap[i] = True;
1673 /***************************************************************************
1674 return the local pointer to a parameter given the service number and the
1675 pointer into the default structure
1676 ***************************************************************************/
1677 void *lp_local_ptr(int snum, void *ptr)
1679 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1682 /***************************************************************************
1683 Process a parameter for a particular service number. If snum < 0
1684 then assume we are in the globals
1685 ***************************************************************************/
1686 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1689 void *parm_ptr=NULL; /* where we are going to store the result */
1692 parmnum = map_parameter(pszParmName);
1696 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1700 def_ptr = parm_table[parmnum].ptr;
1702 /* we might point at a service, the default service or a global */
1706 if (parm_table[parmnum].class == P_GLOBAL) {
1707 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1710 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1714 if (!iSERVICE(snum).copymap)
1715 init_copymap(pSERVICE(snum));
1717 /* this handles the aliases - set the copymap for other entries with
1718 the same data pointer */
1719 for (i=0;parm_table[i].label;i++)
1720 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1721 iSERVICE(snum).copymap[i] = False;
1724 /* if it is a special case then go ahead */
1725 if (parm_table[parmnum].special) {
1726 parm_table[parmnum].special(pszParmValue,parm_ptr);
1730 /* now switch on the type of variable it is */
1731 switch (parm_table[parmnum].type)
1734 set_boolean(parm_ptr,pszParmValue);
1738 set_boolean(parm_ptr,pszParmValue);
1739 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1743 *(int *)parm_ptr = atoi(pszParmValue);
1747 *(char *)parm_ptr = *pszParmValue;
1751 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1755 string_set(parm_ptr,pszParmValue);
1759 string_set(parm_ptr,pszParmValue);
1760 strupper(*(char **)parm_ptr);
1764 strcpy((char *)parm_ptr,pszParmValue);
1768 strcpy((char *)parm_ptr,pszParmValue);
1769 strupper((char *)parm_ptr);
1773 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1774 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1775 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1787 /***************************************************************************
1788 Process a parameter.
1789 ***************************************************************************/
1790 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1792 if (!bInGlobalSection && bGlobalOnly) return(True);
1794 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1796 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1800 /***************************************************************************
1801 print a parameter of the specified type
1802 ***************************************************************************/
1803 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1808 for (i=0;p->enum_list[i].name;i++) {
1809 if (*(int *)ptr == p->enum_list[i].value) {
1810 fprintf(f,"%s",p->enum_list[i].name);
1817 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1821 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1825 fprintf(f,"%d",*(int *)ptr);
1829 fprintf(f,"%c",*(char *)ptr);
1833 fprintf(f,"0%o",*(int *)ptr);
1839 fprintf(f,"%s",(char *)ptr);
1845 fprintf(f,"%s",*(char **)ptr);
1853 /***************************************************************************
1854 check if two parameters are equal
1855 ***************************************************************************/
1856 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1862 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1867 return(*((int *)ptr1) == *((int *)ptr2));
1870 return(*((char *)ptr1) == *((char *)ptr2));
1875 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1876 if (p1 && !*p1) p1 = NULL;
1877 if (p2 && !*p2) p2 = NULL;
1878 return(p1==p2 || strequal(p1,p2));
1883 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1884 if (p1 && !*p1) p1 = NULL;
1885 if (p2 && !*p2) p2 = NULL;
1886 return(p1==p2 || strequal(p1,p2));
1894 /***************************************************************************
1895 Process a new section (service). At this stage all sections are services.
1896 Later we'll have special sections that permit server parameters to be set.
1897 Returns True on success, False on failure.
1898 ***************************************************************************/
1899 static BOOL do_section(char *pszSectionName)
1902 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1903 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1906 /* if we were in a global section then do the local inits */
1907 if (bInGlobalSection && !isglobal)
1910 /* if we've just struck a global section, note the fact. */
1911 bInGlobalSection = isglobal;
1913 /* check for multiple global sections */
1914 if (bInGlobalSection)
1916 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1920 if (!bInGlobalSection && bGlobalOnly) return(True);
1922 /* if we have a current service, tidy it up before moving on */
1925 if (iServiceIndex >= 0)
1926 bRetval = service_ok(iServiceIndex);
1928 /* if all is still well, move to the next record in the services array */
1931 /* We put this here to avoid an odd message order if messages are */
1932 /* issued by the post-processing of a previous section. */
1933 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1935 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1937 DEBUG(0,("Failed to add a new service\n"));
1946 /***************************************************************************
1947 determine if a partcular base parameter is currently set to the default value.
1948 ***************************************************************************/
1949 static BOOL is_default(int i)
1951 if (!defaults_saved) return False;
1952 switch (parm_table[i].type) {
1955 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
1958 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
1961 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
1963 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
1967 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
1975 /***************************************************************************
1976 Display the contents of the global structure.
1977 ***************************************************************************/
1978 static void dump_globals(FILE *f)
1981 fprintf(f, "# Global parameters\n");
1983 for (i=0;parm_table[i].label;i++)
1984 if (parm_table[i].class == P_GLOBAL &&
1985 parm_table[i].ptr &&
1986 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
1987 if (defaults_saved && is_default(i)) continue;
1988 fprintf(f,"\t%s = ",parm_table[i].label);
1989 print_parameter(&parm_table[i],parm_table[i].ptr, f);
1994 /***************************************************************************
1995 return True if a local parameter is currently set to the global default
1996 ***************************************************************************/
1997 BOOL lp_is_default(int snum, struct parm_struct *parm)
1999 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2001 return equal_parameter(parm->type,
2002 ((char *)pSERVICE(snum)) + pdiff,
2003 ((char *)&sDefault) + pdiff);
2007 /***************************************************************************
2008 Display the contents of a single services record.
2009 ***************************************************************************/
2010 static void dump_a_service(service *pService, FILE *f)
2013 if (pService != &sDefault)
2014 fprintf(f,"\n[%s]\n",pService->szService);
2016 for (i=0;parm_table[i].label;i++)
2017 if (parm_table[i].class == P_LOCAL &&
2018 parm_table[i].ptr &&
2019 (*parm_table[i].label != '-') &&
2020 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2021 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2023 if (pService == &sDefault) {
2024 if (defaults_saved && is_default(i)) continue;
2026 if (equal_parameter(parm_table[i].type,
2027 ((char *)pService) + pdiff,
2028 ((char *)&sDefault) + pdiff))
2032 fprintf(f,"\t%s = ",parm_table[i].label);
2033 print_parameter(&parm_table[i],
2034 ((char *)pService) + pdiff, f);
2040 /***************************************************************************
2041 return info about the next service in a service. snum==-1 gives the globals
2043 return NULL when out of parameters
2044 ***************************************************************************/
2045 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2048 /* do the globals */
2049 for (;parm_table[*i].label;(*i)++) {
2050 if (parm_table[*i].class == P_SEPARATOR)
2051 return &parm_table[(*i)++];
2053 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2056 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2059 return &parm_table[(*i)++];
2062 service *pService = pSERVICE(snum);
2064 for (;parm_table[*i].label;(*i)++) {
2065 if (parm_table[*i].class == P_SEPARATOR)
2066 return &parm_table[(*i)++];
2068 if (parm_table[*i].class == P_LOCAL &&
2069 parm_table[*i].ptr &&
2070 (*parm_table[*i].label != '-') &&
2072 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2073 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2075 if (allparameters ||
2076 !equal_parameter(parm_table[*i].type,
2077 ((char *)pService) + pdiff,
2078 ((char *)&sDefault) + pdiff)) {
2079 return &parm_table[(*i)++];
2090 /***************************************************************************
2091 Display the contents of a single copy structure.
2092 ***************************************************************************/
2093 static void dump_copy_map(BOOL *pcopymap)
2096 if (!pcopymap) return;
2098 printf("\n\tNon-Copied parameters:\n");
2100 for (i=0;parm_table[i].label;i++)
2101 if (parm_table[i].class == P_LOCAL &&
2102 parm_table[i].ptr && !pcopymap[i] &&
2103 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2105 printf("\t\t%s\n",parm_table[i].label);
2110 /***************************************************************************
2111 Return TRUE if the passed service number is within range.
2112 ***************************************************************************/
2113 BOOL lp_snum_ok(int iService)
2115 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2119 /***************************************************************************
2120 auto-load some homes and printer services
2121 ***************************************************************************/
2122 static void lp_add_auto_services(char *str)
2126 int homes = lp_servicenumber(HOMES_NAME);
2127 int printers = lp_servicenumber(PRINTERS_NAME);
2135 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2137 char *home = get_home_dir(p);
2139 if (lp_servicenumber(p) >= 0) continue;
2141 if (home && homes >= 0)
2143 lp_add_home(p,homes,home);
2147 if (printers >= 0 && pcap_printername_ok(p,NULL))
2148 lp_add_printer(p,printers);
2153 /***************************************************************************
2154 auto-load one printer
2155 ***************************************************************************/
2156 static void lp_add_one_printer(char *name,char *comment)
2158 int printers = lp_servicenumber(PRINTERS_NAME);
2161 if (lp_servicenumber(name) < 0)
2163 lp_add_printer(name,printers);
2164 if ((i=lp_servicenumber(name)) >= 0)
2165 string_set(&iSERVICE(i).comment,comment);
2170 /***************************************************************************
2171 auto-load printer services
2172 ***************************************************************************/
2173 static void lp_add_all_printers(void)
2175 int printers = lp_servicenumber(PRINTERS_NAME);
2177 if (printers < 0) return;
2179 pcap_printer_fn(lp_add_one_printer);
2182 /***************************************************************************
2183 have we loaded a services file yet?
2184 ***************************************************************************/
2185 BOOL lp_loaded(void)
2190 /***************************************************************************
2191 unload unused services
2192 ***************************************************************************/
2193 void lp_killunused(BOOL (*snumused)(int ))
2196 for (i=0;i<iNumServices;i++)
2197 if (VALID(i) && (!snumused || !snumused(i)))
2199 iSERVICE(i).valid = False;
2200 free_service(pSERVICE(i));
2205 /***************************************************************************
2206 save the curent values of all global and sDefault parameters into the
2207 defaults union. This allows swat and testparm to show only the
2208 changed (ie. non-default) parameters.
2209 ***************************************************************************/
2210 static void lp_save_defaults(void)
2213 for (i = 0; parm_table[i].label; i++) {
2214 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2215 switch (parm_table[i].type) {
2218 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2222 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2226 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2229 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2234 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2240 defaults_saved = True;
2244 /***************************************************************************
2245 Load the services array from the services file. Return True on success,
2247 ***************************************************************************/
2248 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2253 add_to_file_list(pszFname);
2257 bInGlobalSection = True;
2258 bGlobalOnly = global_only;
2262 if (save_defaults) {
2267 pstrcpy(n2,pszFname);
2268 standard_sub_basic(n2);
2270 /* We get sections first, so have to start 'behind' to make up */
2272 bRetval = pm_process(n2, do_section, do_parameter);
2274 /* finish up the last section */
2275 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2277 if (iServiceIndex >= 0)
2278 bRetval = service_ok(iServiceIndex);
2280 lp_add_auto_services(lp_auto_services());
2281 if (lp_load_printers())
2282 lp_add_all_printers();
2287 set_default_server_announce_type();
2295 /***************************************************************************
2296 return the max number of services
2297 ***************************************************************************/
2298 int lp_numservices(void)
2300 return(iNumServices);
2303 /***************************************************************************
2304 Display the contents of the services array in human-readable form.
2305 ***************************************************************************/
2306 void lp_dump(FILE *f)
2312 dump_a_service(&sDefault, f);
2314 for (iService = 0; iService < iNumServices; iService++)
2316 if (VALID(iService))
2318 if (iSERVICE(iService).szService[0] == '\0')
2320 dump_a_service(pSERVICE(iService), f);
2326 /***************************************************************************
2327 Return the number of the service with the given name, or -1 if it doesn't
2328 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2329 getservicebyname()! This works ONLY if all services have been loaded, and
2330 does not copy the found service.
2331 ***************************************************************************/
2332 int lp_servicenumber(char *pszServiceName)
2336 for (iService = iNumServices - 1; iService >= 0; iService--)
2337 if (VALID(iService) &&
2338 strequal(lp_servicename(iService), pszServiceName))
2342 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2347 /*******************************************************************
2348 a useful volume label function
2349 ******************************************************************/
2350 char *volume_label(int snum)
2352 char *ret = lp_volume(snum);
2353 if (!*ret) return(lp_servicename(snum));
2359 * nmbd only loads the global section. There seems to be no way to
2360 * determine exactly is a service is printable by only looking at the
2361 * [global] section so for now always announce as a print server. This
2362 * will need looking at in the future. Jeremy (jallison@whistle.com).
2364 /*******************************************************************
2365 Return true if any printer services are defined.
2366 ******************************************************************/
2367 static BOOL lp_printer_services(void)
2371 for (iService = iNumServices - 1; iService >= 0; iService--)
2372 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2378 /*******************************************************************
2379 Set the server type we will announce as via nmbd.
2380 ********************************************************************/
2381 static void set_default_server_announce_type()
2383 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2384 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2385 if(lp_announce_as() == ANNOUNCE_AS_NT)
2386 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2387 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2388 default_server_announce |= SV_TYPE_WIN95_PLUS;
2389 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2390 default_server_announce |= SV_TYPE_WFW;
2391 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2393 * nmbd only loads the [global] section. There seems to be no way to
2394 * determine exactly if any service is printable by only looking at the
2395 * [global] section so for now always announce as a print server. This
2396 * will need looking at in the future. Jeremy (jallison@whistle.com).
2399 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2404 /*******************************************************************
2406 ********************************************************************/
2407 void lp_rename_service(int snum, char *new_name)
2409 string_set(&pSERVICE(snum)->szService, new_name);
2412 /*******************************************************************
2414 ********************************************************************/
2415 void lp_remove_service(int snum)
2417 pSERVICE(snum)->valid = False;
2420 /*******************************************************************
2422 ********************************************************************/
2423 void lp_copy_service(int snum, char *new_name)
2425 char *oldname = lp_servicename(snum);
2426 do_section(new_name);
2428 snum = lp_servicenumber(new_name);
2430 lp_do_parameter(snum, "copy", oldname);
2435 /*******************************************************************
2436 Get the default server type we will announce as via nmbd.
2437 ********************************************************************/
2438 int lp_default_server_announce(void)
2440 return default_server_announce;
2443 /*******************************************************************
2444 Split the announce version into major and minor numbers.
2445 ********************************************************************/
2446 int lp_major_announce_version(void)
2448 static BOOL got_major = False;
2449 static int major_version = DEFAULT_MAJOR_VERSION;
2454 return major_version;
2457 if((vers = lp_announce_version()) == NULL)
2458 return major_version;
2460 if((p = strchr(vers, '.')) == 0)
2461 return major_version;
2464 major_version = atoi(vers);
2465 return major_version;
2468 int lp_minor_announce_version(void)
2470 static BOOL got_minor = False;
2471 static int minor_version = DEFAULT_MINOR_VERSION;
2476 return minor_version;
2479 if((vers = lp_announce_version()) == NULL)
2480 return minor_version;
2482 if((p = strchr(vers, '.')) == 0)
2483 return minor_version;
2486 minor_version = atoi(p);
2487 return minor_version;
2490 /***********************************************************
2491 Set the global name resolution order (used in smbclient).
2492 ************************************************************/
2494 void lp_set_name_resolve_order(char *new_order)
2496 Globals.szNameResolveOrder = new_order;