xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 3061)
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.6	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 # define BerkHost   MyLocName	/* host name of gateway on Berk net */
143 # define NETV6MAIL		/* use /usr/net/bin/v6mail for local delivery */
144 
145 /* Specific Configurations for Berkeley Machines */
146 
147 /* Berkeley people: mail changes to ingvax:eric or they will be lost! */
148 
149 # ifdef ING70
150 # include "c.ing70.h"
151 # endif ING70
152 
153 # ifdef INGVAX
154 # include "c.ingvax.h"
155 # endif INGVAX
156 
157 # ifdef CSVAX
158 # include "c.csvax.h"
159 # endif CSVAX
160 
161 # ifdef ARPAVAX
162 # include "c.arpavax.h"
163 # endif ARPAVAX
164 
165 # ifdef CORY
166 # include "c.cory.h"
167 # endif CORY
168 
169 # ifdef ONYX
170 # include "c.onyx.h"
171 # endif ONYX
172 
173 # ifdef IMAGE
174 # include "c.image.h"
175 # endif IMAGE
176 
177 # ifdef ESVAX
178 # include "c.esvax.h"
179 # endif ESVAX
180 
181 # ifdef EECS40
182 # include "c.eecs40.h"
183 # endif EECS40
184 
185 # else BERKELEY
186 
187 char	*ArpaHost = "[unknown]";
188 char	*MyLocName = sysname;
189 # define HASUUCP		/* default to having UUCP net */
190 char	*UucpLocal[] = { sysname, NULL };
191 # define BerkMerge	NULL	/* don't merge any berknet sites */
192 # define UucpMerge	NULL	/* don't merge any UUCP sites */
193 
194 # endif BERKELEY
195 
196 
197 
198 # ifndef HASARPA
199 # define ArpaLocal	NULL
200 # endif HASARPA
201 
202 # ifndef HASUUCP
203 # define UucpLocal	NULL
204 # endif HASUUCP
205 
206 
207 /* local mail -- must be #0 */
208 static char	*LocalArgv[] =
209 {
210 	"...local%mail",
211 	"-d",
212 	"$u",
213 	NULL
214 };
215 
216 static struct mailer	LocalMailer =
217 {
218 # ifdef NETV6MAIL
219 	"/usr/net/bin/v6mail",
220 # else
221 	"/bin/mail",
222 # endif
223 	M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT,	EX_NOUSER,	NULL,
224 	"$f",		NULL,			LocalArgv,
225 };
226 
227 /* pipes through programs -- must be #1 */
228 static char	*ProgArgv[] =
229 {
230 	"...prog%mail",
231 	"-fc",
232 	"$u",
233 	NULL
234 };
235 
236 static struct mailer	ProgMailer =
237 {
238 	"/bin/csh",
239 	M_HDR|M_FHDR|M_NOHOST,			EX_UNAVAILABLE,	NULL,
240 	"$f",		NULL,			ProgArgv,
241 };
242 
243 /* local berkeley mail */
244 static char	*BerkArgv[] =
245 {
246 	"...berk%mail",
247 	"-m",
248 	"$h",
249 	"-t",
250 	"$u",
251 	"-h",
252 	"$c",
253 	NULL
254 };
255 
256 static struct mailer	BerkMailer =
257 {
258 	"/usr/net/bin/sendberkmail",
259 	M_FOPT|M_HDR|M_STRIPQ,			EX_UNAVAILABLE,	BerkLocal,
260 	"$B:$f",	BerkMerge,		BerkArgv,
261 };
262 
263 /* arpanet mail */
264 static char	*ArpaArgv[] =
265 {
266 	"...arpa%mail",
267 	"$f",
268 	"$h",
269 	"$u",
270 	NULL
271 };
272 
273 static struct mailer	ArpaMailer =
274 {
275 	"/usr/lib/mailers/arpa",
276 	M_STRIPQ|M_ARPAFMT,			0,		ArpaLocal,
277 	"$f@$A",	NULL,			ArpaArgv,
278 };
279 
280 /* uucp mail (cheat & use Bell's v7 mail) */
281 static char	*UucpArgv[] =
282 {
283 	"...uucp%mail",
284 # ifdef DUMBMAIL
285 	"-d",
286 # endif DUMBMAIL
287 	"$h!$u",
288 	NULL
289 };
290 
291 static struct mailer	UucpMailer =
292 {
293 	"/bin/mail",
294 	M_ROPT|M_STRIPQ,			EX_NOUSER,	UucpLocal,
295 	"$U!$f",	UucpMerge,		UucpArgv,
296 };
297 
298 struct mailer	*Mailer[] =
299 {
300 	&LocalMailer,		/* 0 -- must be 0 */
301 	&ProgMailer,		/* 1 -- must be 1 */
302 	&BerkMailer,		/* 2 */
303 	&ArpaMailer,		/* 3 */
304 	&UucpMailer,		/* 4 */
305 };
306 
307 # define NMAILERS	(sizeof Mailer / sizeof Mailer[0])
308 
309 # define M_LOCAL	0
310 # define M_PROG		1
311 # define M_BERK		2
312 # define M_ARPA		3
313 # define M_UUCP		4
314 
315 /* list of messages for each mailer (sorted by host) */
316 ADDRESS		MailList[NMAILERS];
317 
318 
319 
320 # ifdef BERKELEY
321 struct parsetab ParseTab[] =
322 {
323 	':',	M_BERK,		P_ONE,				NULL,
324 # ifdef HASARPA
325 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
326 # else
327 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
328 # endif HASARPA
329 	'^',	-1,		P_MAP,				"!",
330 # ifdef HASUUCP
331 	'!',	M_UUCP,		0,				NULL,
332 # else
333 	'!',	M_BERK,		P_MOVE,				"csvax",
334 # endif HASUUCP
335 	'.',	-1,		P_MAP|P_ONE,			":",
336 	'\0',	M_LOCAL,	P_MOVE,				"",
337 };
338 # else BERKELEY
339 struct parsetab ParseTab[] =
340 {
341 # ifdef HASARPA
342 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
343 # endif HASARPA
344 # ifdef HASUUCP
345 	'^',	-1,		P_MAP,				"!",
346 	'!',	M_UUCP,		0,				NULL,
347 # endif HASUUCP
348 	'\0',	M_LOCAL,	P_MOVE,				"",
349 };
350 # endif BERKELEY
351 
352 
353 /*
354 **  Header info table
355 **	Final (null) entry contains the flags used for any other field.
356 */
357 
358 struct hdrinfo	HdrInfo[] =
359 {
360 	"date",		0,			NULL,
361 	"from",		0,			NULL,
362 	"to",		0,			NULL,
363 	"cc",		0,			NULL,
364 	"subject",	0,			NULL,
365 	"message-id",	0,			&MsgId,
366 	"message",	H_EOH,			NULL,
367 	NULL,		0,			NULL,
368 };
369 /*
370 **  INITMACS -- initialize predefined macros.
371 **
372 **	Parameters:
373 **		none.
374 **
375 **	Returns:
376 **		none.
377 **
378 **	Side Effects:
379 **		Macros array gets initialized.
380 */
381 
382 char	*Macro[26];
383 
384 # define MACRO(x)	Macro[x - 'A']
385 
386 initmacs()
387 {
388 	MACRO('A') = ArpaHost;
389 	MACRO('B') = BerkHost;
390 	MACRO('U') = UucpHost;
391 }
392 
393 # ifdef V6
394 /*
395 **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
396 **
397 **	Returns the pathname of the user's tty.  Returns NULL if
398 **	the user is not logged in or if s/he has write permission
399 **	denied.
400 **
401 **	Parameters:
402 **		none
403 **
404 **	Returns:
405 **		pathname of the user's tty.
406 **		NULL if not logged in or write permission denied.
407 **
408 **	Side Effects:
409 **		none.
410 **
411 **	WARNING:
412 **		Return value is in a local buffer.
413 **
414 **	Called By:
415 **		savemail
416 */
417 
418 # include <sys/types.h>
419 # include <sys/stat.h>
420 
421 char *
422 ttypath()
423 {
424 	struct stat stbuf;
425 	register int i;
426 	static char pathn[] = "/dev/ttyx";
427 	extern int errno;
428 
429 	/* compute the pathname of the controlling tty */
430 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
431 	{
432 		errno = 0;
433 		return (NULL);
434 	}
435 	pathn[8] = i;
436 
437 	/* see if we have write permission */
438 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
439 	{
440 		errno = 0;
441 		return (NULL);
442 	}
443 
444 	/* see if the user is logged in */
445 	if (getlogin() == NULL)
446 		return (NULL);
447 
448 	/* looks good */
449 	return (pathn);
450 }
451 /*
452 **  FDOPEN -- Open a stdio file given an open file descriptor.
453 **
454 **	This is included here because it is standard in v7, but we
455 **	need it in v6.
456 **
457 **	Algorithm:
458 **		Open /dev/null to create a descriptor.
459 **		Close that descriptor.
460 **		Copy the existing fd into the descriptor.
461 **
462 **	Parameters:
463 **		fd -- the open file descriptor.
464 **		type -- "r", "w", or whatever.
465 **
466 **	Returns:
467 **		The file descriptor it creates.
468 **
469 **	Side Effects:
470 **		none
471 **
472 **	Called By:
473 **		deliver
474 **
475 **	Notes:
476 **		The mode of fd must match "type".
477 */
478 
479 FILE *
480 fdopen(fd, type)
481 	int fd;
482 	char *type;
483 {
484 	register FILE *f;
485 
486 	f = fopen("/dev/null", type);
487 	close(fileno(f));
488 	fileno(f) = fd;
489 	return (f);
490 }
491 /*
492 **  INDEX -- Return pointer to character in string
493 **
494 **	For V7 compatibility.
495 **
496 **	Parameters:
497 **		s -- a string to scan.
498 **		c -- a character to look for.
499 **
500 **	Returns:
501 **		If c is in s, returns the address of the first
502 **			instance of c in s.
503 **		NULL if c is not in s.
504 **
505 **	Side Effects:
506 **		none.
507 */
508 
509 index(s, c)
510 	register char *s;
511 	register char c;
512 {
513 	while (*s != '\0')
514 	{
515 		if (*s++ == c)
516 			return (--s);
517 	}
518 	return (NULL);
519 }
520 # endif V6
521 
522 # ifndef V6
523 /*
524 **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
525 **
526 **	Returns the pathname of the user's tty.  Returns NULL if
527 **	the user is not logged in or if s/he has write permission
528 **	denied.
529 **
530 **	Parameters:
531 **		none
532 **
533 **	Returns:
534 **		pathname of the user's tty.
535 **		NULL if not logged in or write permission denied.
536 **
537 **	Side Effects:
538 **		none.
539 **
540 **	WARNING:
541 **		Return value is in a local buffer.
542 **
543 **	Called By:
544 **		savemail
545 */
546 
547 # include <sys/types.h>
548 # include <sys/stat.h>
549 
550 char *
551 ttypath()
552 {
553 	struct stat stbuf;
554 	register char *pathn;
555 	extern int errno;
556 	extern char *ttyname();
557 
558 	/* compute the pathname of the controlling tty */
559 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
560 	{
561 		errno = 0;
562 		return (NULL);
563 	}
564 
565 	/* see if we have write permission */
566 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
567 	{
568 		errno = 0;
569 		return (NULL);
570 	}
571 
572 	/* see if the user is logged in */
573 	if (getlogin() == NULL)
574 		return (NULL);
575 
576 	/* looks good */
577 	return (pathn);
578 }
579 # endif V6
580 /*
581 **  CHECKCOMPAT -- check for From and To person compatible.
582 **
583 **	This routine can be supplied on a per-installation basis
584 **	to determine whether a person is allowed to send a message.
585 **	This allows restriction of certain types of internet
586 **	forwarding or registration of users.
587 **
588 **	If the hosts are found to be incompatible, an error
589 **	message should be given using "usrerr" and FALSE should
590 **	be returned.
591 **
592 **	Parameters:
593 **		to -- the person being sent to.
594 **
595 **	Returns:
596 **		TRUE -- ok to send.
597 **		FALSE -- not ok.
598 **
599 **	Side Effects:
600 **		none (unless you include the usrerr stuff)
601 */
602 
603 bool
604 checkcompat(to)
605 	register ADDRESS *to;
606 {
607 	return (TRUE);
608 }
609