xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 1388)
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 **
10*1388Seric **	Compilation Flags:
11*1388Seric **		HASARPA -- set if this machine has a connection to
12*1388Seric **			the Arpanet.
13*1388Seric **		HASUUCP -- set if this machine has a connection to
14*1388Seric **			the UUCP network.
15*1388Seric **		NETV6MAIL -- set if you want to use "v6mail" that
16*1388Seric **			comes with the Berkeley network.  Normally
17*1388Seric **			/bin/mail will work fine, but around Berkeley
18*1388Seric **			we use v6mail because it is a "fixed target".
19*1388Seric **		V6 -- running on a version 6 system.  This determines
20*1388Seric **			whether to define certain routines between
21*1388Seric **			the two systems.  If you are running a funny
22*1388Seric **			system, e.g., V6 with long tty names, this
23*1388Seric **			should be checked carefully.
24294Seric **
25*1388Seric **	Configuration Variables:
26*1388Seric **		ArpaHost -- the name of the host through which arpanet
27*1388Seric **			mail will be sent.
28*1388Seric **		MyLocName -- the name of the host on a local network.
29*1388Seric **			This is used to disambiguate the contents of
30*1388Seric **			ArpaHost among many hosts who may be sharing
31*1388Seric **			a gateway.
32*1388Seric **		Mailer -- a table of mailers known to the system.
33*1388Seric **			The fields are:
34*1388Seric **			- the pathname of the mailer.
35*1388Seric **			- a list of flags describing the properties
36*1388Seric **			  of this mailer:
37*1388Seric **			   M_FOPT -- if set, the mailer has a picky "-f"
38*1388Seric **				option.  In this mode, the mailer will
39*1388Seric **				only accept the "-f" option if the
40*1388Seric **				sender is actually "root", "network",
41*1388Seric **				and possibly (but not necessarily) if
42*1388Seric **				the -f argument matches the real sender.
43*1388Seric **				The effect is that if the "-f" option
44*1388Seric **				is given to delivermail then it will be
45*1388Seric **				passed through (as arguments 1 & 2) to
46*1388Seric **				the mailer.
47*1388Seric **			   M_ROPT -- identical to M_FOPT, except uses
48*1388Seric **				-r instead.
49*1388Seric **			   M_QUIET -- if set, don't print a message if
50*1388Seric **				the mailer returns bad status.
51*1388Seric **			   M_RESTR -- if set, this mailer is restricted
52*1388Seric **				to use by "daemon"; otherwise, we do a
53*1388Seric **				setuid(getuid()) before calling the
54*1388Seric **				mailer.
55*1388Seric **			   M_HDR -- if set, the mailer wants us to
56*1388Seric **				insert a UNIX "From" line before
57*1388Seric **				outputing.
58*1388Seric **			   M_NOHOST -- if set, this mailer doesn't care
59*1388Seric **				about the host part (e.g., the local
60*1388Seric **				mailer).
61*1388Seric **			   M_STRIPQ -- if set, strip quote (`"')
62*1388Seric **				characters out of parameters as you
63*1388Seric **				transliterate them into the argument
64*1388Seric **				vector.  For example, the local mailer
65*1388Seric **				is called directly, so these should be
66*1388Seric **				stripped, but the program-mailer (i.e.,
67*1388Seric **				csh) should leave them in.
68*1388Seric **			- an exit status to use as the code for the
69*1388Seric **			  error message print if the mailer returns
70*1388Seric **			  something we don't understand.
71*1388Seric **			- A list of names that are to be considered
72*1388Seric **			  "local" (and hence are stripped off) for
73*1388Seric **			  this mailer.
74*1388Seric **			- An argument vector to be passed to the
75*1388Seric **			  mailer with the following substitutions:
76*1388Seric **			   $f - the from person name.
77*1388Seric **			   $u - the target user name.
78*1388Seric **			   $h - the target user host.
79*1388Seric **			   $c - the hop count.
80*1388Seric **			>>>>>>>>>> Entry zero must be for the local
81*1388Seric **			>> NOTE >> mailer and entry one must be for
82*1388Seric **			>>>>>>>>>> the shell.
83*1388Seric **		ParseTab -- a table driving the parsing process.  Each
84*1388Seric **			entry contains:
85*1388Seric **			- a character that will trigger this entry.
86*1388Seric **			- an index into the Mailer table.
87*1388Seric **			- a word of flags, described in dlvrmail.h.
88*1388Seric **			- an argument.  If we have P_MAP, it is the
89*1388Seric **			  character to turn the trigger character into.
90*1388Seric **			  If we have P_MOVE, it is the site to send it
91*1388Seric **			  to, using the mailer specified above.
92294Seric */
93294Seric 
94294Seric 
95294Seric 
96294Seric 
97*1388Seric static char SccsId[] = "@(#)conf.c	1.8	10/11/80";
98294Seric 
99*1388Seric 
100*1388Seric char	*ArpaHost = "Berkeley";	/* host name of gateway on Arpanet */
101*1388Seric bool	UseMsgId = FALSE;	/* don't put message id's in anywhere */
102*1388Seric 
103*1388Seric # include <whoami.h>		/* definitions of machine id's at berkeley */
104*1388Seric 
105294Seric # ifdef ING70
106294Seric static char	*BerkLocal[] = { "i", "ingres", "ing70", NULL };
107590Seric # define ArpaLocal	NULL
1081206Seric char		*MyLocName = "Ing70";
109294Seric # define HASARPA
110294Seric # define V6
111294Seric # endif ING70
112294Seric 
113294Seric # ifdef INGVAX
114294Seric /* untested */
115294Seric static char	*BerkLocal[] = { "j", "ingvax", NULL };
1161206Seric char		*MyLocName = "IngVax";
117294Seric # endif INGVAX
118294Seric 
119294Seric # ifdef CSVAX
120294Seric /* untested */
121294Seric static char	*BerkLocal[] = { "v", "csvax", "vax", NULL };
122590Seric static char	*UucpLocal[] = { "ucbvax", "ernie", NULL };
1231206Seric char		*MyLocName = "CSVAX";
124294Seric # define HASUUCP
125294Seric # define NETV6MAIL
126294Seric # endif CSVAX
127294Seric 
128294Seric # ifdef CORY
129294Seric /* untested */
130294Seric static char	*BerkLocal[] = { "y", "cory", NULL };
1311206Seric char		*MyLocName = "Cory";
132294Seric # endif CORY
133294Seric 
134294Seric # ifdef IMAGE
135294Seric /* untested */
136294Seric static char	*BerkLocal[] = { "m", "image", NULL };
1371206Seric char		*MyLocName = "Image";
138294Seric # define V6
139294Seric # endif IMAGE
140294Seric 
141294Seric # ifdef ESVAX
142294Seric /* untested */
143294Seric static char	*BerkLocal[] = { "o", "esvax", NULL };
1441206Seric char		*MyLocName = "ESVAX";
145294Seric # endif ESVAX
146294Seric 
147294Seric # ifdef EECS40
148294Seric /* untested */
149294Seric static char	*BerkLocal[] = { "z", "eecs40", NULL };
1501206Seric char		*MyLocName = "EECS40";
151294Seric # define V6
152294Seric # endif EECS40
153294Seric 
154590Seric 
155590Seric # ifndef HASARPA
156590Seric # define ArpaLocal	NULL
157590Seric # endif HASARPA
158590Seric 
159590Seric # ifndef HASUUCP
160590Seric # define UucpLocal	NULL
161590Seric # endif HASUUCP
162590Seric 
163590Seric 
164294Seric struct mailer Mailer[] =
165294Seric {
166294Seric 	/* local mail -- must be #0 */
167294Seric 	{
168294Seric # ifdef NETV6MAIL
169294Seric 		"/usr/net/bin/v6mail",
170294Seric # else
171294Seric 		"/bin/mail",
172294Seric # endif
173294Seric 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
174294Seric 		{ "...local%mail", "-d", "$u", NULL }
175294Seric 	},
176294Seric 	/* pipes through programs -- must be #1 */
177294Seric 	{
178294Seric 		"/bin/csh",
179294Seric 		M_HDR|M_NOHOST,			EX_UNAVAIL,	NULL,
180294Seric 		{ "...prog%mail", "-fc", "$u", NULL }
181294Seric 	},
182294Seric 	/* local berkeley mail */
183294Seric 	{
184294Seric 		"/usr/net/bin/sendberkmail",
185310Seric 		M_FOPT|M_HDR|M_STRIPQ,		EX_UNAVAIL,	BerkLocal,
186294Seric 		{ "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL }
187294Seric 	},
188294Seric 	/* arpanet mail */
189294Seric 	{
190294Seric 		"/usr/lib/mailers/arpa",
191590Seric 		M_STRIPQ,			0,		ArpaLocal,
192294Seric 		{ "...arpa%mail", "$f", "$h", "$u", NULL }
193294Seric 	},
194294Seric 	/* uucp mail (cheat & use Bell's v7 mail) */
195294Seric 	{
196294Seric 		"/bin/mail",
197917Seric 		M_ROPT|M_STRIPQ,		EX_NOUSER,	UucpLocal,
198294Seric # ifdef DUMBMAIL
199294Seric 		{ "...uucp%mail", "$h!$u", NULL }
200294Seric # else
201294Seric 		{ "...uucp%mail", "-d", "$h!$u", NULL }
202294Seric # endif DUMBMAIL
203294Seric 	},
204294Seric };
205294Seric 
206294Seric # define M_LOCAL	0
207294Seric # define M_BERK		2
208294Seric # define M_ARPA		3
209294Seric # define M_UUCP		4
210294Seric 
211294Seric 
212294Seric 
213294Seric struct parsetab ParseTab[] =
214294Seric {
215294Seric 	':',	M_BERK,		P_ONE,				NULL,
216294Seric # ifdef HASARPA
217294Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
218294Seric # else
219294Seric 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
220294Seric # endif HASARPA
221294Seric 	'^',	-1,		P_MAP,				"!",
222294Seric # ifdef HASUUCP
223294Seric 	'!',	M_UUCP,		0,				NULL,
224294Seric # else
225294Seric 	'!',	M_BERK,		P_MOVE,				"csvax",
226294Seric # endif HASUUCP
227294Seric 	'.',	-1,		P_MAP|P_ONE,			":",
228294Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
229294Seric };
230294Seric /*
231294Seric **  GETNAME -- Get the current users login name.
232294Seric **
233294Seric **	This is in config.c because it is somewhat machine dependent.
234294Seric **	Examine it carefully for your installation.
235294Seric **
236294Seric **	Algorithm:
237294Seric **		See if the person is logged in.  If so, return
238294Seric **			the name s/he is logged in as.
239294Seric **		Look up the user id in /etc/passwd.  If found,
240294Seric **			return that name.
241294Seric **		Return NULL.
242294Seric **
243294Seric **	Parameters:
244294Seric **		none
245294Seric **
246294Seric **	Returns:
247294Seric **		The login name of this user.
248294Seric **		NULL if this person is noone.
249294Seric **
250294Seric **	Side Effects:
251294Seric **		none
252294Seric **
253294Seric **	Called By:
254294Seric **		main
255294Seric */
256294Seric 
257294Seric char *
258294Seric getname()
259294Seric {
260294Seric 	register char *p;
261294Seric 	register struct passwd *w;
262294Seric 	extern char *getlogin();
263294Seric 	extern struct passwd *getpwuid();
264294Seric 	static char namebuf[9];
265294Seric 
266294Seric 	p = getlogin();
267294Seric 	if (p != NULL && p[0] != '\0')
268294Seric 		return (p);
269294Seric # ifdef V6
270294Seric 	w = getpwuid(getuid() & 0377);
271294Seric # else
272294Seric 	w = getpwuid(getuid());
273294Seric # endif V6
274294Seric 	if (w != NULL)
275294Seric 	{
276294Seric 		strcpy(namebuf, w->pw_name);
277294Seric 		return (namebuf);
278294Seric 	}
279294Seric 	return (NULL);
280294Seric }
281294Seric 
282294Seric # ifdef V6
283294Seric /*
284294Seric **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
285294Seric **
286294Seric **	Returns the pathname of the user's tty.  Returns NULL if
287294Seric **	the user is not logged in or if s/he has write permission
288294Seric **	denied.
289294Seric **
290294Seric **	Parameters:
291294Seric **		none
292294Seric **
293294Seric **	Returns:
294294Seric **		pathname of the user's tty.
295294Seric **		NULL if not logged in or write permission denied.
296294Seric **
297294Seric **	Side Effects:
298294Seric **		none.
299294Seric **
300294Seric **	WARNING:
301294Seric **		Return value is in a local buffer.
302294Seric **
303294Seric **	Called By:
304294Seric **		savemail
305294Seric */
306294Seric 
307294Seric # include <sys/types.h>
308294Seric # include <sys/stat.h>
309294Seric 
310294Seric char *
311294Seric ttypath()
312294Seric {
313294Seric 	struct stat stbuf;
314294Seric 	register int i;
315294Seric 	static char pathn[] = "/dev/ttyx";
316294Seric 	extern int errno;
317294Seric 
318294Seric 	/* compute the pathname of the controlling tty */
319294Seric 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
320294Seric 	{
321294Seric 		errno = 0;
322294Seric 		return (NULL);
323294Seric 	}
324294Seric 	pathn[8] = i;
325294Seric 
326294Seric 	/* see if we have write permission */
327294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
328294Seric 	{
329294Seric 		errno = 0;
330294Seric 		return (NULL);
331294Seric 	}
332294Seric 
333294Seric 	/* see if the user is logged in */
334294Seric 	if (getlogin() == NULL)
335294Seric 		return (NULL);
336294Seric 
337294Seric 	/* looks good */
338294Seric 	return (pathn);
339294Seric }
340294Seric /*
341294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
342294Seric **
343294Seric **	This is included here because it is standard in v7, but we
344294Seric **	need it in v6.
345294Seric **
346294Seric **	Algorithm:
347294Seric **		Open /dev/null to create a descriptor.
348294Seric **		Close that descriptor.
349294Seric **		Copy the existing fd into the descriptor.
350294Seric **
351294Seric **	Parameters:
352294Seric **		fd -- the open file descriptor.
353294Seric **		type -- "r", "w", or whatever.
354294Seric **
355294Seric **	Returns:
356294Seric **		The file descriptor it creates.
357294Seric **
358294Seric **	Side Effects:
359294Seric **		none
360294Seric **
361294Seric **	Called By:
362294Seric **		deliver
363294Seric **
364294Seric **	Notes:
365294Seric **		The mode of fd must match "type".
366294Seric */
367294Seric 
368294Seric FILE *
369294Seric fdopen(fd, type)
370294Seric 	int fd;
371294Seric 	char *type;
372294Seric {
373294Seric 	register FILE *f;
374294Seric 
375294Seric 	f = fopen("/dev/null", type);
376294Seric 	close(fileno(f));
377294Seric 	fileno(f) = fd;
378294Seric 	return (f);
379294Seric }
380294Seric /*
381294Seric **  INDEX -- Return pointer to character in string
382294Seric **
383294Seric **	For V7 compatibility.
384294Seric **
385294Seric **	Parameters:
386294Seric **		s -- a string to scan.
387294Seric **		c -- a character to look for.
388294Seric **
389294Seric **	Returns:
390294Seric **		If c is in s, returns the address of the first
391294Seric **			instance of c in s.
392294Seric **		NULL if c is not in s.
393294Seric **
394294Seric **	Side Effects:
395294Seric **		none.
396294Seric */
397294Seric 
398294Seric index(s, c)
399294Seric 	register char *s;
400294Seric 	register char c;
401294Seric {
402294Seric 	while (*s != '\0')
403294Seric 	{
404294Seric 		if (*s++ == c)
405294Seric 			return (--s);
406294Seric 	}
407294Seric 	return (NULL);
408294Seric }
409294Seric # endif V6
410294Seric 
411294Seric # ifndef V6
412294Seric /*
413294Seric **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
414294Seric **
415294Seric **	Returns the pathname of the user's tty.  Returns NULL if
416294Seric **	the user is not logged in or if s/he has write permission
417294Seric **	denied.
418294Seric **
419294Seric **	Parameters:
420294Seric **		none
421294Seric **
422294Seric **	Returns:
423294Seric **		pathname of the user's tty.
424294Seric **		NULL if not logged in or write permission denied.
425294Seric **
426294Seric **	Side Effects:
427294Seric **		none.
428294Seric **
429294Seric **	WARNING:
430294Seric **		Return value is in a local buffer.
431294Seric **
432294Seric **	Called By:
433294Seric **		savemail
434294Seric */
435294Seric 
436294Seric # include <sys/types.h>
437294Seric # include <sys/stat.h>
438294Seric 
439294Seric char *
440294Seric ttypath()
441294Seric {
442294Seric 	struct stat stbuf;
443294Seric 	register char *pathn;
444294Seric 	extern int errno;
445294Seric 	extern char *ttyname();
446294Seric 
447294Seric 	/* compute the pathname of the controlling tty */
448294Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
449294Seric 	{
450294Seric 		errno = 0;
451294Seric 		return (NULL);
452294Seric 	}
453294Seric 
454294Seric 	/* see if we have write permission */
455294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
456294Seric 	{
457294Seric 		errno = 0;
458294Seric 		return (NULL);
459294Seric 	}
460294Seric 
461294Seric 	/* see if the user is logged in */
462294Seric 	if (getlogin() == NULL)
463294Seric 		return (NULL);
464294Seric 
465294Seric 	/* looks good */
466294Seric 	return (pathn);
467294Seric }
468294Seric # endif V6
469