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},
475 #endif /* NTDOMAIN */
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)
902 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
903 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
904 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
905 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
906 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
907 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
908 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
909 #endif /* NTDOMAIN */
911 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
912 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
913 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
914 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
915 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
916 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
917 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
918 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
919 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
920 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
921 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
922 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
923 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
924 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
925 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
926 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
927 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
928 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
929 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
930 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
931 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
932 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
933 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
934 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
935 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
936 FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
938 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
939 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
940 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
941 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
942 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
943 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
944 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
945 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
946 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
947 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
948 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
949 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
950 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
951 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
952 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
953 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
954 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
955 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
956 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
957 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
958 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
959 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
960 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
961 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
963 FN_LOCAL_STRING(lp_preexec,szPreExec)
964 FN_LOCAL_STRING(lp_postexec,szPostExec)
965 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
966 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
967 FN_LOCAL_STRING(lp_servicename,szService)
968 FN_LOCAL_STRING(lp_pathname,szPath)
969 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
970 FN_LOCAL_STRING(lp_username,szUsername)
971 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
972 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
973 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
974 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
975 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
976 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
977 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
978 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
979 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
980 FN_LOCAL_STRING(lp_printername,szPrintername)
981 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
982 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
983 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
984 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
985 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
986 FN_LOCAL_STRING(lp_comment,comment)
987 FN_LOCAL_STRING(lp_force_user,force_user)
988 FN_LOCAL_STRING(lp_force_group,force_group)
989 FN_LOCAL_STRING(lp_readlist,readlist)
990 FN_LOCAL_STRING(lp_writelist,writelist)
991 FN_LOCAL_STRING(lp_volume,volume)
992 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
993 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
994 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
995 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
996 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
998 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
999 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
1000 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
1001 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1002 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1003 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1004 FN_LOCAL_BOOL(lp_status,status)
1005 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1006 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1007 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1008 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1009 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1010 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1011 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1012 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1013 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1014 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1015 FN_LOCAL_BOOL(lp_locking,bLocking)
1016 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1017 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1018 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1019 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1020 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1021 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1022 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1023 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1024 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1025 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1026 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1027 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1028 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1029 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
1031 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1032 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1033 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1034 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1035 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1036 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1037 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1038 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1040 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1044 /* local prototypes */
1045 static int strwicmp( char *psz1, char *psz2 );
1046 static int map_parameter( char *pszParmName);
1047 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1048 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1049 static void copy_service( service *pserviceDest,
1050 service *pserviceSource,
1051 BOOL *pcopymapDest );
1052 static BOOL service_ok(int iService);
1053 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1054 static BOOL do_section(char *pszSectionName);
1055 static void init_copymap(service *pservice);
1058 /***************************************************************************
1059 initialise a service to the defaults
1060 ***************************************************************************/
1061 static void init_service(service *pservice)
1063 bzero((char *)pservice,sizeof(service));
1064 copy_service(pservice,&sDefault,NULL);
1068 /***************************************************************************
1069 free the dynamically allocated parts of a service struct
1070 ***************************************************************************/
1071 static void free_service(service *pservice)
1077 if(pservice->szService)
1078 DEBUG(5,("free_service: Freeing service %s\n", pservice->szService));
1080 string_free(&pservice->szService);
1081 if (pservice->copymap)
1083 free(pservice->copymap);
1084 pservice->copymap = NULL;
1087 for (i=0;parm_table[i].label;i++)
1088 if ((parm_table[i].type == P_STRING ||
1089 parm_table[i].type == P_USTRING) &&
1090 parm_table[i].class == P_LOCAL)
1091 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1094 /***************************************************************************
1095 add a new service to the services array initialising it with the given
1097 ***************************************************************************/
1098 static int add_a_service(service *pservice, char *name)
1102 int num_to_alloc = iNumServices+1;
1104 tservice = *pservice;
1106 /* it might already exist */
1109 i = getservicebyname(name,NULL);
1114 /* find an invalid one */
1115 for (i=0;i<iNumServices;i++)
1116 if (!pSERVICE(i)->valid)
1119 /* if not, then create one */
1120 if (i == iNumServices)
1122 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1124 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1126 if (!ServicePtrs || !pSERVICE(iNumServices))
1132 free_service(pSERVICE(i));
1134 pSERVICE(i)->valid = True;
1136 init_service(pSERVICE(i));
1137 copy_service(pSERVICE(i),&tservice,NULL);
1139 string_set(&iSERVICE(i).szService,name);
1144 /***************************************************************************
1145 add a new home service, with the specified home directory, defaults coming
1147 ***************************************************************************/
1148 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1150 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1155 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1156 string_set(&iSERVICE(i).szPath,pszHomedir);
1157 if (!(*(iSERVICE(i).comment)))
1160 sprintf(comment,"Home directory of %s",pszHomename);
1161 string_set(&iSERVICE(i).comment,comment);
1163 iSERVICE(i).bAvailable = sDefault.bAvailable;
1164 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1166 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1171 /***************************************************************************
1172 add a new service, based on an old one
1173 ***************************************************************************/
1174 int lp_add_service(char *pszService, int iDefaultService)
1176 return(add_a_service(pSERVICE(iDefaultService),pszService));
1180 /***************************************************************************
1182 ***************************************************************************/
1183 static BOOL lp_add_ipc(void)
1186 int i = add_a_service(&sDefault,"IPC$");
1191 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1193 string_set(&iSERVICE(i).szPath,tmpdir());
1194 string_set(&iSERVICE(i).szUsername,"");
1195 string_set(&iSERVICE(i).comment,comment);
1196 iSERVICE(i).status = False;
1197 iSERVICE(i).iMaxConnections = 0;
1198 iSERVICE(i).bAvailable = True;
1199 iSERVICE(i).bRead_only = True;
1200 iSERVICE(i).bGuest_only = False;
1201 iSERVICE(i).bGuest_ok = True;
1202 iSERVICE(i).bPrint_ok = False;
1203 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1205 DEBUG(3,("adding IPC service\n"));
1211 /***************************************************************************
1212 add a new printer service, with defaults coming from service iFrom
1213 ***************************************************************************/
1214 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1216 char *comment = "From Printcap";
1217 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1222 /* note that we do NOT default the availability flag to True - */
1223 /* we take it from the default service passed. This allows all */
1224 /* dynamic printers to be disabled by disabling the [printers] */
1225 /* entry (if/when the 'available' keyword is implemented!). */
1227 /* the printer name is set to the service name. */
1228 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1229 string_set(&iSERVICE(i).comment,comment);
1230 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1231 /* Printers cannot be read_only. */
1232 iSERVICE(i).bRead_only = False;
1233 /* No share modes on printer services. */
1234 iSERVICE(i).bShareModes = False;
1235 /* No oplocks on printer services. */
1236 iSERVICE(i).bOpLocks = False;
1237 /* Printer services must be printable. */
1238 iSERVICE(i).bPrint_ok = True;
1240 DEBUG(3,("adding printer service %s\n",pszPrintername));
1246 /***************************************************************************
1247 Do a case-insensitive, whitespace-ignoring string compare.
1248 ***************************************************************************/
1249 static int strwicmp(char *psz1, char *psz2)
1251 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1252 /* appropriate value. */
1262 /* sync the strings on first non-whitespace */
1265 while (isspace(*psz1))
1267 while (isspace(*psz2))
1269 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1274 return (*psz1 - *psz2);
1277 /***************************************************************************
1278 Map a parameter's string representation to something we can use.
1279 Returns False if the parameter string is not recognised, else TRUE.
1280 ***************************************************************************/
1281 static int map_parameter(char *pszParmName)
1285 if (*pszParmName == '-')
1288 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1289 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1292 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1297 /***************************************************************************
1298 Set a boolean variable from the text value stored in the passed string.
1299 Returns True in success, False if the passed string does not correctly
1300 represent a boolean.
1301 ***************************************************************************/
1302 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1307 if (strwicmp(pszParmValue, "yes") == 0 ||
1308 strwicmp(pszParmValue, "true") == 0 ||
1309 strwicmp(pszParmValue, "1") == 0)
1312 if (strwicmp(pszParmValue, "no") == 0 ||
1313 strwicmp(pszParmValue, "False") == 0 ||
1314 strwicmp(pszParmValue, "0") == 0)
1318 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1325 /***************************************************************************
1326 Find a service by name. Otherwise works like get_service.
1327 ***************************************************************************/
1328 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1332 for (iService = iNumServices - 1; iService >= 0; iService--)
1333 if (VALID(iService) &&
1334 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1336 if (pserviceDest != NULL)
1337 copy_service(pserviceDest, pSERVICE(iService), NULL);
1346 /***************************************************************************
1347 Copy a service structure to another
1349 If pcopymapDest is NULL then copy all fields
1350 ***************************************************************************/
1351 static void copy_service(service *pserviceDest,
1352 service *pserviceSource,
1356 BOOL bcopyall = (pcopymapDest == NULL);
1358 for (i=0;parm_table[i].label;i++)
1359 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1360 (bcopyall || pcopymapDest[i]))
1362 void *def_ptr = parm_table[i].ptr;
1364 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1366 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1368 switch (parm_table[i].type)
1372 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1378 *(int *)dest_ptr = *(int *)src_ptr;
1382 *(char *)dest_ptr = *(char *)src_ptr;
1386 string_set(dest_ptr,*(char **)src_ptr);
1390 string_set(dest_ptr,*(char **)src_ptr);
1391 strupper(*(char **)dest_ptr);
1400 init_copymap(pserviceDest);
1401 if (pserviceSource->copymap)
1402 memcpy((void *)pserviceDest->copymap,
1403 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1407 /***************************************************************************
1408 Check a service for consistency. Return False if the service is in any way
1409 incomplete or faulty, else True.
1410 ***************************************************************************/
1411 static BOOL service_ok(int iService)
1416 if (iSERVICE(iService).szService[0] == '\0')
1418 DEBUG(0,( "The following message indicates an internal error:\n"));
1419 DEBUG(0,( "No service name in service entry.\n"));
1423 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1424 /* I can't see why you'd want a non-printable printer service... */
1425 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1426 if (!iSERVICE(iService).bPrint_ok)
1428 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1429 iSERVICE(iService).szService));
1430 iSERVICE(iService).bPrint_ok = True;
1433 if (iSERVICE(iService).szPath[0] == '\0' &&
1434 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1436 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1437 string_set(&iSERVICE(iService).szPath,tmpdir());
1440 /* If a service is flagged unavailable, log the fact at level 0. */
1441 if (!iSERVICE(iService).bAvailable)
1442 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1443 iSERVICE(iService).szService));
1448 static struct file_lists {
1449 struct file_lists *next;
1452 } *file_lists = NULL;
1454 /*******************************************************************
1455 keep a linked list of all config files so we know when one has changed
1456 it's date and needs to be reloaded
1457 ********************************************************************/
1458 static void add_to_file_list(char *fname)
1460 struct file_lists *f=file_lists;
1463 if (f->name && !strcmp(f->name,fname)) break;
1468 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1470 f->next = file_lists;
1471 f->name = strdup(fname);
1482 standard_sub_basic(n2);
1483 f->modtime = file_modtime(n2);
1488 /*******************************************************************
1489 check if a config file has changed date
1490 ********************************************************************/
1491 BOOL lp_file_list_changed(void)
1493 struct file_lists *f = file_lists;
1494 DEBUG(6,("lp_file_list_changed()\n"));
1501 pstrcpy(n2,f->name);
1502 standard_sub_basic(n2);
1504 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1505 f->name, n2, ctime(&f->modtime)));
1507 mod_time = file_modtime(n2);
1509 if (f->modtime != mod_time) {
1510 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1511 f->modtime = mod_time;
1519 /***************************************************************************
1520 handle the interpretation of the coding system parameter
1521 *************************************************************************/
1522 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1524 string_set(ptr,pszParmValue);
1525 interpret_coding_system(pszParmValue);
1529 /***************************************************************************
1530 handle the interpretation of the character set system parameter
1531 ***************************************************************************/
1532 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1534 string_set(ptr,pszParmValue);
1535 interpret_character_set(pszParmValue);
1540 /***************************************************************************
1541 handle the valid chars lines
1542 ***************************************************************************/
1543 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1545 string_set(ptr,pszParmValue);
1547 /* A dependency here is that the parameter client code page must be
1548 set before this is called - as calling codepage_initialise()
1549 would overwrite the valid char lines.
1551 codepage_initialise(lp_client_code_page());
1553 add_char_string(pszParmValue);
1558 /***************************************************************************
1559 handle the include operation
1560 ***************************************************************************/
1561 static BOOL handle_include(char *pszParmValue,char **ptr)
1564 pstrcpy(fname,pszParmValue);
1566 add_to_file_list(fname);
1568 standard_sub_basic(fname);
1570 string_set(ptr,fname);
1572 if (file_exist(fname,NULL))
1573 return(pm_process(fname, do_section, do_parameter));
1575 DEBUG(2,("Can't find include file %s\n",fname));
1581 /***************************************************************************
1582 handle the interpretation of the copy parameter
1583 ***************************************************************************/
1584 static BOOL handle_copy(char *pszParmValue,char **ptr)
1588 service serviceTemp;
1590 string_set(ptr,pszParmValue);
1592 init_service(&serviceTemp);
1596 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1598 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1600 if (iTemp == iServiceIndex)
1602 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1607 copy_service(pSERVICE(iServiceIndex),
1609 iSERVICE(iServiceIndex).copymap);
1615 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1620 free_service(&serviceTemp);
1625 /***************************************************************************
1626 initialise a copymap
1627 ***************************************************************************/
1628 static void init_copymap(service *pservice)
1631 if (pservice->copymap) free(pservice->copymap);
1632 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1633 if (!pservice->copymap)
1634 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1636 for (i=0;i<NUMPARAMETERS;i++)
1637 pservice->copymap[i] = True;
1641 /***************************************************************************
1642 return the local pointer to a parameter given the service number and the
1643 pointer into the default structure
1644 ***************************************************************************/
1645 void *lp_local_ptr(int snum, void *ptr)
1647 return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault));
1650 /***************************************************************************
1651 Process a parameter for a particular service number. If snum < 0
1652 then assume we are in the globals
1653 ***************************************************************************/
1654 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1657 void *parm_ptr=NULL; /* where we are going to store the result */
1660 parmnum = map_parameter(pszParmName);
1664 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1668 def_ptr = parm_table[parmnum].ptr;
1670 /* we might point at a service, the default service or a global */
1674 if (parm_table[parmnum].class == P_GLOBAL) {
1675 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1678 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1682 if (!iSERVICE(snum).copymap)
1683 init_copymap(pSERVICE(snum));
1685 /* this handles the aliases - set the copymap for other entries with
1686 the same data pointer */
1687 for (i=0;parm_table[i].label;i++)
1688 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1689 iSERVICE(snum).copymap[i] = False;
1692 /* if it is a special case then go ahead */
1693 if (parm_table[parmnum].special) {
1694 parm_table[parmnum].special(pszParmValue,parm_ptr);
1698 /* now switch on the type of variable it is */
1699 switch (parm_table[parmnum].type)
1702 set_boolean(parm_ptr,pszParmValue);
1706 set_boolean(parm_ptr,pszParmValue);
1707 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1711 *(int *)parm_ptr = atoi(pszParmValue);
1715 *(char *)parm_ptr = *pszParmValue;
1719 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1723 string_set(parm_ptr,pszParmValue);
1727 string_set(parm_ptr,pszParmValue);
1728 strupper(*(char **)parm_ptr);
1732 strcpy((char *)parm_ptr,pszParmValue);
1736 strcpy((char *)parm_ptr,pszParmValue);
1737 strupper((char *)parm_ptr);
1741 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1742 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1743 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1753 /***************************************************************************
1754 Process a parameter.
1755 ***************************************************************************/
1756 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1758 if (!bInGlobalSection && bGlobalOnly) return(True);
1760 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1762 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1766 /***************************************************************************
1767 print a parameter of the specified type
1768 ***************************************************************************/
1769 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1774 for (i=0;p->enum_list[i].name;i++) {
1775 if (*(int *)ptr == p->enum_list[i].value) {
1776 fprintf(f,"%s",p->enum_list[i].name);
1783 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1787 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1791 fprintf(f,"%d",*(int *)ptr);
1795 fprintf(f,"%c",*(char *)ptr);
1799 fprintf(f,"0%o",*(int *)ptr);
1805 fprintf(f,"%s",(char *)ptr);
1811 fprintf(f,"%s",*(char **)ptr);
1817 /***************************************************************************
1818 check if two parameters are equal
1819 ***************************************************************************/
1820 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1826 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1831 return(*((int *)ptr1) == *((int *)ptr2));
1834 return(*((char *)ptr1) == *((char *)ptr2));
1839 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1840 if (p1 && !*p1) p1 = NULL;
1841 if (p2 && !*p2) p2 = NULL;
1842 return(p1==p2 || strequal(p1,p2));
1847 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1848 if (p1 && !*p1) p1 = NULL;
1849 if (p2 && !*p2) p2 = NULL;
1850 return(p1==p2 || strequal(p1,p2));
1856 /***************************************************************************
1857 Process a new section (service). At this stage all sections are services.
1858 Later we'll have special sections that permit server parameters to be set.
1859 Returns True on success, False on failure.
1860 ***************************************************************************/
1861 static BOOL do_section(char *pszSectionName)
1864 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1865 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1868 /* if we were in a global section then do the local inits */
1869 if (bInGlobalSection && !isglobal)
1872 /* if we've just struck a global section, note the fact. */
1873 bInGlobalSection = isglobal;
1875 /* check for multiple global sections */
1876 if (bInGlobalSection)
1878 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1882 if (!bInGlobalSection && bGlobalOnly) return(True);
1884 /* if we have a current service, tidy it up before moving on */
1887 if (iServiceIndex >= 0)
1888 bRetval = service_ok(iServiceIndex);
1890 /* if all is still well, move to the next record in the services array */
1893 /* We put this here to avoid an odd message order if messages are */
1894 /* issued by the post-processing of a previous section. */
1895 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1897 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1899 DEBUG(0,("Failed to add a new service\n"));
1907 /***************************************************************************
1908 Display the contents of the global structure.
1909 ***************************************************************************/
1910 static void dump_globals(FILE *f)
1913 fprintf(f, "# Global parameters\n");
1915 for (i=0;parm_table[i].label;i++)
1916 if (parm_table[i].class == P_GLOBAL &&
1917 parm_table[i].ptr &&
1918 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1920 fprintf(f,"\t%s = ",parm_table[i].label);
1921 print_parameter(&parm_table[i],parm_table[i].ptr, f);
1926 /***************************************************************************
1927 Display the contents of a single services record.
1928 ***************************************************************************/
1929 static void dump_a_service(service *pService, FILE *f)
1932 if (pService == &sDefault)
1933 fprintf(f,"\n\n# Default service parameters\n");
1935 fprintf(f,"\n[%s]\n",pService->szService);
1937 for (i=0;parm_table[i].label;i++)
1938 if (parm_table[i].class == P_LOCAL &&
1939 parm_table[i].ptr &&
1940 (*parm_table[i].label != '-') &&
1941 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1943 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1945 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1946 ((char *)pService) + pdiff,
1947 ((char *)&sDefault) + pdiff))
1949 fprintf(f,"\t%s = ",parm_table[i].label);
1950 print_parameter(&parm_table[i],
1951 ((char *)pService) + pdiff, f);
1958 /***************************************************************************
1959 return info about the next service in a service. snum==-1 gives the default
1960 serice and snum==-2 gives the globals
1962 return 0 when out of parameters
1963 ***************************************************************************/
1964 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
1967 /* do the globals */
1968 for (;parm_table[*i].label;(*i)++)
1969 if (parm_table[*i].class == P_GLOBAL &&
1970 parm_table[*i].ptr &&
1971 (*parm_table[*i].label != '-') &&
1973 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
1974 return &parm_table[(*i)++];
1978 service *pService = (snum==-1?&sDefault:pSERVICE(snum));
1980 for (;parm_table[*i].label;(*i)++)
1981 if (parm_table[*i].class == P_LOCAL &&
1982 parm_table[*i].ptr &&
1983 (*parm_table[*i].label != '-') &&
1985 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
1986 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
1988 if (snum == -1 || allparameters ||
1989 !equal_parameter(parm_table[*i].type,
1990 ((char *)pService) + pdiff,
1991 ((char *)&sDefault) + pdiff)) {
1992 return &parm_table[(*i)++];
2002 /***************************************************************************
2003 Display the contents of a single copy structure.
2004 ***************************************************************************/
2005 static void dump_copy_map(BOOL *pcopymap)
2008 if (!pcopymap) return;
2010 printf("\n\tNon-Copied parameters:\n");
2012 for (i=0;parm_table[i].label;i++)
2013 if (parm_table[i].class == P_LOCAL &&
2014 parm_table[i].ptr && !pcopymap[i] &&
2015 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2017 printf("\t\t%s\n",parm_table[i].label);
2022 /***************************************************************************
2023 Return TRUE if the passed service number is within range.
2024 ***************************************************************************/
2025 BOOL lp_snum_ok(int iService)
2027 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2031 /***************************************************************************
2032 auto-load some homes and printer services
2033 ***************************************************************************/
2034 static void lp_add_auto_services(char *str)
2038 int homes = lp_servicenumber(HOMES_NAME);
2039 int printers = lp_servicenumber(PRINTERS_NAME);
2047 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2049 char *home = get_home_dir(p);
2051 if (lp_servicenumber(p) >= 0) continue;
2053 if (home && homes >= 0)
2055 lp_add_home(p,homes,home);
2059 if (printers >= 0 && pcap_printername_ok(p,NULL))
2060 lp_add_printer(p,printers);
2065 /***************************************************************************
2066 auto-load one printer
2067 ***************************************************************************/
2068 static void lp_add_one_printer(char *name,char *comment)
2070 int printers = lp_servicenumber(PRINTERS_NAME);
2073 if (lp_servicenumber(name) < 0)
2075 lp_add_printer(name,printers);
2076 if ((i=lp_servicenumber(name)) >= 0)
2077 string_set(&iSERVICE(i).comment,comment);
2082 /***************************************************************************
2083 auto-load printer services
2084 ***************************************************************************/
2085 static void lp_add_all_printers(void)
2087 int printers = lp_servicenumber(PRINTERS_NAME);
2089 if (printers < 0) return;
2091 pcap_printer_fn(lp_add_one_printer);
2094 /***************************************************************************
2095 have we loaded a services file yet?
2096 ***************************************************************************/
2097 BOOL lp_loaded(void)
2102 /***************************************************************************
2103 unload unused services
2104 ***************************************************************************/
2105 void lp_killunused(BOOL (*snumused)(int ))
2108 for (i=0;i<iNumServices;i++)
2109 if (VALID(i) && (!snumused || !snumused(i)))
2111 iSERVICE(i).valid = False;
2112 free_service(pSERVICE(i));
2116 /***************************************************************************
2117 Load the services array from the services file. Return True on success,
2119 ***************************************************************************/
2120 BOOL lp_load(char *pszFname,BOOL global_only)
2125 add_to_file_list(pszFname);
2129 bInGlobalSection = True;
2130 bGlobalOnly = global_only;
2134 pstrcpy(n2,pszFname);
2135 standard_sub_basic(n2);
2137 /* We get sections first, so have to start 'behind' to make up */
2139 bRetval = pm_process(n2, do_section, do_parameter);
2141 /* finish up the last section */
2142 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2144 if (iServiceIndex >= 0)
2145 bRetval = service_ok(iServiceIndex);
2147 lp_add_auto_services(lp_auto_services());
2148 if (lp_load_printers())
2149 lp_add_all_printers();
2153 set_default_server_announce_type();
2161 /***************************************************************************
2162 return the max number of services
2163 ***************************************************************************/
2164 int lp_numservices(void)
2166 return(iNumServices);
2169 /***************************************************************************
2170 Display the contents of the services array in human-readable form.
2171 ***************************************************************************/
2172 void lp_dump(FILE *f)
2178 dump_a_service(&sDefault, f);
2180 for (iService = 0; iService < iNumServices; iService++)
2182 if (VALID(iService))
2184 if (iSERVICE(iService).szService[0] == '\0')
2186 dump_a_service(pSERVICE(iService), f);
2192 /***************************************************************************
2193 Return the number of the service with the given name, or -1 if it doesn't
2194 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2195 getservicebyname()! This works ONLY if all services have been loaded, and
2196 does not copy the found service.
2197 ***************************************************************************/
2198 int lp_servicenumber(char *pszServiceName)
2202 for (iService = iNumServices - 1; iService >= 0; iService--)
2203 if (VALID(iService) &&
2204 strequal(lp_servicename(iService), pszServiceName))
2208 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2213 /*******************************************************************
2214 a useful volume label function
2215 ******************************************************************/
2216 char *volume_label(int snum)
2218 char *ret = lp_volume(snum);
2219 if (!*ret) return(lp_servicename(snum));
2225 * nmbd only loads the global section. There seems to be no way to
2226 * determine exactly is a service is printable by only looking at the
2227 * [global] section so for now always announce as a print server. This
2228 * will need looking at in the future. Jeremy (jallison@whistle.com).
2230 /*******************************************************************
2231 Return true if any printer services are defined.
2232 ******************************************************************/
2233 static BOOL lp_printer_services(void)
2237 for (iService = iNumServices - 1; iService >= 0; iService--)
2238 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2244 /*******************************************************************
2245 Set the server type we will announce as via nmbd.
2246 ********************************************************************/
2247 static void set_default_server_announce_type()
2249 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2250 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2251 if(lp_announce_as() == ANNOUNCE_AS_NT)
2252 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2253 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2254 default_server_announce |= SV_TYPE_WIN95_PLUS;
2255 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2256 default_server_announce |= SV_TYPE_WFW;
2257 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2259 * nmbd only loads the [global] section. There seems to be no way to
2260 * determine exactly if any service is printable by only looking at the
2261 * [global] section so for now always announce as a print server. This
2262 * will need looking at in the future. Jeremy (jallison@whistle.com).
2265 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2270 /*******************************************************************
2272 ********************************************************************/
2273 void lp_rename_service(int snum, char *new_name)
2275 string_set(&pSERVICE(snum)->szService, new_name);
2278 /*******************************************************************
2280 ********************************************************************/
2281 void lp_remove_service(int snum)
2283 pSERVICE(snum)->valid = False;
2286 /*******************************************************************
2288 ********************************************************************/
2289 void lp_copy_service(int snum, char *new_name)
2291 char *oldname = lp_servicename(snum);
2292 do_section(new_name);
2294 snum = lp_servicenumber(new_name);
2296 lp_do_parameter(snum, "copy", oldname);
2301 /*******************************************************************
2302 Get the default server type we will announce as via nmbd.
2303 ********************************************************************/
2304 int lp_default_server_announce(void)
2306 return default_server_announce;
2309 /*******************************************************************
2310 Split the announce version into major and minor numbers.
2311 ********************************************************************/
2312 int lp_major_announce_version(void)
2314 static BOOL got_major = False;
2315 static int major_version = DEFAULT_MAJOR_VERSION;
2320 return major_version;
2323 if((vers = lp_announce_version()) == NULL)
2324 return major_version;
2326 if((p = strchr(vers, '.')) == 0)
2327 return major_version;
2330 major_version = atoi(vers);
2331 return major_version;
2334 int lp_minor_announce_version(void)
2336 static BOOL got_minor = False;
2337 static int minor_version = DEFAULT_MINOR_VERSION;
2342 return minor_version;
2345 if((vers = lp_announce_version()) == NULL)
2346 return minor_version;
2348 if((p = strchr(vers, '.')) == 0)
2349 return minor_version;
2352 minor_version = atoi(p);
2353 return minor_version;