xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 40993)
122698Sdist /*
234920Sbostic  * Copyright (c) 1983 Eric P. Allman
333728Sbostic  * Copyright (c) 1988 Regents of the University of California.
433728Sbostic  * All rights reserved.
533728Sbostic  *
633728Sbostic  * Redistribution and use in source and binary forms are permitted
734920Sbostic  * provided that the above copyright notice and this paragraph are
834920Sbostic  * duplicated in all such forms and that any documentation,
934920Sbostic  * advertising materials, and other materials related to such
1034920Sbostic  * distribution and use acknowledge that the software was developed
1134920Sbostic  * by the University of California, Berkeley.  The name of the
1234920Sbostic  * University may not be used to endorse or promote products derived
1334920Sbostic  * from this software without specific prior written permission.
1434920Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1534920Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1634920Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1733728Sbostic  */
1822698Sdist 
1922698Sdist #ifndef lint
20*40993Sbostic static char sccsid[] = "@(#)conf.c	5.25 (Berkeley) 04/19/90";
2133728Sbostic #endif /* not lint */
2222698Sdist 
2314881Seric # include <sys/ioctl.h>
2424943Seric # include <sys/param.h>
2536928Sbostic # include <pwd.h>
263309Seric # include "sendmail.h"
2740980Sbostic # include "pathnames.h"
28404Seric 
29294Seric /*
303309Seric **  CONF.C -- Sendmail Configuration Tables.
31294Seric **
32294Seric **	Defines the configuration of this installation.
33294Seric **
341388Seric **	Compilation Flags:
3514872Seric **		VMUNIX -- running on a Berkeley UNIX system.
36294Seric **
371388Seric **	Configuration Variables:
382897Seric **		HdrInfo -- a table describing well-known header fields.
392897Seric **			Each entry has the field name and some flags,
404147Seric **			which are described in sendmail.h.
414093Seric **
424093Seric **	Notes:
434093Seric **		I have tried to put almost all the reasonable
444093Seric **		configuration information into the configuration
454093Seric **		file read at runtime.  My intent is that anything
464093Seric **		here is a function of the version of UNIX you
474093Seric **		are running, or is really static -- for example
484093Seric **		the headers are a superset of widely used
494093Seric **		protocols.  If you find yourself playing with
504093Seric **		this file too much, you may be making a mistake!
51294Seric */
52294Seric 
53294Seric 
54294Seric 
55294Seric 
564437Seric /*
572897Seric **  Header info table
583057Seric **	Final (null) entry contains the flags used for any other field.
594147Seric **
604147Seric **	Not all of these are actually handled specially by sendmail
614147Seric **	at this time.  They are included as placeholders, to let
624147Seric **	you know that "someday" I intend to have sendmail do
634147Seric **	something with them.
642897Seric */
652897Seric 
662897Seric struct hdrinfo	HdrInfo[] =
672897Seric {
688060Seric 		/* originator fields, most to least significant  */
6911417Seric 	"resent-sender",	H_FROM|H_RESENT,
7011417Seric 	"resent-from",		H_FROM|H_RESENT,
7125686Seric 	"resent-reply-to",	H_FROM|H_RESENT,
729055Seric 	"sender",		H_FROM,
739055Seric 	"from",			H_FROM,
7425686Seric 	"reply-to",		H_FROM,
759055Seric 	"full-name",		H_ACHECK,
769055Seric 	"return-receipt-to",	H_FROM,
779055Seric 	"errors-to",		H_FROM,
788060Seric 		/* destination fields */
799055Seric 	"to",			H_RCPT,
8011417Seric 	"resent-to",		H_RCPT|H_RESENT,
819055Seric 	"cc",			H_RCPT,
8211417Seric 	"resent-cc",		H_RCPT|H_RESENT,
839055Seric 	"bcc",			H_RCPT|H_ACHECK,
8411417Seric 	"resent-bcc",		H_RCPT|H_ACHECK|H_RESENT,
858060Seric 		/* message identification and control */
8611417Seric 	"message-id",		0,
8711417Seric 	"resent-message-id",	H_RESENT,
889055Seric 	"message",		H_EOH,
899055Seric 	"text",			H_EOH,
9011417Seric 		/* date fields */
9111417Seric 	"date",			0,
9211417Seric 	"resent-date",		H_RESENT,
938060Seric 		/* trace fields */
949055Seric 	"received",		H_TRACE|H_FORCE,
959055Seric 	"via",			H_TRACE|H_FORCE,
969055Seric 	"mail-from",		H_TRACE|H_FORCE,
978060Seric 
989055Seric 	NULL,			0,
992897Seric };
1004166Seric 
1014166Seric 
1024166Seric /*
1034166Seric **  ARPANET error message numbers.
1044166Seric */
1054166Seric 
1067956Seric char	Arpa_Info[] =		"050";	/* arbitrary info */
1077956Seric char	Arpa_TSyserr[] =	"451";	/* some (transient) system error */
1087956Seric char	Arpa_PSyserr[] =	"554";	/* some (permanent) system error */
1097956Seric char	Arpa_Usrerr[] =		"554";	/* some (fatal) user error */
1104282Seric 
1114282Seric 
1124282Seric 
1134282Seric /*
1144282Seric **  Location of system files/databases/etc.
1154282Seric */
1164282Seric 
11740980Sbostic char	*ConfFile =	_PATH_SENDMAILCF;	/* runtime configuration */
11840980Sbostic char	*FreezeFile =	_PATH_SENDMAILFC;	/* frozen version of above */
1199039Seric 
1209064Seric 
1219064Seric 
1229039Seric /*
12324943Seric **  Miscellaneous stuff.
1249039Seric */
1259039Seric 
12624943Seric int	DtableSize =	50;		/* max open files; reset in 4.2bsd */
12740938Srick extern int la;				/* load average */
12824943Seric /*
12924943Seric **  SETDEFAULTS -- set default values
13024943Seric **
13124943Seric **	Because of the way freezing is done, these must be initialized
13224943Seric **	using direct code.
13324943Seric **
13424943Seric **	Parameters:
13524943Seric **		none.
13624943Seric **
13724943Seric **	Returns:
13824943Seric **		none.
13924943Seric **
14024943Seric **	Side Effects:
14124943Seric **		Initializes a bunch of global variables to their
14224943Seric **		default values.
14324943Seric */
14424943Seric 
14524943Seric setdefaults()
14624943Seric {
14724943Seric 	QueueLA = 8;
14824943Seric 	QueueFactor = 10000;
14924943Seric 	RefuseLA = 12;
15024943Seric 	SpaceSub = ' ';
15124981Seric 	WkRecipFact = 1000;
15224981Seric 	WkClassFact = 1800;
15325812Seric 	WkTimeFact = 9000;
15424981Seric 	FileMode = 0644;
15524981Seric 	DefUid = 1;
15624981Seric 	DefGid = 1;
15740973Sbostic 	setdefuser();
15824943Seric }
159294Seric 
16040973Sbostic 
1614326Seric /*
16240973Sbostic **  SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
16340973Sbostic */
16440973Sbostic 
16540973Sbostic setdefuser()
16640973Sbostic {
16740973Sbostic 	struct passwd *defpwent;
16840973Sbostic 
16940973Sbostic 	if (DefUser != NULL)
17040973Sbostic 		free(DefUser);
17140973Sbostic 	if ((defpwent = getpwuid(DefUid)) != NULL)
17240973Sbostic 		DefUser = newstr(defpwent->pw_name);
17340973Sbostic 	else
17440973Sbostic 		DefUser = newstr("nobody");
17540973Sbostic }
17640973Sbostic 
17740973Sbostic 
17840973Sbostic /*
1794326Seric **  GETRUID -- get real user id (V7)
1804326Seric */
1814326Seric 
1824326Seric getruid()
1834326Seric {
1849274Seric 	if (OpMode == MD_DAEMON)
1854536Seric 		return (RealUid);
1864536Seric 	else
1874536Seric 		return (getuid());
1884326Seric }
1894326Seric 
1904326Seric 
1914326Seric /*
1924326Seric **  GETRGID -- get real group id (V7).
1934326Seric */
1944326Seric 
1954326Seric getrgid()
1964326Seric {
1979274Seric 	if (OpMode == MD_DAEMON)
1984536Seric 		return (RealGid);
1994536Seric 	else
2004536Seric 		return (getgid());
2014326Seric }
2024326Seric 
20333936Sbostic /*
2049369Seric **  USERNAME -- return the user id of the logged in user.
2059369Seric **
2069369Seric **	Parameters:
2079369Seric **		none.
2089369Seric **
2099369Seric **	Returns:
2109369Seric **		The login name of the logged in user.
2119369Seric **
2129369Seric **	Side Effects:
2139369Seric **		none.
2149369Seric **
2159369Seric **	Notes:
2169369Seric **		The return value is statically allocated.
2179369Seric */
2189369Seric 
2199369Seric char *
2209369Seric username()
2219369Seric {
22217469Seric 	static char *myname = NULL;
2239369Seric 	extern char *getlogin();
22419904Smiriam 	register struct passwd *pw;
22519904Smiriam 	extern struct passwd *getpwuid();
2269369Seric 
22717469Seric 	/* cache the result */
22817469Seric 	if (myname == NULL)
22917469Seric 	{
23017469Seric 		myname = getlogin();
23117469Seric 		if (myname == NULL || myname[0] == '\0')
23217469Seric 		{
23317469Seric 
23417469Seric 			pw = getpwuid(getruid());
23517469Seric 			if (pw != NULL)
236*40993Sbostic 				myname = newstr(pw->pw_name);
23717469Seric 		}
23819904Smiriam 		else
23919904Smiriam 		{
24019873Smiriam 
241*40993Sbostic 			myname = newstr(myname);
242*40993Sbostic 			if ((pw = getpwnam(myname)) == NULL ||
243*40993Sbostic 			      getuid() != pw->pw_uid)
24419904Smiriam 			{
24519873Smiriam 				pw = getpwuid(getuid());
24624945Seric 				if (pw != NULL)
247*40993Sbostic 					myname = newstr(pw->pw_name);
24819873Smiriam 			}
24919873Smiriam 		}
25017469Seric 		if (myname == NULL || myname[0] == '\0')
25117469Seric 		{
25217469Seric 			syserr("Who are you?");
25317469Seric 			myname = "postmaster";
25417469Seric 		}
25517469Seric 	}
25617469Seric 
25717469Seric 	return (myname);
2589369Seric }
2599369Seric /*
2604190Seric **  TTYPATH -- Get the path of the user's tty
261294Seric **
262294Seric **	Returns the pathname of the user's tty.  Returns NULL if
263294Seric **	the user is not logged in or if s/he has write permission
264294Seric **	denied.
265294Seric **
266294Seric **	Parameters:
267294Seric **		none
268294Seric **
269294Seric **	Returns:
270294Seric **		pathname of the user's tty.
271294Seric **		NULL if not logged in or write permission denied.
272294Seric **
273294Seric **	Side Effects:
274294Seric **		none.
275294Seric **
276294Seric **	WARNING:
277294Seric **		Return value is in a local buffer.
278294Seric **
279294Seric **	Called By:
280294Seric **		savemail
281294Seric */
282294Seric 
283294Seric # include <sys/stat.h>
284294Seric 
285294Seric char *
286294Seric ttypath()
287294Seric {
288294Seric 	struct stat stbuf;
289294Seric 	register char *pathn;
290294Seric 	extern char *ttyname();
2914081Seric 	extern char *getlogin();
292294Seric 
293294Seric 	/* compute the pathname of the controlling tty */
2949369Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
2959369Seric 	    (pathn = ttyname(0)) == NULL)
296294Seric 	{
297294Seric 		errno = 0;
298294Seric 		return (NULL);
299294Seric 	}
300294Seric 
301294Seric 	/* see if we have write permission */
3022967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
303294Seric 	{
304294Seric 		errno = 0;
305294Seric 		return (NULL);
306294Seric 	}
307294Seric 
308294Seric 	/* see if the user is logged in */
309294Seric 	if (getlogin() == NULL)
310294Seric 		return (NULL);
311294Seric 
312294Seric 	/* looks good */
313294Seric 	return (pathn);
314294Seric }
3152967Seric /*
3162967Seric **  CHECKCOMPAT -- check for From and To person compatible.
3172967Seric **
3182967Seric **	This routine can be supplied on a per-installation basis
3192967Seric **	to determine whether a person is allowed to send a message.
3202967Seric **	This allows restriction of certain types of internet
3212967Seric **	forwarding or registration of users.
3222967Seric **
3232967Seric **	If the hosts are found to be incompatible, an error
3242967Seric **	message should be given using "usrerr" and FALSE should
3252967Seric **	be returned.
3262967Seric **
3274288Seric **	'NoReturn' can be set to suppress the return-to-sender
3284288Seric **	function; this should be done on huge messages.
3294288Seric **
3302967Seric **	Parameters:
3312967Seric **		to -- the person being sent to.
3322967Seric **
3332967Seric **	Returns:
3342967Seric **		TRUE -- ok to send.
3352967Seric **		FALSE -- not ok.
3362967Seric **
3372967Seric **	Side Effects:
3382967Seric **		none (unless you include the usrerr stuff)
3392967Seric */
3402967Seric 
3412967Seric bool
3422967Seric checkcompat(to)
3432967Seric 	register ADDRESS *to;
3442967Seric {
34512133Seric # ifdef lint
34612133Seric 	if (to == NULL)
34712133Seric 		to++;
34812133Seric # endif lint
34910698Seric # ifdef EXAMPLE_CODE
35010698Seric 	/* this code is intended as an example only */
3514437Seric 	register STAB *s;
3524437Seric 
3534437Seric 	s = stab("arpa", ST_MAILER, ST_FIND);
3549369Seric 	if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
3559369Seric 	    to->q_mailer == s->s_mailer)
3564437Seric 	{
3574437Seric 		usrerr("No ARPA mail through this machine: see your system administration");
35810698Seric 		/* NoReturn = TRUE; to supress return copy */
3594437Seric 		return (FALSE);
3604437Seric 	}
36110698Seric # endif EXAMPLE_CODE
3622967Seric 	return (TRUE);
3632967Seric }
3649369Seric /*
3659369Seric **  HOLDSIGS -- arrange to hold all signals
3669369Seric **
3679369Seric **	Parameters:
3689369Seric **		none.
3699369Seric **
3709369Seric **	Returns:
3719369Seric **		none.
3729369Seric **
3739369Seric **	Side Effects:
3749369Seric **		Arranges that signals are held.
3759369Seric */
3769369Seric 
3779369Seric holdsigs()
3789369Seric {
3799369Seric }
3809369Seric /*
3819369Seric **  RLSESIGS -- arrange to release all signals
3829369Seric **
3839369Seric **	This undoes the effect of holdsigs.
3849369Seric **
3859369Seric **	Parameters:
3869369Seric **		none.
3879369Seric **
3889369Seric **	Returns:
3899369Seric **		none.
3909369Seric **
3919369Seric **	Side Effects:
3929369Seric **		Arranges that signals are released.
3939369Seric */
3949369Seric 
3959369Seric rlsesigs()
3969369Seric {
3979369Seric }
39814872Seric /*
39914872Seric **  GETLA -- get the current load average
40014872Seric **
40114881Seric **	This code stolen from la.c.
40214881Seric **
40314872Seric **	Parameters:
40414872Seric **		none.
40514872Seric **
40614872Seric **	Returns:
40714872Seric **		The current load average as an integer.
40814872Seric **
40914872Seric **	Side Effects:
41014872Seric **		none.
41114872Seric */
41214872Seric 
41338196Smckusick #ifndef sun
41414872Seric 
41538196Smckusick getla()
41638196Smckusick {
41738196Smckusick 	double avenrun[3];
41838196Smckusick 
41938196Smckusick 	if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
42038196Smckusick 		return (0);
42138196Smckusick 	return ((int) (avenrun[0] + 0.5));
42238196Smckusick }
42338196Smckusick 
42438196Smckusick #else /* sun */
42538196Smckusick 
42614872Seric #include <nlist.h>
42714872Seric 
42814872Seric struct	nlist Nl[] =
42914872Seric {
43014872Seric 	{ "_avenrun" },
43114872Seric #define	X_AVENRUN	0
43214872Seric 	{ 0 },
43314872Seric };
43414872Seric 
43540930Srick 
43640930Srick extern int la;
43740930Srick 
43814872Seric getla()
43914872Seric {
44014872Seric 	static int kmem = -1;
44124943Seric 	long avenrun[3];
44225615Seric 	extern off_t lseek();
44314872Seric 
44414872Seric 	if (kmem < 0)
44514872Seric 	{
44624945Seric 		kmem = open("/dev/kmem", 0, 0);
44714872Seric 		if (kmem < 0)
44814872Seric 			return (-1);
44923118Seric 		(void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
45014872Seric 		nlist("/vmunix", Nl);
45114872Seric 		if (Nl[0].n_type == 0)
45214872Seric 			return (-1);
45314872Seric 	}
45424945Seric 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
45523118Seric 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
45619967Seric 	{
45719967Seric 		/* thank you Ian */
45819967Seric 		return (-1);
45919967Seric 	}
46024943Seric 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
46114872Seric }
46214872Seric 
46338196Smckusick #endif /* sun */
46424943Seric /*
46524943Seric **  SHOULDQUEUE -- should this message be queued or sent?
46624943Seric **
46724943Seric **	Compares the message cost to the load average to decide.
46824943Seric **
46924943Seric **	Parameters:
47024943Seric **		pri -- the priority of the message in question.
47124943Seric **
47224943Seric **	Returns:
47324943Seric **		TRUE -- if this message should be queued up for the
47424943Seric **			time being.
47524943Seric **		FALSE -- if the load is low enough to send this message.
47624943Seric **
47724943Seric **	Side Effects:
47824943Seric **		none.
47924943Seric */
48024943Seric 
48124943Seric bool
48224943Seric shouldqueue(pri)
48324943Seric 	long pri;
48424943Seric {
48524943Seric 	if (la < QueueLA)
48624943Seric 		return (FALSE);
48724943Seric 	return (pri > (QueueFactor / (la - QueueLA + 1)));
48824943Seric }
48924943Seric /*
49024943Seric **  SETPROCTITLE -- set process title for ps
49124943Seric **
49224943Seric **	Parameters:
49324943Seric **		fmt -- a printf style format string.
49424943Seric **		a, b, c -- possible parameters to fmt.
49524943Seric **
49624943Seric **	Returns:
49724943Seric **		none.
49824943Seric **
49924943Seric **	Side Effects:
50024943Seric **		Clobbers argv of our main procedure so ps(1) will
50124943Seric **		display the title.
50224943Seric */
50324943Seric 
50424943Seric /*VARARGS1*/
50524943Seric setproctitle(fmt, a, b, c)
50624943Seric 	char *fmt;
50724943Seric {
50824943Seric # ifdef SETPROCTITLE
50924943Seric 	register char *p;
51025049Seric 	register int i;
51124943Seric 	extern char **Argv;
51224943Seric 	extern char *LastArgv;
51325049Seric 	char buf[MAXLINE];
51424943Seric 
51525049Seric 	(void) sprintf(buf, fmt, a, b, c);
51624943Seric 
51724943Seric 	/* make ps print "(sendmail)" */
51825049Seric 	p = Argv[0];
51924943Seric 	*p++ = '-';
52024943Seric 
52125049Seric 	i = strlen(buf);
52225049Seric 	if (i > LastArgv - p - 2)
52325049Seric 	{
52425049Seric 		i = LastArgv - p - 2;
52525049Seric 		buf[i] = '\0';
52625049Seric 	}
52725049Seric 	(void) strcpy(p, buf);
52825049Seric 	p += i;
52924943Seric 	while (p < LastArgv)
53024943Seric 		*p++ = ' ';
53124943Seric # endif SETPROCTITLE
53224943Seric }
53325698Seric /*
53425698Seric **  REAPCHILD -- pick up the body of my child, lest it become a zombie
53525698Seric **
53625698Seric **	Parameters:
53725698Seric **		none.
53825698Seric **
53925698Seric **	Returns:
54025698Seric **		none.
54125698Seric **
54225698Seric **	Side Effects:
54325698Seric **		Picks up extant zombies.
54425698Seric */
54525698Seric 
54625698Seric # ifdef VMUNIX
54725698Seric # include <sys/wait.h>
54825698Seric # endif VMUNIX
54925698Seric 
55025698Seric reapchild()
55125698Seric {
55225698Seric # ifdef WNOHANG
55325698Seric 	union wait status;
55425698Seric 
55525698Seric 	while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
55625698Seric 		continue;
55725698Seric # else WNOHANG
55825698Seric 	auto int status;
55925698Seric 
56025698Seric 	while (wait(&status) > 0)
56125698Seric 		continue;
56225698Seric # endif WNOHANG
56325698Seric }
564