xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 3061)
1294Seric # include <stdio.h>
2294Seric # include <pwd.h>
32967Seric # include "postbox.h"
4404Seric 
5294Seric /*
62967Seric **  CONF.C -- Postbox Configuration Tables.
7294Seric **
8294Seric **	Defines the configuration of this installation.
9294Seric **
101388Seric **	Compilation Flags:
111388Seric **		HASARPA -- set if this machine has a connection to
121388Seric **			the Arpanet.
131388Seric **		HASUUCP -- set if this machine has a connection to
141388Seric **			the UUCP network.
151388Seric **		NETV6MAIL -- set if you want to use "v6mail" that
161388Seric **			comes with the Berkeley network.  Normally
171388Seric **			/bin/mail will work fine, but around Berkeley
181388Seric **			we use v6mail because it is a "fixed target".
192355Seric **			Also, only v6mail has the "/dev/mail" stuff
202355Seric **			in it (for biff(1)).
211388Seric **		V6 -- running on a version 6 system.  This determines
221388Seric **			whether to define certain routines between
231388Seric **			the two systems.  If you are running a funny
241388Seric **			system, e.g., V6 with long tty names, this
251388Seric **			should be checked carefully.
261573Seric **		DUMBMAIL -- set if your /bin/mail doesn't have the
271573Seric **			-d flag.
28294Seric **
291388Seric **	Configuration Variables:
301573Seric **		ArpaHost -- the arpanet name of the host through
311573Seric **			which arpanet mail will be sent.
321388Seric **		MyLocName -- the name of the host on a local network.
331388Seric **			This is used to disambiguate the contents of
341388Seric **			ArpaHost among many hosts who may be sharing
351388Seric **			a gateway.
362099Seric **		DaemonName -- the name of this agent for use in
372099Seric **			error messages, typically "~MAILER~DAEMON~"
382099Seric **			at this host on the local net.
391573Seric **		ArpaLocal -- a list of local names for this host on
401573Seric **			the arpanet.  Only functional if HASARPA set.
411573Seric **		UucpLocal -- ditto for the Arpanet.
421573Seric **		BerkLocal -- ditto for the Berknet.
431388Seric **		Mailer -- a table of mailers known to the system.
441388Seric **			The fields are:
451388Seric **			- the pathname of the mailer.
461388Seric **			- a list of flags describing the properties
471388Seric **			  of this mailer:
481388Seric **			   M_FOPT -- if set, the mailer has a picky "-f"
491388Seric **				option.  In this mode, the mailer will
501388Seric **				only accept the "-f" option if the
511388Seric **				sender is actually "root", "network",
521388Seric **				and possibly (but not necessarily) if
531388Seric **				the -f argument matches the real sender.
541388Seric **				The effect is that if the "-f" option
552967Seric **				is given to postbox then it will be
561388Seric **				passed through (as arguments 1 & 2) to
571388Seric **				the mailer.
581388Seric **			   M_ROPT -- identical to M_FOPT, except uses
591388Seric **				-r instead.
601388Seric **			   M_QUIET -- if set, don't print a message if
611388Seric **				the mailer returns bad status.
621388Seric **			   M_RESTR -- if set, this mailer is restricted
631388Seric **				to use by "daemon"; otherwise, we do a
641388Seric **				setuid(getuid()) before calling the
651388Seric **				mailer.
661388Seric **			   M_HDR -- if set, the mailer wants us to
671388Seric **				insert a UNIX "From" line before
681388Seric **				outputing.
691827Seric **			   M_FHDR -- if set, the header that we
701827Seric **				generate will be used literally, so
711827Seric **				we must force it to be correct.  The
721827Seric **				effect is that we generate a header
731827Seric **				even if one exists.
741388Seric **			   M_NOHOST -- if set, this mailer doesn't care
751388Seric **				about the host part (e.g., the local
761388Seric **				mailer).
771388Seric **			   M_STRIPQ -- if set, strip quote (`"')
781388Seric **				characters out of parameters as you
791388Seric **				transliterate them into the argument
801388Seric **				vector.  For example, the local mailer
811388Seric **				is called directly, so these should be
821388Seric **				stripped, but the program-mailer (i.e.,
831388Seric **				csh) should leave them in.
842897Seric **			   M_NEEDDATE -- this mailer requires a Date:
852897Seric **				field in the message.
862897Seric **			   M_NEEDFROM -- this mailer requires a From:
872897Seric **				field in the message.
882897Seric **			   M_MSGID -- this mailer requires a Message-Id
892897Seric **				field in the message.
902897Seric **			   M_COMMAS -- this mailer wants comma-
912897Seric **				seperated To: and Cc: fields.
922897Seric **			   M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID|
932897Seric **				M_COMMAS.
941388Seric **			- an exit status to use as the code for the
951388Seric **			  error message print if the mailer returns
961388Seric **			  something we don't understand.
971388Seric **			- A list of names that are to be considered
981388Seric **			  "local" (and hence are stripped off) for
991388Seric **			  this mailer.
1001388Seric **			- An argument vector to be passed to the
1011388Seric **			  mailer with the following substitutions:
1021388Seric **			   $f - the from person name.
1031388Seric **			   $u - the target user name.
1041388Seric **			   $h - the target user host.
1051388Seric **			   $c - the hop count.
1061388Seric **			>>>>>>>>>> Entry zero must be for the local
1071388Seric **			>> NOTE >> mailer and entry one must be for
1081388Seric **			>>>>>>>>>> the shell.
1091388Seric **		ParseTab -- a table driving the parsing process.  Each
1101388Seric **			entry contains:
1111388Seric **			- a character that will trigger this entry.
1121388Seric **			- an index into the Mailer table.
1132967Seric **			- a word of flags, described in postbox.h.
1141388Seric **			- an argument.  If we have P_MAP, it is the
1151388Seric **			  character to turn the trigger character into.
1161388Seric **			  If we have P_MOVE, it is the site to send it
1171388Seric **			  to, using the mailer specified above.
1181573Seric **			This table will almost certainly have to be
1191573Seric **			changed on your site if you have anything more
1201573Seric **			than the UUCP net.
1212897Seric **		HdrInfo -- a table describing well-known header fields.
1222897Seric **			Each entry has the field name and some flags,
1232897Seric **			which can be:
1243057Seric **			- H_EOH -- this field is equivalent to a blank
1253057Seric **			  line; i.e., it signifies end of header.
1263057Seric **			- H_DELETE -- delete this field.
1273057Seric **			There is also a field pointing to a pointer
1283057Seric **			that should be set to point to this header.
129294Seric */
130294Seric 
131294Seric 
132294Seric 
133294Seric 
134*3061Seric static char SccsId[] = "@(#)conf.c	3.6	03/07/81";
135294Seric 
1361388Seric 
1371388Seric # include <whoami.h>		/* definitions of machine id's at berkeley */
1381388Seric 
1391573Seric # ifdef BERKELEY
1402099Seric 
1411573Seric char	*ArpaHost = "Berkeley";	/* host name of gateway on Arpanet */
1422897Seric # define BerkHost   MyLocName	/* host name of gateway on Berk net */
1432355Seric # define NETV6MAIL		/* use /usr/net/bin/v6mail for local delivery */
1442099Seric 
1452099Seric /* Specific Configurations for Berkeley Machines */
1462099Seric 
147*3061Seric /* Berkeley people: mail changes to ingvax:eric or they will be lost! */
1482099Seric 
149294Seric # ifdef ING70
150*3061Seric # include "c.ing70.h"
151294Seric # endif ING70
152294Seric 
153294Seric # ifdef INGVAX
154*3061Seric # include "c.ingvax.h"
155294Seric # endif INGVAX
156294Seric 
157294Seric # ifdef CSVAX
158*3061Seric # include "c.csvax.h"
159294Seric # endif CSVAX
160294Seric 
1612355Seric # ifdef ARPAVAX
162*3061Seric # include "c.arpavax.h"
1632355Seric # endif ARPAVAX
1642355Seric 
165294Seric # ifdef CORY
166*3061Seric # include "c.cory.h"
167294Seric # endif CORY
168294Seric 
1692420Seric # ifdef ONYX
170*3061Seric # include "c.onyx.h"
1712420Seric # endif ONYX
1722420Seric 
173294Seric # ifdef IMAGE
174*3061Seric # include "c.image.h"
175294Seric # endif IMAGE
176294Seric 
177294Seric # ifdef ESVAX
178*3061Seric # include "c.esvax.h"
179294Seric # endif ESVAX
180294Seric 
181294Seric # ifdef EECS40
182*3061Seric # include "c.eecs40.h"
183294Seric # endif EECS40
184294Seric 
185*3061Seric # else BERKELEY
186590Seric 
187*3061Seric char	*ArpaHost = "[unknown]";
188*3061Seric char	*MyLocName = sysname;
189*3061Seric # define HASUUCP		/* default to having UUCP net */
190*3061Seric char	*UucpLocal[] = { sysname, NULL };
191*3061Seric # define BerkMerge	NULL	/* don't merge any berknet sites */
192*3061Seric # define UucpMerge	NULL	/* don't merge any UUCP sites */
193*3061Seric 
194*3061Seric # endif BERKELEY
195*3061Seric 
196*3061Seric 
197*3061Seric 
198590Seric # ifndef HASARPA
199590Seric # define ArpaLocal	NULL
200590Seric # endif HASARPA
201590Seric 
202590Seric # ifndef HASUUCP
203590Seric # define UucpLocal	NULL
204590Seric # endif HASUUCP
205590Seric 
206590Seric 
2073046Seric /* local mail -- must be #0 */
2083046Seric static char	*LocalArgv[] =
209294Seric {
2103046Seric 	"...local%mail",
2113046Seric 	"-d",
2123046Seric 	"$u",
2133046Seric 	NULL
2143046Seric };
2153046Seric 
2163046Seric static struct mailer	LocalMailer =
2173046Seric {
218294Seric # ifdef NETV6MAIL
2193046Seric 	"/usr/net/bin/v6mail",
220294Seric # else
2213046Seric 	"/bin/mail",
222294Seric # endif
2233046Seric 	M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT,	EX_NOUSER,	NULL,
2243046Seric 	"$f",		NULL,			LocalArgv,
2253046Seric };
2263046Seric 
2273046Seric /* pipes through programs -- must be #1 */
2283046Seric static char	*ProgArgv[] =
2293046Seric {
2303046Seric 	"...prog%mail",
2313046Seric 	"-fc",
2323046Seric 	"$u",
2333046Seric 	NULL
2343046Seric };
2353046Seric 
2363046Seric static struct mailer	ProgMailer =
2373046Seric {
2383046Seric 	"/bin/csh",
2393046Seric 	M_HDR|M_FHDR|M_NOHOST,			EX_UNAVAILABLE,	NULL,
2403046Seric 	"$f",		NULL,			ProgArgv,
2413046Seric };
2423046Seric 
2433046Seric /* local berkeley mail */
2443046Seric static char	*BerkArgv[] =
2453046Seric {
2463046Seric 	"...berk%mail",
2473046Seric 	"-m",
2483046Seric 	"$h",
2493046Seric 	"-t",
2503046Seric 	"$u",
2513046Seric 	"-h",
2523046Seric 	"$c",
2533046Seric 	NULL
2543046Seric };
2553046Seric 
2563046Seric static struct mailer	BerkMailer =
2573046Seric {
2583046Seric 	"/usr/net/bin/sendberkmail",
2593046Seric 	M_FOPT|M_HDR|M_STRIPQ,			EX_UNAVAILABLE,	BerkLocal,
260*3061Seric 	"$B:$f",	BerkMerge,		BerkArgv,
2613046Seric };
2623046Seric 
2633046Seric /* arpanet mail */
2643046Seric static char	*ArpaArgv[] =
2653046Seric {
2663046Seric 	"...arpa%mail",
2673046Seric 	"$f",
2683046Seric 	"$h",
2693046Seric 	"$u",
2703046Seric 	NULL
2713046Seric };
2723046Seric 
2733046Seric static struct mailer	ArpaMailer =
2743046Seric {
2753046Seric 	"/usr/lib/mailers/arpa",
2763046Seric 	M_STRIPQ|M_ARPAFMT,			0,		ArpaLocal,
2773046Seric 	"$f@$A",	NULL,			ArpaArgv,
2783046Seric };
2793046Seric 
2803046Seric /* uucp mail (cheat & use Bell's v7 mail) */
2813046Seric static char	*UucpArgv[] =
2823046Seric {
2833046Seric 	"...uucp%mail",
284294Seric # ifdef DUMBMAIL
2853046Seric 	"-d",
286294Seric # endif DUMBMAIL
2873046Seric 	"$h!$u",
2883046Seric 	NULL
289294Seric };
290294Seric 
2913046Seric static struct mailer	UucpMailer =
2923046Seric {
2933046Seric 	"/bin/mail",
2943046Seric 	M_ROPT|M_STRIPQ,			EX_NOUSER,	UucpLocal,
295*3061Seric 	"$U!$f",	UucpMerge,		UucpArgv,
2963046Seric };
2973046Seric 
2983046Seric struct mailer	*Mailer[] =
2993046Seric {
3003046Seric 	&LocalMailer,		/* 0 -- must be 0 */
3013046Seric 	&ProgMailer,		/* 1 -- must be 1 */
3023046Seric 	&BerkMailer,		/* 2 */
3033046Seric 	&ArpaMailer,		/* 3 */
3043046Seric 	&UucpMailer,		/* 4 */
3053046Seric };
3063046Seric 
3073046Seric # define NMAILERS	(sizeof Mailer / sizeof Mailer[0])
3083046Seric 
309294Seric # define M_LOCAL	0
3103046Seric # define M_PROG		1
311294Seric # define M_BERK		2
312294Seric # define M_ARPA		3
313294Seric # define M_UUCP		4
314294Seric 
3153046Seric /* list of messages for each mailer (sorted by host) */
3163046Seric ADDRESS		MailList[NMAILERS];
317294Seric 
318294Seric 
3193046Seric 
3201573Seric # ifdef BERKELEY
321294Seric struct parsetab ParseTab[] =
322294Seric {
323294Seric 	':',	M_BERK,		P_ONE,				NULL,
324294Seric # ifdef HASARPA
325294Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
326294Seric # else
327294Seric 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
328294Seric # endif HASARPA
329294Seric 	'^',	-1,		P_MAP,				"!",
330294Seric # ifdef HASUUCP
331294Seric 	'!',	M_UUCP,		0,				NULL,
332294Seric # else
333294Seric 	'!',	M_BERK,		P_MOVE,				"csvax",
334294Seric # endif HASUUCP
335294Seric 	'.',	-1,		P_MAP|P_ONE,			":",
336294Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
337294Seric };
3381573Seric # else BERKELEY
3391573Seric struct parsetab ParseTab[] =
3401573Seric {
3411573Seric # ifdef HASARPA
3421573Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
3431573Seric # endif HASARPA
3441573Seric # ifdef HASUUCP
3451573Seric 	'^',	-1,		P_MAP,				"!",
3461573Seric 	'!',	M_UUCP,		0,				NULL,
3471573Seric # endif HASUUCP
3481573Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
3491573Seric };
3501573Seric # endif BERKELEY
3512897Seric 
3522897Seric 
3532897Seric /*
3542897Seric **  Header info table
3553057Seric **	Final (null) entry contains the flags used for any other field.
3562897Seric */
3572897Seric 
3582897Seric struct hdrinfo	HdrInfo[] =
3592897Seric {
3603057Seric 	"date",		0,			NULL,
3613057Seric 	"from",		0,			NULL,
3623057Seric 	"to",		0,			NULL,
3633057Seric 	"cc",		0,			NULL,
3643057Seric 	"subject",	0,			NULL,
3653057Seric 	"message-id",	0,			&MsgId,
3663057Seric 	"message",	H_EOH,			NULL,
3673057Seric 	NULL,		0,			NULL,
3682897Seric };
369294Seric /*
3702897Seric **  INITMACS -- initialize predefined macros.
3712897Seric **
3722897Seric **	Parameters:
3732897Seric **		none.
3742897Seric **
3752897Seric **	Returns:
3762897Seric **		none.
3772897Seric **
3782897Seric **	Side Effects:
3792897Seric **		Macros array gets initialized.
3802897Seric */
3812897Seric 
3822897Seric char	*Macro[26];
3832897Seric 
3842897Seric # define MACRO(x)	Macro[x - 'A']
3852897Seric 
3862897Seric initmacs()
3872897Seric {
3882897Seric 	MACRO('A') = ArpaHost;
3892897Seric 	MACRO('B') = BerkHost;
3902897Seric 	MACRO('U') = UucpHost;
3912897Seric }
392294Seric 
393294Seric # ifdef V6
394294Seric /*
395294Seric **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
396294Seric **
397294Seric **	Returns the pathname of the user's tty.  Returns NULL if
398294Seric **	the user is not logged in or if s/he has write permission
399294Seric **	denied.
400294Seric **
401294Seric **	Parameters:
402294Seric **		none
403294Seric **
404294Seric **	Returns:
405294Seric **		pathname of the user's tty.
406294Seric **		NULL if not logged in or write permission denied.
407294Seric **
408294Seric **	Side Effects:
409294Seric **		none.
410294Seric **
411294Seric **	WARNING:
412294Seric **		Return value is in a local buffer.
413294Seric **
414294Seric **	Called By:
415294Seric **		savemail
416294Seric */
417294Seric 
418294Seric # include <sys/types.h>
419294Seric # include <sys/stat.h>
420294Seric 
421294Seric char *
422294Seric ttypath()
423294Seric {
424294Seric 	struct stat stbuf;
425294Seric 	register int i;
426294Seric 	static char pathn[] = "/dev/ttyx";
427294Seric 	extern int errno;
428294Seric 
429294Seric 	/* compute the pathname of the controlling tty */
430294Seric 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
431294Seric 	{
432294Seric 		errno = 0;
433294Seric 		return (NULL);
434294Seric 	}
435294Seric 	pathn[8] = i;
436294Seric 
437294Seric 	/* see if we have write permission */
4382967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
439294Seric 	{
440294Seric 		errno = 0;
441294Seric 		return (NULL);
442294Seric 	}
443294Seric 
444294Seric 	/* see if the user is logged in */
445294Seric 	if (getlogin() == NULL)
446294Seric 		return (NULL);
447294Seric 
448294Seric 	/* looks good */
449294Seric 	return (pathn);
450294Seric }
451294Seric /*
452294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
453294Seric **
454294Seric **	This is included here because it is standard in v7, but we
455294Seric **	need it in v6.
456294Seric **
457294Seric **	Algorithm:
458294Seric **		Open /dev/null to create a descriptor.
459294Seric **		Close that descriptor.
460294Seric **		Copy the existing fd into the descriptor.
461294Seric **
462294Seric **	Parameters:
463294Seric **		fd -- the open file descriptor.
464294Seric **		type -- "r", "w", or whatever.
465294Seric **
466294Seric **	Returns:
467294Seric **		The file descriptor it creates.
468294Seric **
469294Seric **	Side Effects:
470294Seric **		none
471294Seric **
472294Seric **	Called By:
473294Seric **		deliver
474294Seric **
475294Seric **	Notes:
476294Seric **		The mode of fd must match "type".
477294Seric */
478294Seric 
479294Seric FILE *
480294Seric fdopen(fd, type)
481294Seric 	int fd;
482294Seric 	char *type;
483294Seric {
484294Seric 	register FILE *f;
485294Seric 
486294Seric 	f = fopen("/dev/null", type);
487294Seric 	close(fileno(f));
488294Seric 	fileno(f) = fd;
489294Seric 	return (f);
490294Seric }
491294Seric /*
492294Seric **  INDEX -- Return pointer to character in string
493294Seric **
494294Seric **	For V7 compatibility.
495294Seric **
496294Seric **	Parameters:
497294Seric **		s -- a string to scan.
498294Seric **		c -- a character to look for.
499294Seric **
500294Seric **	Returns:
501294Seric **		If c is in s, returns the address of the first
502294Seric **			instance of c in s.
503294Seric **		NULL if c is not in s.
504294Seric **
505294Seric **	Side Effects:
506294Seric **		none.
507294Seric */
508294Seric 
509294Seric index(s, c)
510294Seric 	register char *s;
511294Seric 	register char c;
512294Seric {
513294Seric 	while (*s != '\0')
514294Seric 	{
515294Seric 		if (*s++ == c)
516294Seric 			return (--s);
517294Seric 	}
518294Seric 	return (NULL);
519294Seric }
520294Seric # endif V6
521294Seric 
522294Seric # ifndef V6
523294Seric /*
524294Seric **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
525294Seric **
526294Seric **	Returns the pathname of the user's tty.  Returns NULL if
527294Seric **	the user is not logged in or if s/he has write permission
528294Seric **	denied.
529294Seric **
530294Seric **	Parameters:
531294Seric **		none
532294Seric **
533294Seric **	Returns:
534294Seric **		pathname of the user's tty.
535294Seric **		NULL if not logged in or write permission denied.
536294Seric **
537294Seric **	Side Effects:
538294Seric **		none.
539294Seric **
540294Seric **	WARNING:
541294Seric **		Return value is in a local buffer.
542294Seric **
543294Seric **	Called By:
544294Seric **		savemail
545294Seric */
546294Seric 
547294Seric # include <sys/types.h>
548294Seric # include <sys/stat.h>
549294Seric 
550294Seric char *
551294Seric ttypath()
552294Seric {
553294Seric 	struct stat stbuf;
554294Seric 	register char *pathn;
555294Seric 	extern int errno;
556294Seric 	extern char *ttyname();
557294Seric 
558294Seric 	/* compute the pathname of the controlling tty */
559294Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
560294Seric 	{
561294Seric 		errno = 0;
562294Seric 		return (NULL);
563294Seric 	}
564294Seric 
565294Seric 	/* see if we have write permission */
5662967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
567294Seric 	{
568294Seric 		errno = 0;
569294Seric 		return (NULL);
570294Seric 	}
571294Seric 
572294Seric 	/* see if the user is logged in */
573294Seric 	if (getlogin() == NULL)
574294Seric 		return (NULL);
575294Seric 
576294Seric 	/* looks good */
577294Seric 	return (pathn);
578294Seric }
579294Seric # endif V6
5802967Seric /*
5812967Seric **  CHECKCOMPAT -- check for From and To person compatible.
5822967Seric **
5832967Seric **	This routine can be supplied on a per-installation basis
5842967Seric **	to determine whether a person is allowed to send a message.
5852967Seric **	This allows restriction of certain types of internet
5862967Seric **	forwarding or registration of users.
5872967Seric **
5882967Seric **	If the hosts are found to be incompatible, an error
5892967Seric **	message should be given using "usrerr" and FALSE should
5902967Seric **	be returned.
5912967Seric **
5922967Seric **	Parameters:
5932967Seric **		to -- the person being sent to.
5942967Seric **
5952967Seric **	Returns:
5962967Seric **		TRUE -- ok to send.
5972967Seric **		FALSE -- not ok.
5982967Seric **
5992967Seric **	Side Effects:
6002967Seric **		none (unless you include the usrerr stuff)
6012967Seric */
6022967Seric 
6032967Seric bool
6042967Seric checkcompat(to)
6052967Seric 	register ADDRESS *to;
6062967Seric {
6072967Seric 	return (TRUE);
6082967Seric }
609