xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 34920)
122698Sdist /*
2*34920Sbostic  * 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
7*34920Sbostic  * provided that the above copyright notice and this paragraph are
8*34920Sbostic  * duplicated in all such forms and that any documentation,
9*34920Sbostic  * advertising materials, and other materials related to such
10*34920Sbostic  * distribution and use acknowledge that the software was developed
11*34920Sbostic  * by the University of California, Berkeley.  The name of the
12*34920Sbostic  * University may not be used to endorse or promote products derived
13*34920Sbostic  * from this software without specific prior written permission.
14*34920Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15*34920Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16*34920Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1733728Sbostic  */
1822698Sdist 
1922698Sdist #ifndef lint
20*34920Sbostic static char sccsid[] = "@(#)conf.c	5.17 (Berkeley) 06/30/88";
2133728Sbostic #endif /* not lint */
2222698Sdist 
23294Seric # include <pwd.h>
2414881Seric # include <sys/ioctl.h>
2524943Seric # ifdef sun
2624943Seric # include <sys/param.h>
2724943Seric # endif sun
283309Seric # include "sendmail.h"
29404Seric 
30294Seric /*
313309Seric **  CONF.C -- Sendmail Configuration Tables.
32294Seric **
33294Seric **	Defines the configuration of this installation.
34294Seric **
351388Seric **	Compilation Flags:
3614872Seric **		VMUNIX -- running on a Berkeley UNIX system.
37294Seric **
381388Seric **	Configuration Variables:
392897Seric **		HdrInfo -- a table describing well-known header fields.
402897Seric **			Each entry has the field name and some flags,
414147Seric **			which are described in sendmail.h.
424093Seric **
434093Seric **	Notes:
444093Seric **		I have tried to put almost all the reasonable
454093Seric **		configuration information into the configuration
464093Seric **		file read at runtime.  My intent is that anything
474093Seric **		here is a function of the version of UNIX you
484093Seric **		are running, or is really static -- for example
494093Seric **		the headers are a superset of widely used
504093Seric **		protocols.  If you find yourself playing with
514093Seric **		this file too much, you may be making a mistake!
52294Seric */
53294Seric 
54294Seric 
55294Seric 
56294Seric 
574437Seric /*
582897Seric **  Header info table
593057Seric **	Final (null) entry contains the flags used for any other field.
604147Seric **
614147Seric **	Not all of these are actually handled specially by sendmail
624147Seric **	at this time.  They are included as placeholders, to let
634147Seric **	you know that "someday" I intend to have sendmail do
644147Seric **	something with them.
652897Seric */
662897Seric 
672897Seric struct hdrinfo	HdrInfo[] =
682897Seric {
698060Seric 		/* originator fields, most to least significant  */
7011417Seric 	"resent-sender",	H_FROM|H_RESENT,
7111417Seric 	"resent-from",		H_FROM|H_RESENT,
7225686Seric 	"resent-reply-to",	H_FROM|H_RESENT,
739055Seric 	"sender",		H_FROM,
749055Seric 	"from",			H_FROM,
7525686Seric 	"reply-to",		H_FROM,
769055Seric 	"full-name",		H_ACHECK,
779055Seric 	"return-receipt-to",	H_FROM,
789055Seric 	"errors-to",		H_FROM,
798060Seric 		/* destination fields */
809055Seric 	"to",			H_RCPT,
8111417Seric 	"resent-to",		H_RCPT|H_RESENT,
829055Seric 	"cc",			H_RCPT,
8311417Seric 	"resent-cc",		H_RCPT|H_RESENT,
849055Seric 	"bcc",			H_RCPT|H_ACHECK,
8511417Seric 	"resent-bcc",		H_RCPT|H_ACHECK|H_RESENT,
868060Seric 		/* message identification and control */
8711417Seric 	"message-id",		0,
8811417Seric 	"resent-message-id",	H_RESENT,
899055Seric 	"message",		H_EOH,
909055Seric 	"text",			H_EOH,
9111417Seric 		/* date fields */
9211417Seric 	"date",			0,
9311417Seric 	"resent-date",		H_RESENT,
948060Seric 		/* trace fields */
959055Seric 	"received",		H_TRACE|H_FORCE,
969055Seric 	"via",			H_TRACE|H_FORCE,
979055Seric 	"mail-from",		H_TRACE|H_FORCE,
988060Seric 
999055Seric 	NULL,			0,
1002897Seric };
1014166Seric 
1024166Seric 
1034166Seric /*
1044166Seric **  ARPANET error message numbers.
1054166Seric */
1064166Seric 
1077956Seric char	Arpa_Info[] =		"050";	/* arbitrary info */
1087956Seric char	Arpa_TSyserr[] =	"451";	/* some (transient) system error */
1097956Seric char	Arpa_PSyserr[] =	"554";	/* some (permanent) system error */
1107956Seric char	Arpa_Usrerr[] =		"554";	/* some (fatal) user error */
1114282Seric 
1124282Seric 
1134282Seric 
1144282Seric /*
1154282Seric **  Location of system files/databases/etc.
1164282Seric */
1174282Seric 
1184282Seric char	*ConfFile =	"/usr/lib/sendmail.cf";	/* runtime configuration */
1199064Seric char	*FreezeFile =	"/usr/lib/sendmail.fc";	/* frozen version of above */
1209039Seric 
1219064Seric 
1229064Seric 
1239039Seric /*
12424943Seric **  Miscellaneous stuff.
1259039Seric */
1269039Seric 
12724943Seric int	DtableSize =	50;		/* max open files; reset in 4.2bsd */
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;
15724943Seric }
158294Seric 
1594326Seric /*
1604326Seric **  GETRUID -- get real user id (V7)
1614326Seric */
1624326Seric 
1634326Seric getruid()
1644326Seric {
1659274Seric 	if (OpMode == MD_DAEMON)
1664536Seric 		return (RealUid);
1674536Seric 	else
1684536Seric 		return (getuid());
1694326Seric }
1704326Seric 
1714326Seric 
1724326Seric /*
1734326Seric **  GETRGID -- get real group id (V7).
1744326Seric */
1754326Seric 
1764326Seric getrgid()
1774326Seric {
1789274Seric 	if (OpMode == MD_DAEMON)
1794536Seric 		return (RealGid);
1804536Seric 	else
1814536Seric 		return (getgid());
1824326Seric }
1834326Seric 
18433936Sbostic /*
1859369Seric **  USERNAME -- return the user id of the logged in user.
1869369Seric **
1879369Seric **	Parameters:
1889369Seric **		none.
1899369Seric **
1909369Seric **	Returns:
1919369Seric **		The login name of the logged in user.
1929369Seric **
1939369Seric **	Side Effects:
1949369Seric **		none.
1959369Seric **
1969369Seric **	Notes:
1979369Seric **		The return value is statically allocated.
1989369Seric */
1999369Seric 
2009369Seric char *
2019369Seric username()
2029369Seric {
20317469Seric 	static char *myname = NULL;
2049369Seric 	extern char *getlogin();
20519904Smiriam 	register struct passwd *pw;
20619904Smiriam 	extern struct passwd *getpwuid();
2079369Seric 
20817469Seric 	/* cache the result */
20917469Seric 	if (myname == NULL)
21017469Seric 	{
21117469Seric 		myname = getlogin();
21217469Seric 		if (myname == NULL || myname[0] == '\0')
21317469Seric 		{
21417469Seric 
21517469Seric 			pw = getpwuid(getruid());
21617469Seric 			if (pw != NULL)
21717469Seric 				myname = pw->pw_name;
21817469Seric 		}
21919904Smiriam 		else
22019904Smiriam 		{
22119873Smiriam 
22219873Smiriam 			pw = getpwnam(myname);
22319904Smiriam 			if(getuid() != pw->pw_uid)
22419904Smiriam 			{
22519873Smiriam 				pw = getpwuid(getuid());
22624945Seric 				if (pw != NULL)
22724945Seric 					myname = pw->pw_name;
22819873Smiriam 			}
22919873Smiriam 		}
23017469Seric 		if (myname == NULL || myname[0] == '\0')
23117469Seric 		{
23217469Seric 			syserr("Who are you?");
23317469Seric 			myname = "postmaster";
23417469Seric 		}
23517469Seric 	}
23617469Seric 
23717469Seric 	return (myname);
2389369Seric }
2399369Seric /*
2404190Seric **  TTYPATH -- Get the path of the user's tty
241294Seric **
242294Seric **	Returns the pathname of the user's tty.  Returns NULL if
243294Seric **	the user is not logged in or if s/he has write permission
244294Seric **	denied.
245294Seric **
246294Seric **	Parameters:
247294Seric **		none
248294Seric **
249294Seric **	Returns:
250294Seric **		pathname of the user's tty.
251294Seric **		NULL if not logged in or write permission denied.
252294Seric **
253294Seric **	Side Effects:
254294Seric **		none.
255294Seric **
256294Seric **	WARNING:
257294Seric **		Return value is in a local buffer.
258294Seric **
259294Seric **	Called By:
260294Seric **		savemail
261294Seric */
262294Seric 
263294Seric # include <sys/stat.h>
264294Seric 
265294Seric char *
266294Seric ttypath()
267294Seric {
268294Seric 	struct stat stbuf;
269294Seric 	register char *pathn;
270294Seric 	extern char *ttyname();
2714081Seric 	extern char *getlogin();
272294Seric 
273294Seric 	/* compute the pathname of the controlling tty */
2749369Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
2759369Seric 	    (pathn = ttyname(0)) == NULL)
276294Seric 	{
277294Seric 		errno = 0;
278294Seric 		return (NULL);
279294Seric 	}
280294Seric 
281294Seric 	/* see if we have write permission */
2822967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
283294Seric 	{
284294Seric 		errno = 0;
285294Seric 		return (NULL);
286294Seric 	}
287294Seric 
288294Seric 	/* see if the user is logged in */
289294Seric 	if (getlogin() == NULL)
290294Seric 		return (NULL);
291294Seric 
292294Seric 	/* looks good */
293294Seric 	return (pathn);
294294Seric }
2952967Seric /*
2962967Seric **  CHECKCOMPAT -- check for From and To person compatible.
2972967Seric **
2982967Seric **	This routine can be supplied on a per-installation basis
2992967Seric **	to determine whether a person is allowed to send a message.
3002967Seric **	This allows restriction of certain types of internet
3012967Seric **	forwarding or registration of users.
3022967Seric **
3032967Seric **	If the hosts are found to be incompatible, an error
3042967Seric **	message should be given using "usrerr" and FALSE should
3052967Seric **	be returned.
3062967Seric **
3074288Seric **	'NoReturn' can be set to suppress the return-to-sender
3084288Seric **	function; this should be done on huge messages.
3094288Seric **
3102967Seric **	Parameters:
3112967Seric **		to -- the person being sent to.
3122967Seric **
3132967Seric **	Returns:
3142967Seric **		TRUE -- ok to send.
3152967Seric **		FALSE -- not ok.
3162967Seric **
3172967Seric **	Side Effects:
3182967Seric **		none (unless you include the usrerr stuff)
3192967Seric */
3202967Seric 
3212967Seric bool
3222967Seric checkcompat(to)
3232967Seric 	register ADDRESS *to;
3242967Seric {
32512133Seric # ifdef lint
32612133Seric 	if (to == NULL)
32712133Seric 		to++;
32812133Seric # endif lint
32910698Seric # ifdef EXAMPLE_CODE
33010698Seric 	/* this code is intended as an example only */
3314437Seric 	register STAB *s;
3324437Seric 
3334437Seric 	s = stab("arpa", ST_MAILER, ST_FIND);
3349369Seric 	if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
3359369Seric 	    to->q_mailer == s->s_mailer)
3364437Seric 	{
3374437Seric 		usrerr("No ARPA mail through this machine: see your system administration");
33810698Seric 		/* NoReturn = TRUE; to supress return copy */
3394437Seric 		return (FALSE);
3404437Seric 	}
34110698Seric # endif EXAMPLE_CODE
3422967Seric 	return (TRUE);
3432967Seric }
3449369Seric /*
3459369Seric **  HOLDSIGS -- arrange to hold all signals
3469369Seric **
3479369Seric **	Parameters:
3489369Seric **		none.
3499369Seric **
3509369Seric **	Returns:
3519369Seric **		none.
3529369Seric **
3539369Seric **	Side Effects:
3549369Seric **		Arranges that signals are held.
3559369Seric */
3569369Seric 
3579369Seric holdsigs()
3589369Seric {
3599369Seric }
3609369Seric /*
3619369Seric **  RLSESIGS -- arrange to release all signals
3629369Seric **
3639369Seric **	This undoes the effect of holdsigs.
3649369Seric **
3659369Seric **	Parameters:
3669369Seric **		none.
3679369Seric **
3689369Seric **	Returns:
3699369Seric **		none.
3709369Seric **
3719369Seric **	Side Effects:
3729369Seric **		Arranges that signals are released.
3739369Seric */
3749369Seric 
3759369Seric rlsesigs()
3769369Seric {
3779369Seric }
37814872Seric /*
37914872Seric **  GETLA -- get the current load average
38014872Seric **
38114881Seric **	This code stolen from la.c.
38214881Seric **
38314872Seric **	Parameters:
38414872Seric **		none.
38514872Seric **
38614872Seric **	Returns:
38714872Seric **		The current load average as an integer.
38814872Seric **
38914872Seric **	Side Effects:
39014872Seric **		none.
39114872Seric */
39214872Seric 
39314872Seric #ifdef VMUNIX
39414872Seric 
39514872Seric #include <nlist.h>
39614872Seric 
39714872Seric struct	nlist Nl[] =
39814872Seric {
39914872Seric 	{ "_avenrun" },
40014872Seric #define	X_AVENRUN	0
40114872Seric 	{ 0 },
40214872Seric };
40314872Seric 
40414872Seric getla()
40514872Seric {
40614872Seric 	static int kmem = -1;
40724943Seric # ifdef sun
40824943Seric 	long avenrun[3];
40924943Seric # else
41014872Seric 	double avenrun[3];
41124943Seric # endif
41225615Seric 	extern off_t lseek();
41314872Seric 
41414872Seric 	if (kmem < 0)
41514872Seric 	{
41624945Seric 		kmem = open("/dev/kmem", 0, 0);
41714872Seric 		if (kmem < 0)
41814872Seric 			return (-1);
41923118Seric 		(void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
42014872Seric 		nlist("/vmunix", Nl);
42114872Seric 		if (Nl[0].n_type == 0)
42214872Seric 			return (-1);
42314872Seric 	}
42424945Seric 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
42523118Seric 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
42619967Seric 	{
42719967Seric 		/* thank you Ian */
42819967Seric 		return (-1);
42919967Seric 	}
43024943Seric # ifdef sun
43124943Seric 	return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
43224943Seric # else
43314872Seric 	return ((int) (avenrun[0] + 0.5));
43424943Seric # endif
43514872Seric }
43614872Seric 
43714872Seric #else VMUNIX
43814872Seric 
43914872Seric getla()
44014872Seric {
44114872Seric 	return (0);
44214872Seric }
44314872Seric 
44414872Seric #endif VMUNIX
44524943Seric /*
44624943Seric **  SHOULDQUEUE -- should this message be queued or sent?
44724943Seric **
44824943Seric **	Compares the message cost to the load average to decide.
44924943Seric **
45024943Seric **	Parameters:
45124943Seric **		pri -- the priority of the message in question.
45224943Seric **
45324943Seric **	Returns:
45424943Seric **		TRUE -- if this message should be queued up for the
45524943Seric **			time being.
45624943Seric **		FALSE -- if the load is low enough to send this message.
45724943Seric **
45824943Seric **	Side Effects:
45924943Seric **		none.
46024943Seric */
46124943Seric 
46224943Seric bool
46324943Seric shouldqueue(pri)
46424943Seric 	long pri;
46524943Seric {
46624943Seric 	int la;
46724943Seric 
46824943Seric 	la = getla();
46924943Seric 	if (la < QueueLA)
47024943Seric 		return (FALSE);
47124943Seric 	return (pri > (QueueFactor / (la - QueueLA + 1)));
47224943Seric }
47324943Seric /*
47424943Seric **  SETPROCTITLE -- set process title for ps
47524943Seric **
47624943Seric **	Parameters:
47724943Seric **		fmt -- a printf style format string.
47824943Seric **		a, b, c -- possible parameters to fmt.
47924943Seric **
48024943Seric **	Returns:
48124943Seric **		none.
48224943Seric **
48324943Seric **	Side Effects:
48424943Seric **		Clobbers argv of our main procedure so ps(1) will
48524943Seric **		display the title.
48624943Seric */
48724943Seric 
48824943Seric /*VARARGS1*/
48924943Seric setproctitle(fmt, a, b, c)
49024943Seric 	char *fmt;
49124943Seric {
49224943Seric # ifdef SETPROCTITLE
49324943Seric 	register char *p;
49425049Seric 	register int i;
49524943Seric 	extern char **Argv;
49624943Seric 	extern char *LastArgv;
49725049Seric 	char buf[MAXLINE];
49824943Seric 
49925049Seric 	(void) sprintf(buf, fmt, a, b, c);
50024943Seric 
50124943Seric 	/* make ps print "(sendmail)" */
50225049Seric 	p = Argv[0];
50324943Seric 	*p++ = '-';
50424943Seric 
50525049Seric 	i = strlen(buf);
50625049Seric 	if (i > LastArgv - p - 2)
50725049Seric 	{
50825049Seric 		i = LastArgv - p - 2;
50925049Seric 		buf[i] = '\0';
51025049Seric 	}
51125049Seric 	(void) strcpy(p, buf);
51225049Seric 	p += i;
51324943Seric 	while (p < LastArgv)
51424943Seric 		*p++ = ' ';
51524943Seric # endif SETPROCTITLE
51624943Seric }
51725698Seric /*
51825698Seric **  REAPCHILD -- pick up the body of my child, lest it become a zombie
51925698Seric **
52025698Seric **	Parameters:
52125698Seric **		none.
52225698Seric **
52325698Seric **	Returns:
52425698Seric **		none.
52525698Seric **
52625698Seric **	Side Effects:
52725698Seric **		Picks up extant zombies.
52825698Seric */
52925698Seric 
53025698Seric # ifdef VMUNIX
53125698Seric # include <sys/wait.h>
53225698Seric # endif VMUNIX
53325698Seric 
53425698Seric reapchild()
53525698Seric {
53625698Seric # ifdef WNOHANG
53725698Seric 	union wait status;
53825698Seric 
53925698Seric 	while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
54025698Seric 		continue;
54125698Seric # else WNOHANG
54225698Seric 	auto int status;
54325698Seric 
54425698Seric 	while (wait(&status) > 0)
54525698Seric 		continue;
54625698Seric # endif WNOHANG
54725698Seric }
548