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;
194 BOOL bUnixPasswdSync;
197 static global Globals;
202 * This structure describes a single service.
210 char *szGuestaccount;
211 char *szInvalidUsers;
219 char *szRootPostExec;
220 char *szPrintcommand;
223 char *szLppausecommand;
224 char *szLpresumecommand;
226 char *szPrinterDriver;
227 char *szPrinterDriverLocation;
236 char *szVetoOplockFiles;
245 int iCreate_force_mode;
255 BOOL bShortCasePreserve;
281 BOOL bDeleteReadonly;
283 BOOL bDeleteVetoFiles;
285 BOOL bDosFiletimeResolution;
286 BOOL bFakeDirCreateTimes;
287 char dummy[3]; /* for alignment */
291 /* This is a default service used to prime a services structure */
292 static service sDefault =
295 NULL, /* szService */
297 NULL, /* szUsername */
298 NULL, /* szGuestAccount - this is set in init_globals() */
299 NULL, /* szInvalidUsers */
300 NULL, /* szValidUsers */
301 NULL, /* szAdminUsers */
303 NULL, /* szInclude */
304 NULL, /* szPreExec */
305 NULL, /* szPostExec */
306 NULL, /* szRootPreExec */
307 NULL, /* szRootPostExec */
308 NULL, /* szPrintcommand */
309 NULL, /* szLpqcommand */
310 NULL, /* szLprmcommand */
311 NULL, /* szLppausecommand */
312 NULL, /* szLpresumecommand */
313 NULL, /* szPrintername */
314 NULL, /* szPrinterDriver - this is set in init_globals() */
315 NULL, /* szPrinterDriverLocation */
316 NULL, /* szDontdescend */
317 NULL, /* szHostsallow */
318 NULL, /* szHostsdeny */
319 NULL, /* szMagicScript */
320 NULL, /* szMagicOutput */
321 NULL, /* szMangledMap */
322 NULL, /* szVetoFiles */
323 NULL, /* szHideFiles */
324 NULL, /* szVetoOplockFiles */
326 NULL, /* force user */
327 NULL, /* force group */
329 NULL, /* writelist */
331 0, /* iMinPrintSpace */
332 0744, /* iCreate_mask */
333 0000, /* iCreate_force_mode */
334 0755, /* iDir_mask */
335 0000, /* iDir_force_mode */
336 0, /* iMaxConnections */
337 CASE_LOWER, /* iDefaultCase */
338 DEFAULT_PRINTING, /* iPrinting */
339 False, /* bAlternatePerm */
340 False, /* revalidate */
341 False, /* case sensitive */
342 False, /* case preserve */
343 False, /* short case preserve */
344 False, /* case mangle */
346 True, /* bHideDotFiles */
347 True, /* bBrowseable */
348 True, /* bAvailable */
349 True, /* bRead_only */
350 True, /* bNo_set_dir */
351 False, /* bGuest_only */
352 False, /* bGuest_ok */
353 False, /* bPrint_ok */
354 False, /* bPostscript */
355 False, /* bMap_system */
356 False, /* bMap_hidden */
357 True, /* bMap_archive */
359 False, /* bStrictLocking */
360 True, /* bShareModes */
362 False, /* bOnlyUser */
363 True, /* bMangledNames */
364 True, /* bWidelinks */
365 True, /* bSymlinks */
366 False, /* bSyncAlways */
367 '~', /* magic char */
369 False, /* bDeleteReadonly */
370 False, /* bFakeOplocks */
371 False, /* bDeleteVetoFiles */
372 False, /* bDosFiletimes */
373 False, /* bDosFiletimeResolution */
374 False, /* bFakeDirCreateTimes */
380 /* local variables */
381 static service **ServicePtrs = NULL;
382 static int iNumServices = 0;
383 static int iServiceIndex = 0;
384 static BOOL bInGlobalSection = True;
385 static BOOL bGlobalOnly = False;
386 static int default_server_announce;
388 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
390 /* prototypes for the special type handlers */
391 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
392 static BOOL handle_include(char *pszParmValue, char **ptr);
393 static BOOL handle_copy(char *pszParmValue, char **ptr);
394 static BOOL handle_character_set(char *pszParmValue,char **ptr);
395 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
397 static void set_default_server_announce_type(void);
399 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
400 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
401 {PROTOCOL_COREPLUS, "COREPLUS"},
402 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
404 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
405 {SEC_SERVER, "SERVER"}, {-1, NULL}};
407 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
408 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
409 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
410 {PRINT_LPRNG, "lprng"}, {-1, NULL}};
412 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
413 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
415 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
417 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
419 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
420 static struct parm_struct parm_table[] =
422 {"Base Options", P_SEP, P_SEPARATOR},
423 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
424 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
425 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
426 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
427 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL, NULL, FLAG_BASIC},
428 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
429 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
430 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
431 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
433 {"Security Options", P_SEP, P_SEPARATOR},
434 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
435 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
436 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
437 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
438 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
439 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
440 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
441 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
442 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
443 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
444 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
445 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
446 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
447 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
448 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
449 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
450 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL},
451 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
452 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
453 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
454 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
455 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
456 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
457 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
458 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
459 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
460 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
461 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
462 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
463 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
464 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
465 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
466 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
467 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
468 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
469 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
470 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
471 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
472 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
473 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
474 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
475 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
476 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
477 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
478 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
479 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
480 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
481 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
482 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
484 {"Logging Options", P_SEP, P_SEPARATOR},
485 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
486 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
487 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
488 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
489 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
490 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
491 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
493 {"Protocol Options", P_SEP, P_SEPARATOR},
494 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
495 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
496 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
497 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
498 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
499 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
500 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
501 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
502 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
503 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
504 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
505 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
506 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
507 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
508 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
509 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
511 {"Tuning Options", P_SEP, P_SEPARATOR},
512 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
513 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
514 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
515 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
516 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
517 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
518 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
519 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
520 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
521 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
522 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
523 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
525 {"Printing Options", P_SEP, P_SEPARATOR},
526 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
527 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
528 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
529 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
530 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
531 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
532 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
533 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
534 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
535 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
536 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
537 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
538 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
539 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
540 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
541 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
542 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
545 {"Filename Handling", P_SEP, P_SEPARATOR},
546 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
547 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
548 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
549 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
550 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
551 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
552 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
553 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
554 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
555 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
556 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
557 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
558 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
559 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
560 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
561 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
562 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
563 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
564 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
565 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
566 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
567 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
569 {"Domain Options", P_SEP, P_SEPARATOR},
570 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
571 {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL, 0},
572 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
573 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
574 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
575 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
576 {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
577 {"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
578 {"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
579 {"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
581 {"Logon Options", P_SEP, P_SEPARATOR},
582 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
583 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
584 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
585 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
586 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
588 {"Browse Options", P_SEP, P_SEPARATOR},
589 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, 0},
590 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
591 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
592 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
593 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
594 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, 0},
595 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, 0},
596 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
597 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
598 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
600 {"WINS Options", P_SEP, P_SEPARATOR},
601 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
602 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
603 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
604 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
606 {"Locking Options", P_SEP, P_SEPARATOR},
607 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
608 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
609 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
610 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
611 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
613 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
614 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
615 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
616 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
617 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
618 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
619 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
620 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
621 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
622 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
623 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
624 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
625 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
626 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
627 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
628 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
629 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
630 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
631 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
632 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
633 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
634 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
635 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
636 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
637 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
638 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
639 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
640 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
641 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
642 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
643 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
644 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
645 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
646 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
647 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
648 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
649 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
650 {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
652 {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
653 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
658 /***************************************************************************
659 Initialise the global parameter structure.
660 ***************************************************************************/
661 static void init_globals(void)
663 static BOOL done_init = False;
669 bzero((void *)&Globals,sizeof(Globals));
671 for (i = 0; parm_table[i].label; i++)
672 if ((parm_table[i].type == P_STRING ||
673 parm_table[i].type == P_USTRING) &&
675 string_init(parm_table[i].ptr,"");
677 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
678 string_set(&sDefault.szPrinterDriver, "NULL");
684 DEBUG(3,("Initialising global parameters\n"));
686 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
687 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
688 string_set(&Globals.szWorkGroup, WORKGROUP);
689 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
690 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
691 string_set(&Globals.szDriverFile, DRIVERFILE);
692 string_set(&Globals.szLockDir, LOCKDIR);
693 string_set(&Globals.szRootdir, "/");
694 string_set(&Globals.szSmbrun, SMBRUN);
695 string_set(&Globals.szSocketAddress, "0.0.0.0");
696 sprintf(s,"Samba %s",VERSION);
697 string_set(&Globals.szServerString,s);
698 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
699 string_set(&Globals.szAnnounceVersion,s);
701 string_set(&Globals.szLogonDrive, "");
702 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
703 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
704 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
706 string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast");
708 Globals.bLoadPrinters = True;
709 Globals.bUseRhosts = False;
710 Globals.max_packet = 65535;
711 Globals.mangled_stack = 50;
712 Globals.max_xmit = 65535;
713 Globals.max_mux = 50; /* This is *needed* for profile support. */
714 Globals.lpqcachetime = 10;
715 Globals.pwordlevel = 0;
716 Globals.unamelevel = 0;
717 Globals.deadtime = 0;
718 Globals.max_log_size = 5000;
719 Globals.maxprotocol = PROTOCOL_NT1;
720 Globals.security = SEC_SHARE;
721 Globals.bEncryptPasswords = False;
722 Globals.bReadRaw = True;
723 Globals.bWriteRaw = True;
724 Globals.bReadPrediction = False;
725 Globals.bReadbmpx = True;
726 Globals.bNullPasswords = False;
727 Globals.bStripDot = False;
729 Globals.bSyslogOnly = False;
730 Globals.os_level = 0;
731 Globals.max_ttl = 60*60*4; /* 4 hours default */
732 Globals.max_wins_ttl = 60*60*24*3; /* 3 days default */
733 Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
734 Globals.ReadSize = 16*1024;
735 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
736 Globals.lm_interval = 60;
737 Globals.shmem_size = SHMEM_SIZE;
738 Globals.announce_as = ANNOUNCE_AS_NT;
739 Globals.bUnixRealname = False;
740 #if (defined(NETGROUP) && defined(AUTOMOUNT))
741 Globals.bNISHomeMap = False;
742 string_set(&Globals.szNISHomeMapName, "auto.home");
744 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
745 Globals.bTimeServer = False;
746 Globals.bBindInterfacesOnly = False;
747 Globals.bNetWkstaUserLogon = True;
748 Globals.bUnixPasswdSync = False;
750 /* these parameters are set to defaults that are more appropriate
751 for the increasing samba install base:
753 as a member of the workgroup, that will possibly become a
754 _local_ master browser (lm = True). this is opposed to a forced
755 local master browser startup (pm = True).
757 doesn't provide WINS server service by default (wsupp = False),
758 and doesn't provide domain master browser services by default, either.
762 Globals.bPreferredMaster = False;
763 Globals.bLocalMaster = True;
764 Globals.bDomainMaster = False;
765 Globals.bDomainLogons = False;
766 Globals.bBrowseList = True;
767 Globals.bWINSsupport = False;
768 Globals.bWINSproxy = False;
770 Globals.bDNSproxy = True;
773 * This must be done last as it checks the value in
777 interpret_coding_system(KANJI);
780 /***************************************************************************
781 check if a string is initialised and if not then initialise it
782 ***************************************************************************/
783 static void string_initial(char **s,char *v)
790 /***************************************************************************
791 Initialise the sDefault parameter structure.
792 ***************************************************************************/
793 static void init_locals(void)
795 /* choose defaults depending on the type of printing */
796 switch (sDefault.iPrinting)
802 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
803 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
804 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
809 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
810 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
811 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
813 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
814 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
819 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
820 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
821 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
829 /******************************************************************* a
830 convenience routine to grab string parameters into a rotating buffer,
831 and run standard_sub_basic on them. The buffers can be written to by
832 callers without affecting the source string.
833 ********************************************************************/
834 char *lp_string(char *s)
836 static char *bufs[10];
837 static int buflen[10];
838 static int next = -1;
841 int len = s?strlen(s):0;
852 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
855 if (buflen[next] != len) {
857 if (bufs[next]) free(bufs[next]);
858 bufs[next] = (char *)malloc(len);
860 DEBUG(0,("out of memory in lp_string()"));
865 ret = &bufs[next][0];
873 trim_string(ret, "\"", "\"");
875 standard_sub_basic(ret);
881 In this section all the functions that are used to access the
882 parameters from the rest of the program are defined
885 #define FN_GLOBAL_STRING(fn_name,ptr) \
886 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
887 #define FN_GLOBAL_BOOL(fn_name,ptr) \
888 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
889 #define FN_GLOBAL_CHAR(fn_name,ptr) \
890 char fn_name(void) {return(*(char *)(ptr));}
891 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
892 int fn_name(void) {return(*(int *)(ptr));}
894 #define FN_LOCAL_STRING(fn_name,val) \
895 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
896 #define FN_LOCAL_BOOL(fn_name,val) \
897 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
898 #define FN_LOCAL_CHAR(fn_name,val) \
899 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
900 #define FN_LOCAL_INTEGER(fn_name,val) \
901 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
903 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
904 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
905 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
906 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
907 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
908 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
909 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
910 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
911 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
912 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
913 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
914 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
915 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
916 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
917 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
918 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
919 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
920 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
921 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
922 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
923 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
924 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
925 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
926 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
927 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
928 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
929 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
930 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
931 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
932 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
933 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
934 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
935 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
937 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
938 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
939 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
940 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
941 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
942 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
943 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
945 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
946 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
947 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
948 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
949 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
950 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
951 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
952 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
953 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
954 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
955 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
956 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
957 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
958 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
959 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
960 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
961 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
962 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
963 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
964 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
965 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
966 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
967 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
968 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
969 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
970 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
971 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
973 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
974 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
975 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
976 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
977 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
978 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
979 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
980 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
981 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
982 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
983 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
984 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
985 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
986 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
987 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
988 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
989 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
990 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
991 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
992 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
993 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
994 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
995 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
996 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
998 FN_LOCAL_STRING(lp_preexec,szPreExec)
999 FN_LOCAL_STRING(lp_postexec,szPostExec)
1000 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
1001 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
1002 FN_LOCAL_STRING(lp_servicename,szService)
1003 FN_LOCAL_STRING(lp_pathname,szPath)
1004 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
1005 FN_LOCAL_STRING(lp_username,szUsername)
1006 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
1007 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
1008 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
1009 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
1010 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
1011 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
1012 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
1013 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
1014 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
1015 FN_LOCAL_STRING(lp_printername,szPrintername)
1016 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
1017 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
1018 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
1019 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
1020 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
1021 FN_LOCAL_STRING(lp_comment,comment)
1022 FN_LOCAL_STRING(lp_force_user,force_user)
1023 FN_LOCAL_STRING(lp_force_group,force_group)
1024 FN_LOCAL_STRING(lp_readlist,readlist)
1025 FN_LOCAL_STRING(lp_writelist,writelist)
1026 FN_LOCAL_STRING(lp_volume,volume)
1027 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
1028 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
1029 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
1030 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
1031 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
1033 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
1034 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1035 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1036 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1037 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1038 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1039 FN_LOCAL_BOOL(lp_status,status)
1040 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1041 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1042 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1043 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1044 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1045 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1046 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1047 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1048 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1049 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1050 FN_LOCAL_BOOL(lp_locking,bLocking)
1051 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1052 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1053 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1054 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1055 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1056 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1057 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1058 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1059 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1060 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1061 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1062 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1063 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1064 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1065 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
1067 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1068 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1069 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1070 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1071 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1072 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1073 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1074 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1076 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1080 /* local prototypes */
1081 static int strwicmp( char *psz1, char *psz2 );
1082 static int map_parameter( char *pszParmName);
1083 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1084 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1085 static void copy_service( service *pserviceDest,
1086 service *pserviceSource,
1087 BOOL *pcopymapDest );
1088 static BOOL service_ok(int iService);
1089 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1090 static BOOL do_section(char *pszSectionName);
1091 static void init_copymap(service *pservice);
1094 /***************************************************************************
1095 initialise a service to the defaults
1096 ***************************************************************************/
1097 static void init_service(service *pservice)
1099 bzero((char *)pservice,sizeof(service));
1100 copy_service(pservice,&sDefault,NULL);
1104 /***************************************************************************
1105 free the dynamically allocated parts of a service struct
1106 ***************************************************************************/
1107 static void free_service(service *pservice)
1113 if(pservice->szService)
1114 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1116 string_free(&pservice->szService);
1117 if (pservice->copymap)
1119 free(pservice->copymap);
1120 pservice->copymap = NULL;
1123 for (i=0;parm_table[i].label;i++)
1124 if ((parm_table[i].type == P_STRING ||
1125 parm_table[i].type == P_USTRING) &&
1126 parm_table[i].class == P_LOCAL)
1127 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1130 /***************************************************************************
1131 add a new service to the services array initialising it with the given
1133 ***************************************************************************/
1134 static int add_a_service(service *pservice, char *name)
1138 int num_to_alloc = iNumServices+1;
1140 tservice = *pservice;
1142 /* it might already exist */
1145 i = getservicebyname(name,NULL);
1150 /* find an invalid one */
1151 for (i=0;i<iNumServices;i++)
1152 if (!pSERVICE(i)->valid)
1155 /* if not, then create one */
1156 if (i == iNumServices)
1158 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1160 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1162 if (!ServicePtrs || !pSERVICE(iNumServices))
1168 free_service(pSERVICE(i));
1170 pSERVICE(i)->valid = True;
1172 init_service(pSERVICE(i));
1173 copy_service(pSERVICE(i),&tservice,NULL);
1175 string_set(&iSERVICE(i).szService,name);
1180 /***************************************************************************
1181 add a new home service, with the specified home directory, defaults coming
1183 ***************************************************************************/
1184 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1186 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1191 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1192 string_set(&iSERVICE(i).szPath,pszHomedir);
1193 if (!(*(iSERVICE(i).comment)))
1196 sprintf(comment,"Home directory of %s",pszHomename);
1197 string_set(&iSERVICE(i).comment,comment);
1199 iSERVICE(i).bAvailable = sDefault.bAvailable;
1200 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1202 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1207 /***************************************************************************
1208 add a new service, based on an old one
1209 ***************************************************************************/
1210 int lp_add_service(char *pszService, int iDefaultService)
1212 return(add_a_service(pSERVICE(iDefaultService),pszService));
1216 /***************************************************************************
1218 ***************************************************************************/
1219 static BOOL lp_add_ipc(void)
1222 int i = add_a_service(&sDefault,"IPC$");
1227 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1229 string_set(&iSERVICE(i).szPath,tmpdir());
1230 string_set(&iSERVICE(i).szUsername,"");
1231 string_set(&iSERVICE(i).comment,comment);
1232 iSERVICE(i).status = False;
1233 iSERVICE(i).iMaxConnections = 0;
1234 iSERVICE(i).bAvailable = True;
1235 iSERVICE(i).bRead_only = True;
1236 iSERVICE(i).bGuest_only = False;
1237 iSERVICE(i).bGuest_ok = True;
1238 iSERVICE(i).bPrint_ok = False;
1239 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1241 DEBUG(3,("adding IPC service\n"));
1247 /***************************************************************************
1248 add a new printer service, with defaults coming from service iFrom
1249 ***************************************************************************/
1250 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1252 char *comment = "From Printcap";
1253 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1258 /* note that we do NOT default the availability flag to True - */
1259 /* we take it from the default service passed. This allows all */
1260 /* dynamic printers to be disabled by disabling the [printers] */
1261 /* entry (if/when the 'available' keyword is implemented!). */
1263 /* the printer name is set to the service name. */
1264 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1265 string_set(&iSERVICE(i).comment,comment);
1266 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1267 /* Printers cannot be read_only. */
1268 iSERVICE(i).bRead_only = False;
1269 /* No share modes on printer services. */
1270 iSERVICE(i).bShareModes = False;
1271 /* No oplocks on printer services. */
1272 iSERVICE(i).bOpLocks = False;
1273 /* Printer services must be printable. */
1274 iSERVICE(i).bPrint_ok = True;
1276 DEBUG(3,("adding printer service %s\n",pszPrintername));
1282 /***************************************************************************
1283 Do a case-insensitive, whitespace-ignoring string compare.
1284 ***************************************************************************/
1285 static int strwicmp(char *psz1, char *psz2)
1287 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1288 /* appropriate value. */
1298 /* sync the strings on first non-whitespace */
1301 while (isspace(*psz1))
1303 while (isspace(*psz2))
1305 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1310 return (*psz1 - *psz2);
1313 /***************************************************************************
1314 Map a parameter's string representation to something we can use.
1315 Returns False if the parameter string is not recognised, else TRUE.
1316 ***************************************************************************/
1317 static int map_parameter(char *pszParmName)
1321 if (*pszParmName == '-')
1324 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1325 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1328 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1333 /***************************************************************************
1334 Set a boolean variable from the text value stored in the passed string.
1335 Returns True in success, False if the passed string does not correctly
1336 represent a boolean.
1337 ***************************************************************************/
1338 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1343 if (strwicmp(pszParmValue, "yes") == 0 ||
1344 strwicmp(pszParmValue, "true") == 0 ||
1345 strwicmp(pszParmValue, "1") == 0)
1348 if (strwicmp(pszParmValue, "no") == 0 ||
1349 strwicmp(pszParmValue, "False") == 0 ||
1350 strwicmp(pszParmValue, "0") == 0)
1354 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1361 /***************************************************************************
1362 Find a service by name. Otherwise works like get_service.
1363 ***************************************************************************/
1364 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1368 for (iService = iNumServices - 1; iService >= 0; iService--)
1369 if (VALID(iService) &&
1370 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1372 if (pserviceDest != NULL)
1373 copy_service(pserviceDest, pSERVICE(iService), NULL);
1382 /***************************************************************************
1383 Copy a service structure to another
1385 If pcopymapDest is NULL then copy all fields
1386 ***************************************************************************/
1387 static void copy_service(service *pserviceDest,
1388 service *pserviceSource,
1392 BOOL bcopyall = (pcopymapDest == NULL);
1394 for (i=0;parm_table[i].label;i++)
1395 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1396 (bcopyall || pcopymapDest[i]))
1398 void *def_ptr = parm_table[i].ptr;
1400 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1402 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1404 switch (parm_table[i].type)
1408 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1414 *(int *)dest_ptr = *(int *)src_ptr;
1418 *(char *)dest_ptr = *(char *)src_ptr;
1422 string_set(dest_ptr,*(char **)src_ptr);
1426 string_set(dest_ptr,*(char **)src_ptr);
1427 strupper(*(char **)dest_ptr);
1436 init_copymap(pserviceDest);
1437 if (pserviceSource->copymap)
1438 memcpy((void *)pserviceDest->copymap,
1439 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1443 /***************************************************************************
1444 Check a service for consistency. Return False if the service is in any way
1445 incomplete or faulty, else True.
1446 ***************************************************************************/
1447 static BOOL service_ok(int iService)
1452 if (iSERVICE(iService).szService[0] == '\0')
1454 DEBUG(0,( "The following message indicates an internal error:\n"));
1455 DEBUG(0,( "No service name in service entry.\n"));
1459 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1460 /* I can't see why you'd want a non-printable printer service... */
1461 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1462 if (!iSERVICE(iService).bPrint_ok)
1464 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1465 iSERVICE(iService).szService));
1466 iSERVICE(iService).bPrint_ok = True;
1469 if (iSERVICE(iService).szPath[0] == '\0' &&
1470 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1472 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1473 string_set(&iSERVICE(iService).szPath,tmpdir());
1476 /* If a service is flagged unavailable, log the fact at level 0. */
1477 if (!iSERVICE(iService).bAvailable)
1478 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1479 iSERVICE(iService).szService));
1484 static struct file_lists {
1485 struct file_lists *next;
1488 } *file_lists = NULL;
1490 /*******************************************************************
1491 keep a linked list of all config files so we know when one has changed
1492 it's date and needs to be reloaded
1493 ********************************************************************/
1494 static void add_to_file_list(char *fname)
1496 struct file_lists *f=file_lists;
1499 if (f->name && !strcmp(f->name,fname)) break;
1504 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1506 f->next = file_lists;
1507 f->name = strdup(fname);
1518 standard_sub_basic(n2);
1519 f->modtime = file_modtime(n2);
1524 /*******************************************************************
1525 check if a config file has changed date
1526 ********************************************************************/
1527 BOOL lp_file_list_changed(void)
1529 struct file_lists *f = file_lists;
1530 DEBUG(6,("lp_file_list_changed()\n"));
1537 pstrcpy(n2,f->name);
1538 standard_sub_basic(n2);
1540 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1541 f->name, n2, ctime(&f->modtime)));
1543 mod_time = file_modtime(n2);
1545 if (f->modtime != mod_time) {
1546 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1547 f->modtime = mod_time;
1555 /***************************************************************************
1556 handle the interpretation of the coding system parameter
1557 *************************************************************************/
1558 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1560 string_set(ptr,pszParmValue);
1561 interpret_coding_system(pszParmValue);
1565 /***************************************************************************
1566 handle the interpretation of the character set system parameter
1567 ***************************************************************************/
1568 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1570 string_set(ptr,pszParmValue);
1571 interpret_character_set(pszParmValue);
1576 /***************************************************************************
1577 handle the valid chars lines
1578 ***************************************************************************/
1579 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1581 string_set(ptr,pszParmValue);
1583 /* A dependency here is that the parameter client code page must be
1584 set before this is called - as calling codepage_initialise()
1585 would overwrite the valid char lines.
1587 codepage_initialise(lp_client_code_page());
1589 add_char_string(pszParmValue);
1594 /***************************************************************************
1595 handle the include operation
1596 ***************************************************************************/
1597 static BOOL handle_include(char *pszParmValue,char **ptr)
1600 pstrcpy(fname,pszParmValue);
1602 add_to_file_list(fname);
1604 standard_sub_basic(fname);
1606 string_set(ptr,fname);
1608 if (file_exist(fname,NULL))
1609 return(pm_process(fname, do_section, do_parameter));
1611 DEBUG(2,("Can't find include file %s\n",fname));
1617 /***************************************************************************
1618 handle the interpretation of the copy parameter
1619 ***************************************************************************/
1620 static BOOL handle_copy(char *pszParmValue,char **ptr)
1624 service serviceTemp;
1626 string_set(ptr,pszParmValue);
1628 init_service(&serviceTemp);
1632 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1634 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1636 if (iTemp == iServiceIndex)
1638 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1643 copy_service(pSERVICE(iServiceIndex),
1645 iSERVICE(iServiceIndex).copymap);
1651 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1656 free_service(&serviceTemp);
1661 /***************************************************************************
1662 initialise a copymap
1663 ***************************************************************************/
1664 static void init_copymap(service *pservice)
1667 if (pservice->copymap) free(pservice->copymap);
1668 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1669 if (!pservice->copymap)
1670 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1672 for (i=0;i<NUMPARAMETERS;i++)
1673 pservice->copymap[i] = True;
1677 /***************************************************************************
1678 return the local pointer to a parameter given the service number and the
1679 pointer into the default structure
1680 ***************************************************************************/
1681 void *lp_local_ptr(int snum, void *ptr)
1683 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1686 /***************************************************************************
1687 Process a parameter for a particular service number. If snum < 0
1688 then assume we are in the globals
1689 ***************************************************************************/
1690 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1693 void *parm_ptr=NULL; /* where we are going to store the result */
1696 parmnum = map_parameter(pszParmName);
1700 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1704 def_ptr = parm_table[parmnum].ptr;
1706 /* we might point at a service, the default service or a global */
1710 if (parm_table[parmnum].class == P_GLOBAL) {
1711 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1714 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1718 if (!iSERVICE(snum).copymap)
1719 init_copymap(pSERVICE(snum));
1721 /* this handles the aliases - set the copymap for other entries with
1722 the same data pointer */
1723 for (i=0;parm_table[i].label;i++)
1724 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1725 iSERVICE(snum).copymap[i] = False;
1728 /* if it is a special case then go ahead */
1729 if (parm_table[parmnum].special) {
1730 parm_table[parmnum].special(pszParmValue,parm_ptr);
1734 /* now switch on the type of variable it is */
1735 switch (parm_table[parmnum].type)
1738 set_boolean(parm_ptr,pszParmValue);
1742 set_boolean(parm_ptr,pszParmValue);
1743 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1747 *(int *)parm_ptr = atoi(pszParmValue);
1751 *(char *)parm_ptr = *pszParmValue;
1755 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1759 string_set(parm_ptr,pszParmValue);
1763 string_set(parm_ptr,pszParmValue);
1764 strupper(*(char **)parm_ptr);
1768 strcpy((char *)parm_ptr,pszParmValue);
1772 strcpy((char *)parm_ptr,pszParmValue);
1773 strupper((char *)parm_ptr);
1777 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1778 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1779 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1791 /***************************************************************************
1792 Process a parameter.
1793 ***************************************************************************/
1794 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1796 if (!bInGlobalSection && bGlobalOnly) return(True);
1798 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1800 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1804 /***************************************************************************
1805 print a parameter of the specified type
1806 ***************************************************************************/
1807 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1812 for (i=0;p->enum_list[i].name;i++) {
1813 if (*(int *)ptr == p->enum_list[i].value) {
1814 fprintf(f,"%s",p->enum_list[i].name);
1821 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1825 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1829 fprintf(f,"%d",*(int *)ptr);
1833 fprintf(f,"%c",*(char *)ptr);
1837 fprintf(f,"0%o",*(int *)ptr);
1843 fprintf(f,"%s",(char *)ptr);
1849 fprintf(f,"%s",*(char **)ptr);
1857 /***************************************************************************
1858 check if two parameters are equal
1859 ***************************************************************************/
1860 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1866 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1871 return(*((int *)ptr1) == *((int *)ptr2));
1874 return(*((char *)ptr1) == *((char *)ptr2));
1879 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1880 if (p1 && !*p1) p1 = NULL;
1881 if (p2 && !*p2) p2 = NULL;
1882 return(p1==p2 || strequal(p1,p2));
1887 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1888 if (p1 && !*p1) p1 = NULL;
1889 if (p2 && !*p2) p2 = NULL;
1890 return(p1==p2 || strequal(p1,p2));
1898 /***************************************************************************
1899 Process a new section (service). At this stage all sections are services.
1900 Later we'll have special sections that permit server parameters to be set.
1901 Returns True on success, False on failure.
1902 ***************************************************************************/
1903 static BOOL do_section(char *pszSectionName)
1906 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1907 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1910 /* if we were in a global section then do the local inits */
1911 if (bInGlobalSection && !isglobal)
1914 /* if we've just struck a global section, note the fact. */
1915 bInGlobalSection = isglobal;
1917 /* check for multiple global sections */
1918 if (bInGlobalSection)
1920 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1924 if (!bInGlobalSection && bGlobalOnly) return(True);
1926 /* if we have a current service, tidy it up before moving on */
1929 if (iServiceIndex >= 0)
1930 bRetval = service_ok(iServiceIndex);
1932 /* if all is still well, move to the next record in the services array */
1935 /* We put this here to avoid an odd message order if messages are */
1936 /* issued by the post-processing of a previous section. */
1937 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1939 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1941 DEBUG(0,("Failed to add a new service\n"));
1950 /***************************************************************************
1951 determine if a partcular base parameter is currently set to the default value.
1952 ***************************************************************************/
1953 static BOOL is_default(int i)
1955 if (!defaults_saved) return False;
1956 switch (parm_table[i].type) {
1959 return strequal(parm_table[i].def.svalue,*(char **)parm_table[i].ptr);
1962 return strequal(parm_table[i].def.svalue,(char *)parm_table[i].ptr);
1965 return parm_table[i].def.bvalue == *(BOOL *)parm_table[i].ptr;
1967 return parm_table[i].def.cvalue == *(char *)parm_table[i].ptr;
1971 return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
1979 /***************************************************************************
1980 Display the contents of the global structure.
1981 ***************************************************************************/
1982 static void dump_globals(FILE *f)
1985 fprintf(f, "# Global parameters\n");
1987 for (i=0;parm_table[i].label;i++)
1988 if (parm_table[i].class == P_GLOBAL &&
1989 parm_table[i].ptr &&
1990 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
1991 if (defaults_saved && is_default(i)) continue;
1992 fprintf(f,"\t%s = ",parm_table[i].label);
1993 print_parameter(&parm_table[i],parm_table[i].ptr, f);
1998 /***************************************************************************
1999 return True if a local parameter is currently set to the global default
2000 ***************************************************************************/
2001 BOOL lp_is_default(int snum, struct parm_struct *parm)
2003 int pdiff = PTR_DIFF(parm->ptr,&sDefault);
2005 return equal_parameter(parm->type,
2006 ((char *)pSERVICE(snum)) + pdiff,
2007 ((char *)&sDefault) + pdiff);
2011 /***************************************************************************
2012 Display the contents of a single services record.
2013 ***************************************************************************/
2014 static void dump_a_service(service *pService, FILE *f)
2017 if (pService != &sDefault)
2018 fprintf(f,"\n[%s]\n",pService->szService);
2020 for (i=0;parm_table[i].label;i++)
2021 if (parm_table[i].class == P_LOCAL &&
2022 parm_table[i].ptr &&
2023 (*parm_table[i].label != '-') &&
2024 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) {
2025 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
2027 if (pService == &sDefault) {
2028 if (defaults_saved && is_default(i)) continue;
2030 if (equal_parameter(parm_table[i].type,
2031 ((char *)pService) + pdiff,
2032 ((char *)&sDefault) + pdiff))
2036 fprintf(f,"\t%s = ",parm_table[i].label);
2037 print_parameter(&parm_table[i],
2038 ((char *)pService) + pdiff, f);
2044 /***************************************************************************
2045 return info about the next service in a service. snum==-1 gives the globals
2047 return NULL when out of parameters
2048 ***************************************************************************/
2049 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2052 /* do the globals */
2053 for (;parm_table[*i].label;(*i)++) {
2054 if (parm_table[*i].class == P_SEPARATOR)
2055 return &parm_table[(*i)++];
2057 if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2060 if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr))
2063 return &parm_table[(*i)++];
2066 service *pService = pSERVICE(snum);
2068 for (;parm_table[*i].label;(*i)++) {
2069 if (parm_table[*i].class == P_SEPARATOR)
2070 return &parm_table[(*i)++];
2072 if (parm_table[*i].class == P_LOCAL &&
2073 parm_table[*i].ptr &&
2074 (*parm_table[*i].label != '-') &&
2076 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2077 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2079 if (allparameters ||
2080 !equal_parameter(parm_table[*i].type,
2081 ((char *)pService) + pdiff,
2082 ((char *)&sDefault) + pdiff)) {
2083 return &parm_table[(*i)++];
2094 /***************************************************************************
2095 Display the contents of a single copy structure.
2096 ***************************************************************************/
2097 static void dump_copy_map(BOOL *pcopymap)
2100 if (!pcopymap) return;
2102 printf("\n\tNon-Copied parameters:\n");
2104 for (i=0;parm_table[i].label;i++)
2105 if (parm_table[i].class == P_LOCAL &&
2106 parm_table[i].ptr && !pcopymap[i] &&
2107 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2109 printf("\t\t%s\n",parm_table[i].label);
2114 /***************************************************************************
2115 Return TRUE if the passed service number is within range.
2116 ***************************************************************************/
2117 BOOL lp_snum_ok(int iService)
2119 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2123 /***************************************************************************
2124 auto-load some homes and printer services
2125 ***************************************************************************/
2126 static void lp_add_auto_services(char *str)
2130 int homes = lp_servicenumber(HOMES_NAME);
2131 int printers = lp_servicenumber(PRINTERS_NAME);
2139 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2141 char *home = get_home_dir(p);
2143 if (lp_servicenumber(p) >= 0) continue;
2145 if (home && homes >= 0)
2147 lp_add_home(p,homes,home);
2151 if (printers >= 0 && pcap_printername_ok(p,NULL))
2152 lp_add_printer(p,printers);
2157 /***************************************************************************
2158 auto-load one printer
2159 ***************************************************************************/
2160 static void lp_add_one_printer(char *name,char *comment)
2162 int printers = lp_servicenumber(PRINTERS_NAME);
2165 if (lp_servicenumber(name) < 0)
2167 lp_add_printer(name,printers);
2168 if ((i=lp_servicenumber(name)) >= 0)
2169 string_set(&iSERVICE(i).comment,comment);
2174 /***************************************************************************
2175 auto-load printer services
2176 ***************************************************************************/
2177 static void lp_add_all_printers(void)
2179 int printers = lp_servicenumber(PRINTERS_NAME);
2181 if (printers < 0) return;
2183 pcap_printer_fn(lp_add_one_printer);
2186 /***************************************************************************
2187 have we loaded a services file yet?
2188 ***************************************************************************/
2189 BOOL lp_loaded(void)
2194 /***************************************************************************
2195 unload unused services
2196 ***************************************************************************/
2197 void lp_killunused(BOOL (*snumused)(int ))
2200 for (i=0;i<iNumServices;i++)
2201 if (VALID(i) && (!snumused || !snumused(i)))
2203 iSERVICE(i).valid = False;
2204 free_service(pSERVICE(i));
2209 /***************************************************************************
2210 save the curent values of all global and sDefault parameters into the
2211 defaults union. This allows swat and testparm to show only the
2212 changed (ie. non-default) parameters.
2213 ***************************************************************************/
2214 static void lp_save_defaults(void)
2217 for (i = 0; parm_table[i].label; i++) {
2218 if (i>0 && parm_table[i].ptr == parm_table[i-1].ptr) continue;
2219 switch (parm_table[i].type) {
2222 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2226 parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
2230 parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr;
2233 parm_table[i].def.cvalue = *(char *)parm_table[i].ptr;
2238 parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
2244 defaults_saved = True;
2248 /***************************************************************************
2249 Load the services array from the services file. Return True on success,
2251 ***************************************************************************/
2252 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2257 add_to_file_list(pszFname);
2261 bInGlobalSection = True;
2262 bGlobalOnly = global_only;
2266 if (save_defaults) {
2271 pstrcpy(n2,pszFname);
2272 standard_sub_basic(n2);
2274 /* We get sections first, so have to start 'behind' to make up */
2276 bRetval = pm_process(n2, do_section, do_parameter);
2278 /* finish up the last section */
2279 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2281 if (iServiceIndex >= 0)
2282 bRetval = service_ok(iServiceIndex);
2284 lp_add_auto_services(lp_auto_services());
2285 if (lp_load_printers())
2286 lp_add_all_printers();
2291 set_default_server_announce_type();
2299 /***************************************************************************
2300 return the max number of services
2301 ***************************************************************************/
2302 int lp_numservices(void)
2304 return(iNumServices);
2307 /***************************************************************************
2308 Display the contents of the services array in human-readable form.
2309 ***************************************************************************/
2310 void lp_dump(FILE *f, BOOL show_defaults)
2314 if (show_defaults) {
2315 defaults_saved = False;
2320 dump_a_service(&sDefault, f);
2322 for (iService = 0; iService < iNumServices; iService++)
2324 if (VALID(iService))
2326 if (iSERVICE(iService).szService[0] == '\0')
2328 dump_a_service(pSERVICE(iService), f);
2334 /***************************************************************************
2335 Return the number of the service with the given name, or -1 if it doesn't
2336 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2337 getservicebyname()! This works ONLY if all services have been loaded, and
2338 does not copy the found service.
2339 ***************************************************************************/
2340 int lp_servicenumber(char *pszServiceName)
2344 for (iService = iNumServices - 1; iService >= 0; iService--)
2345 if (VALID(iService) &&
2346 strequal(lp_servicename(iService), pszServiceName))
2350 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2355 /*******************************************************************
2356 a useful volume label function
2357 ******************************************************************/
2358 char *volume_label(int snum)
2360 char *ret = lp_volume(snum);
2361 if (!*ret) return(lp_servicename(snum));
2367 * nmbd only loads the global section. There seems to be no way to
2368 * determine exactly is a service is printable by only looking at the
2369 * [global] section so for now always announce as a print server. This
2370 * will need looking at in the future. Jeremy (jallison@whistle.com).
2372 /*******************************************************************
2373 Return true if any printer services are defined.
2374 ******************************************************************/
2375 static BOOL lp_printer_services(void)
2379 for (iService = iNumServices - 1; iService >= 0; iService--)
2380 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2386 /*******************************************************************
2387 Set the server type we will announce as via nmbd.
2388 ********************************************************************/
2389 static void set_default_server_announce_type()
2391 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2392 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2393 if(lp_announce_as() == ANNOUNCE_AS_NT)
2394 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2395 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2396 default_server_announce |= SV_TYPE_WIN95_PLUS;
2397 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2398 default_server_announce |= SV_TYPE_WFW;
2399 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2401 * nmbd only loads the [global] section. There seems to be no way to
2402 * determine exactly if any service is printable by only looking at the
2403 * [global] section so for now always announce as a print server. This
2404 * will need looking at in the future. Jeremy (jallison@whistle.com).
2407 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2412 /*******************************************************************
2414 ********************************************************************/
2415 void lp_rename_service(int snum, char *new_name)
2417 string_set(&pSERVICE(snum)->szService, new_name);
2420 /*******************************************************************
2422 ********************************************************************/
2423 void lp_remove_service(int snum)
2425 pSERVICE(snum)->valid = False;
2428 /*******************************************************************
2430 ********************************************************************/
2431 void lp_copy_service(int snum, char *new_name)
2433 char *oldname = lp_servicename(snum);
2434 do_section(new_name);
2436 snum = lp_servicenumber(new_name);
2438 lp_do_parameter(snum, "copy", oldname);
2443 /*******************************************************************
2444 Get the default server type we will announce as via nmbd.
2445 ********************************************************************/
2446 int lp_default_server_announce(void)
2448 return default_server_announce;
2451 /*******************************************************************
2452 Split the announce version into major and minor numbers.
2453 ********************************************************************/
2454 int lp_major_announce_version(void)
2456 static BOOL got_major = False;
2457 static int major_version = DEFAULT_MAJOR_VERSION;
2462 return major_version;
2465 if((vers = lp_announce_version()) == NULL)
2466 return major_version;
2468 if((p = strchr(vers, '.')) == 0)
2469 return major_version;
2472 major_version = atoi(vers);
2473 return major_version;
2476 int lp_minor_announce_version(void)
2478 static BOOL got_minor = False;
2479 static int minor_version = DEFAULT_MINOR_VERSION;
2484 return minor_version;
2487 if((vers = lp_announce_version()) == NULL)
2488 return minor_version;
2490 if((p = strchr(vers, '.')) == 0)
2491 return minor_version;
2494 minor_version = atoi(p);
2495 return minor_version;
2498 /***********************************************************
2499 Set the global name resolution order (used in smbclient).
2500 ************************************************************/
2502 void lp_set_name_resolve_order(char *new_order)
2504 Globals.szNameResolveOrder = new_order;