xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 3057)
1 # include <stdio.h>
2 # include <pwd.h>
3 # include "postbox.h"
4 
5 /*
6 **  CONF.C -- Postbox Configuration Tables.
7 **
8 **	Defines the configuration of this installation.
9 **
10 **	Compilation Flags:
11 **		HASARPA -- set if this machine has a connection to
12 **			the Arpanet.
13 **		HASUUCP -- set if this machine has a connection to
14 **			the UUCP network.
15 **		NETV6MAIL -- set if you want to use "v6mail" that
16 **			comes with the Berkeley network.  Normally
17 **			/bin/mail will work fine, but around Berkeley
18 **			we use v6mail because it is a "fixed target".
19 **			Also, only v6mail has the "/dev/mail" stuff
20 **			in it (for biff(1)).
21 **		V6 -- running on a version 6 system.  This determines
22 **			whether to define certain routines between
23 **			the two systems.  If you are running a funny
24 **			system, e.g., V6 with long tty names, this
25 **			should be checked carefully.
26 **		DUMBMAIL -- set if your /bin/mail doesn't have the
27 **			-d flag.
28 **
29 **	Configuration Variables:
30 **		ArpaHost -- the arpanet name of the host through
31 **			which arpanet mail will be sent.
32 **		MyLocName -- the name of the host on a local network.
33 **			This is used to disambiguate the contents of
34 **			ArpaHost among many hosts who may be sharing
35 **			a gateway.
36 **		DaemonName -- the name of this agent for use in
37 **			error messages, typically "~MAILER~DAEMON~"
38 **			at this host on the local net.
39 **		ArpaLocal -- a list of local names for this host on
40 **			the arpanet.  Only functional if HASARPA set.
41 **		UucpLocal -- ditto for the Arpanet.
42 **		BerkLocal -- ditto for the Berknet.
43 **		Mailer -- a table of mailers known to the system.
44 **			The fields are:
45 **			- the pathname of the mailer.
46 **			- a list of flags describing the properties
47 **			  of this mailer:
48 **			   M_FOPT -- if set, the mailer has a picky "-f"
49 **				option.  In this mode, the mailer will
50 **				only accept the "-f" option if the
51 **				sender is actually "root", "network",
52 **				and possibly (but not necessarily) if
53 **				the -f argument matches the real sender.
54 **				The effect is that if the "-f" option
55 **				is given to postbox then it will be
56 **				passed through (as arguments 1 & 2) to
57 **				the mailer.
58 **			   M_ROPT -- identical to M_FOPT, except uses
59 **				-r instead.
60 **			   M_QUIET -- if set, don't print a message if
61 **				the mailer returns bad status.
62 **			   M_RESTR -- if set, this mailer is restricted
63 **				to use by "daemon"; otherwise, we do a
64 **				setuid(getuid()) before calling the
65 **				mailer.
66 **			   M_HDR -- if set, the mailer wants us to
67 **				insert a UNIX "From" line before
68 **				outputing.
69 **			   M_FHDR -- if set, the header that we
70 **				generate will be used literally, so
71 **				we must force it to be correct.  The
72 **				effect is that we generate a header
73 **				even if one exists.
74 **			   M_NOHOST -- if set, this mailer doesn't care
75 **				about the host part (e.g., the local
76 **				mailer).
77 **			   M_STRIPQ -- if set, strip quote (`"')
78 **				characters out of parameters as you
79 **				transliterate them into the argument
80 **				vector.  For example, the local mailer
81 **				is called directly, so these should be
82 **				stripped, but the program-mailer (i.e.,
83 **				csh) should leave them in.
84 **			   M_NEEDDATE -- this mailer requires a Date:
85 **				field in the message.
86 **			   M_NEEDFROM -- this mailer requires a From:
87 **				field in the message.
88 **			   M_MSGID -- this mailer requires a Message-Id
89 **				field in the message.
90 **			   M_COMMAS -- this mailer wants comma-
91 **				seperated To: and Cc: fields.
92 **			   M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID|
93 **				M_COMMAS.
94 **			- an exit status to use as the code for the
95 **			  error message print if the mailer returns
96 **			  something we don't understand.
97 **			- A list of names that are to be considered
98 **			  "local" (and hence are stripped off) for
99 **			  this mailer.
100 **			- An argument vector to be passed to the
101 **			  mailer with the following substitutions:
102 **			   $f - the from person name.
103 **			   $u - the target user name.
104 **			   $h - the target user host.
105 **			   $c - the hop count.
106 **			>>>>>>>>>> Entry zero must be for the local
107 **			>> NOTE >> mailer and entry one must be for
108 **			>>>>>>>>>> the shell.
109 **		ParseTab -- a table driving the parsing process.  Each
110 **			entry contains:
111 **			- a character that will trigger this entry.
112 **			- an index into the Mailer table.
113 **			- a word of flags, described in postbox.h.
114 **			- an argument.  If we have P_MAP, it is the
115 **			  character to turn the trigger character into.
116 **			  If we have P_MOVE, it is the site to send it
117 **			  to, using the mailer specified above.
118 **			This table will almost certainly have to be
119 **			changed on your site if you have anything more
120 **			than the UUCP net.
121 **		HdrInfo -- a table describing well-known header fields.
122 **			Each entry has the field name and some flags,
123 **			which can be:
124 **			- H_EOH -- this field is equivalent to a blank
125 **			  line; i.e., it signifies end of header.
126 **			- H_DELETE -- delete this field.
127 **			There is also a field pointing to a pointer
128 **			that should be set to point to this header.
129 */
130 
131 
132 
133 
134 static char SccsId[] = "@(#)conf.c	3.5	03/07/81";
135 
136 
137 # include <whoami.h>		/* definitions of machine id's at berkeley */
138 
139 # ifdef BERKELEY
140 
141 char	*ArpaHost = "Berkeley";	/* host name of gateway on Arpanet */
142 char	*UucpHost = "ucbvax";	/* host name of gateway on UUCP net */
143 # define BerkHost   MyLocName	/* host name of gateway on Berk net */
144 # define NETV6MAIL		/* use /usr/net/bin/v6mail for local delivery */
145 
146 # else BERKELEY
147 
148 char	*ArpaHost = "[unknown]";
149 char	*MyLocName = sysname;
150 # define HASUUCP		/* default to having UUCP net */
151 char	*UucpLocal[] = { sysname, NULL };
152 
153 # endif BERKELEY
154 
155 
156 /* Specific Configurations for Berkeley Machines */
157 
158 /* Berkeley people: mail changes to csvax:eric or they will be lost! */
159 
160 # ifdef ING70
161 static char	*BerkLocal[] = { "i", "ingres", "ing70", NULL };
162 char		*ArpaLocal = { "berkeley", "ucb", NULL };
163 char		*MyLocName = "Ing70";
164 char		*DaemonName = "Ing70:~MAILER~DAEMON~";
165 # define HASARPA
166 # define V6
167 # endif ING70
168 
169 # ifdef INGVAX
170 static char	*BerkLocal[] = { "j", "ingvax", NULL };
171 char		*MyLocName = "IngVax";
172 char		*DaemonName = "IngVax:~MAILER~DAEMON~";
173 # endif INGVAX
174 
175 # ifdef CSVAX
176 static char	*BerkLocal[] = { "v", "csvax", "vax", NULL };
177 static char	*UucpLocal[] = { "ucbvax", "ernie", NULL };
178 char		*MyLocName = "CSVAX";
179 char		*DaemonName = "CSVAX:~MAILER~DAEMON~";
180 # define HASUUCP
181 # endif CSVAX
182 
183 # ifdef ARPAVAX
184 static char	*BerkLocal[] = { "r", "arpavax", NULL };
185 char		*MyLocName = "ARPAVAX";
186 char		*DaemonName = "ARPAVAX:~MAILER~DAEMON~";
187 # endif ARPAVAX
188 
189 # ifdef CORY
190 static char	*BerkLocal[] = { "y", "cory", NULL };
191 char		*MyLocName = "Cory";
192 char		*DaemonName = "Cory:~MAILER~DAEMON~";
193 # endif CORY
194 
195 # ifdef ONYX
196 static char	*BerkLocal[[] = { "x", "onyx", NULL };
197 char		*MyLocName = "Onyx";
198 char		*DaemonName = "Onyx:~MAILER~DAEMON~";
199 # endif ONYX
200 
201 # ifdef IMAGE
202 /* untested */
203 static char	*BerkLocal[] = { "m", "image", NULL };
204 char		*MyLocName = "Image";
205 char		*DaemonName = "Image:~MAILER~DAEMON~";
206 # define V6
207 # endif IMAGE
208 
209 # ifdef ESVAX
210 static char	*BerkLocal[] = { "o", "esvax", NULL };
211 char		*MyLocName = "ESVAX";
212 char		*DaemonName = "ESVAX:~MAILER~DAEMON~";
213 # endif ESVAX
214 
215 # ifdef EECS40
216 /* untested */
217 static char	*BerkLocal[] = { "z", "eecs40", NULL };
218 char		*MyLocName = "EECS40";
219 char		*DaemonName = "EECS40:~MAILER~DAEMON~";
220 # define V6
221 # endif EECS40
222 
223 
224 # ifndef HASARPA
225 # define ArpaLocal	NULL
226 # endif HASARPA
227 
228 # ifndef HASUUCP
229 # define UucpLocal	NULL
230 # endif HASUUCP
231 
232 
233 /* local mail -- must be #0 */
234 static char	*LocalArgv[] =
235 {
236 	"...local%mail",
237 	"-d",
238 	"$u",
239 	NULL
240 };
241 
242 static struct mailer	LocalMailer =
243 {
244 # ifdef NETV6MAIL
245 	"/usr/net/bin/v6mail",
246 # else
247 	"/bin/mail",
248 # endif
249 	M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT,	EX_NOUSER,	NULL,
250 	"$f",		NULL,			LocalArgv,
251 };
252 
253 /* pipes through programs -- must be #1 */
254 static char	*ProgArgv[] =
255 {
256 	"...prog%mail",
257 	"-fc",
258 	"$u",
259 	NULL
260 };
261 
262 static struct mailer	ProgMailer =
263 {
264 	"/bin/csh",
265 	M_HDR|M_FHDR|M_NOHOST,			EX_UNAVAILABLE,	NULL,
266 	"$f",		NULL,			ProgArgv,
267 };
268 
269 /* local berkeley mail */
270 static char	*BerkArgv[] =
271 {
272 	"...berk%mail",
273 	"-m",
274 	"$h",
275 	"-t",
276 	"$u",
277 	"-h",
278 	"$c",
279 	NULL
280 };
281 
282 static struct mailer	BerkMailer =
283 {
284 	"/usr/net/bin/sendberkmail",
285 	M_FOPT|M_HDR|M_STRIPQ,			EX_UNAVAILABLE,	BerkLocal,
286 	"$B:$f",	NULL,			BerkArgv,
287 };
288 
289 /* arpanet mail */
290 static char	*ArpaArgv[] =
291 {
292 	"...arpa%mail",
293 	"$f",
294 	"$h",
295 	"$u",
296 	NULL
297 };
298 
299 static struct mailer	ArpaMailer =
300 {
301 	"/usr/lib/mailers/arpa",
302 	M_STRIPQ|M_ARPAFMT,			0,		ArpaLocal,
303 	"$f@$A",	NULL,			ArpaArgv,
304 };
305 
306 /* uucp mail (cheat & use Bell's v7 mail) */
307 static char	*UucpArgv[] =
308 {
309 	"...uucp%mail",
310 # ifdef DUMBMAIL
311 	"-d",
312 # endif DUMBMAIL
313 	"$h!$u",
314 	NULL
315 };
316 
317 static struct mailer	UucpMailer =
318 {
319 	"/bin/mail",
320 	M_ROPT|M_STRIPQ,			EX_NOUSER,	UucpLocal,
321 	"$U!$f",	NULL,			UucpArgv,
322 };
323 
324 struct mailer	*Mailer[] =
325 {
326 	&LocalMailer,		/* 0 -- must be 0 */
327 	&ProgMailer,		/* 1 -- must be 1 */
328 	&BerkMailer,		/* 2 */
329 	&ArpaMailer,		/* 3 */
330 	&UucpMailer,		/* 4 */
331 };
332 
333 # define NMAILERS	(sizeof Mailer / sizeof Mailer[0])
334 
335 # define M_LOCAL	0
336 # define M_PROG		1
337 # define M_BERK		2
338 # define M_ARPA		3
339 # define M_UUCP		4
340 
341 /* list of messages for each mailer (sorted by host) */
342 ADDRESS		MailList[NMAILERS];
343 
344 
345 
346 # ifdef BERKELEY
347 struct parsetab ParseTab[] =
348 {
349 	':',	M_BERK,		P_ONE,				NULL,
350 # ifdef HASARPA
351 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
352 # else
353 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
354 # endif HASARPA
355 	'^',	-1,		P_MAP,				"!",
356 # ifdef HASUUCP
357 	'!',	M_UUCP,		0,				NULL,
358 # else
359 	'!',	M_BERK,		P_MOVE,				"csvax",
360 # endif HASUUCP
361 	'.',	-1,		P_MAP|P_ONE,			":",
362 	'\0',	M_LOCAL,	P_MOVE,				"",
363 };
364 # else BERKELEY
365 struct parsetab ParseTab[] =
366 {
367 # ifdef HASARPA
368 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
369 # endif HASARPA
370 # ifdef HASUUCP
371 	'^',	-1,		P_MAP,				"!",
372 	'!',	M_UUCP,		0,				NULL,
373 # endif HASUUCP
374 	'\0',	M_LOCAL,	P_MOVE,				"",
375 };
376 # endif BERKELEY
377 
378 
379 /*
380 **  Header info table
381 **	Final (null) entry contains the flags used for any other field.
382 */
383 
384 struct hdrinfo	HdrInfo[] =
385 {
386 	"date",		0,			NULL,
387 	"from",		0,			NULL,
388 	"to",		0,			NULL,
389 	"cc",		0,			NULL,
390 	"subject",	0,			NULL,
391 	"message-id",	0,			&MsgId,
392 	"message",	H_EOH,			NULL,
393 	NULL,		0,			NULL,
394 };
395 /*
396 **  INITMACS -- initialize predefined macros.
397 **
398 **	Parameters:
399 **		none.
400 **
401 **	Returns:
402 **		none.
403 **
404 **	Side Effects:
405 **		Macros array gets initialized.
406 */
407 
408 char	*Macro[26];
409 
410 # define MACRO(x)	Macro[x - 'A']
411 
412 initmacs()
413 {
414 	MACRO('A') = ArpaHost;
415 	MACRO('B') = BerkHost;
416 	MACRO('U') = UucpHost;
417 }
418 
419 # ifdef V6
420 /*
421 **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
422 **
423 **	Returns the pathname of the user's tty.  Returns NULL if
424 **	the user is not logged in or if s/he has write permission
425 **	denied.
426 **
427 **	Parameters:
428 **		none
429 **
430 **	Returns:
431 **		pathname of the user's tty.
432 **		NULL if not logged in or write permission denied.
433 **
434 **	Side Effects:
435 **		none.
436 **
437 **	WARNING:
438 **		Return value is in a local buffer.
439 **
440 **	Called By:
441 **		savemail
442 */
443 
444 # include <sys/types.h>
445 # include <sys/stat.h>
446 
447 char *
448 ttypath()
449 {
450 	struct stat stbuf;
451 	register int i;
452 	static char pathn[] = "/dev/ttyx";
453 	extern int errno;
454 
455 	/* compute the pathname of the controlling tty */
456 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
457 	{
458 		errno = 0;
459 		return (NULL);
460 	}
461 	pathn[8] = i;
462 
463 	/* see if we have write permission */
464 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
465 	{
466 		errno = 0;
467 		return (NULL);
468 	}
469 
470 	/* see if the user is logged in */
471 	if (getlogin() == NULL)
472 		return (NULL);
473 
474 	/* looks good */
475 	return (pathn);
476 }
477 /*
478 **  FDOPEN -- Open a stdio file given an open file descriptor.
479 **
480 **	This is included here because it is standard in v7, but we
481 **	need it in v6.
482 **
483 **	Algorithm:
484 **		Open /dev/null to create a descriptor.
485 **		Close that descriptor.
486 **		Copy the existing fd into the descriptor.
487 **
488 **	Parameters:
489 **		fd -- the open file descriptor.
490 **		type -- "r", "w", or whatever.
491 **
492 **	Returns:
493 **		The file descriptor it creates.
494 **
495 **	Side Effects:
496 **		none
497 **
498 **	Called By:
499 **		deliver
500 **
501 **	Notes:
502 **		The mode of fd must match "type".
503 */
504 
505 FILE *
506 fdopen(fd, type)
507 	int fd;
508 	char *type;
509 {
510 	register FILE *f;
511 
512 	f = fopen("/dev/null", type);
513 	close(fileno(f));
514 	fileno(f) = fd;
515 	return (f);
516 }
517 /*
518 **  INDEX -- Return pointer to character in string
519 **
520 **	For V7 compatibility.
521 **
522 **	Parameters:
523 **		s -- a string to scan.
524 **		c -- a character to look for.
525 **
526 **	Returns:
527 **		If c is in s, returns the address of the first
528 **			instance of c in s.
529 **		NULL if c is not in s.
530 **
531 **	Side Effects:
532 **		none.
533 */
534 
535 index(s, c)
536 	register char *s;
537 	register char c;
538 {
539 	while (*s != '\0')
540 	{
541 		if (*s++ == c)
542 			return (--s);
543 	}
544 	return (NULL);
545 }
546 # endif V6
547 
548 # ifndef V6
549 /*
550 **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
551 **
552 **	Returns the pathname of the user's tty.  Returns NULL if
553 **	the user is not logged in or if s/he has write permission
554 **	denied.
555 **
556 **	Parameters:
557 **		none
558 **
559 **	Returns:
560 **		pathname of the user's tty.
561 **		NULL if not logged in or write permission denied.
562 **
563 **	Side Effects:
564 **		none.
565 **
566 **	WARNING:
567 **		Return value is in a local buffer.
568 **
569 **	Called By:
570 **		savemail
571 */
572 
573 # include <sys/types.h>
574 # include <sys/stat.h>
575 
576 char *
577 ttypath()
578 {
579 	struct stat stbuf;
580 	register char *pathn;
581 	extern int errno;
582 	extern char *ttyname();
583 
584 	/* compute the pathname of the controlling tty */
585 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
586 	{
587 		errno = 0;
588 		return (NULL);
589 	}
590 
591 	/* see if we have write permission */
592 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
593 	{
594 		errno = 0;
595 		return (NULL);
596 	}
597 
598 	/* see if the user is logged in */
599 	if (getlogin() == NULL)
600 		return (NULL);
601 
602 	/* looks good */
603 	return (pathn);
604 }
605 # endif V6
606 /*
607 **  CHECKCOMPAT -- check for From and To person compatible.
608 **
609 **	This routine can be supplied on a per-installation basis
610 **	to determine whether a person is allowed to send a message.
611 **	This allows restriction of certain types of internet
612 **	forwarding or registration of users.
613 **
614 **	If the hosts are found to be incompatible, an error
615 **	message should be given using "usrerr" and FALSE should
616 **	be returned.
617 **
618 **	Parameters:
619 **		to -- the person being sent to.
620 **
621 **	Returns:
622 **		TRUE -- ok to send.
623 **		FALSE -- not ok.
624 **
625 **	Side Effects:
626 **		none (unless you include the usrerr stuff)
627 */
628 
629 bool
630 checkcompat(to)
631 	register ADDRESS *to;
632 {
633 	return (TRUE);
634 }
635