2 Unix SMB/Netbios implementation.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993,1997
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
54 extern int DEBUGLEVEL;
55 extern pstring user_socket_options;
56 extern pstring myname;
59 #define GLOBAL_NAME "global"
64 #define PRINTCAP_NAME "/etc/qconfig"
66 #define PRINTCAP_NAME "/etc/printcap"
71 #define PRINTERS_NAME "printers"
75 #define HOMES_NAME "homes"
78 /* some helpful bits */
79 #define pSERVICE(i) ServicePtrs[i]
80 #define iSERVICE(i) (*pSERVICE(i))
81 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
82 #define VALID(i) iSERVICE(i).valid
84 /* these are the types of parameter we have */
87 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
88 P_STRING,P_USTRING,P_GSTRING,P_UGSTRING
93 P_LOCAL,P_GLOBAL,P_NONE
97 extern BOOL use_getwd_cache;
99 extern int extra_time_offset;
101 extern int coding_system;
105 * This structure describes global (ie., server-wide) parameters.
109 char *szPrintcapname;
112 char *szDefaultService;
116 char *szServerString;
117 char *szAutoServices;
118 char *szPasswdProgram;
122 char *szSMBPasswdFile;
123 char *szPasswordServer;
124 char *szSocketOptions;
127 char *szDomainController;
129 char *szCharacterSet;
135 char *szRemoteAnnounce;
136 char *szSocketAddress;
137 char *szNISHomeMapName;
156 int client_code_page;
161 BOOL bPreferredMaster;
164 BOOL bEncryptPasswords;
171 BOOL bReadPrediction;
180 static global Globals;
185 * This structure describes a single service.
193 char *szGuestaccount;
194 char *szInvalidUsers;
202 char *szRootPostExec;
203 char *szPrintcommand;
206 char *szLppausecommand;
207 char *szLpresumecommand;
209 char *szPrinterDriver;
226 int iCreate_force_mode;
235 BOOL bShortCasePreserve;
260 BOOL bDeleteReadonly;
262 char dummy[3]; /* for alignment */
266 /* This is a default service used to prime a services structure */
267 static service sDefault =
270 NULL, /* szService */
272 NULL, /* szUsername */
273 NULL, /* szGuestAccount */
274 NULL, /* szInvalidUsers */
275 NULL, /* szValidUsers */
276 NULL, /* szAdminUsers */
278 NULL, /* szInclude */
279 NULL, /* szPreExec */
280 NULL, /* szPostExec */
281 NULL, /* szRootPreExec */
282 NULL, /* szRootPostExec */
283 NULL, /* szPrintcommand */
284 NULL, /* szLpqcommand */
285 NULL, /* szLprmcommand */
286 NULL, /* szLppausecommand */
287 NULL, /* szLpresumecommand */
288 NULL, /* szPrintername */
289 NULL, /* szPrinterDriver */
290 NULL, /* szDontdescend */
291 NULL, /* szHostsallow */
292 NULL, /* szHostsdeny */
293 NULL, /* szMagicScript */
294 NULL, /* szMagicOutput */
295 NULL, /* szMangledMap */
296 NULL, /* szVetoFiles */
297 DEFAULT_FILES_TO_HIDE, /* szHideFiles */
299 NULL, /* force user */
300 NULL, /* force group */
302 NULL, /* writelist */
304 0, /* iMinPrintSpace */
305 0644, /* iCreate_mode */
306 0000, /* iCreate_force_mode */
307 0755, /* iDir_mode */
308 0000, /* iDir_force_mode */
309 0, /* iMaxConnections */
310 CASE_LOWER, /* iDefaultCase */
311 False, /* bAlternatePerm */
312 False, /* revalidate */
313 False, /* case sensitive */
314 False, /* case preserve */
315 False, /* short case preserve */
316 False, /* case mangle */
318 True, /* bHideDotFiles */
319 True, /* bBrowseable */
320 True, /* bAvailable */
321 True, /* bRead_only */
322 True, /* bNo_set_dir */
323 False, /* bGuest_only */
324 False, /* bGuest_ok */
325 False, /* bPrint_ok */
326 False, /* bPostscript */
327 False, /* bMap_system */
328 False, /* bMap_hidden */
329 True, /* bMap_archive */
331 False, /* bStrictLocking */
332 True, /* bShareModes */
333 False, /* bOnlyUser */
334 True, /* bMangledNames */
335 True, /* bWidelinks */
336 True, /* bSymlinks */
337 False, /* bSyncAlways */
338 '~', /* magic char */
340 False, /* bDeleteReadonly */
341 False, /* bFakeOplocks */
347 /* local variables */
348 static service **ServicePtrs = NULL;
349 static int iNumServices = 0;
350 static int iServiceIndex = 0;
351 static BOOL bInGlobalSection = True;
352 static BOOL bGlobalOnly = False;
355 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
357 /* prototypes for the special type handlers */
358 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
359 static BOOL handle_include(char *pszParmValue, char **ptr);
360 static BOOL handle_copy(char *pszParmValue, char **ptr);
361 static BOOL handle_protocol(char *pszParmValue,int *val);
362 static BOOL handle_security(char *pszParmValue,int *val);
363 static BOOL handle_case(char *pszParmValue,int *val);
364 static BOOL handle_printing(char *pszParmValue,int *val);
365 static BOOL handle_character_set(char *pszParmValue,int *val);
367 static BOOL handle_coding_system(char *pszParmValue,int *val);
379 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
380 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
381 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
382 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
383 {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
384 {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
385 {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
386 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
387 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
388 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
389 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
390 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
391 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
392 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
393 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
394 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
395 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
396 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
397 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
398 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
399 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
400 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
401 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
402 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
403 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
404 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
405 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
406 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
407 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
408 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
409 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
410 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
411 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
412 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
413 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
414 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
415 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
416 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
417 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
418 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
419 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
420 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
421 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
422 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
423 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
424 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
425 {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
426 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
427 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
428 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
429 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL},
430 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
431 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
432 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL},
433 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
434 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
435 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
436 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
437 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
438 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
439 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
440 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
441 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
442 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
443 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
444 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL},
445 {"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL},
447 {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
449 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL},
450 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
451 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
452 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL},
453 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
454 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
455 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
456 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
457 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
458 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL},
459 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
460 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
461 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
462 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL},
463 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL},
464 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL},
465 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
466 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
467 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
468 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
469 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
470 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
471 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
472 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
473 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
474 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
475 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
476 {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
477 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
478 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
479 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
480 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
481 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
482 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
483 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
484 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
485 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
486 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
487 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
488 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
489 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
490 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
491 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
492 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
493 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
494 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
495 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
496 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
497 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
498 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
499 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
500 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
501 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
502 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
503 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
504 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
505 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
506 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
507 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL},
508 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL},
509 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL},
510 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mode, NULL},
511 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mode, NULL},
512 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL},
513 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
514 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
515 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
516 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL},
517 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL},
518 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
519 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
520 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
521 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
522 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
523 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
524 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
525 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
526 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
527 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
528 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
529 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
530 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
531 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
532 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
533 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL},
534 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
535 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
536 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL},
537 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
538 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
539 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
540 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
541 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
542 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
543 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
544 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
545 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
546 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
547 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
548 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
549 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
550 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
551 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
552 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
553 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
555 {NULL, P_BOOL, P_NONE, NULL, NULL}
560 /***************************************************************************
561 Initialise the global parameter structure.
562 ***************************************************************************/
563 static void init_globals(void)
565 static BOOL done_init = False;
571 bzero((void *)&Globals,sizeof(Globals));
573 for (i = 0; parm_table[i].label; i++)
574 if ((parm_table[i].type == P_STRING ||
575 parm_table[i].type == P_USTRING) &&
577 string_init(parm_table[i].ptr,"");
579 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
580 string_set(&sDefault.szPrinterDriver, "NULL");
586 DEBUG(3,("Initialising global parameters\n"));
588 #ifdef SMB_PASSWD_FILE
589 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
591 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
592 string_set(&Globals.szWorkGroup, WORKGROUP);
594 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
596 string_set(&Globals.szPasswdProgram, "/bin/passwd");
598 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
599 string_set(&Globals.szLockDir, LOCKDIR);
600 string_set(&Globals.szRootdir, "/");
601 string_set(&Globals.szSmbrun, SMBRUN);
602 string_set(&Globals.szSocketAddress, "0.0.0.0");
603 sprintf(s,"Samba %s",VERSION);
604 string_set(&Globals.szServerString,s);
605 Globals.bLoadPrinters = True;
606 Globals.bUseRhosts = False;
607 Globals.max_packet = 65535;
608 Globals.mangled_stack = 50;
609 Globals.max_xmit = 65535;
610 Globals.max_mux = 50; /* This is *needed* for profile support. */
611 Globals.lpqcachetime = 10;
612 Globals.pwordlevel = 0;
613 Globals.deadtime = 0;
614 Globals.max_log_size = 5000;
615 Globals.maxprotocol = PROTOCOL_NT1;
616 Globals.security = SEC_SHARE;
617 Globals.bEncryptPasswords = False;
618 Globals.printing = DEFAULT_PRINTING;
619 Globals.bReadRaw = True;
620 Globals.bWriteRaw = True;
621 Globals.bReadPrediction = False;
622 Globals.bReadbmpx = True;
623 Globals.bNullPasswords = False;
624 Globals.bStripDot = False;
626 Globals.bSyslogOnly = False;
627 Globals.os_level = 0;
628 Globals.max_ttl = 60*60*4; /* 2 hours default */
629 Globals.ReadSize = 16*1024;
630 Globals.shmem_size = SHMEM_SIZE;
631 Globals.shmem_hash_size = SHMEM_HASH_SIZE;
632 Globals.bUnixRealname = False;
633 #if (defined(NETGROUP) && defined(AUTOMOUNT))
634 Globals.bNISHomeMap = False;
635 string_set(&Globals.szNISHomeMapName, "auto.home");
638 coding_system = interpret_coding_system (KANJI, SJIS_CODE);
640 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
641 Globals.bTimeServer = False;
643 /* these parameters are set to defaults that are more appropriate
644 for the increasing samba install base:
646 as a member of the workgroup, that will possibly become a
647 _local_ master browser (lm = True). this is opposed to a forced
648 local master browser startup (pm = True).
650 doesn't provide WINS server service by default (wsupp = False),
651 and doesn't provide domain master browser services by default, either.
655 Globals.bPreferredMaster = False;
656 Globals.bLocalMaster = True;
657 Globals.bDomainMaster = False;
658 Globals.bDomainLogons = False;
659 Globals.bBrowseList = True;
660 Globals.bWINSsupport = False;
661 Globals.bWINSproxy = False;
663 /* this parameter is currently set to the default functionality
664 in samba. given that w95 and NT is starting to use DNS for
665 server resolution, i expect that at some point it would be
666 sensible to default this to False.
668 this parameter is added because nmbd is a single process, and
669 gethostbyname is a blocking call, which can take out nmbd for
670 several seconds while a dns lookup is performed.
674 Globals.bDNSproxy = True;
677 /***************************************************************************
678 check if a string is initialised and if not then initialise it
679 ***************************************************************************/
680 static void string_initial(char **s,char *v)
687 /***************************************************************************
688 Initialise the sDefault parameter structure.
689 ***************************************************************************/
690 static void init_locals(void)
692 /* choose defaults depending on the type of printing */
693 switch (Globals.printing)
699 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
700 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
701 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
706 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
707 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
708 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
710 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
711 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
716 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
717 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
718 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
726 /******************************************************************* a
727 convenience routine to grab string parameters into a rotating buffer,
728 and run standard_sub_basic on them. The buffers can be written to by
729 callers without affecting the source string.
730 ********************************************************************/
731 char *lp_string(char *s)
733 static char *bufs[10];
734 static int buflen[10];
735 static int next = -1;
738 int len = s?strlen(s):0;
749 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
752 if (buflen[next] != len) {
754 if (bufs[next]) free(bufs[next]);
755 bufs[next] = (char *)malloc(len);
757 DEBUG(0,("out of memory in lp_string()"));
762 ret = &bufs[next][0];
770 standard_sub_basic(ret);
776 In this section all the functions that are used to access the
777 parameters from the rest of the program are defined
780 #define FN_GLOBAL_STRING(fn_name,ptr) \
781 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
782 #define FN_GLOBAL_BOOL(fn_name,ptr) \
783 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
784 #define FN_GLOBAL_CHAR(fn_name,ptr) \
785 char fn_name(void) {return(*(char *)(ptr));}
786 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
787 int fn_name(void) {return(*(int *)(ptr));}
789 #define FN_LOCAL_STRING(fn_name,val) \
790 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
791 #define FN_LOCAL_BOOL(fn_name,val) \
792 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
793 #define FN_LOCAL_CHAR(fn_name,val) \
794 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
795 #define FN_LOCAL_INTEGER(fn_name,val) \
796 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
798 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
799 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
800 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
801 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
802 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
803 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
804 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
805 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
806 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
807 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
808 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
809 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
810 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
811 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
812 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
813 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
814 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
815 FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
816 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
817 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
818 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
819 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
820 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
821 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
822 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
823 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
824 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
826 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
827 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
828 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
829 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
830 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
831 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
832 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
833 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
834 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
835 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
836 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
837 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
838 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
839 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
840 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
841 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
842 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
843 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
844 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
845 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
846 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
847 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
849 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
850 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
851 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
852 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
853 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
854 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
855 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
856 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
857 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
858 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
859 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
860 FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size)
861 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
862 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
863 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
864 FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
865 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
866 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
867 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
868 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
870 FN_LOCAL_STRING(lp_preexec,szPreExec)
871 FN_LOCAL_STRING(lp_postexec,szPostExec)
872 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
873 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
874 FN_LOCAL_STRING(lp_servicename,szService)
875 FN_LOCAL_STRING(lp_pathname,szPath)
876 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
877 FN_LOCAL_STRING(lp_username,szUsername)
878 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
879 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
880 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
881 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
882 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
883 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
884 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
885 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
886 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
887 FN_LOCAL_STRING(lp_printername,szPrintername)
888 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
889 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
890 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
891 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
892 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
893 FN_LOCAL_STRING(lp_comment,comment)
894 FN_LOCAL_STRING(lp_force_user,force_user)
895 FN_LOCAL_STRING(lp_force_group,force_group)
896 FN_LOCAL_STRING(lp_readlist,readlist)
897 FN_LOCAL_STRING(lp_writelist,writelist)
898 FN_LOCAL_STRING(lp_volume,volume)
899 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
900 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
901 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
903 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
904 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
905 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
906 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
907 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
908 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
909 FN_LOCAL_BOOL(lp_status,status)
910 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
911 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
912 FN_LOCAL_BOOL(lp_readonly,bRead_only)
913 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
914 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
915 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
916 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
917 FN_LOCAL_BOOL(lp_postscript,bPostscript)
918 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
919 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
920 FN_LOCAL_BOOL(lp_locking,bLocking)
921 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
922 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
923 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
924 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
925 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
926 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
927 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
928 FN_LOCAL_BOOL(lp_map_system,bMap_system)
929 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
930 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
932 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mode)
933 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
934 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mode)
935 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
936 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
937 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
938 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
940 FN_LOCAL_CHAR(lp_magicchar,magic_char)
944 /* local prototypes */
945 static int strwicmp( char *psz1, char *psz2 );
946 static int map_parameter( char *pszParmName);
947 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
948 static int getservicebyname(char *pszServiceName, service *pserviceDest);
949 static void copy_service( service *pserviceDest,
950 service *pserviceSource,
951 BOOL *pcopymapDest );
952 static BOOL service_ok(int iService);
953 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
954 static BOOL do_section(char *pszSectionName);
955 static void dump_globals(void);
956 static void dump_a_service(service *pService);
957 static void init_copymap(service *pservice);
960 /***************************************************************************
961 initialise a service to the defaults
962 ***************************************************************************/
963 static void init_service(service *pservice)
965 bzero((char *)pservice,sizeof(service));
966 copy_service(pservice,&sDefault,NULL);
970 /***************************************************************************
971 free the dynamically allocated parts of a service struct
972 ***************************************************************************/
973 static void free_service(service *pservice)
979 for (i=0;parm_table[i].label;i++)
980 if ((parm_table[i].type == P_STRING ||
981 parm_table[i].type == P_STRING) &&
982 parm_table[i].class == P_LOCAL)
983 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
986 /***************************************************************************
987 add a new service to the services array initialising it with the given
989 ***************************************************************************/
990 static int add_a_service(service *pservice, char *name)
994 int num_to_alloc = iNumServices+1;
996 tservice = *pservice;
998 /* it might already exist */
1001 i = getservicebyname(name,NULL);
1006 /* find an invalid one */
1007 for (i=0;i<iNumServices;i++)
1008 if (!pSERVICE(i)->valid)
1011 /* if not, then create one */
1012 if (i == iNumServices)
1014 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1016 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1018 if (!ServicePtrs || !pSERVICE(iNumServices))
1024 free_service(pSERVICE(i));
1026 pSERVICE(i)->valid = True;
1028 init_service(pSERVICE(i));
1029 copy_service(pSERVICE(i),&tservice,NULL);
1031 string_set(&iSERVICE(i).szService,name);
1036 /***************************************************************************
1037 add a new home service, with the specified home directory, defaults coming
1039 ***************************************************************************/
1040 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1042 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1047 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1048 string_set(&iSERVICE(i).szPath,pszHomedir);
1049 if (!(*(iSERVICE(i).comment)))
1052 sprintf(comment,"Home directory of %s",pszHomename);
1053 string_set(&iSERVICE(i).comment,comment);
1055 iSERVICE(i).bAvailable = sDefault.bAvailable;
1056 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1058 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1063 /***************************************************************************
1064 add a new service, based on an old one
1065 ***************************************************************************/
1066 int lp_add_service(char *pszService, int iDefaultService)
1068 return(add_a_service(pSERVICE(iDefaultService),pszService));
1072 /***************************************************************************
1074 ***************************************************************************/
1075 static BOOL lp_add_ipc(void)
1078 int i = add_a_service(&sDefault,"IPC$");
1083 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1085 string_set(&iSERVICE(i).szPath,tmpdir());
1086 string_set(&iSERVICE(i).szUsername,"");
1087 string_set(&iSERVICE(i).comment,comment);
1088 iSERVICE(i).status = False;
1089 iSERVICE(i).iMaxConnections = 0;
1090 iSERVICE(i).bAvailable = True;
1091 iSERVICE(i).bRead_only = True;
1092 iSERVICE(i).bGuest_only = False;
1093 iSERVICE(i).bGuest_ok = True;
1094 iSERVICE(i).bPrint_ok = False;
1095 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1097 DEBUG(3,("adding IPC service\n"));
1103 /***************************************************************************
1104 add a new printer service, with defaults coming from service iFrom
1105 ***************************************************************************/
1106 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1108 char *comment = "From Printcap";
1109 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1114 /* note that we do NOT default the availability flag to True - */
1115 /* we take it from the default service passed. This allows all */
1116 /* dynamic printers to be disabled by disabling the [printers] */
1117 /* entry (if/when the 'available' keyword is implemented!). */
1119 /* the printer name is set to the service name. */
1120 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1121 string_set(&iSERVICE(i).comment,comment);
1122 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1123 /* Printers cannot be read_only. */
1124 iSERVICE(i).bRead_only = False;
1125 /* No share modes on printer services. */
1126 iSERVICE(i).bShareModes = False;
1128 DEBUG(3,("adding printer service %s\n",pszPrintername));
1134 /***************************************************************************
1135 Do a case-insensitive, whitespace-ignoring string compare.
1136 ***************************************************************************/
1137 static int strwicmp(char *psz1, char *psz2)
1139 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1140 /* appropriate value. */
1150 /* sync the strings on first non-whitespace */
1153 while (isspace(*psz1))
1155 while (isspace(*psz2))
1157 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1162 return (*psz1 - *psz2);
1165 /***************************************************************************
1166 Map a parameter's string representation to something we can use.
1167 Returns False if the parameter string is not recognised, else TRUE.
1168 ***************************************************************************/
1169 static int map_parameter(char *pszParmName)
1173 if (*pszParmName == '-')
1176 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1177 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1180 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1185 /***************************************************************************
1186 Set a boolean variable from the text value stored in the passed string.
1187 Returns True in success, False if the passed string does not correctly
1188 represent a boolean.
1189 ***************************************************************************/
1190 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1195 if (strwicmp(pszParmValue, "yes") == 0 ||
1196 strwicmp(pszParmValue, "true") == 0 ||
1197 strwicmp(pszParmValue, "1") == 0)
1200 if (strwicmp(pszParmValue, "no") == 0 ||
1201 strwicmp(pszParmValue, "False") == 0 ||
1202 strwicmp(pszParmValue, "0") == 0)
1206 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1213 /***************************************************************************
1214 Find a service by name. Otherwise works like get_service.
1215 ***************************************************************************/
1216 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1220 for (iService = iNumServices - 1; iService >= 0; iService--)
1221 if (VALID(iService) &&
1222 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1224 if (pserviceDest != NULL)
1225 copy_service(pserviceDest, pSERVICE(iService), NULL);
1234 /***************************************************************************
1235 Copy a service structure to another
1237 If pcopymapDest is NULL then copy all fields
1238 ***************************************************************************/
1239 static void copy_service(service *pserviceDest,
1240 service *pserviceSource,
1244 BOOL bcopyall = (pcopymapDest == NULL);
1246 for (i=0;parm_table[i].label;i++)
1247 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1248 (bcopyall || pcopymapDest[i]))
1250 void *def_ptr = parm_table[i].ptr;
1252 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1254 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1256 switch (parm_table[i].type)
1260 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1265 *(int *)dest_ptr = *(int *)src_ptr;
1269 *(char *)dest_ptr = *(char *)src_ptr;
1273 string_set(dest_ptr,*(char **)src_ptr);
1277 string_set(dest_ptr,*(char **)src_ptr);
1278 strupper(*(char **)dest_ptr);
1287 init_copymap(pserviceDest);
1288 if (pserviceSource->copymap)
1289 memcpy((void *)pserviceDest->copymap,
1290 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1294 /***************************************************************************
1295 Check a service for consistency. Return False if the service is in any way
1296 incomplete or faulty, else True.
1297 ***************************************************************************/
1298 static BOOL service_ok(int iService)
1303 if (iSERVICE(iService).szService[0] == '\0')
1305 DEBUG(0,( "The following message indicates an internal error:\n"));
1306 DEBUG(0,( "No service name in service entry.\n"));
1310 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1311 /* I can't see why you'd want a non-printable printer service... */
1312 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1313 if (!iSERVICE(iService).bPrint_ok)
1315 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1316 iSERVICE(iService).szService));
1317 iSERVICE(iService).bPrint_ok = True;
1320 if (iSERVICE(iService).szPath[0] == '\0' &&
1321 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1323 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1324 string_set(&iSERVICE(iService).szPath,tmpdir());
1327 /* If a service is flagged unavailable, log the fact at level 0. */
1328 if (!iSERVICE(iService).bAvailable)
1329 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1330 iSERVICE(iService).szService));
1335 static struct file_lists {
1336 struct file_lists *next;
1339 } *file_lists = NULL;
1341 /*******************************************************************
1342 keep a linked list of all config files so we know when one has changed
1343 it's date and needs to be reloaded
1344 ********************************************************************/
1345 static void add_to_file_list(char *fname)
1347 struct file_lists *f=file_lists;
1350 if (f->name && !strcmp(f->name,fname)) break;
1355 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1357 f->next = file_lists;
1358 f->name = strdup(fname);
1369 standard_sub_basic(n2);
1370 f->modtime = file_modtime(n2);
1375 /*******************************************************************
1376 check if a config file has changed date
1377 ********************************************************************/
1378 BOOL lp_file_list_changed(void)
1380 struct file_lists *f = file_lists;
1384 standard_sub_basic(n2);
1385 if (f->modtime != file_modtime(n2)) return(True);
1392 /***************************************************************************
1393 handle the interpretation of the coding system parameter
1394 *************************************************************************/
1395 static BOOL handle_coding_system(char *pszParmValue,int *val)
1397 *val = interpret_coding_system(pszParmValue,*val);
1402 /***************************************************************************
1403 handle the interpretation of the character set system parameter
1404 ***************************************************************************/
1405 static BOOL handle_character_set(char *pszParmValue,int *val)
1407 string_set(&Globals.szCharacterSet,pszParmValue);
1408 *val = interpret_character_set(pszParmValue,*val);
1413 /***************************************************************************
1414 handle the interpretation of the protocol parameter
1415 ***************************************************************************/
1416 static BOOL handle_protocol(char *pszParmValue,int *val)
1418 *val = interpret_protocol(pszParmValue,*val);
1422 /***************************************************************************
1423 handle the interpretation of the security parameter
1424 ***************************************************************************/
1425 static BOOL handle_security(char *pszParmValue,int *val)
1427 *val = interpret_security(pszParmValue,*val);
1431 /***************************************************************************
1432 handle the interpretation of the default case
1433 ***************************************************************************/
1434 static BOOL handle_case(char *pszParmValue,int *val)
1436 if (strequal(pszParmValue,"LOWER"))
1438 else if (strequal(pszParmValue,"UPPER"))
1443 /***************************************************************************
1444 handle the interpretation of the printing system
1445 ***************************************************************************/
1446 static BOOL handle_printing(char *pszParmValue,int *val)
1448 if (strequal(pszParmValue,"sysv"))
1450 else if (strequal(pszParmValue,"aix"))
1452 else if (strequal(pszParmValue,"hpux"))
1454 else if (strequal(pszParmValue,"bsd"))
1456 else if (strequal(pszParmValue,"qnx"))
1458 else if (strequal(pszParmValue,"plp"))
1460 else if (strequal(pszParmValue,"lprng"))
1465 /***************************************************************************
1466 handle the valid chars lines
1467 ***************************************************************************/
1468 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1470 string_set(ptr,pszParmValue);
1472 add_char_string(pszParmValue);
1477 /***************************************************************************
1478 handle the include operation
1479 ***************************************************************************/
1480 static BOOL handle_include(char *pszParmValue,char **ptr)
1483 strcpy(fname,pszParmValue);
1485 add_to_file_list(fname);
1487 standard_sub_basic(fname);
1489 string_set(ptr,fname);
1491 if (file_exist(fname,NULL))
1492 return(pm_process(fname, do_section, do_parameter));
1494 DEBUG(2,("Can't find include file %s\n",fname));
1500 /***************************************************************************
1501 handle the interpretation of the copy parameter
1502 ***************************************************************************/
1503 static BOOL handle_copy(char *pszParmValue,char **ptr)
1507 service serviceTemp;
1509 string_set(ptr,pszParmValue);
1511 init_service(&serviceTemp);
1515 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1517 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1519 if (iTemp == iServiceIndex)
1521 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1526 copy_service(pSERVICE(iServiceIndex),
1528 iSERVICE(iServiceIndex).copymap);
1534 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1539 free_service(&serviceTemp);
1544 /***************************************************************************
1545 initialise a copymap
1546 ***************************************************************************/
1547 static void init_copymap(service *pservice)
1550 if (pservice->copymap) free(pservice->copymap);
1551 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1552 if (!pservice->copymap)
1553 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1555 for (i=0;i<NUMPARAMETERS;i++)
1556 pservice->copymap[i] = True;
1560 /***************************************************************************
1561 Process a parameter.
1562 ***************************************************************************/
1563 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1566 void *parm_ptr=NULL; /* where we are going to store the result */
1569 if (!bInGlobalSection && bGlobalOnly) return(True);
1571 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1573 parmnum = map_parameter(pszParmName);
1577 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1581 def_ptr = parm_table[parmnum].ptr;
1583 /* we might point at a service, the default service or a global */
1584 if (bInGlobalSection)
1588 if (parm_table[parmnum].class == P_GLOBAL)
1590 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1593 parm_ptr = ((char *)pSERVICE(iServiceIndex)) + PTR_DIFF(def_ptr,&sDefault);
1596 if (!bInGlobalSection)
1599 if (!iSERVICE(iServiceIndex).copymap)
1600 init_copymap(pSERVICE(iServiceIndex));
1602 /* this handles the aliases - set the copymap for other entries with
1603 the same data pointer */
1604 for (i=0;parm_table[i].label;i++)
1605 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1606 iSERVICE(iServiceIndex).copymap[i] = False;
1609 /* if it is a special case then go ahead */
1610 if (parm_table[parmnum].special)
1612 parm_table[parmnum].special(pszParmValue,parm_ptr);
1616 /* now switch on the type of variable it is */
1617 switch (parm_table[parmnum].type)
1620 set_boolean(parm_ptr,pszParmValue);
1624 set_boolean(parm_ptr,pszParmValue);
1625 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1629 *(int *)parm_ptr = atoi(pszParmValue);
1633 *(char *)parm_ptr = *pszParmValue;
1637 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1641 string_set(parm_ptr,pszParmValue);
1645 string_set(parm_ptr,pszParmValue);
1646 strupper(*(char **)parm_ptr);
1650 strcpy((char *)parm_ptr,pszParmValue);
1654 strcpy((char *)parm_ptr,pszParmValue);
1655 strupper((char *)parm_ptr);
1662 /***************************************************************************
1663 print a parameter of the specified type
1664 ***************************************************************************/
1665 static void print_parameter(parm_type type,void *ptr)
1670 printf("%s",BOOLSTR(*(BOOL *)ptr));
1674 printf("%s",BOOLSTR(! *(BOOL *)ptr));
1678 printf("%d",*(int *)ptr);
1682 printf("%c",*(char *)ptr);
1686 printf("0%o",*(int *)ptr);
1692 printf("%s",(char *)ptr);
1698 printf("%s",*(char **)ptr);
1704 /***************************************************************************
1705 check if two parameters are equal
1706 ***************************************************************************/
1707 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1713 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1717 return(*((int *)ptr1) == *((int *)ptr2));
1720 return(*((char *)ptr1) == *((char *)ptr2));
1725 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1726 if (p1 && !*p1) p1 = NULL;
1727 if (p2 && !*p2) p2 = NULL;
1728 return(p1==p2 || strequal(p1,p2));
1733 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1734 if (p1 && !*p1) p1 = NULL;
1735 if (p2 && !*p2) p2 = NULL;
1736 return(p1==p2 || strequal(p1,p2));
1742 /***************************************************************************
1743 Process a new section (service). At this stage all sections are services.
1744 Later we'll have special sections that permit server parameters to be set.
1745 Returns True on success, False on failure.
1746 ***************************************************************************/
1747 static BOOL do_section(char *pszSectionName)
1750 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1751 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1754 /* if we were in a global section then do the local inits */
1755 if (bInGlobalSection && !isglobal)
1758 /* if we've just struck a global section, note the fact. */
1759 bInGlobalSection = isglobal;
1761 /* check for multiple global sections */
1762 if (bInGlobalSection)
1764 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1768 if (!bInGlobalSection && bGlobalOnly) return(True);
1770 /* if we have a current service, tidy it up before moving on */
1773 if (iServiceIndex >= 0)
1774 bRetval = service_ok(iServiceIndex);
1776 /* if all is still well, move to the next record in the services array */
1779 /* We put this here to avoid an odd message order if messages are */
1780 /* issued by the post-processing of a previous section. */
1781 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1783 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1785 DEBUG(0,("Failed to add a new service\n"));
1793 /***************************************************************************
1794 Display the contents of the global structure.
1795 ***************************************************************************/
1796 static void dump_globals(void)
1799 printf("Global parameters:\n");
1801 for (i=0;parm_table[i].label;i++)
1802 if (parm_table[i].class == P_GLOBAL &&
1803 parm_table[i].ptr &&
1804 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1806 printf("\t%s: ",parm_table[i].label);
1807 print_parameter(parm_table[i].type,parm_table[i].ptr);
1812 /***************************************************************************
1813 Display the contents of a single services record.
1814 ***************************************************************************/
1815 static void dump_a_service(service *pService)
1818 if (pService == &sDefault)
1819 printf("\nDefault service parameters:\n");
1821 printf("\nService parameters [%s]:\n",pService->szService);
1823 for (i=0;parm_table[i].label;i++)
1824 if (parm_table[i].class == P_LOCAL &&
1825 parm_table[i].ptr &&
1826 (*parm_table[i].label != '-') &&
1827 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1829 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1831 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1832 ((char *)pService) + pdiff,
1833 ((char *)&sDefault) + pdiff))
1835 printf("\t%s: ",parm_table[i].label);
1836 print_parameter(parm_table[i].type,
1837 ((char *)pService) + pdiff);
1844 /***************************************************************************
1845 Display the contents of a single copy structure.
1846 ***************************************************************************/
1847 static void dump_copy_map(BOOL *pcopymap)
1850 if (!pcopymap) return;
1852 printf("\n\tNon-Copied parameters:\n");
1854 for (i=0;parm_table[i].label;i++)
1855 if (parm_table[i].class == P_LOCAL &&
1856 parm_table[i].ptr && !pcopymap[i] &&
1857 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1859 printf("\t\t%s\n",parm_table[i].label);
1864 /***************************************************************************
1865 Return TRUE if the passed service number is within range.
1866 ***************************************************************************/
1867 BOOL lp_snum_ok(int iService)
1869 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
1873 /***************************************************************************
1874 auto-load some homes and printer services
1875 ***************************************************************************/
1876 static void lp_add_auto_services(char *str)
1880 int homes = lp_servicenumber(HOMES_NAME);
1881 int printers = lp_servicenumber(PRINTERS_NAME);
1889 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
1891 char *home = get_home_dir(p);
1893 if (lp_servicenumber(p) >= 0) continue;
1895 if (home && homes >= 0)
1897 lp_add_home(p,homes,home);
1901 if (printers >= 0 && pcap_printername_ok(p,NULL))
1902 lp_add_printer(p,printers);
1907 /***************************************************************************
1908 auto-load one printer
1909 ***************************************************************************/
1910 static void lp_add_one_printer(char *name,char *comment)
1912 int printers = lp_servicenumber(PRINTERS_NAME);
1915 if (lp_servicenumber(name) < 0)
1917 lp_add_printer(name,printers);
1918 if ((i=lp_servicenumber(name)) >= 0)
1919 string_set(&iSERVICE(i).comment,comment);
1924 /***************************************************************************
1925 auto-load printer services
1926 ***************************************************************************/
1927 static void lp_add_all_printers(void)
1929 int printers = lp_servicenumber(PRINTERS_NAME);
1931 if (printers < 0) return;
1933 pcap_printer_fn(lp_add_one_printer);
1936 /***************************************************************************
1937 have we loaded a services file yet?
1938 ***************************************************************************/
1939 BOOL lp_loaded(void)
1944 /***************************************************************************
1945 unload unused services
1946 ***************************************************************************/
1947 void lp_killunused(BOOL (*snumused)(int ))
1950 for (i=0;i<iNumServices;i++)
1951 if (VALID(i) && !snumused(i))
1953 iSERVICE(i).valid = False;
1954 free_service(pSERVICE(i));
1958 /***************************************************************************
1959 Load the services array from the services file. Return True on success,
1961 ***************************************************************************/
1962 BOOL lp_load(char *pszFname,BOOL global_only)
1967 add_to_file_list(pszFname);
1971 bInGlobalSection = True;
1972 bGlobalOnly = global_only;
1976 strcpy(n2,pszFname);
1977 standard_sub_basic(n2);
1979 /* We get sections first, so have to start 'behind' to make up */
1981 bRetval = pm_process(n2, do_section, do_parameter);
1983 /* finish up the last section */
1984 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
1986 if (iServiceIndex >= 0)
1987 bRetval = service_ok(iServiceIndex);
1989 lp_add_auto_services(lp_auto_services());
1990 if (lp_load_printers())
1991 lp_add_all_printers();
2001 /***************************************************************************
2002 return the max number of services
2003 ***************************************************************************/
2004 int lp_numservices(void)
2006 return(iNumServices);
2009 /***************************************************************************
2010 Display the contents of the services array in human-readable form.
2011 ***************************************************************************/
2018 dump_a_service(&sDefault);
2020 for (iService = 0; iService < iNumServices; iService++)
2022 if (VALID(iService))
2024 if (iSERVICE(iService).szService[0] == '\0')
2026 dump_a_service(pSERVICE(iService));
2031 /***************************************************************************
2032 Return the number of the service with the given name, or -1 if it doesn't
2033 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2034 getservicebyname()! This works ONLY if all services have been loaded, and
2035 does not copy the found service.
2036 ***************************************************************************/
2037 int lp_servicenumber(char *pszServiceName)
2041 for (iService = iNumServices - 1; iService >= 0; iService--)
2042 if (VALID(iService) &&
2043 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
2047 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2052 /*******************************************************************
2053 a useful volume label function
2054 ******************************************************************/
2055 char *volume_label(int snum)
2057 char *ret = lp_volume(snum);
2058 if (!*ret) return(lp_servicename(snum));