xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 4078)
1294Seric # include <stdio.h>
2294Seric # include <pwd.h>
33309Seric # include "sendmail.h"
4404Seric 
5294Seric /*
63309Seric **  CONF.C -- Sendmail Configuration Tables.
7294Seric **
8294Seric **	Defines the configuration of this installation.
9294Seric **
101388Seric **	Compilation Flags:
111388Seric **		NETV6MAIL -- set if you want to use "v6mail" that
121388Seric **			comes with the Berkeley network.  Normally
131388Seric **			/bin/mail will work fine, but around Berkeley
141388Seric **			we use v6mail because it is a "fixed target".
152355Seric **			Also, only v6mail has the "/dev/mail" stuff
162355Seric **			in it (for biff(1)).
171388Seric **		V6 -- running on a version 6 system.  This determines
181388Seric **			whether to define certain routines between
191388Seric **			the two systems.  If you are running a funny
201388Seric **			system, e.g., V6 with long tty names, this
211388Seric **			should be checked carefully.
22294Seric **
231388Seric **	Configuration Variables:
241388Seric **		Mailer -- a table of mailers known to the system.
253438Seric **			This should be fairly static.  The fields are:
261388Seric **			- the pathname of the mailer.
271388Seric **			- a list of flags describing the properties
281388Seric **			  of this mailer:
291388Seric **			   M_FOPT -- if set, the mailer has a picky "-f"
301388Seric **				option.  In this mode, the mailer will
311388Seric **				only accept the "-f" option if the
321388Seric **				sender is actually "root", "network",
331388Seric **				and possibly (but not necessarily) if
341388Seric **				the -f argument matches the real sender.
351388Seric **				The effect is that if the "-f" option
363309Seric **				is given to sendmail then it will be
371388Seric **				passed through (as arguments 1 & 2) to
381388Seric **				the mailer.
391388Seric **			   M_ROPT -- identical to M_FOPT, except uses
401388Seric **				-r instead.
411388Seric **			   M_QUIET -- if set, don't print a message if
421388Seric **				the mailer returns bad status.
431388Seric **			   M_RESTR -- if set, this mailer is restricted
441388Seric **				to use by "daemon"; otherwise, we do a
451388Seric **				setuid(getuid()) before calling the
461388Seric **				mailer.
473185Seric **			   M_NHDR -- if set, the mailer doesn't want us
483185Seric **				to insert a UNIX "From" line before
491388Seric **				outputing.
501388Seric **			   M_NOHOST -- if set, this mailer doesn't care
511388Seric **				about the host part (e.g., the local
521388Seric **				mailer).
531388Seric **			   M_STRIPQ -- if set, strip quote (`"')
541388Seric **				characters out of parameters as you
551388Seric **				transliterate them into the argument
561388Seric **				vector.  For example, the local mailer
571388Seric **				is called directly, so these should be
581388Seric **				stripped, but the program-mailer (i.e.,
591388Seric **				csh) should leave them in.
602897Seric **			   M_NEEDDATE -- this mailer requires a Date:
612897Seric **				field in the message.
622897Seric **			   M_NEEDFROM -- this mailer requires a From:
632897Seric **				field in the message.
642897Seric **			   M_MSGID -- this mailer requires a Message-Id
652897Seric **				field in the message.
663185Seric **			   M_ARPAFMT == M_NEEDDATE|M_NEEDFROM|M_MSGID.
671388Seric **			- an exit status to use as the code for the
681388Seric **			  error message print if the mailer returns
691388Seric **			  something we don't understand.
701388Seric **			- A list of names that are to be considered
711388Seric **			  "local" (and hence are stripped off) for
721388Seric **			  this mailer.
731388Seric **			- An argument vector to be passed to the
743438Seric **			  mailer; this is macro substituted.
751388Seric **			>>>>>>>>>> Entry zero must be for the local
761388Seric **			>> NOTE >> mailer and entry one must be for
771388Seric **			>>>>>>>>>> the shell.
782897Seric **		HdrInfo -- a table describing well-known header fields.
792897Seric **			Each entry has the field name and some flags,
802897Seric **			which can be:
813057Seric **			- H_EOH -- this field is equivalent to a blank
823057Seric **			  line; i.e., it signifies end of header.
833057Seric **			- H_DELETE -- delete this field.
843057Seric **			There is also a field pointing to a pointer
853057Seric **			that should be set to point to this header.
86294Seric */
87294Seric 
88294Seric 
89294Seric 
90294Seric 
91*4078Seric static char SccsId[] = "@(#)conf.c	3.14	08/09/81";
92294Seric 
931388Seric 
941388Seric # include <whoami.h>		/* definitions of machine id's at berkeley */
951388Seric 
961573Seric # ifdef BERKELEY
972355Seric # define NETV6MAIL		/* use /usr/net/bin/v6mail for local delivery */
983061Seric # endif BERKELEY
993061Seric 
1003061Seric 
1013061Seric 
1023046Seric /* local mail -- must be #0 */
1033046Seric static char	*LocalArgv[] =
104294Seric {
1053046Seric 	"...local%mail",
1063046Seric 	"-d",
1073046Seric 	"$u",
1083046Seric 	NULL
1093046Seric };
1103046Seric 
1113046Seric static struct mailer	LocalMailer =
1123046Seric {
113294Seric # ifdef NETV6MAIL
1143185Seric 	"local",	"/usr/net/bin/v6mail",
115294Seric # else
1163185Seric 	"local",	"/bin/mail",
117294Seric # endif
1183185Seric 	M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT|M_MUSER|M_NHDR,
1193185Seric 	EX_NOUSER,	"$f",		LocalArgv,	NULL,
1203046Seric };
1213046Seric 
1223185Seric /* pipes through programs -- must be #1 -- also used for files */
1233046Seric static char	*ProgArgv[] =
1243046Seric {
1253046Seric 	"...prog%mail",
1263046Seric 	"-fc",
1273046Seric 	"$u",
1283046Seric 	NULL
1293046Seric };
1303046Seric 
1313046Seric static struct mailer	ProgMailer =
1323046Seric {
1333185Seric 	"prog",		"/bin/csh",
1343185Seric 	M_NOHOST|M_ARPAFMT,
1353185Seric 	EX_UNAVAILABLE, "$f",		ProgArgv,	NULL,
1363046Seric };
1373046Seric 
138*4078Seric /* user-private mailers -- must be #2 */
139*4078Seric static char	*PrivArgv[] =
140*4078Seric {
141*4078Seric 	"...priv%mail",
142*4078Seric 	"$u",
143*4078Seric 	NULL
144*4078Seric };
145*4078Seric 
146*4078Seric static struct mailer	PrivMailer =
147*4078Seric {
148*4078Seric 	"priv",		NULL,
149*4078Seric 	M_ROPT|M_NOHOST|M_STRIPQ|M_ARPAFMT,
150*4078Seric 	EX_UNAVAILABLE,	"$f",		PrivArgv,	NULL,
151*4078Seric };
152*4078Seric 
1533046Seric /* local berkeley mail */
1543046Seric static char	*BerkArgv[] =
1553046Seric {
1563046Seric 	"...berk%mail",
1573046Seric 	"-m",
1583046Seric 	"$h",
1593232Seric 	"-h",
1603232Seric 	"$c",
1613046Seric 	"-t",
1623046Seric 	"$u",
1633046Seric 	NULL
1643046Seric };
1653046Seric 
1663046Seric static struct mailer	BerkMailer =
1673046Seric {
1683185Seric 	"berk",		"/usr/net/bin/sendberkmail",
1693388Seric 	M_FOPT|M_NEEDDATE|M_FULLNAME|M_STRIPQ,
1703185Seric 	EX_UNAVAILABLE,	"$B:$f",	BerkArgv,	NULL,
1713046Seric };
1723046Seric 
1733046Seric /* arpanet mail */
1743046Seric static char	*ArpaArgv[] =
1753046Seric {
1763046Seric 	"...arpa%mail",
1773046Seric 	"$f",
1783046Seric 	"$h",
1793046Seric 	"$u",
1803046Seric 	NULL
1813046Seric };
1823046Seric 
1833046Seric static struct mailer	ArpaMailer =
1843046Seric {
1853185Seric 	"arpa",		"/usr/lib/mailers/arpa",
1863185Seric 	M_STRIPQ|M_ARPAFMT|M_USR_UPPER,
1873185Seric 	0,		"$f@$A",	ArpaArgv,	NULL,
1883046Seric };
1893046Seric 
1903046Seric /* uucp mail (cheat & use Bell's v7 mail) */
1913046Seric static char	*UucpArgv[] =
1923046Seric {
1933046Seric 	"...uucp%mail",
1943232Seric 	"-",
1953232Seric 	"$h!rmail",
1963232Seric 	"($u)",
1973046Seric 	NULL
198294Seric };
199294Seric 
2003046Seric static struct mailer	UucpMailer =
2013046Seric {
2023232Seric 	"uucp",		"/usr/bin/uux",
2033388Seric 	M_ROPT|M_STRIPQ|M_NEEDDATE|M_FULLNAME|M_MUSER,
2043185Seric 	EX_NOUSER,	"$U!$f",	UucpArgv,	NULL,
2053046Seric };
2063046Seric 
2073046Seric struct mailer	*Mailer[] =
2083046Seric {
2093046Seric 	&LocalMailer,		/* 0 -- must be 0 */
2103046Seric 	&ProgMailer,		/* 1 -- must be 1 */
211*4078Seric 	&PrivMailer,		/* 2 -- must be 2 */
212*4078Seric 	&BerkMailer,		/* 3 */
213*4078Seric 	&ArpaMailer,		/* 4 */
214*4078Seric 	&UucpMailer,		/* 5 */
2153144Seric 	NULL
2163046Seric };
2173046Seric 
218*4078Seric /* offsets for arbitrary mailers */
219*4078Seric # define M_BERK		2	/* berknet */
220*4078Seric # define M_ARPA		3	/* arpanet */
221*4078Seric # define M_UUCP		4	/* UUCPnet */
222294Seric 
223294Seric 
224294Seric 
2253046Seric 
2262897Seric 
2272897Seric /*
2282897Seric **  Header info table
2293057Seric **	Final (null) entry contains the flags used for any other field.
2302897Seric */
2312897Seric 
2322897Seric struct hdrinfo	HdrInfo[] =
2332897Seric {
2343384Seric 	"date",		H_CHECK,		M_NEEDDATE,
2353384Seric 	"from",		H_CHECK,		M_NEEDFROM,
2363388Seric 	"full-name",	H_ACHECK,		M_FULLNAME,
2373057Seric 	"to",		0,			NULL,
2383057Seric 	"cc",		0,			NULL,
2393057Seric 	"subject",	0,			NULL,
2403384Seric 	"message-id",	H_CHECK,		M_MSGID,
2413057Seric 	"message",	H_EOH,			NULL,
2423057Seric 	NULL,		0,			NULL,
2432897Seric };
244294Seric 
245294Seric # ifdef V6
246294Seric /*
247294Seric **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
248294Seric **
249294Seric **	Returns the pathname of the user's tty.  Returns NULL if
250294Seric **	the user is not logged in or if s/he has write permission
251294Seric **	denied.
252294Seric **
253294Seric **	Parameters:
254294Seric **		none
255294Seric **
256294Seric **	Returns:
257294Seric **		pathname of the user's tty.
258294Seric **		NULL if not logged in or write permission denied.
259294Seric **
260294Seric **	Side Effects:
261294Seric **		none.
262294Seric **
263294Seric **	WARNING:
264294Seric **		Return value is in a local buffer.
265294Seric **
266294Seric **	Called By:
267294Seric **		savemail
268294Seric */
269294Seric 
270294Seric # include <sys/types.h>
271294Seric # include <sys/stat.h>
272294Seric 
273294Seric char *
274294Seric ttypath()
275294Seric {
276294Seric 	struct stat stbuf;
277294Seric 	register int i;
278294Seric 	static char pathn[] = "/dev/ttyx";
279294Seric 	extern int errno;
280294Seric 
281294Seric 	/* compute the pathname of the controlling tty */
282294Seric 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
283294Seric 	{
284294Seric 		errno = 0;
285294Seric 		return (NULL);
286294Seric 	}
287294Seric 	pathn[8] = i;
288294Seric 
289294Seric 	/* see if we have write permission */
2902967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
291294Seric 	{
292294Seric 		errno = 0;
293294Seric 		return (NULL);
294294Seric 	}
295294Seric 
296294Seric 	/* see if the user is logged in */
297294Seric 	if (getlogin() == NULL)
298294Seric 		return (NULL);
299294Seric 
300294Seric 	/* looks good */
301294Seric 	return (pathn);
302294Seric }
303294Seric /*
304294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
305294Seric **
306294Seric **	This is included here because it is standard in v7, but we
307294Seric **	need it in v6.
308294Seric **
309294Seric **	Algorithm:
310294Seric **		Open /dev/null to create a descriptor.
311294Seric **		Close that descriptor.
312294Seric **		Copy the existing fd into the descriptor.
313294Seric **
314294Seric **	Parameters:
315294Seric **		fd -- the open file descriptor.
316294Seric **		type -- "r", "w", or whatever.
317294Seric **
318294Seric **	Returns:
319294Seric **		The file descriptor it creates.
320294Seric **
321294Seric **	Side Effects:
322294Seric **		none
323294Seric **
324294Seric **	Called By:
325294Seric **		deliver
326294Seric **
327294Seric **	Notes:
328294Seric **		The mode of fd must match "type".
329294Seric */
330294Seric 
331294Seric FILE *
332294Seric fdopen(fd, type)
333294Seric 	int fd;
334294Seric 	char *type;
335294Seric {
336294Seric 	register FILE *f;
337294Seric 
338294Seric 	f = fopen("/dev/null", type);
339294Seric 	close(fileno(f));
340294Seric 	fileno(f) = fd;
341294Seric 	return (f);
342294Seric }
343294Seric /*
344294Seric **  INDEX -- Return pointer to character in string
345294Seric **
346294Seric **	For V7 compatibility.
347294Seric **
348294Seric **	Parameters:
349294Seric **		s -- a string to scan.
350294Seric **		c -- a character to look for.
351294Seric **
352294Seric **	Returns:
353294Seric **		If c is in s, returns the address of the first
354294Seric **			instance of c in s.
355294Seric **		NULL if c is not in s.
356294Seric **
357294Seric **	Side Effects:
358294Seric **		none.
359294Seric */
360294Seric 
361294Seric index(s, c)
362294Seric 	register char *s;
363294Seric 	register char c;
364294Seric {
365294Seric 	while (*s != '\0')
366294Seric 	{
367294Seric 		if (*s++ == c)
368294Seric 			return (--s);
369294Seric 	}
370294Seric 	return (NULL);
371294Seric }
372294Seric # endif V6
373294Seric 
374294Seric # ifndef V6
375294Seric /*
376294Seric **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
377294Seric **
378294Seric **	Returns the pathname of the user's tty.  Returns NULL if
379294Seric **	the user is not logged in or if s/he has write permission
380294Seric **	denied.
381294Seric **
382294Seric **	Parameters:
383294Seric **		none
384294Seric **
385294Seric **	Returns:
386294Seric **		pathname of the user's tty.
387294Seric **		NULL if not logged in or write permission denied.
388294Seric **
389294Seric **	Side Effects:
390294Seric **		none.
391294Seric **
392294Seric **	WARNING:
393294Seric **		Return value is in a local buffer.
394294Seric **
395294Seric **	Called By:
396294Seric **		savemail
397294Seric */
398294Seric 
399294Seric # include <sys/types.h>
400294Seric # include <sys/stat.h>
401294Seric 
402294Seric char *
403294Seric ttypath()
404294Seric {
405294Seric 	struct stat stbuf;
406294Seric 	register char *pathn;
407294Seric 	extern int errno;
408294Seric 	extern char *ttyname();
409294Seric 
410294Seric 	/* compute the pathname of the controlling tty */
411294Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
412294Seric 	{
413294Seric 		errno = 0;
414294Seric 		return (NULL);
415294Seric 	}
416294Seric 
417294Seric 	/* see if we have write permission */
4182967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
419294Seric 	{
420294Seric 		errno = 0;
421294Seric 		return (NULL);
422294Seric 	}
423294Seric 
424294Seric 	/* see if the user is logged in */
425294Seric 	if (getlogin() == NULL)
426294Seric 		return (NULL);
427294Seric 
428294Seric 	/* looks good */
429294Seric 	return (pathn);
430294Seric }
431294Seric # endif V6
4322967Seric /*
4332967Seric **  CHECKCOMPAT -- check for From and To person compatible.
4342967Seric **
4352967Seric **	This routine can be supplied on a per-installation basis
4362967Seric **	to determine whether a person is allowed to send a message.
4372967Seric **	This allows restriction of certain types of internet
4382967Seric **	forwarding or registration of users.
4392967Seric **
4402967Seric **	If the hosts are found to be incompatible, an error
4412967Seric **	message should be given using "usrerr" and FALSE should
4422967Seric **	be returned.
4432967Seric **
4442967Seric **	Parameters:
4452967Seric **		to -- the person being sent to.
4462967Seric **
4472967Seric **	Returns:
4482967Seric **		TRUE -- ok to send.
4492967Seric **		FALSE -- not ok.
4502967Seric **
4512967Seric **	Side Effects:
4522967Seric **		none (unless you include the usrerr stuff)
4532967Seric */
4542967Seric 
4552967Seric bool
4562967Seric checkcompat(to)
4572967Seric 	register ADDRESS *to;
4582967Seric {
4592967Seric 	return (TRUE);
4602967Seric }
461