xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 2098)
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.
241573Seric **		DUMBMAIL -- set if your /bin/mail doesn't have the
251573Seric **			-d flag.
26294Seric **
271388Seric **	Configuration Variables:
281573Seric **		ArpaHost -- the arpanet name of the host through
291573Seric **			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.
341573Seric **		ArpaLocal -- a list of local names for this host on
351573Seric **			the arpanet.  Only functional if HASARPA set.
361573Seric **		UucpLocal -- ditto for the Arpanet.
371573Seric **		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.
641827Seric **			   M_FHDR -- if set, the header that we
651827Seric **				generate will be used literally, so
661827Seric **				we must force it to be correct.  The
671827Seric **				effect is that we generate a header
681827Seric **				even if one exists.
691388Seric **			   M_NOHOST -- if set, this mailer doesn't care
701388Seric **				about the host part (e.g., the local
711388Seric **				mailer).
721388Seric **			   M_STRIPQ -- if set, strip quote (`"')
731388Seric **				characters out of parameters as you
741388Seric **				transliterate them into the argument
751388Seric **				vector.  For example, the local mailer
761388Seric **				is called directly, so these should be
771388Seric **				stripped, but the program-mailer (i.e.,
781388Seric **				csh) should leave them in.
791388Seric **			- an exit status to use as the code for the
801388Seric **			  error message print if the mailer returns
811388Seric **			  something we don't understand.
821388Seric **			- A list of names that are to be considered
831388Seric **			  "local" (and hence are stripped off) for
841388Seric **			  this mailer.
851388Seric **			- An argument vector to be passed to the
861388Seric **			  mailer with the following substitutions:
871388Seric **			   $f - the from person name.
881388Seric **			   $u - the target user name.
891388Seric **			   $h - the target user host.
901388Seric **			   $c - the hop count.
911388Seric **			>>>>>>>>>> Entry zero must be for the local
921388Seric **			>> NOTE >> mailer and entry one must be for
931388Seric **			>>>>>>>>>> the shell.
941388Seric **		ParseTab -- a table driving the parsing process.  Each
951388Seric **			entry contains:
961388Seric **			- a character that will trigger this entry.
971388Seric **			- an index into the Mailer table.
981388Seric **			- a word of flags, described in dlvrmail.h.
991388Seric **			- an argument.  If we have P_MAP, it is the
1001388Seric **			  character to turn the trigger character into.
1011388Seric **			  If we have P_MOVE, it is the site to send it
1021388Seric **			  to, using the mailer specified above.
1031573Seric **			This table will almost certainly have to be
1041573Seric **			changed on your site if you have anything more
1051573Seric **			than the UUCP net.
106294Seric */
107294Seric 
108294Seric 
109294Seric 
110294Seric 
111*2098Seric static char SccsId[] = "@(#)conf.c	2.3	01/10/81";
112294Seric 
1131388Seric 
1141388Seric bool	UseMsgId = FALSE;	/* don't put message id's in anywhere */
1151388Seric 
1161388Seric # include <whoami.h>		/* definitions of machine id's at berkeley */
1171388Seric 
1181573Seric # ifdef BERKELEY
1191573Seric char	*ArpaHost = "Berkeley";	/* host name of gateway on Arpanet */
1201573Seric # else BERKELEY
1211573Seric char	*ArpaHost = "[unknown]";
1221573Seric char	*MyLocName = sysname;
1231573Seric # define HASUUCP		/* default to having UUCP net */
1241573Seric char	*UucpLocal[] = { sysname, NULL };
1251573Seric # endif BERKELEY
1261573Seric 
127294Seric # ifdef ING70
128294Seric static char	*BerkLocal[] = { "i", "ingres", "ing70", NULL };
129590Seric # define ArpaLocal	NULL
1301206Seric char		*MyLocName = "Ing70";
131*2098Seric char		*DaemonName = "Ing70:~MAILER~DAEMON~";
132294Seric # define HASARPA
133294Seric # define V6
134294Seric # endif ING70
135294Seric 
136294Seric # ifdef INGVAX
137294Seric static char	*BerkLocal[] = { "j", "ingvax", NULL };
1381206Seric char		*MyLocName = "IngVax";
139*2098Seric char		*DaemonName = "IngVax:~MAILER~DAEMON~";
140294Seric # endif INGVAX
141294Seric 
142294Seric # ifdef CSVAX
143294Seric static char	*BerkLocal[] = { "v", "csvax", "vax", NULL };
144590Seric static char	*UucpLocal[] = { "ucbvax", "ernie", NULL };
1451206Seric char		*MyLocName = "CSVAX";
146*2098Seric char		*DaemonName = "CSVAX:~MAILER~DAEMON~";
147294Seric # define HASUUCP
148294Seric # define NETV6MAIL
149294Seric # endif CSVAX
150294Seric 
151294Seric # ifdef CORY
152294Seric static char	*BerkLocal[] = { "y", "cory", NULL };
1531206Seric char		*MyLocName = "Cory";
154*2098Seric char		*DaemonName = "Cory:~MAILER~DAEMON~";
155294Seric # endif CORY
156294Seric 
157294Seric # ifdef IMAGE
158294Seric /* untested */
159294Seric static char	*BerkLocal[] = { "m", "image", NULL };
1601206Seric char		*MyLocName = "Image";
161*2098Seric char		*DaemonName = "Image:~MAILER~DAEMON~";
162294Seric # define V6
163294Seric # endif IMAGE
164294Seric 
165294Seric # ifdef ESVAX
166294Seric static char	*BerkLocal[] = { "o", "esvax", NULL };
1671206Seric char		*MyLocName = "ESVAX";
168*2098Seric char		*DaemonName = "ESVAX:~MAILER~DAEMON~";
169294Seric # endif ESVAX
170294Seric 
171294Seric # ifdef EECS40
172294Seric /* untested */
173294Seric static char	*BerkLocal[] = { "z", "eecs40", NULL };
1741206Seric char		*MyLocName = "EECS40";
175*2098Seric char		*DaemonName = "EECS40:~MAILER~DAEMON~";
176294Seric # define V6
177294Seric # endif EECS40
178294Seric 
179590Seric 
180590Seric # ifndef HASARPA
181590Seric # define ArpaLocal	NULL
182590Seric # endif HASARPA
183590Seric 
184590Seric # ifndef HASUUCP
185590Seric # define UucpLocal	NULL
186590Seric # endif HASUUCP
187590Seric 
188590Seric 
189294Seric struct mailer Mailer[] =
190294Seric {
191294Seric 	/* local mail -- must be #0 */
192294Seric 	{
193294Seric # ifdef NETV6MAIL
194294Seric 		"/usr/net/bin/v6mail",
195294Seric # else
196294Seric 		"/bin/mail",
197294Seric # endif
198294Seric 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
199294Seric 		{ "...local%mail", "-d", "$u", NULL }
200294Seric 	},
201294Seric 	/* pipes through programs -- must be #1 */
202294Seric 	{
203294Seric 		"/bin/csh",
2041827Seric 		M_HDR|M_FHDR|M_NOHOST,		EX_UNAVAILABLE,	NULL,
205294Seric 		{ "...prog%mail", "-fc", "$u", NULL }
206294Seric 	},
207294Seric 	/* local berkeley mail */
208294Seric 	{
209294Seric 		"/usr/net/bin/sendberkmail",
2101596Seric 		M_FOPT|M_HDR|M_STRIPQ,		EX_UNAVAILABLE,	BerkLocal,
211294Seric 		{ "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL }
212294Seric 	},
213294Seric 	/* arpanet mail */
214294Seric 	{
215294Seric 		"/usr/lib/mailers/arpa",
216590Seric 		M_STRIPQ,			0,		ArpaLocal,
217294Seric 		{ "...arpa%mail", "$f", "$h", "$u", NULL }
218294Seric 	},
219294Seric 	/* uucp mail (cheat & use Bell's v7 mail) */
220294Seric 	{
221294Seric 		"/bin/mail",
222917Seric 		M_ROPT|M_STRIPQ,		EX_NOUSER,	UucpLocal,
223294Seric # ifdef DUMBMAIL
224294Seric 		{ "...uucp%mail", "$h!$u", NULL }
225294Seric # else
226294Seric 		{ "...uucp%mail", "-d", "$h!$u", NULL }
227294Seric # endif DUMBMAIL
228294Seric 	},
229294Seric };
230294Seric 
231294Seric # define M_LOCAL	0
232294Seric # define M_BERK		2
233294Seric # define M_ARPA		3
234294Seric # define M_UUCP		4
235294Seric 
236294Seric 
237294Seric 
2381573Seric # ifdef BERKELEY
239294Seric struct parsetab ParseTab[] =
240294Seric {
241294Seric 	':',	M_BERK,		P_ONE,				NULL,
242294Seric # ifdef HASARPA
243294Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
244294Seric # else
245294Seric 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
246294Seric # endif HASARPA
247294Seric 	'^',	-1,		P_MAP,				"!",
248294Seric # ifdef HASUUCP
249294Seric 	'!',	M_UUCP,		0,				NULL,
250294Seric # else
251294Seric 	'!',	M_BERK,		P_MOVE,				"csvax",
252294Seric # endif HASUUCP
253294Seric 	'.',	-1,		P_MAP|P_ONE,			":",
254294Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
255294Seric };
2561573Seric # else BERKELEY
2571573Seric struct parsetab ParseTab[] =
2581573Seric {
2591573Seric # ifdef HASARPA
2601573Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
2611573Seric # endif HASARPA
2621573Seric # ifdef HASUUCP
2631573Seric 	'^',	-1,		P_MAP,				"!",
2641573Seric 	'!',	M_UUCP,		0,				NULL,
2651573Seric # endif HASUUCP
2661573Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
2671573Seric };
2681573Seric # endif BERKELEY
269294Seric /*
270294Seric **  GETNAME -- Get the current users login name.
271294Seric **
272294Seric **	This is in config.c because it is somewhat machine dependent.
273294Seric **	Examine it carefully for your installation.
274294Seric **
275294Seric **	Algorithm:
276294Seric **		See if the person is logged in.  If so, return
277294Seric **			the name s/he is logged in as.
278294Seric **		Look up the user id in /etc/passwd.  If found,
279294Seric **			return that name.
280294Seric **		Return NULL.
281294Seric **
282294Seric **	Parameters:
283294Seric **		none
284294Seric **
285294Seric **	Returns:
286294Seric **		The login name of this user.
287294Seric **		NULL if this person is noone.
288294Seric **
289294Seric **	Side Effects:
290294Seric **		none
291294Seric **
292294Seric **	Called By:
293294Seric **		main
294294Seric */
295294Seric 
296294Seric char *
297294Seric getname()
298294Seric {
299294Seric 	register char *p;
300294Seric 	register struct passwd *w;
301294Seric 	extern char *getlogin();
302294Seric 	extern struct passwd *getpwuid();
303294Seric 	static char namebuf[9];
304294Seric 
305294Seric 	p = getlogin();
306294Seric 	if (p != NULL && p[0] != '\0')
307294Seric 		return (p);
308294Seric # ifdef V6
309294Seric 	w = getpwuid(getuid() & 0377);
310294Seric # else
311294Seric 	w = getpwuid(getuid());
312294Seric # endif V6
313294Seric 	if (w != NULL)
314294Seric 	{
315294Seric 		strcpy(namebuf, w->pw_name);
316294Seric 		return (namebuf);
317294Seric 	}
318294Seric 	return (NULL);
319294Seric }
320294Seric 
321294Seric # ifdef V6
322294Seric /*
323294Seric **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
324294Seric **
325294Seric **	Returns the pathname of the user's tty.  Returns NULL if
326294Seric **	the user is not logged in or if s/he has write permission
327294Seric **	denied.
328294Seric **
329294Seric **	Parameters:
330294Seric **		none
331294Seric **
332294Seric **	Returns:
333294Seric **		pathname of the user's tty.
334294Seric **		NULL if not logged in or write permission denied.
335294Seric **
336294Seric **	Side Effects:
337294Seric **		none.
338294Seric **
339294Seric **	WARNING:
340294Seric **		Return value is in a local buffer.
341294Seric **
342294Seric **	Called By:
343294Seric **		savemail
344294Seric */
345294Seric 
346294Seric # include <sys/types.h>
347294Seric # include <sys/stat.h>
348294Seric 
349294Seric char *
350294Seric ttypath()
351294Seric {
352294Seric 	struct stat stbuf;
353294Seric 	register int i;
354294Seric 	static char pathn[] = "/dev/ttyx";
355294Seric 	extern int errno;
356294Seric 
357294Seric 	/* compute the pathname of the controlling tty */
358294Seric 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
359294Seric 	{
360294Seric 		errno = 0;
361294Seric 		return (NULL);
362294Seric 	}
363294Seric 	pathn[8] = i;
364294Seric 
365294Seric 	/* see if we have write permission */
366294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
367294Seric 	{
368294Seric 		errno = 0;
369294Seric 		return (NULL);
370294Seric 	}
371294Seric 
372294Seric 	/* see if the user is logged in */
373294Seric 	if (getlogin() == NULL)
374294Seric 		return (NULL);
375294Seric 
376294Seric 	/* looks good */
377294Seric 	return (pathn);
378294Seric }
379294Seric /*
380294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
381294Seric **
382294Seric **	This is included here because it is standard in v7, but we
383294Seric **	need it in v6.
384294Seric **
385294Seric **	Algorithm:
386294Seric **		Open /dev/null to create a descriptor.
387294Seric **		Close that descriptor.
388294Seric **		Copy the existing fd into the descriptor.
389294Seric **
390294Seric **	Parameters:
391294Seric **		fd -- the open file descriptor.
392294Seric **		type -- "r", "w", or whatever.
393294Seric **
394294Seric **	Returns:
395294Seric **		The file descriptor it creates.
396294Seric **
397294Seric **	Side Effects:
398294Seric **		none
399294Seric **
400294Seric **	Called By:
401294Seric **		deliver
402294Seric **
403294Seric **	Notes:
404294Seric **		The mode of fd must match "type".
405294Seric */
406294Seric 
407294Seric FILE *
408294Seric fdopen(fd, type)
409294Seric 	int fd;
410294Seric 	char *type;
411294Seric {
412294Seric 	register FILE *f;
413294Seric 
414294Seric 	f = fopen("/dev/null", type);
415294Seric 	close(fileno(f));
416294Seric 	fileno(f) = fd;
417294Seric 	return (f);
418294Seric }
419294Seric /*
420294Seric **  INDEX -- Return pointer to character in string
421294Seric **
422294Seric **	For V7 compatibility.
423294Seric **
424294Seric **	Parameters:
425294Seric **		s -- a string to scan.
426294Seric **		c -- a character to look for.
427294Seric **
428294Seric **	Returns:
429294Seric **		If c is in s, returns the address of the first
430294Seric **			instance of c in s.
431294Seric **		NULL if c is not in s.
432294Seric **
433294Seric **	Side Effects:
434294Seric **		none.
435294Seric */
436294Seric 
437294Seric index(s, c)
438294Seric 	register char *s;
439294Seric 	register char c;
440294Seric {
441294Seric 	while (*s != '\0')
442294Seric 	{
443294Seric 		if (*s++ == c)
444294Seric 			return (--s);
445294Seric 	}
446294Seric 	return (NULL);
447294Seric }
448294Seric # endif V6
449294Seric 
450294Seric # ifndef V6
451294Seric /*
452294Seric **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
453294Seric **
454294Seric **	Returns the pathname of the user's tty.  Returns NULL if
455294Seric **	the user is not logged in or if s/he has write permission
456294Seric **	denied.
457294Seric **
458294Seric **	Parameters:
459294Seric **		none
460294Seric **
461294Seric **	Returns:
462294Seric **		pathname of the user's tty.
463294Seric **		NULL if not logged in or write permission denied.
464294Seric **
465294Seric **	Side Effects:
466294Seric **		none.
467294Seric **
468294Seric **	WARNING:
469294Seric **		Return value is in a local buffer.
470294Seric **
471294Seric **	Called By:
472294Seric **		savemail
473294Seric */
474294Seric 
475294Seric # include <sys/types.h>
476294Seric # include <sys/stat.h>
477294Seric 
478294Seric char *
479294Seric ttypath()
480294Seric {
481294Seric 	struct stat stbuf;
482294Seric 	register char *pathn;
483294Seric 	extern int errno;
484294Seric 	extern char *ttyname();
485294Seric 
486294Seric 	/* compute the pathname of the controlling tty */
487294Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
488294Seric 	{
489294Seric 		errno = 0;
490294Seric 		return (NULL);
491294Seric 	}
492294Seric 
493294Seric 	/* see if we have write permission */
494294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
495294Seric 	{
496294Seric 		errno = 0;
497294Seric 		return (NULL);
498294Seric 	}
499294Seric 
500294Seric 	/* see if the user is logged in */
501294Seric 	if (getlogin() == NULL)
502294Seric 		return (NULL);
503294Seric 
504294Seric 	/* looks good */
505294Seric 	return (pathn);
506294Seric }
507294Seric # endif V6
508