xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 2420)
1294Seric # include <stdio.h>
2294Seric # include <pwd.h>
3294Seric # include "dlvrmail.h"
4404Seric 
5294Seric /*
6294Seric **  CONF.C -- Delivermail 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
551388Seric **				is given to delivermail 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.
841388Seric **			- an exit status to use as the code for the
851388Seric **			  error message print if the mailer returns
861388Seric **			  something we don't understand.
871388Seric **			- A list of names that are to be considered
881388Seric **			  "local" (and hence are stripped off) for
891388Seric **			  this mailer.
901388Seric **			- An argument vector to be passed to the
911388Seric **			  mailer with the following substitutions:
921388Seric **			   $f - the from person name.
931388Seric **			   $u - the target user name.
941388Seric **			   $h - the target user host.
951388Seric **			   $c - the hop count.
961388Seric **			>>>>>>>>>> Entry zero must be for the local
971388Seric **			>> NOTE >> mailer and entry one must be for
981388Seric **			>>>>>>>>>> the shell.
991388Seric **		ParseTab -- a table driving the parsing process.  Each
1001388Seric **			entry contains:
1011388Seric **			- a character that will trigger this entry.
1021388Seric **			- an index into the Mailer table.
1031388Seric **			- a word of flags, described in dlvrmail.h.
1041388Seric **			- an argument.  If we have P_MAP, it is the
1051388Seric **			  character to turn the trigger character into.
1061388Seric **			  If we have P_MOVE, it is the site to send it
1071388Seric **			  to, using the mailer specified above.
1081573Seric **			This table will almost certainly have to be
1091573Seric **			changed on your site if you have anything more
1101573Seric **			than the UUCP net.
111294Seric */
112294Seric 
113294Seric 
114294Seric 
115294Seric 
116*2420Seric static char SccsId[] = "@(#)conf.c	2.6	02/15/81";
117294Seric 
1181388Seric 
1191388Seric bool	UseMsgId = FALSE;	/* don't put message id's in anywhere */
1201388Seric 
1211388Seric # include <whoami.h>		/* definitions of machine id's at berkeley */
1221388Seric 
1231573Seric # ifdef BERKELEY
1242099Seric 
1251573Seric char	*ArpaHost = "Berkeley";	/* host name of gateway on Arpanet */
1262355Seric # define NETV6MAIL		/* use /usr/net/bin/v6mail for local delivery */
1272099Seric 
1281573Seric # else BERKELEY
1292099Seric 
1301573Seric char	*ArpaHost = "[unknown]";
1311573Seric char	*MyLocName = sysname;
1321573Seric # define HASUUCP		/* default to having UUCP net */
1331573Seric char	*UucpLocal[] = { sysname, NULL };
1342099Seric 
1351573Seric # endif BERKELEY
1361573Seric 
1372099Seric 
1382099Seric /* Specific Configurations for Berkeley Machines */
1392099Seric 
1402099Seric /* Berkeley people: mail changes to csvax:eric or they will be lost! */
1412099Seric 
142294Seric # ifdef ING70
143294Seric static char	*BerkLocal[] = { "i", "ingres", "ing70", NULL };
1442099Seric char		*ArpaLocal = { "berkeley", "ucb", NULL };
1451206Seric char		*MyLocName = "Ing70";
1462098Seric char		*DaemonName = "Ing70:~MAILER~DAEMON~";
147294Seric # define HASARPA
148294Seric # define V6
149294Seric # endif ING70
150294Seric 
151294Seric # ifdef INGVAX
152294Seric static char	*BerkLocal[] = { "j", "ingvax", NULL };
1531206Seric char		*MyLocName = "IngVax";
1542098Seric char		*DaemonName = "IngVax:~MAILER~DAEMON~";
155294Seric # endif INGVAX
156294Seric 
157294Seric # ifdef CSVAX
158294Seric static char	*BerkLocal[] = { "v", "csvax", "vax", NULL };
159590Seric static char	*UucpLocal[] = { "ucbvax", "ernie", NULL };
1601206Seric char		*MyLocName = "CSVAX";
1612098Seric char		*DaemonName = "CSVAX:~MAILER~DAEMON~";
162294Seric # define HASUUCP
163294Seric # endif CSVAX
164294Seric 
1652355Seric # ifdef ARPAVAX
1662355Seric static char	*BerkLocal[] = { "r", "arpavax", NULL };
1672355Seric char		*MyLocName = "ARPAVAX";
1682355Seric char		*DaemonName = "ARPAVAX:~MAILER~DAEMON~";
1692355Seric # endif ARPAVAX
1702355Seric 
171294Seric # ifdef CORY
172294Seric static char	*BerkLocal[] = { "y", "cory", NULL };
1731206Seric char		*MyLocName = "Cory";
1742098Seric char		*DaemonName = "Cory:~MAILER~DAEMON~";
175294Seric # endif CORY
176294Seric 
177*2420Seric # ifdef ONYX
178*2420Seric static char	*BerkLocal[[] = { "x", "onyx", NULL };
179*2420Seric char		*MyLocName = "Onyx";
180*2420Seric char		*DaemonName = "Onyx:~MAILER~DAEMON~";
181*2420Seric # endif ONYX
182*2420Seric 
183294Seric # ifdef IMAGE
184294Seric /* untested */
185294Seric static char	*BerkLocal[] = { "m", "image", NULL };
1861206Seric char		*MyLocName = "Image";
1872098Seric char		*DaemonName = "Image:~MAILER~DAEMON~";
188294Seric # define V6
189294Seric # endif IMAGE
190294Seric 
191294Seric # ifdef ESVAX
192294Seric static char	*BerkLocal[] = { "o", "esvax", NULL };
1931206Seric char		*MyLocName = "ESVAX";
1942098Seric char		*DaemonName = "ESVAX:~MAILER~DAEMON~";
195294Seric # endif ESVAX
196294Seric 
197294Seric # ifdef EECS40
198294Seric /* untested */
199294Seric static char	*BerkLocal[] = { "z", "eecs40", NULL };
2001206Seric char		*MyLocName = "EECS40";
2012098Seric char		*DaemonName = "EECS40:~MAILER~DAEMON~";
202294Seric # define V6
203294Seric # endif EECS40
204294Seric 
205590Seric 
206590Seric # ifndef HASARPA
207590Seric # define ArpaLocal	NULL
208590Seric # endif HASARPA
209590Seric 
210590Seric # ifndef HASUUCP
211590Seric # define UucpLocal	NULL
212590Seric # endif HASUUCP
213590Seric 
214590Seric 
215294Seric struct mailer Mailer[] =
216294Seric {
217294Seric 	/* local mail -- must be #0 */
218294Seric 	{
219294Seric # ifdef NETV6MAIL
220294Seric 		"/usr/net/bin/v6mail",
221294Seric # else
222294Seric 		"/bin/mail",
223294Seric # endif
224294Seric 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
225294Seric 		{ "...local%mail", "-d", "$u", NULL }
226294Seric 	},
227294Seric 	/* pipes through programs -- must be #1 */
228294Seric 	{
229294Seric 		"/bin/csh",
2301827Seric 		M_HDR|M_FHDR|M_NOHOST,		EX_UNAVAILABLE,	NULL,
231294Seric 		{ "...prog%mail", "-fc", "$u", NULL }
232294Seric 	},
233294Seric 	/* local berkeley mail */
234294Seric 	{
235294Seric 		"/usr/net/bin/sendberkmail",
2361596Seric 		M_FOPT|M_HDR|M_STRIPQ,		EX_UNAVAILABLE,	BerkLocal,
237294Seric 		{ "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL }
238294Seric 	},
239294Seric 	/* arpanet mail */
240294Seric 	{
241294Seric 		"/usr/lib/mailers/arpa",
242590Seric 		M_STRIPQ,			0,		ArpaLocal,
243294Seric 		{ "...arpa%mail", "$f", "$h", "$u", NULL }
244294Seric 	},
245294Seric 	/* uucp mail (cheat & use Bell's v7 mail) */
246294Seric 	{
247294Seric 		"/bin/mail",
248917Seric 		M_ROPT|M_STRIPQ,		EX_NOUSER,	UucpLocal,
249294Seric # ifdef DUMBMAIL
250294Seric 		{ "...uucp%mail", "$h!$u", NULL }
251294Seric # else
252294Seric 		{ "...uucp%mail", "-d", "$h!$u", NULL }
253294Seric # endif DUMBMAIL
254294Seric 	},
255294Seric };
256294Seric 
257294Seric # define M_LOCAL	0
258294Seric # define M_BERK		2
259294Seric # define M_ARPA		3
260294Seric # define M_UUCP		4
261294Seric 
262294Seric 
263294Seric 
2641573Seric # ifdef BERKELEY
265294Seric struct parsetab ParseTab[] =
266294Seric {
267294Seric 	':',	M_BERK,		P_ONE,				NULL,
268294Seric # ifdef HASARPA
269294Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
270294Seric # else
271294Seric 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
272294Seric # endif HASARPA
273294Seric 	'^',	-1,		P_MAP,				"!",
274294Seric # ifdef HASUUCP
275294Seric 	'!',	M_UUCP,		0,				NULL,
276294Seric # else
277294Seric 	'!',	M_BERK,		P_MOVE,				"csvax",
278294Seric # endif HASUUCP
279294Seric 	'.',	-1,		P_MAP|P_ONE,			":",
280294Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
281294Seric };
2821573Seric # else BERKELEY
2831573Seric struct parsetab ParseTab[] =
2841573Seric {
2851573Seric # ifdef HASARPA
2861573Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
2871573Seric # endif HASARPA
2881573Seric # ifdef HASUUCP
2891573Seric 	'^',	-1,		P_MAP,				"!",
2901573Seric 	'!',	M_UUCP,		0,				NULL,
2911573Seric # endif HASUUCP
2921573Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
2931573Seric };
2941573Seric # endif BERKELEY
295294Seric /*
296294Seric **  GETNAME -- Get the current users login name.
297294Seric **
298294Seric **	This is in config.c because it is somewhat machine dependent.
299294Seric **	Examine it carefully for your installation.
300294Seric **
301294Seric **	Algorithm:
302294Seric **		See if the person is logged in.  If so, return
303294Seric **			the name s/he is logged in as.
304294Seric **		Look up the user id in /etc/passwd.  If found,
305294Seric **			return that name.
306294Seric **		Return NULL.
307294Seric **
308294Seric **	Parameters:
309294Seric **		none
310294Seric **
311294Seric **	Returns:
312294Seric **		The login name of this user.
313294Seric **		NULL if this person is noone.
314294Seric **
315294Seric **	Side Effects:
316294Seric **		none
317294Seric **
318294Seric **	Called By:
319294Seric **		main
320294Seric */
321294Seric 
322294Seric char *
323294Seric getname()
324294Seric {
325294Seric 	register char *p;
326294Seric 	register struct passwd *w;
327294Seric 	extern char *getlogin();
328294Seric 	extern struct passwd *getpwuid();
329294Seric 	static char namebuf[9];
330294Seric 
331294Seric 	p = getlogin();
332294Seric 	if (p != NULL && p[0] != '\0')
333294Seric 		return (p);
334294Seric # ifdef V6
335294Seric 	w = getpwuid(getuid() & 0377);
336294Seric # else
337294Seric 	w = getpwuid(getuid());
338294Seric # endif V6
339294Seric 	if (w != NULL)
340294Seric 	{
341294Seric 		strcpy(namebuf, w->pw_name);
342294Seric 		return (namebuf);
343294Seric 	}
344294Seric 	return (NULL);
345294Seric }
346294Seric 
347294Seric # ifdef V6
348294Seric /*
349294Seric **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
350294Seric **
351294Seric **	Returns the pathname of the user's tty.  Returns NULL if
352294Seric **	the user is not logged in or if s/he has write permission
353294Seric **	denied.
354294Seric **
355294Seric **	Parameters:
356294Seric **		none
357294Seric **
358294Seric **	Returns:
359294Seric **		pathname of the user's tty.
360294Seric **		NULL if not logged in or write permission denied.
361294Seric **
362294Seric **	Side Effects:
363294Seric **		none.
364294Seric **
365294Seric **	WARNING:
366294Seric **		Return value is in a local buffer.
367294Seric **
368294Seric **	Called By:
369294Seric **		savemail
370294Seric */
371294Seric 
372294Seric # include <sys/types.h>
373294Seric # include <sys/stat.h>
374294Seric 
375294Seric char *
376294Seric ttypath()
377294Seric {
378294Seric 	struct stat stbuf;
379294Seric 	register int i;
380294Seric 	static char pathn[] = "/dev/ttyx";
381294Seric 	extern int errno;
382294Seric 
383294Seric 	/* compute the pathname of the controlling tty */
384294Seric 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
385294Seric 	{
386294Seric 		errno = 0;
387294Seric 		return (NULL);
388294Seric 	}
389294Seric 	pathn[8] = i;
390294Seric 
391294Seric 	/* see if we have write permission */
392294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
393294Seric 	{
394294Seric 		errno = 0;
395294Seric 		return (NULL);
396294Seric 	}
397294Seric 
398294Seric 	/* see if the user is logged in */
399294Seric 	if (getlogin() == NULL)
400294Seric 		return (NULL);
401294Seric 
402294Seric 	/* looks good */
403294Seric 	return (pathn);
404294Seric }
405294Seric /*
406294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
407294Seric **
408294Seric **	This is included here because it is standard in v7, but we
409294Seric **	need it in v6.
410294Seric **
411294Seric **	Algorithm:
412294Seric **		Open /dev/null to create a descriptor.
413294Seric **		Close that descriptor.
414294Seric **		Copy the existing fd into the descriptor.
415294Seric **
416294Seric **	Parameters:
417294Seric **		fd -- the open file descriptor.
418294Seric **		type -- "r", "w", or whatever.
419294Seric **
420294Seric **	Returns:
421294Seric **		The file descriptor it creates.
422294Seric **
423294Seric **	Side Effects:
424294Seric **		none
425294Seric **
426294Seric **	Called By:
427294Seric **		deliver
428294Seric **
429294Seric **	Notes:
430294Seric **		The mode of fd must match "type".
431294Seric */
432294Seric 
433294Seric FILE *
434294Seric fdopen(fd, type)
435294Seric 	int fd;
436294Seric 	char *type;
437294Seric {
438294Seric 	register FILE *f;
439294Seric 
440294Seric 	f = fopen("/dev/null", type);
441294Seric 	close(fileno(f));
442294Seric 	fileno(f) = fd;
443294Seric 	return (f);
444294Seric }
445294Seric /*
446294Seric **  INDEX -- Return pointer to character in string
447294Seric **
448294Seric **	For V7 compatibility.
449294Seric **
450294Seric **	Parameters:
451294Seric **		s -- a string to scan.
452294Seric **		c -- a character to look for.
453294Seric **
454294Seric **	Returns:
455294Seric **		If c is in s, returns the address of the first
456294Seric **			instance of c in s.
457294Seric **		NULL if c is not in s.
458294Seric **
459294Seric **	Side Effects:
460294Seric **		none.
461294Seric */
462294Seric 
463294Seric index(s, c)
464294Seric 	register char *s;
465294Seric 	register char c;
466294Seric {
467294Seric 	while (*s != '\0')
468294Seric 	{
469294Seric 		if (*s++ == c)
470294Seric 			return (--s);
471294Seric 	}
472294Seric 	return (NULL);
473294Seric }
474294Seric # endif V6
475294Seric 
476294Seric # ifndef V6
477294Seric /*
478294Seric **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
479294Seric **
480294Seric **	Returns the pathname of the user's tty.  Returns NULL if
481294Seric **	the user is not logged in or if s/he has write permission
482294Seric **	denied.
483294Seric **
484294Seric **	Parameters:
485294Seric **		none
486294Seric **
487294Seric **	Returns:
488294Seric **		pathname of the user's tty.
489294Seric **		NULL if not logged in or write permission denied.
490294Seric **
491294Seric **	Side Effects:
492294Seric **		none.
493294Seric **
494294Seric **	WARNING:
495294Seric **		Return value is in a local buffer.
496294Seric **
497294Seric **	Called By:
498294Seric **		savemail
499294Seric */
500294Seric 
501294Seric # include <sys/types.h>
502294Seric # include <sys/stat.h>
503294Seric 
504294Seric char *
505294Seric ttypath()
506294Seric {
507294Seric 	struct stat stbuf;
508294Seric 	register char *pathn;
509294Seric 	extern int errno;
510294Seric 	extern char *ttyname();
511294Seric 
512294Seric 	/* compute the pathname of the controlling tty */
513294Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
514294Seric 	{
515294Seric 		errno = 0;
516294Seric 		return (NULL);
517294Seric 	}
518294Seric 
519294Seric 	/* see if we have write permission */
520294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
521294Seric 	{
522294Seric 		errno = 0;
523294Seric 		return (NULL);
524294Seric 	}
525294Seric 
526294Seric 	/* see if the user is logged in */
527294Seric 	if (getlogin() == NULL)
528294Seric 		return (NULL);
529294Seric 
530294Seric 	/* looks good */
531294Seric 	return (pathn);
532294Seric }
533294Seric # endif V6
534