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
93 extern BOOL use_getwd_cache;
95 extern int extra_time_offset;
98 * This structure describes global (ie., server-wide) parameters.
102 char *szPrintcapname;
105 char *szDefaultService;
109 char *szServerString;
110 char *szAutoServices;
111 char *szPasswdProgram;
115 char *szSMBPasswdFile;
116 char *szPasswordServer;
117 char *szSocketOptions;
120 char *szDomainAdminUsers;
121 char *szDomainGuestUsers;
122 char *szDomainHostsallow;
123 char *szDomainHostsdeny;
125 char *szCharacterSet;
132 char *szCodingSystem;
134 char *szRemoteAnnounce;
135 char *szRemoteBrowseSync;
136 char *szSocketAddress;
137 char *szNISHomeMapName;
138 char *szAnnounceVersion; /* This is initialised in init_globals */
139 char *szNetbiosAliases;
141 char *szDomainOtherSIDs;
142 char *szDomainGroups;
165 int client_code_page;
166 int announce_as; /* This is initialised in init_globals */
171 BOOL bPreferredMaster;
172 BOOL bDomainController;
175 BOOL bEncryptPasswords;
182 BOOL bReadPrediction;
189 BOOL bBindInterfacesOnly;
190 BOOL bNetWkstaUserLogon;
193 static global Globals;
198 * This structure describes a single service.
206 char *szGuestaccount;
207 char *szInvalidUsers;
215 char *szRootPostExec;
216 char *szPrintcommand;
219 char *szLppausecommand;
220 char *szLpresumecommand;
222 char *szPrinterDriver;
223 char *szPrinterDriverLocation;
232 char *szVetoOplockFiles;
241 int iCreate_force_mode;
251 BOOL bShortCasePreserve;
277 BOOL bDeleteReadonly;
279 BOOL bDeleteVetoFiles;
281 BOOL bDosFiletimeResolution;
282 char dummy[3]; /* for alignment */
286 /* This is a default service used to prime a services structure */
287 static service sDefault =
290 NULL, /* szService */
292 NULL, /* szUsername */
293 NULL, /* szGuestAccount - this is set in init_globals() */
294 NULL, /* szInvalidUsers */
295 NULL, /* szValidUsers */
296 NULL, /* szAdminUsers */
298 NULL, /* szInclude */
299 NULL, /* szPreExec */
300 NULL, /* szPostExec */
301 NULL, /* szRootPreExec */
302 NULL, /* szRootPostExec */
303 NULL, /* szPrintcommand */
304 NULL, /* szLpqcommand */
305 NULL, /* szLprmcommand */
306 NULL, /* szLppausecommand */
307 NULL, /* szLpresumecommand */
308 NULL, /* szPrintername */
309 NULL, /* szPrinterDriver - this is set in init_globals() */
310 NULL, /* szPrinterDriverLocation */
311 NULL, /* szDontdescend */
312 NULL, /* szHostsallow */
313 NULL, /* szHostsdeny */
314 NULL, /* szMagicScript */
315 NULL, /* szMagicOutput */
316 NULL, /* szMangledMap */
317 NULL, /* szVetoFiles */
318 NULL, /* szHideFiles */
319 NULL, /* szVetoOplockFiles */
321 NULL, /* force user */
322 NULL, /* force group */
324 NULL, /* writelist */
326 0, /* iMinPrintSpace */
327 0744, /* iCreate_mask */
328 0000, /* iCreate_force_mode */
329 0755, /* iDir_mask */
330 0000, /* iDir_force_mode */
331 0, /* iMaxConnections */
332 CASE_LOWER, /* iDefaultCase */
333 DEFAULT_PRINTING, /* iPrinting */
334 False, /* bAlternatePerm */
335 False, /* revalidate */
336 False, /* case sensitive */
337 False, /* case preserve */
338 False, /* short case preserve */
339 False, /* case mangle */
341 True, /* bHideDotFiles */
342 True, /* bBrowseable */
343 True, /* bAvailable */
344 True, /* bRead_only */
345 True, /* bNo_set_dir */
346 False, /* bGuest_only */
347 False, /* bGuest_ok */
348 False, /* bPrint_ok */
349 False, /* bPostscript */
350 False, /* bMap_system */
351 False, /* bMap_hidden */
352 True, /* bMap_archive */
354 False, /* bStrictLocking */
355 True, /* bShareModes */
357 False, /* bOnlyUser */
358 True, /* bMangledNames */
359 True, /* bWidelinks */
360 True, /* bSymlinks */
361 False, /* bSyncAlways */
362 '~', /* magic char */
364 False, /* bDeleteReadonly */
365 False, /* bFakeOplocks */
366 False, /* bDeleteVetoFiles */
367 False, /* bDosFiletimes */
368 False, /* bDosFiletimeResolution */
374 /* local variables */
375 static service **ServicePtrs = NULL;
376 static int iNumServices = 0;
377 static int iServiceIndex = 0;
378 static BOOL bInGlobalSection = True;
379 static BOOL bGlobalOnly = False;
380 static int default_server_announce;
382 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
384 /* prototypes for the special type handlers */
385 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
386 static BOOL handle_include(char *pszParmValue, char **ptr);
387 static BOOL handle_copy(char *pszParmValue, char **ptr);
388 static BOOL handle_character_set(char *pszParmValue,char **ptr);
389 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
391 static void set_default_server_announce_type(void);
393 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
394 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
395 {PROTOCOL_COREPLUS, "COREPLUS"},
396 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
398 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
399 {SEC_SERVER, "SERVER"}, {-1, NULL}};
401 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
402 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
403 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
404 {PRINT_LPRNG, "lprng"}, {-1, NULL}};
406 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
407 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
409 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
411 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
413 static struct parm_struct parm_table[] =
415 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
416 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
417 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
418 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
419 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
420 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
421 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
422 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
423 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
424 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
425 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
426 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
427 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
428 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
429 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
430 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
431 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
432 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
433 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
434 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
435 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
436 {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL, 0},
437 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
438 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
439 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL, NULL, FLAG_BASIC},
440 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
441 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
442 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
443 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, 0},
444 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
445 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
446 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
447 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
448 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
449 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
450 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
451 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
452 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
453 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
454 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
455 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
456 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
457 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
458 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
459 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
460 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0},
461 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
462 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
463 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
465 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
466 {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL, 0},
467 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
468 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL, 0},
469 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
470 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
471 {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
472 {"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
473 {"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
474 {"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
476 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
477 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
478 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
479 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
480 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
481 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
482 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0},
483 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0},
484 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
485 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
486 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
487 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
488 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
489 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
490 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
491 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
492 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
493 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
494 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
495 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
496 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
497 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
498 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
499 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
500 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
501 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
502 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, 0},
503 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
504 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
505 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
506 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
507 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
508 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
509 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
510 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
511 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
512 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
513 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
514 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, 0},
515 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, 0},
516 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
517 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
518 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
519 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
520 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
521 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
522 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
523 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
524 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
525 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
526 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
527 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
528 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
529 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
530 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
531 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, 0},
532 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, 0},
533 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
534 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
535 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
536 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, 0},
537 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, 0},
538 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, 0},
539 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, 0},
540 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
541 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
542 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
543 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
544 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
545 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
546 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
547 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
548 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
549 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, 0},
550 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, 0},
551 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, 0},
552 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, 0},
553 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, 0},
554 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
555 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
556 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
557 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
558 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
559 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
560 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
561 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
562 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
563 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
564 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, 0},
565 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, 0},
566 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, 0},
567 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, 0},
568 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, 0},
569 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, 0},
570 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
571 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, 0},
572 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, 0},
573 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, 0},
574 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, 0},
575 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, 0},
576 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, 0},
577 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
578 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
579 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
580 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
581 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
582 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
583 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
584 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, 0},
585 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, 0},
586 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, 0},
587 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, 0},
588 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, 0},
589 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, 0},
590 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, 0},
591 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
592 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, 0},
593 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, 0},
594 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
595 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, 0},
596 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
597 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT},
598 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT},
599 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT},
600 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT},
601 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, 0},
602 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, 0},
603 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
604 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
605 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
606 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, 0},
607 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
608 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
609 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
610 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
611 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
612 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
613 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
614 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, 0},
615 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, 0},
616 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, 0},
617 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, 0},
619 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
624 /***************************************************************************
625 Initialise the global parameter structure.
626 ***************************************************************************/
627 static void init_globals(void)
629 static BOOL done_init = False;
635 bzero((void *)&Globals,sizeof(Globals));
637 for (i = 0; parm_table[i].label; i++)
638 if ((parm_table[i].type == P_STRING ||
639 parm_table[i].type == P_USTRING) &&
641 string_init(parm_table[i].ptr,"");
643 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
644 string_set(&sDefault.szPrinterDriver, "NULL");
650 DEBUG(3,("Initialising global parameters\n"));
652 #ifdef SMB_PASSWD_FILE
653 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
655 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
656 string_set(&Globals.szWorkGroup, WORKGROUP);
657 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
658 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
659 string_set(&Globals.szDriverFile, DRIVERFILE);
660 string_set(&Globals.szLockDir, LOCKDIR);
661 string_set(&Globals.szRootdir, "/");
662 string_set(&Globals.szSmbrun, SMBRUN);
663 string_set(&Globals.szSocketAddress, "0.0.0.0");
664 sprintf(s,"Samba %s",VERSION);
665 string_set(&Globals.szServerString,s);
666 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
667 string_set(&Globals.szAnnounceVersion,s);
669 string_set(&Globals.szLogonDrive, "");
670 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
671 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
672 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
674 Globals.bLoadPrinters = True;
675 Globals.bUseRhosts = False;
676 Globals.max_packet = 65535;
677 Globals.mangled_stack = 50;
678 Globals.max_xmit = 65535;
679 Globals.max_mux = 50; /* This is *needed* for profile support. */
680 Globals.lpqcachetime = 10;
681 Globals.pwordlevel = 0;
682 Globals.unamelevel = 0;
683 Globals.deadtime = 0;
684 Globals.max_log_size = 5000;
685 Globals.maxprotocol = PROTOCOL_NT1;
686 Globals.security = SEC_SHARE;
687 Globals.bEncryptPasswords = False;
688 Globals.bReadRaw = True;
689 Globals.bWriteRaw = True;
690 Globals.bReadPrediction = False;
691 Globals.bReadbmpx = True;
692 Globals.bNullPasswords = False;
693 Globals.bStripDot = False;
695 Globals.bSyslogOnly = False;
696 Globals.os_level = 0;
697 Globals.max_ttl = 60*60*4; /* 4 hours default */
698 Globals.max_wins_ttl = 60*60*24*3; /* 3 days default */
699 Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
700 Globals.ReadSize = 16*1024;
701 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
702 Globals.lm_interval = 60;
703 Globals.shmem_size = SHMEM_SIZE;
704 Globals.announce_as = ANNOUNCE_AS_NT;
705 Globals.bUnixRealname = False;
706 #if (defined(NETGROUP) && defined(AUTOMOUNT))
707 Globals.bNISHomeMap = False;
708 string_set(&Globals.szNISHomeMapName, "auto.home");
710 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
711 Globals.bTimeServer = False;
712 Globals.bBindInterfacesOnly = False;
713 Globals.bNetWkstaUserLogon = True;
715 /* these parameters are set to defaults that are more appropriate
716 for the increasing samba install base:
718 as a member of the workgroup, that will possibly become a
719 _local_ master browser (lm = True). this is opposed to a forced
720 local master browser startup (pm = True).
722 doesn't provide WINS server service by default (wsupp = False),
723 and doesn't provide domain master browser services by default, either.
727 Globals.bPreferredMaster = False;
728 Globals.bLocalMaster = True;
729 Globals.bDomainMaster = False;
730 Globals.bDomainLogons = False;
731 Globals.bBrowseList = True;
732 Globals.bWINSsupport = False;
733 Globals.bWINSproxy = False;
735 Globals.bDNSproxy = True;
738 * This must be done last as it checks the value in
742 interpret_coding_system(KANJI);
745 /***************************************************************************
746 check if a string is initialised and if not then initialise it
747 ***************************************************************************/
748 static void string_initial(char **s,char *v)
755 /***************************************************************************
756 Initialise the sDefault parameter structure.
757 ***************************************************************************/
758 static void init_locals(void)
760 /* choose defaults depending on the type of printing */
761 switch (sDefault.iPrinting)
767 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
768 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
769 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
774 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
775 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
776 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
778 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
779 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
784 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
785 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
786 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
794 /******************************************************************* a
795 convenience routine to grab string parameters into a rotating buffer,
796 and run standard_sub_basic on them. The buffers can be written to by
797 callers without affecting the source string.
798 ********************************************************************/
799 char *lp_string(char *s)
801 static char *bufs[10];
802 static int buflen[10];
803 static int next = -1;
806 int len = s?strlen(s):0;
817 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
820 if (buflen[next] != len) {
822 if (bufs[next]) free(bufs[next]);
823 bufs[next] = (char *)malloc(len);
825 DEBUG(0,("out of memory in lp_string()"));
830 ret = &bufs[next][0];
838 trim_string(ret, "\"", "\"");
840 standard_sub_basic(ret);
846 In this section all the functions that are used to access the
847 parameters from the rest of the program are defined
850 #define FN_GLOBAL_STRING(fn_name,ptr) \
851 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
852 #define FN_GLOBAL_BOOL(fn_name,ptr) \
853 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
854 #define FN_GLOBAL_CHAR(fn_name,ptr) \
855 char fn_name(void) {return(*(char *)(ptr));}
856 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
857 int fn_name(void) {return(*(int *)(ptr));}
859 #define FN_LOCAL_STRING(fn_name,val) \
860 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
861 #define FN_LOCAL_BOOL(fn_name,val) \
862 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
863 #define FN_LOCAL_CHAR(fn_name,val) \
864 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
865 #define FN_LOCAL_INTEGER(fn_name,val) \
866 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
868 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
869 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
870 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
871 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
872 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
873 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
874 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
875 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
876 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
877 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
878 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
879 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
880 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
881 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
882 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
883 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
884 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
885 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
886 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
887 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
888 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
889 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
890 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
891 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
892 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
893 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
894 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
895 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
896 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
897 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
898 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
899 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
901 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
902 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
903 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
904 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
905 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
906 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
907 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
909 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
910 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
911 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
912 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
913 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
914 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
915 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
916 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
917 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
918 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
919 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
920 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
921 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
922 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
923 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
924 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
925 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
926 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
927 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
928 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
929 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
930 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
931 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
932 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
933 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
934 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
936 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
937 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
938 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
939 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
940 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
941 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
942 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
943 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
944 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
945 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
946 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
947 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
948 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
949 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
950 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
951 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
952 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
953 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
954 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
955 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
956 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
957 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
958 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
959 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
961 FN_LOCAL_STRING(lp_preexec,szPreExec)
962 FN_LOCAL_STRING(lp_postexec,szPostExec)
963 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
964 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
965 FN_LOCAL_STRING(lp_servicename,szService)
966 FN_LOCAL_STRING(lp_pathname,szPath)
967 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
968 FN_LOCAL_STRING(lp_username,szUsername)
969 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
970 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
971 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
972 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
973 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
974 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
975 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
976 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
977 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
978 FN_LOCAL_STRING(lp_printername,szPrintername)
979 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
980 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
981 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
982 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
983 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
984 FN_LOCAL_STRING(lp_comment,comment)
985 FN_LOCAL_STRING(lp_force_user,force_user)
986 FN_LOCAL_STRING(lp_force_group,force_group)
987 FN_LOCAL_STRING(lp_readlist,readlist)
988 FN_LOCAL_STRING(lp_writelist,writelist)
989 FN_LOCAL_STRING(lp_volume,volume)
990 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
991 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
992 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
993 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
994 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
996 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
997 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
998 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
999 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1000 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1001 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1002 FN_LOCAL_BOOL(lp_status,status)
1003 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1004 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1005 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1006 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1007 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1008 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1009 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1010 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1011 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1012 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1013 FN_LOCAL_BOOL(lp_locking,bLocking)
1014 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1015 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1016 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1017 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1018 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1019 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1020 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1021 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1022 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1023 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1024 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1025 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1026 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1027 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1029 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1030 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1031 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1032 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1033 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1034 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1035 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1036 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1038 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1042 /* local prototypes */
1043 static int strwicmp( char *psz1, char *psz2 );
1044 static int map_parameter( char *pszParmName);
1045 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1046 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1047 static void copy_service( service *pserviceDest,
1048 service *pserviceSource,
1049 BOOL *pcopymapDest );
1050 static BOOL service_ok(int iService);
1051 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1052 static BOOL do_section(char *pszSectionName);
1053 static void init_copymap(service *pservice);
1056 /***************************************************************************
1057 initialise a service to the defaults
1058 ***************************************************************************/
1059 static void init_service(service *pservice)
1061 bzero((char *)pservice,sizeof(service));
1062 copy_service(pservice,&sDefault,NULL);
1066 /***************************************************************************
1067 free the dynamically allocated parts of a service struct
1068 ***************************************************************************/
1069 static void free_service(service *pservice)
1075 if(pservice->szService)
1076 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1078 string_free(&pservice->szService);
1079 if (pservice->copymap)
1081 free(pservice->copymap);
1082 pservice->copymap = NULL;
1085 for (i=0;parm_table[i].label;i++)
1086 if ((parm_table[i].type == P_STRING ||
1087 parm_table[i].type == P_USTRING) &&
1088 parm_table[i].class == P_LOCAL)
1089 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1092 /***************************************************************************
1093 add a new service to the services array initialising it with the given
1095 ***************************************************************************/
1096 static int add_a_service(service *pservice, char *name)
1100 int num_to_alloc = iNumServices+1;
1102 tservice = *pservice;
1104 /* it might already exist */
1107 i = getservicebyname(name,NULL);
1112 /* find an invalid one */
1113 for (i=0;i<iNumServices;i++)
1114 if (!pSERVICE(i)->valid)
1117 /* if not, then create one */
1118 if (i == iNumServices)
1120 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1122 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1124 if (!ServicePtrs || !pSERVICE(iNumServices))
1130 free_service(pSERVICE(i));
1132 pSERVICE(i)->valid = True;
1134 init_service(pSERVICE(i));
1135 copy_service(pSERVICE(i),&tservice,NULL);
1137 string_set(&iSERVICE(i).szService,name);
1142 /***************************************************************************
1143 add a new home service, with the specified home directory, defaults coming
1145 ***************************************************************************/
1146 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1148 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1153 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1154 string_set(&iSERVICE(i).szPath,pszHomedir);
1155 if (!(*(iSERVICE(i).comment)))
1158 sprintf(comment,"Home directory of %s",pszHomename);
1159 string_set(&iSERVICE(i).comment,comment);
1161 iSERVICE(i).bAvailable = sDefault.bAvailable;
1162 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1164 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1169 /***************************************************************************
1170 add a new service, based on an old one
1171 ***************************************************************************/
1172 int lp_add_service(char *pszService, int iDefaultService)
1174 return(add_a_service(pSERVICE(iDefaultService),pszService));
1178 /***************************************************************************
1180 ***************************************************************************/
1181 static BOOL lp_add_ipc(void)
1184 int i = add_a_service(&sDefault,"IPC$");
1189 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1191 string_set(&iSERVICE(i).szPath,tmpdir());
1192 string_set(&iSERVICE(i).szUsername,"");
1193 string_set(&iSERVICE(i).comment,comment);
1194 iSERVICE(i).status = False;
1195 iSERVICE(i).iMaxConnections = 0;
1196 iSERVICE(i).bAvailable = True;
1197 iSERVICE(i).bRead_only = True;
1198 iSERVICE(i).bGuest_only = False;
1199 iSERVICE(i).bGuest_ok = True;
1200 iSERVICE(i).bPrint_ok = False;
1201 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1203 DEBUG(3,("adding IPC service\n"));
1209 /***************************************************************************
1210 add a new printer service, with defaults coming from service iFrom
1211 ***************************************************************************/
1212 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1214 char *comment = "From Printcap";
1215 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1220 /* note that we do NOT default the availability flag to True - */
1221 /* we take it from the default service passed. This allows all */
1222 /* dynamic printers to be disabled by disabling the [printers] */
1223 /* entry (if/when the 'available' keyword is implemented!). */
1225 /* the printer name is set to the service name. */
1226 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1227 string_set(&iSERVICE(i).comment,comment);
1228 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1229 /* Printers cannot be read_only. */
1230 iSERVICE(i).bRead_only = False;
1231 /* No share modes on printer services. */
1232 iSERVICE(i).bShareModes = False;
1233 /* No oplocks on printer services. */
1234 iSERVICE(i).bOpLocks = False;
1235 /* Printer services must be printable. */
1236 iSERVICE(i).bPrint_ok = True;
1238 DEBUG(3,("adding printer service %s\n",pszPrintername));
1244 /***************************************************************************
1245 Do a case-insensitive, whitespace-ignoring string compare.
1246 ***************************************************************************/
1247 static int strwicmp(char *psz1, char *psz2)
1249 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1250 /* appropriate value. */
1260 /* sync the strings on first non-whitespace */
1263 while (isspace(*psz1))
1265 while (isspace(*psz2))
1267 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1272 return (*psz1 - *psz2);
1275 /***************************************************************************
1276 Map a parameter's string representation to something we can use.
1277 Returns False if the parameter string is not recognised, else TRUE.
1278 ***************************************************************************/
1279 static int map_parameter(char *pszParmName)
1283 if (*pszParmName == '-')
1286 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1287 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1290 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1295 /***************************************************************************
1296 Set a boolean variable from the text value stored in the passed string.
1297 Returns True in success, False if the passed string does not correctly
1298 represent a boolean.
1299 ***************************************************************************/
1300 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1305 if (strwicmp(pszParmValue, "yes") == 0 ||
1306 strwicmp(pszParmValue, "true") == 0 ||
1307 strwicmp(pszParmValue, "1") == 0)
1310 if (strwicmp(pszParmValue, "no") == 0 ||
1311 strwicmp(pszParmValue, "False") == 0 ||
1312 strwicmp(pszParmValue, "0") == 0)
1316 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1323 /***************************************************************************
1324 Find a service by name. Otherwise works like get_service.
1325 ***************************************************************************/
1326 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1330 for (iService = iNumServices - 1; iService >= 0; iService--)
1331 if (VALID(iService) &&
1332 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1334 if (pserviceDest != NULL)
1335 copy_service(pserviceDest, pSERVICE(iService), NULL);
1344 /***************************************************************************
1345 Copy a service structure to another
1347 If pcopymapDest is NULL then copy all fields
1348 ***************************************************************************/
1349 static void copy_service(service *pserviceDest,
1350 service *pserviceSource,
1354 BOOL bcopyall = (pcopymapDest == NULL);
1356 for (i=0;parm_table[i].label;i++)
1357 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1358 (bcopyall || pcopymapDest[i]))
1360 void *def_ptr = parm_table[i].ptr;
1362 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1364 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1366 switch (parm_table[i].type)
1370 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1376 *(int *)dest_ptr = *(int *)src_ptr;
1380 *(char *)dest_ptr = *(char *)src_ptr;
1384 string_set(dest_ptr,*(char **)src_ptr);
1388 string_set(dest_ptr,*(char **)src_ptr);
1389 strupper(*(char **)dest_ptr);
1398 init_copymap(pserviceDest);
1399 if (pserviceSource->copymap)
1400 memcpy((void *)pserviceDest->copymap,
1401 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1405 /***************************************************************************
1406 Check a service for consistency. Return False if the service is in any way
1407 incomplete or faulty, else True.
1408 ***************************************************************************/
1409 static BOOL service_ok(int iService)
1414 if (iSERVICE(iService).szService[0] == '\0')
1416 DEBUG(0,( "The following message indicates an internal error:\n"));
1417 DEBUG(0,( "No service name in service entry.\n"));
1421 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1422 /* I can't see why you'd want a non-printable printer service... */
1423 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1424 if (!iSERVICE(iService).bPrint_ok)
1426 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1427 iSERVICE(iService).szService));
1428 iSERVICE(iService).bPrint_ok = True;
1431 if (iSERVICE(iService).szPath[0] == '\0' &&
1432 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1434 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1435 string_set(&iSERVICE(iService).szPath,tmpdir());
1438 /* If a service is flagged unavailable, log the fact at level 0. */
1439 if (!iSERVICE(iService).bAvailable)
1440 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1441 iSERVICE(iService).szService));
1446 static struct file_lists {
1447 struct file_lists *next;
1450 } *file_lists = NULL;
1452 /*******************************************************************
1453 keep a linked list of all config files so we know when one has changed
1454 it's date and needs to be reloaded
1455 ********************************************************************/
1456 static void add_to_file_list(char *fname)
1458 struct file_lists *f=file_lists;
1461 if (f->name && !strcmp(f->name,fname)) break;
1466 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1468 f->next = file_lists;
1469 f->name = strdup(fname);
1480 standard_sub_basic(n2);
1481 f->modtime = file_modtime(n2);
1486 /*******************************************************************
1487 check if a config file has changed date
1488 ********************************************************************/
1489 BOOL lp_file_list_changed(void)
1491 struct file_lists *f = file_lists;
1492 DEBUG(6,("lp_file_list_changed()\n"));
1499 pstrcpy(n2,f->name);
1500 standard_sub_basic(n2);
1502 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1503 f->name, n2, ctime(&f->modtime)));
1505 mod_time = file_modtime(n2);
1507 if (f->modtime != mod_time) {
1508 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1509 f->modtime = mod_time;
1517 /***************************************************************************
1518 handle the interpretation of the coding system parameter
1519 *************************************************************************/
1520 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1522 string_set(ptr,pszParmValue);
1523 interpret_coding_system(pszParmValue);
1527 /***************************************************************************
1528 handle the interpretation of the character set system parameter
1529 ***************************************************************************/
1530 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1532 string_set(ptr,pszParmValue);
1533 interpret_character_set(pszParmValue);
1538 /***************************************************************************
1539 handle the valid chars lines
1540 ***************************************************************************/
1541 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1543 string_set(ptr,pszParmValue);
1545 /* A dependency here is that the parameter client code page must be
1546 set before this is called - as calling codepage_initialise()
1547 would overwrite the valid char lines.
1549 codepage_initialise(lp_client_code_page());
1551 add_char_string(pszParmValue);
1556 /***************************************************************************
1557 handle the include operation
1558 ***************************************************************************/
1559 static BOOL handle_include(char *pszParmValue,char **ptr)
1562 pstrcpy(fname,pszParmValue);
1564 add_to_file_list(fname);
1566 standard_sub_basic(fname);
1568 string_set(ptr,fname);
1570 if (file_exist(fname,NULL))
1571 return(pm_process(fname, do_section, do_parameter));
1573 DEBUG(2,("Can't find include file %s\n",fname));
1579 /***************************************************************************
1580 handle the interpretation of the copy parameter
1581 ***************************************************************************/
1582 static BOOL handle_copy(char *pszParmValue,char **ptr)
1586 service serviceTemp;
1588 string_set(ptr,pszParmValue);
1590 init_service(&serviceTemp);
1594 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1596 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1598 if (iTemp == iServiceIndex)
1600 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1605 copy_service(pSERVICE(iServiceIndex),
1607 iSERVICE(iServiceIndex).copymap);
1613 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1618 free_service(&serviceTemp);
1623 /***************************************************************************
1624 initialise a copymap
1625 ***************************************************************************/
1626 static void init_copymap(service *pservice)
1629 if (pservice->copymap) free(pservice->copymap);
1630 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1631 if (!pservice->copymap)
1632 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1634 for (i=0;i<NUMPARAMETERS;i++)
1635 pservice->copymap[i] = True;
1639 /***************************************************************************
1640 return the local pointer to a parameter given the service number and the
1641 pointer into the default structure
1642 ***************************************************************************/
1643 void *lp_local_ptr(int snum, void *ptr)
1645 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1648 /***************************************************************************
1649 Process a parameter for a particular service number. If snum < 0
1650 then assume we are in the globals
1651 ***************************************************************************/
1652 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1655 void *parm_ptr=NULL; /* where we are going to store the result */
1658 parmnum = map_parameter(pszParmName);
1662 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1666 def_ptr = parm_table[parmnum].ptr;
1668 /* we might point at a service, the default service or a global */
1672 if (parm_table[parmnum].class == P_GLOBAL) {
1673 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1676 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1680 if (!iSERVICE(snum).copymap)
1681 init_copymap(pSERVICE(snum));
1683 /* this handles the aliases - set the copymap for other entries with
1684 the same data pointer */
1685 for (i=0;parm_table[i].label;i++)
1686 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1687 iSERVICE(snum).copymap[i] = False;
1690 /* if it is a special case then go ahead */
1691 if (parm_table[parmnum].special) {
1692 parm_table[parmnum].special(pszParmValue,parm_ptr);
1696 /* now switch on the type of variable it is */
1697 switch (parm_table[parmnum].type)
1700 set_boolean(parm_ptr,pszParmValue);
1704 set_boolean(parm_ptr,pszParmValue);
1705 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1709 *(int *)parm_ptr = atoi(pszParmValue);
1713 *(char *)parm_ptr = *pszParmValue;
1717 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1721 string_set(parm_ptr,pszParmValue);
1725 string_set(parm_ptr,pszParmValue);
1726 strupper(*(char **)parm_ptr);
1730 strcpy((char *)parm_ptr,pszParmValue);
1734 strcpy((char *)parm_ptr,pszParmValue);
1735 strupper((char *)parm_ptr);
1739 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1740 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1741 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1751 /***************************************************************************
1752 Process a parameter.
1753 ***************************************************************************/
1754 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1756 if (!bInGlobalSection && bGlobalOnly) return(True);
1758 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1760 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1764 /***************************************************************************
1765 print a parameter of the specified type
1766 ***************************************************************************/
1767 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1772 for (i=0;p->enum_list[i].name;i++) {
1773 if (*(int *)ptr == p->enum_list[i].value) {
1774 fprintf(f,"%s",p->enum_list[i].name);
1781 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1785 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1789 fprintf(f,"%d",*(int *)ptr);
1793 fprintf(f,"%c",*(char *)ptr);
1797 fprintf(f,"0%o",*(int *)ptr);
1803 fprintf(f,"%s",(char *)ptr);
1809 fprintf(f,"%s",*(char **)ptr);
1815 /***************************************************************************
1816 check if two parameters are equal
1817 ***************************************************************************/
1818 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1824 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1829 return(*((int *)ptr1) == *((int *)ptr2));
1832 return(*((char *)ptr1) == *((char *)ptr2));
1837 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1838 if (p1 && !*p1) p1 = NULL;
1839 if (p2 && !*p2) p2 = NULL;
1840 return(p1==p2 || strequal(p1,p2));
1845 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1846 if (p1 && !*p1) p1 = NULL;
1847 if (p2 && !*p2) p2 = NULL;
1848 return(p1==p2 || strequal(p1,p2));
1854 /***************************************************************************
1855 Process a new section (service). At this stage all sections are services.
1856 Later we'll have special sections that permit server parameters to be set.
1857 Returns True on success, False on failure.
1858 ***************************************************************************/
1859 static BOOL do_section(char *pszSectionName)
1862 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1863 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1866 /* if we were in a global section then do the local inits */
1867 if (bInGlobalSection && !isglobal)
1870 /* if we've just struck a global section, note the fact. */
1871 bInGlobalSection = isglobal;
1873 /* check for multiple global sections */
1874 if (bInGlobalSection)
1876 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1880 if (!bInGlobalSection && bGlobalOnly) return(True);
1882 /* if we have a current service, tidy it up before moving on */
1885 if (iServiceIndex >= 0)
1886 bRetval = service_ok(iServiceIndex);
1888 /* if all is still well, move to the next record in the services array */
1891 /* We put this here to avoid an odd message order if messages are */
1892 /* issued by the post-processing of a previous section. */
1893 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1895 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1897 DEBUG(0,("Failed to add a new service\n"));
1905 /***************************************************************************
1906 Display the contents of the global structure.
1907 ***************************************************************************/
1908 static void dump_globals(FILE *f)
1911 fprintf(f, "# Global parameters\n");
1913 for (i=0;parm_table[i].label;i++)
1914 if (parm_table[i].class == P_GLOBAL &&
1915 parm_table[i].ptr &&
1916 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1918 fprintf(f,"\t%s = ",parm_table[i].label);
1919 print_parameter(&parm_table[i],parm_table[i].ptr, f);
1924 /***************************************************************************
1925 Display the contents of a single services record.
1926 ***************************************************************************/
1927 static void dump_a_service(service *pService, FILE *f)
1930 if (pService == &sDefault)
1931 fprintf(f,"\n\n# Default service parameters\n");
1933 fprintf(f,"\n[%s]\n",pService->szService);
1935 for (i=0;parm_table[i].label;i++)
1936 if (parm_table[i].class == P_LOCAL &&
1937 parm_table[i].ptr &&
1938 (*parm_table[i].label != '-') &&
1939 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1941 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1943 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1944 ((char *)pService) + pdiff,
1945 ((char *)&sDefault) + pdiff))
1947 fprintf(f,"\t%s = ",parm_table[i].label);
1948 print_parameter(&parm_table[i],
1949 ((char *)pService) + pdiff, f);
1956 /***************************************************************************
1957 return info about the next service in a service. snum==-1 gives the default
1958 serice and snum==-2 gives the globals
1960 return 0 when out of parameters
1961 ***************************************************************************/
1962 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
1965 /* do the globals */
1966 for (;parm_table[*i].label;(*i)++)
1967 if (parm_table[*i].class == P_GLOBAL &&
1968 parm_table[*i].ptr &&
1969 (*parm_table[*i].label != '-') &&
1971 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
1972 return &parm_table[(*i)++];
1976 service *pService = (snum==-1?&sDefault:pSERVICE(snum));
1978 for (;parm_table[*i].label;(*i)++)
1979 if (parm_table[*i].class == P_LOCAL &&
1980 parm_table[*i].ptr &&
1981 (*parm_table[*i].label != '-') &&
1983 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
1984 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
1986 if (snum == -1 || allparameters ||
1987 !equal_parameter(parm_table[*i].type,
1988 ((char *)pService) + pdiff,
1989 ((char *)&sDefault) + pdiff)) {
1990 return &parm_table[(*i)++];
2000 /***************************************************************************
2001 Display the contents of a single copy structure.
2002 ***************************************************************************/
2003 static void dump_copy_map(BOOL *pcopymap)
2006 if (!pcopymap) return;
2008 printf("\n\tNon-Copied parameters:\n");
2010 for (i=0;parm_table[i].label;i++)
2011 if (parm_table[i].class == P_LOCAL &&
2012 parm_table[i].ptr && !pcopymap[i] &&
2013 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2015 printf("\t\t%s\n",parm_table[i].label);
2020 /***************************************************************************
2021 Return TRUE if the passed service number is within range.
2022 ***************************************************************************/
2023 BOOL lp_snum_ok(int iService)
2025 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2029 /***************************************************************************
2030 auto-load some homes and printer services
2031 ***************************************************************************/
2032 static void lp_add_auto_services(char *str)
2036 int homes = lp_servicenumber(HOMES_NAME);
2037 int printers = lp_servicenumber(PRINTERS_NAME);
2045 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2047 char *home = get_home_dir(p);
2049 if (lp_servicenumber(p) >= 0) continue;
2051 if (home && homes >= 0)
2053 lp_add_home(p,homes,home);
2057 if (printers >= 0 && pcap_printername_ok(p,NULL))
2058 lp_add_printer(p,printers);
2063 /***************************************************************************
2064 auto-load one printer
2065 ***************************************************************************/
2066 static void lp_add_one_printer(char *name,char *comment)
2068 int printers = lp_servicenumber(PRINTERS_NAME);
2071 if (lp_servicenumber(name) < 0)
2073 lp_add_printer(name,printers);
2074 if ((i=lp_servicenumber(name)) >= 0)
2075 string_set(&iSERVICE(i).comment,comment);
2080 /***************************************************************************
2081 auto-load printer services
2082 ***************************************************************************/
2083 static void lp_add_all_printers(void)
2085 int printers = lp_servicenumber(PRINTERS_NAME);
2087 if (printers < 0) return;
2089 pcap_printer_fn(lp_add_one_printer);
2092 /***************************************************************************
2093 have we loaded a services file yet?
2094 ***************************************************************************/
2095 BOOL lp_loaded(void)
2100 /***************************************************************************
2101 unload unused services
2102 ***************************************************************************/
2103 void lp_killunused(BOOL (*snumused)(int ))
2106 for (i=0;i<iNumServices;i++)
2107 if (VALID(i) && (!snumused || !snumused(i)))
2109 iSERVICE(i).valid = False;
2110 free_service(pSERVICE(i));
2114 /***************************************************************************
2115 Load the services array from the services file. Return True on success,
2117 ***************************************************************************/
2118 BOOL lp_load(char *pszFname,BOOL global_only)
2123 add_to_file_list(pszFname);
2127 bInGlobalSection = True;
2128 bGlobalOnly = global_only;
2132 pstrcpy(n2,pszFname);
2133 standard_sub_basic(n2);
2135 /* We get sections first, so have to start 'behind' to make up */
2137 bRetval = pm_process(n2, do_section, do_parameter);
2139 /* finish up the last section */
2140 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2142 if (iServiceIndex >= 0)
2143 bRetval = service_ok(iServiceIndex);
2145 lp_add_auto_services(lp_auto_services());
2146 if (lp_load_printers())
2147 lp_add_all_printers();
2151 set_default_server_announce_type();
2159 /***************************************************************************
2160 return the max number of services
2161 ***************************************************************************/
2162 int lp_numservices(void)
2164 return(iNumServices);
2167 /***************************************************************************
2168 Display the contents of the services array in human-readable form.
2169 ***************************************************************************/
2170 void lp_dump(FILE *f)
2176 dump_a_service(&sDefault, f);
2178 for (iService = 0; iService < iNumServices; iService++)
2180 if (VALID(iService))
2182 if (iSERVICE(iService).szService[0] == '\0')
2184 dump_a_service(pSERVICE(iService), f);
2190 /***************************************************************************
2191 Return the number of the service with the given name, or -1 if it doesn't
2192 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2193 getservicebyname()! This works ONLY if all services have been loaded, and
2194 does not copy the found service.
2195 ***************************************************************************/
2196 int lp_servicenumber(char *pszServiceName)
2200 for (iService = iNumServices - 1; iService >= 0; iService--)
2201 if (VALID(iService) &&
2202 strequal(lp_servicename(iService), pszServiceName))
2206 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2211 /*******************************************************************
2212 a useful volume label function
2213 ******************************************************************/
2214 char *volume_label(int snum)
2216 char *ret = lp_volume(snum);
2217 if (!*ret) return(lp_servicename(snum));
2223 * nmbd only loads the global section. There seems to be no way to
2224 * determine exactly is a service is printable by only looking at the
2225 * [global] section so for now always announce as a print server. This
2226 * will need looking at in the future. Jeremy (jallison@whistle.com).
2228 /*******************************************************************
2229 Return true if any printer services are defined.
2230 ******************************************************************/
2231 static BOOL lp_printer_services(void)
2235 for (iService = iNumServices - 1; iService >= 0; iService--)
2236 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2242 /*******************************************************************
2243 Set the server type we will announce as via nmbd.
2244 ********************************************************************/
2245 static void set_default_server_announce_type()
2247 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2248 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2249 if(lp_announce_as() == ANNOUNCE_AS_NT)
2250 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2251 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2252 default_server_announce |= SV_TYPE_WIN95_PLUS;
2253 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2254 default_server_announce |= SV_TYPE_WFW;
2255 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2257 * nmbd only loads the [global] section. There seems to be no way to
2258 * determine exactly if any service is printable by only looking at the
2259 * [global] section so for now always announce as a print server. This
2260 * will need looking at in the future. Jeremy (jallison@whistle.com).
2263 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2268 /*******************************************************************
2270 ********************************************************************/
2271 void lp_rename_service(int snum, char *new_name)
2273 string_set(&pSERVICE(snum)->szService, new_name);
2276 /*******************************************************************
2278 ********************************************************************/
2279 void lp_remove_service(int snum)
2281 pSERVICE(snum)->valid = False;
2284 /*******************************************************************
2286 ********************************************************************/
2287 void lp_copy_service(int snum, char *new_name)
2289 char *oldname = lp_servicename(snum);
2290 do_section(new_name);
2292 snum = lp_servicenumber(new_name);
2294 lp_do_parameter(snum, "copy", oldname);
2299 /*******************************************************************
2300 Get the default server type we will announce as via nmbd.
2301 ********************************************************************/
2302 int lp_default_server_announce(void)
2304 return default_server_announce;
2307 /*******************************************************************
2308 Split the announce version into major and minor numbers.
2309 ********************************************************************/
2310 int lp_major_announce_version(void)
2312 static BOOL got_major = False;
2313 static int major_version = DEFAULT_MAJOR_VERSION;
2318 return major_version;
2321 if((vers = lp_announce_version()) == NULL)
2322 return major_version;
2324 if((p = strchr(vers, '.')) == 0)
2325 return major_version;
2328 major_version = atoi(vers);
2329 return major_version;
2332 int lp_minor_announce_version(void)
2334 static BOOL got_minor = False;
2335 static int minor_version = DEFAULT_MINOR_VERSION;
2340 return minor_version;
2343 if((vers = lp_announce_version()) == NULL)
2344 return minor_version;
2346 if((p = strchr(vers, '.')) == 0)
2347 return minor_version;
2350 minor_version = atoi(p);
2351 return minor_version;