xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 1573)
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".
191388Seric **		V6 -- running on a version 6 system.  This determines
201388Seric **			whether to define certain routines between
211388Seric **			the two systems.  If you are running a funny
221388Seric **			system, e.g., V6 with long tty names, this
231388Seric **			should be checked carefully.
24*1573Seric **		DUMBMAIL -- set if your /bin/mail doesn't have the
25*1573Seric **			-d flag.
26294Seric **
271388Seric **	Configuration Variables:
28*1573Seric **		ArpaHost -- the arpanet name of the host through
29*1573Seric **			which arpanet mail will be sent.
301388Seric **		MyLocName -- the name of the host on a local network.
311388Seric **			This is used to disambiguate the contents of
321388Seric **			ArpaHost among many hosts who may be sharing
331388Seric **			a gateway.
34*1573Seric **		ArpaLocal -- a list of local names for this host on
35*1573Seric **			the arpanet.  Only functional if HASARPA set.
36*1573Seric **		UucpLocal -- ditto for the Arpanet.
37*1573Seric **		BerkLocal -- ditto for the Berknet.
381388Seric **		Mailer -- a table of mailers known to the system.
391388Seric **			The fields are:
401388Seric **			- the pathname of the mailer.
411388Seric **			- a list of flags describing the properties
421388Seric **			  of this mailer:
431388Seric **			   M_FOPT -- if set, the mailer has a picky "-f"
441388Seric **				option.  In this mode, the mailer will
451388Seric **				only accept the "-f" option if the
461388Seric **				sender is actually "root", "network",
471388Seric **				and possibly (but not necessarily) if
481388Seric **				the -f argument matches the real sender.
491388Seric **				The effect is that if the "-f" option
501388Seric **				is given to delivermail then it will be
511388Seric **				passed through (as arguments 1 & 2) to
521388Seric **				the mailer.
531388Seric **			   M_ROPT -- identical to M_FOPT, except uses
541388Seric **				-r instead.
551388Seric **			   M_QUIET -- if set, don't print a message if
561388Seric **				the mailer returns bad status.
571388Seric **			   M_RESTR -- if set, this mailer is restricted
581388Seric **				to use by "daemon"; otherwise, we do a
591388Seric **				setuid(getuid()) before calling the
601388Seric **				mailer.
611388Seric **			   M_HDR -- if set, the mailer wants us to
621388Seric **				insert a UNIX "From" line before
631388Seric **				outputing.
641388Seric **			   M_NOHOST -- if set, this mailer doesn't care
651388Seric **				about the host part (e.g., the local
661388Seric **				mailer).
671388Seric **			   M_STRIPQ -- if set, strip quote (`"')
681388Seric **				characters out of parameters as you
691388Seric **				transliterate them into the argument
701388Seric **				vector.  For example, the local mailer
711388Seric **				is called directly, so these should be
721388Seric **				stripped, but the program-mailer (i.e.,
731388Seric **				csh) should leave them in.
741388Seric **			- an exit status to use as the code for the
751388Seric **			  error message print if the mailer returns
761388Seric **			  something we don't understand.
771388Seric **			- A list of names that are to be considered
781388Seric **			  "local" (and hence are stripped off) for
791388Seric **			  this mailer.
801388Seric **			- An argument vector to be passed to the
811388Seric **			  mailer with the following substitutions:
821388Seric **			   $f - the from person name.
831388Seric **			   $u - the target user name.
841388Seric **			   $h - the target user host.
851388Seric **			   $c - the hop count.
861388Seric **			>>>>>>>>>> Entry zero must be for the local
871388Seric **			>> NOTE >> mailer and entry one must be for
881388Seric **			>>>>>>>>>> the shell.
891388Seric **		ParseTab -- a table driving the parsing process.  Each
901388Seric **			entry contains:
911388Seric **			- a character that will trigger this entry.
921388Seric **			- an index into the Mailer table.
931388Seric **			- a word of flags, described in dlvrmail.h.
941388Seric **			- an argument.  If we have P_MAP, it is the
951388Seric **			  character to turn the trigger character into.
961388Seric **			  If we have P_MOVE, it is the site to send it
971388Seric **			  to, using the mailer specified above.
98*1573Seric **			This table will almost certainly have to be
99*1573Seric **			changed on your site if you have anything more
100*1573Seric **			than the UUCP net.
101294Seric */
102294Seric 
103294Seric 
104294Seric 
105294Seric 
106*1573Seric static char SccsId[] = "@(#)conf.c	1.9	10/20/80";
107294Seric 
1081388Seric 
1091388Seric bool	UseMsgId = FALSE;	/* don't put message id's in anywhere */
1101388Seric 
1111388Seric # include <whoami.h>		/* definitions of machine id's at berkeley */
1121388Seric 
113*1573Seric # ifdef BERKELEY
114*1573Seric char	*ArpaHost = "Berkeley";	/* host name of gateway on Arpanet */
115*1573Seric # else BERKELEY
116*1573Seric char	*ArpaHost = "[unknown]";
117*1573Seric char	*MyLocName = sysname;
118*1573Seric # define HASUUCP		/* default to having UUCP net */
119*1573Seric char	*UucpLocal[] = { sysname, NULL };
120*1573Seric # endif BERKELEY
121*1573Seric 
122294Seric # ifdef ING70
123294Seric static char	*BerkLocal[] = { "i", "ingres", "ing70", NULL };
124590Seric # define ArpaLocal	NULL
1251206Seric char		*MyLocName = "Ing70";
126294Seric # define HASARPA
127294Seric # define V6
128294Seric # endif ING70
129294Seric 
130294Seric # ifdef INGVAX
131294Seric static char	*BerkLocal[] = { "j", "ingvax", NULL };
1321206Seric char		*MyLocName = "IngVax";
133294Seric # endif INGVAX
134294Seric 
135294Seric # ifdef CSVAX
136294Seric static char	*BerkLocal[] = { "v", "csvax", "vax", NULL };
137590Seric static char	*UucpLocal[] = { "ucbvax", "ernie", NULL };
1381206Seric char		*MyLocName = "CSVAX";
139294Seric # define HASUUCP
140294Seric # define NETV6MAIL
141294Seric # endif CSVAX
142294Seric 
143294Seric # ifdef CORY
144294Seric /* untested */
145294Seric static char	*BerkLocal[] = { "y", "cory", NULL };
1461206Seric char		*MyLocName = "Cory";
147294Seric # endif CORY
148294Seric 
149294Seric # ifdef IMAGE
150294Seric /* untested */
151294Seric static char	*BerkLocal[] = { "m", "image", NULL };
1521206Seric char		*MyLocName = "Image";
153294Seric # define V6
154294Seric # endif IMAGE
155294Seric 
156294Seric # ifdef ESVAX
157294Seric /* untested */
158294Seric static char	*BerkLocal[] = { "o", "esvax", NULL };
1591206Seric char		*MyLocName = "ESVAX";
160294Seric # endif ESVAX
161294Seric 
162294Seric # ifdef EECS40
163294Seric /* untested */
164294Seric static char	*BerkLocal[] = { "z", "eecs40", NULL };
1651206Seric char		*MyLocName = "EECS40";
166294Seric # define V6
167294Seric # endif EECS40
168294Seric 
169590Seric 
170590Seric # ifndef HASARPA
171590Seric # define ArpaLocal	NULL
172590Seric # endif HASARPA
173590Seric 
174590Seric # ifndef HASUUCP
175590Seric # define UucpLocal	NULL
176590Seric # endif HASUUCP
177590Seric 
178590Seric 
179294Seric struct mailer Mailer[] =
180294Seric {
181294Seric 	/* local mail -- must be #0 */
182294Seric 	{
183294Seric # ifdef NETV6MAIL
184294Seric 		"/usr/net/bin/v6mail",
185294Seric # else
186294Seric 		"/bin/mail",
187294Seric # endif
188294Seric 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
189294Seric 		{ "...local%mail", "-d", "$u", NULL }
190294Seric 	},
191294Seric 	/* pipes through programs -- must be #1 */
192294Seric 	{
193294Seric 		"/bin/csh",
194294Seric 		M_HDR|M_NOHOST,			EX_UNAVAIL,	NULL,
195294Seric 		{ "...prog%mail", "-fc", "$u", NULL }
196294Seric 	},
197294Seric 	/* local berkeley mail */
198294Seric 	{
199294Seric 		"/usr/net/bin/sendberkmail",
200310Seric 		M_FOPT|M_HDR|M_STRIPQ,		EX_UNAVAIL,	BerkLocal,
201294Seric 		{ "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL }
202294Seric 	},
203294Seric 	/* arpanet mail */
204294Seric 	{
205294Seric 		"/usr/lib/mailers/arpa",
206590Seric 		M_STRIPQ,			0,		ArpaLocal,
207294Seric 		{ "...arpa%mail", "$f", "$h", "$u", NULL }
208294Seric 	},
209294Seric 	/* uucp mail (cheat & use Bell's v7 mail) */
210294Seric 	{
211294Seric 		"/bin/mail",
212917Seric 		M_ROPT|M_STRIPQ,		EX_NOUSER,	UucpLocal,
213294Seric # ifdef DUMBMAIL
214294Seric 		{ "...uucp%mail", "$h!$u", NULL }
215294Seric # else
216294Seric 		{ "...uucp%mail", "-d", "$h!$u", NULL }
217294Seric # endif DUMBMAIL
218294Seric 	},
219294Seric };
220294Seric 
221294Seric # define M_LOCAL	0
222294Seric # define M_BERK		2
223294Seric # define M_ARPA		3
224294Seric # define M_UUCP		4
225294Seric 
226294Seric 
227294Seric 
228*1573Seric # ifdef BERKELEY
229294Seric struct parsetab ParseTab[] =
230294Seric {
231294Seric 	':',	M_BERK,		P_ONE,				NULL,
232294Seric # ifdef HASARPA
233294Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
234294Seric # else
235294Seric 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
236294Seric # endif HASARPA
237294Seric 	'^',	-1,		P_MAP,				"!",
238294Seric # ifdef HASUUCP
239294Seric 	'!',	M_UUCP,		0,				NULL,
240294Seric # else
241294Seric 	'!',	M_BERK,		P_MOVE,				"csvax",
242294Seric # endif HASUUCP
243294Seric 	'.',	-1,		P_MAP|P_ONE,			":",
244294Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
245294Seric };
246*1573Seric # else BERKELEY
247*1573Seric struct parsetab ParseTab[] =
248*1573Seric {
249*1573Seric # ifdef HASARPA
250*1573Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
251*1573Seric # endif HASARPA
252*1573Seric # ifdef HASUUCP
253*1573Seric 	'^',	-1,		P_MAP,				"!",
254*1573Seric 	'!',	M_UUCP,		0,				NULL,
255*1573Seric # endif HASUUCP
256*1573Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
257*1573Seric };
258*1573Seric # endif BERKELEY
259294Seric /*
260294Seric **  GETNAME -- Get the current users login name.
261294Seric **
262294Seric **	This is in config.c because it is somewhat machine dependent.
263294Seric **	Examine it carefully for your installation.
264294Seric **
265294Seric **	Algorithm:
266294Seric **		See if the person is logged in.  If so, return
267294Seric **			the name s/he is logged in as.
268294Seric **		Look up the user id in /etc/passwd.  If found,
269294Seric **			return that name.
270294Seric **		Return NULL.
271294Seric **
272294Seric **	Parameters:
273294Seric **		none
274294Seric **
275294Seric **	Returns:
276294Seric **		The login name of this user.
277294Seric **		NULL if this person is noone.
278294Seric **
279294Seric **	Side Effects:
280294Seric **		none
281294Seric **
282294Seric **	Called By:
283294Seric **		main
284294Seric */
285294Seric 
286294Seric char *
287294Seric getname()
288294Seric {
289294Seric 	register char *p;
290294Seric 	register struct passwd *w;
291294Seric 	extern char *getlogin();
292294Seric 	extern struct passwd *getpwuid();
293294Seric 	static char namebuf[9];
294294Seric 
295294Seric 	p = getlogin();
296294Seric 	if (p != NULL && p[0] != '\0')
297294Seric 		return (p);
298294Seric # ifdef V6
299294Seric 	w = getpwuid(getuid() & 0377);
300294Seric # else
301294Seric 	w = getpwuid(getuid());
302294Seric # endif V6
303294Seric 	if (w != NULL)
304294Seric 	{
305294Seric 		strcpy(namebuf, w->pw_name);
306294Seric 		return (namebuf);
307294Seric 	}
308294Seric 	return (NULL);
309294Seric }
310294Seric 
311294Seric # ifdef V6
312294Seric /*
313294Seric **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
314294Seric **
315294Seric **	Returns the pathname of the user's tty.  Returns NULL if
316294Seric **	the user is not logged in or if s/he has write permission
317294Seric **	denied.
318294Seric **
319294Seric **	Parameters:
320294Seric **		none
321294Seric **
322294Seric **	Returns:
323294Seric **		pathname of the user's tty.
324294Seric **		NULL if not logged in or write permission denied.
325294Seric **
326294Seric **	Side Effects:
327294Seric **		none.
328294Seric **
329294Seric **	WARNING:
330294Seric **		Return value is in a local buffer.
331294Seric **
332294Seric **	Called By:
333294Seric **		savemail
334294Seric */
335294Seric 
336294Seric # include <sys/types.h>
337294Seric # include <sys/stat.h>
338294Seric 
339294Seric char *
340294Seric ttypath()
341294Seric {
342294Seric 	struct stat stbuf;
343294Seric 	register int i;
344294Seric 	static char pathn[] = "/dev/ttyx";
345294Seric 	extern int errno;
346294Seric 
347294Seric 	/* compute the pathname of the controlling tty */
348294Seric 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
349294Seric 	{
350294Seric 		errno = 0;
351294Seric 		return (NULL);
352294Seric 	}
353294Seric 	pathn[8] = i;
354294Seric 
355294Seric 	/* see if we have write permission */
356294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
357294Seric 	{
358294Seric 		errno = 0;
359294Seric 		return (NULL);
360294Seric 	}
361294Seric 
362294Seric 	/* see if the user is logged in */
363294Seric 	if (getlogin() == NULL)
364294Seric 		return (NULL);
365294Seric 
366294Seric 	/* looks good */
367294Seric 	return (pathn);
368294Seric }
369294Seric /*
370294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
371294Seric **
372294Seric **	This is included here because it is standard in v7, but we
373294Seric **	need it in v6.
374294Seric **
375294Seric **	Algorithm:
376294Seric **		Open /dev/null to create a descriptor.
377294Seric **		Close that descriptor.
378294Seric **		Copy the existing fd into the descriptor.
379294Seric **
380294Seric **	Parameters:
381294Seric **		fd -- the open file descriptor.
382294Seric **		type -- "r", "w", or whatever.
383294Seric **
384294Seric **	Returns:
385294Seric **		The file descriptor it creates.
386294Seric **
387294Seric **	Side Effects:
388294Seric **		none
389294Seric **
390294Seric **	Called By:
391294Seric **		deliver
392294Seric **
393294Seric **	Notes:
394294Seric **		The mode of fd must match "type".
395294Seric */
396294Seric 
397294Seric FILE *
398294Seric fdopen(fd, type)
399294Seric 	int fd;
400294Seric 	char *type;
401294Seric {
402294Seric 	register FILE *f;
403294Seric 
404294Seric 	f = fopen("/dev/null", type);
405294Seric 	close(fileno(f));
406294Seric 	fileno(f) = fd;
407294Seric 	return (f);
408294Seric }
409294Seric /*
410294Seric **  INDEX -- Return pointer to character in string
411294Seric **
412294Seric **	For V7 compatibility.
413294Seric **
414294Seric **	Parameters:
415294Seric **		s -- a string to scan.
416294Seric **		c -- a character to look for.
417294Seric **
418294Seric **	Returns:
419294Seric **		If c is in s, returns the address of the first
420294Seric **			instance of c in s.
421294Seric **		NULL if c is not in s.
422294Seric **
423294Seric **	Side Effects:
424294Seric **		none.
425294Seric */
426294Seric 
427294Seric index(s, c)
428294Seric 	register char *s;
429294Seric 	register char c;
430294Seric {
431294Seric 	while (*s != '\0')
432294Seric 	{
433294Seric 		if (*s++ == c)
434294Seric 			return (--s);
435294Seric 	}
436294Seric 	return (NULL);
437294Seric }
438294Seric # endif V6
439294Seric 
440294Seric # ifndef V6
441294Seric /*
442294Seric **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
443294Seric **
444294Seric **	Returns the pathname of the user's tty.  Returns NULL if
445294Seric **	the user is not logged in or if s/he has write permission
446294Seric **	denied.
447294Seric **
448294Seric **	Parameters:
449294Seric **		none
450294Seric **
451294Seric **	Returns:
452294Seric **		pathname of the user's tty.
453294Seric **		NULL if not logged in or write permission denied.
454294Seric **
455294Seric **	Side Effects:
456294Seric **		none.
457294Seric **
458294Seric **	WARNING:
459294Seric **		Return value is in a local buffer.
460294Seric **
461294Seric **	Called By:
462294Seric **		savemail
463294Seric */
464294Seric 
465294Seric # include <sys/types.h>
466294Seric # include <sys/stat.h>
467294Seric 
468294Seric char *
469294Seric ttypath()
470294Seric {
471294Seric 	struct stat stbuf;
472294Seric 	register char *pathn;
473294Seric 	extern int errno;
474294Seric 	extern char *ttyname();
475294Seric 
476294Seric 	/* compute the pathname of the controlling tty */
477294Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
478294Seric 	{
479294Seric 		errno = 0;
480294Seric 		return (NULL);
481294Seric 	}
482294Seric 
483294Seric 	/* see if we have write permission */
484294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
485294Seric 	{
486294Seric 		errno = 0;
487294Seric 		return (NULL);
488294Seric 	}
489294Seric 
490294Seric 	/* see if the user is logged in */
491294Seric 	if (getlogin() == NULL)
492294Seric 		return (NULL);
493294Seric 
494294Seric 	/* looks good */
495294Seric 	return (pathn);
496294Seric }
497294Seric # endif V6
498