xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 22698)
1*22698Sdist /*
2*22698Sdist **  Sendmail
3*22698Sdist **  Copyright (c) 1983  Eric P. Allman
4*22698Sdist **  Berkeley, California
5*22698Sdist **
6*22698Sdist **  Copyright (c) 1983 Regents of the University of California.
7*22698Sdist **  All rights reserved.  The Berkeley software License Agreement
8*22698Sdist **  specifies the terms and conditions for redistribution.
9*22698Sdist */
10*22698Sdist 
11*22698Sdist #ifndef lint
12*22698Sdist static char	SccsId[] = "@(#)conf.c	5.1 (Berkeley) 06/07/85";
13*22698Sdist #endif not lint
14*22698Sdist 
15294Seric # include <pwd.h>
1614881Seric # include <sys/ioctl.h>
173309Seric # include "sendmail.h"
18404Seric 
19294Seric /*
203309Seric **  CONF.C -- Sendmail Configuration Tables.
21294Seric **
22294Seric **	Defines the configuration of this installation.
23294Seric **
241388Seric **	Compilation Flags:
251388Seric **		V6 -- running on a version 6 system.  This determines
261388Seric **			whether to define certain routines between
271388Seric **			the two systems.  If you are running a funny
281388Seric **			system, e.g., V6 with long tty names, this
291388Seric **			should be checked carefully.
3014872Seric **		VMUNIX -- running on a Berkeley UNIX system.
31294Seric **
321388Seric **	Configuration Variables:
332897Seric **		HdrInfo -- a table describing well-known header fields.
342897Seric **			Each entry has the field name and some flags,
354147Seric **			which are described in sendmail.h.
364093Seric **
374093Seric **	Notes:
384093Seric **		I have tried to put almost all the reasonable
394093Seric **		configuration information into the configuration
404093Seric **		file read at runtime.  My intent is that anything
414093Seric **		here is a function of the version of UNIX you
424093Seric **		are running, or is really static -- for example
434093Seric **		the headers are a superset of widely used
444093Seric **		protocols.  If you find yourself playing with
454093Seric **		this file too much, you may be making a mistake!
46294Seric */
47294Seric 
48294Seric 
49294Seric 
50294Seric 
51*22698Sdist SCCSID(@(#)conf.c	5.1		06/07/85);
524437Seric 
534437Seric 
544437Seric 
554437Seric /*
562897Seric **  Header info table
573057Seric **	Final (null) entry contains the flags used for any other field.
584147Seric **
594147Seric **	Not all of these are actually handled specially by sendmail
604147Seric **	at this time.  They are included as placeholders, to let
614147Seric **	you know that "someday" I intend to have sendmail do
624147Seric **	something with them.
632897Seric */
642897Seric 
652897Seric struct hdrinfo	HdrInfo[] =
662897Seric {
678060Seric 		/* originator fields, most to least significant  */
6811417Seric 	"resent-sender",	H_FROM|H_RESENT,
6911417Seric 	"resent-from",		H_FROM|H_RESENT,
709055Seric 	"sender",		H_FROM,
719055Seric 	"from",			H_FROM,
729055Seric 	"full-name",		H_ACHECK,
739055Seric 	"return-receipt-to",	H_FROM,
749055Seric 	"errors-to",		H_FROM,
758060Seric 		/* destination fields */
769055Seric 	"to",			H_RCPT,
7711417Seric 	"resent-to",		H_RCPT|H_RESENT,
789055Seric 	"cc",			H_RCPT,
7911417Seric 	"resent-cc",		H_RCPT|H_RESENT,
809055Seric 	"bcc",			H_RCPT|H_ACHECK,
8111417Seric 	"resent-bcc",		H_RCPT|H_ACHECK|H_RESENT,
828060Seric 		/* message identification and control */
8311417Seric 	"message-id",		0,
8411417Seric 	"resent-message-id",	H_RESENT,
859055Seric 	"message",		H_EOH,
869055Seric 	"text",			H_EOH,
8711417Seric 		/* date fields */
8811417Seric 	"date",			0,
8911417Seric 	"resent-date",		H_RESENT,
908060Seric 		/* trace fields */
919055Seric 	"received",		H_TRACE|H_FORCE,
929055Seric 	"via",			H_TRACE|H_FORCE,
939055Seric 	"mail-from",		H_TRACE|H_FORCE,
948060Seric 
959055Seric 	NULL,			0,
962897Seric };
974166Seric 
984166Seric 
994166Seric /*
1004166Seric **  ARPANET error message numbers.
1014166Seric */
1024166Seric 
1037956Seric char	Arpa_Info[] =		"050";	/* arbitrary info */
1047956Seric char	Arpa_TSyserr[] =	"451";	/* some (transient) system error */
1057956Seric char	Arpa_PSyserr[] =	"554";	/* some (permanent) system error */
1067956Seric char	Arpa_Usrerr[] =		"554";	/* some (fatal) user error */
1074282Seric 
1084282Seric 
1094282Seric 
1104282Seric /*
1114282Seric **  Location of system files/databases/etc.
1124282Seric */
1134282Seric 
1144282Seric char	*ConfFile =	"/usr/lib/sendmail.cf";	/* runtime configuration */
1159064Seric char	*FreezeFile =	"/usr/lib/sendmail.fc";	/* frozen version of above */
1169039Seric 
1179064Seric 
1189064Seric 
1199039Seric /*
1209039Seric **  Some other configuration....
1219039Seric */
1229039Seric 
12316881Seric char	SpaceSub;		/* character to replace <lwsp> in addrs */
12416881Seric int	QueueLA;		/* load avg > QueueLA -> just queue */
12516881Seric int	RefuseLA;		/* load avg > RefuseLA -> refuse connections */
126294Seric 
127294Seric # ifdef V6
128294Seric /*
1294190Seric **  TTYNAME -- return name of terminal.
130294Seric **
131294Seric **	Parameters:
1324190Seric **		fd -- file descriptor to check.
133294Seric **
134294Seric **	Returns:
1354190Seric **		pointer to full path of tty.
1364190Seric **		NULL if no tty.
137294Seric **
138294Seric **	Side Effects:
139294Seric **		none.
140294Seric */
141294Seric 
142294Seric char *
1434190Seric ttyname(fd)
1444190Seric 	int fd;
145294Seric {
1464190Seric 	register char tn;
147294Seric 	static char pathn[] = "/dev/ttyx";
148294Seric 
149294Seric 	/* compute the pathname of the controlling tty */
1504190Seric 	if ((tn = ttyn(fd)) == NULL)
151294Seric 	{
152294Seric 		errno = 0;
153294Seric 		return (NULL);
154294Seric 	}
1554190Seric 	pathn[8] = tn;
156294Seric 	return (pathn);
157294Seric }
158294Seric /*
159294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
160294Seric **
161294Seric **	This is included here because it is standard in v7, but we
162294Seric **	need it in v6.
163294Seric **
164294Seric **	Algorithm:
165294Seric **		Open /dev/null to create a descriptor.
166294Seric **		Close that descriptor.
167294Seric **		Copy the existing fd into the descriptor.
168294Seric **
169294Seric **	Parameters:
170294Seric **		fd -- the open file descriptor.
171294Seric **		type -- "r", "w", or whatever.
172294Seric **
173294Seric **	Returns:
174294Seric **		The file descriptor it creates.
175294Seric **
176294Seric **	Side Effects:
177294Seric **		none
178294Seric **
179294Seric **	Called By:
180294Seric **		deliver
181294Seric **
182294Seric **	Notes:
183294Seric **		The mode of fd must match "type".
184294Seric */
185294Seric 
186294Seric FILE *
187294Seric fdopen(fd, type)
188294Seric 	int fd;
189294Seric 	char *type;
190294Seric {
191294Seric 	register FILE *f;
192294Seric 
193294Seric 	f = fopen("/dev/null", type);
1944081Seric 	(void) close(fileno(f));
195294Seric 	fileno(f) = fd;
196294Seric 	return (f);
197294Seric }
198294Seric /*
199294Seric **  INDEX -- Return pointer to character in string
200294Seric **
201294Seric **	For V7 compatibility.
202294Seric **
203294Seric **	Parameters:
204294Seric **		s -- a string to scan.
205294Seric **		c -- a character to look for.
206294Seric **
207294Seric **	Returns:
208294Seric **		If c is in s, returns the address of the first
209294Seric **			instance of c in s.
210294Seric **		NULL if c is not in s.
211294Seric **
212294Seric **	Side Effects:
213294Seric **		none.
214294Seric */
215294Seric 
2164437Seric char *
217294Seric index(s, c)
218294Seric 	register char *s;
219294Seric 	register char c;
220294Seric {
221294Seric 	while (*s != '\0')
222294Seric 	{
223294Seric 		if (*s++ == c)
224294Seric 			return (--s);
225294Seric 	}
226294Seric 	return (NULL);
227294Seric }
2284326Seric /*
2294326Seric **  UMASK -- fake the umask system call.
2304326Seric **
2314326Seric **	Since V6 always acts like the umask is zero, we will just
2324326Seric **	assume the same thing.
2334326Seric */
2344326Seric 
2354326Seric /*ARGSUSED*/
2364326Seric umask(nmask)
2374326Seric {
2384326Seric 	return (0);
2394326Seric }
2404326Seric 
2414326Seric 
2424326Seric /*
2434326Seric **  GETRUID -- get real user id.
2444326Seric */
2454326Seric 
2464326Seric getruid()
2474326Seric {
2484326Seric 	return (getuid() & 0377);
2494326Seric }
2504326Seric 
2514326Seric 
2524326Seric /*
2534326Seric **  GETRGID -- get real group id.
2544326Seric */
2554326Seric 
2564326Seric getrgid()
2574326Seric {
2584326Seric 	return (getgid() & 0377);
2594326Seric }
2604326Seric 
2614326Seric 
2624326Seric /*
2634326Seric **  GETEUID -- get effective user id.
2644326Seric */
2654326Seric 
2664326Seric geteuid()
2674326Seric {
2684326Seric 	return ((getuid() >> 8) & 0377);
2694326Seric }
2704326Seric 
2714326Seric 
2724326Seric /*
2734326Seric **  GETEGID -- get effective group id.
2744326Seric */
2754326Seric 
2764326Seric getegid()
2774326Seric {
2784326Seric 	return ((getgid() >> 8) & 0377);
2794326Seric }
2804326Seric 
281294Seric # endif V6
2824326Seric 
2834326Seric # ifndef V6
2844326Seric 
2854326Seric /*
2864326Seric **  GETRUID -- get real user id (V7)
2874326Seric */
2884326Seric 
2894326Seric getruid()
2904326Seric {
2919274Seric 	if (OpMode == MD_DAEMON)
2924536Seric 		return (RealUid);
2934536Seric 	else
2944536Seric 		return (getuid());
2954326Seric }
2964326Seric 
2974326Seric 
2984326Seric /*
2994326Seric **  GETRGID -- get real group id (V7).
3004326Seric */
3014326Seric 
3024326Seric getrgid()
3034326Seric {
3049274Seric 	if (OpMode == MD_DAEMON)
3054536Seric 		return (RealGid);
3064536Seric 	else
3074536Seric 		return (getgid());
3084326Seric }
3094326Seric 
3104326Seric # endif V6
3114190Seric /*
3129369Seric **  USERNAME -- return the user id of the logged in user.
3139369Seric **
3149369Seric **	Parameters:
3159369Seric **		none.
3169369Seric **
3179369Seric **	Returns:
3189369Seric **		The login name of the logged in user.
3199369Seric **
3209369Seric **	Side Effects:
3219369Seric **		none.
3229369Seric **
3239369Seric **	Notes:
3249369Seric **		The return value is statically allocated.
3259369Seric */
3269369Seric 
3279369Seric char *
3289369Seric username()
3299369Seric {
33017469Seric 	static char *myname = NULL;
3319369Seric 	extern char *getlogin();
33219904Smiriam 	register struct passwd *pw;
33319904Smiriam 	extern struct passwd *getpwuid();
3349369Seric 
33517469Seric 	/* cache the result */
33617469Seric 	if (myname == NULL)
33717469Seric 	{
33817469Seric 		myname = getlogin();
33917469Seric 		if (myname == NULL || myname[0] == '\0')
34017469Seric 		{
34117469Seric 
34217469Seric 			pw = getpwuid(getruid());
34317469Seric 			if (pw != NULL)
34417469Seric 				myname = pw->pw_name;
34517469Seric 		}
34619904Smiriam 		else
34719904Smiriam 		{
34819873Smiriam 
34919873Smiriam 			pw = getpwnam(myname);
35019904Smiriam 			if(getuid() != pw->pw_uid)
35119904Smiriam 			{
35219873Smiriam 				pw = getpwuid(getuid());
35319873Smiriam 				myname = pw->pw_name;
35419873Smiriam 			}
35519873Smiriam 		}
35617469Seric 		if (myname == NULL || myname[0] == '\0')
35717469Seric 		{
35817469Seric 			syserr("Who are you?");
35917469Seric 			myname = "postmaster";
36017469Seric 		}
36117469Seric 	}
36217469Seric 
36317469Seric 	return (myname);
3649369Seric }
3659369Seric /*
3664190Seric **  TTYPATH -- Get the path of the user's tty
367294Seric **
368294Seric **	Returns the pathname of the user's tty.  Returns NULL if
369294Seric **	the user is not logged in or if s/he has write permission
370294Seric **	denied.
371294Seric **
372294Seric **	Parameters:
373294Seric **		none
374294Seric **
375294Seric **	Returns:
376294Seric **		pathname of the user's tty.
377294Seric **		NULL if not logged in or write permission denied.
378294Seric **
379294Seric **	Side Effects:
380294Seric **		none.
381294Seric **
382294Seric **	WARNING:
383294Seric **		Return value is in a local buffer.
384294Seric **
385294Seric **	Called By:
386294Seric **		savemail
387294Seric */
388294Seric 
389294Seric # include <sys/stat.h>
390294Seric 
391294Seric char *
392294Seric ttypath()
393294Seric {
394294Seric 	struct stat stbuf;
395294Seric 	register char *pathn;
396294Seric 	extern char *ttyname();
3974081Seric 	extern char *getlogin();
398294Seric 
399294Seric 	/* compute the pathname of the controlling tty */
4009369Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
4019369Seric 	    (pathn = ttyname(0)) == NULL)
402294Seric 	{
403294Seric 		errno = 0;
404294Seric 		return (NULL);
405294Seric 	}
406294Seric 
407294Seric 	/* see if we have write permission */
4082967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
409294Seric 	{
410294Seric 		errno = 0;
411294Seric 		return (NULL);
412294Seric 	}
413294Seric 
414294Seric 	/* see if the user is logged in */
415294Seric 	if (getlogin() == NULL)
416294Seric 		return (NULL);
417294Seric 
418294Seric 	/* looks good */
419294Seric 	return (pathn);
420294Seric }
4212967Seric /*
4222967Seric **  CHECKCOMPAT -- check for From and To person compatible.
4232967Seric **
4242967Seric **	This routine can be supplied on a per-installation basis
4252967Seric **	to determine whether a person is allowed to send a message.
4262967Seric **	This allows restriction of certain types of internet
4272967Seric **	forwarding or registration of users.
4282967Seric **
4292967Seric **	If the hosts are found to be incompatible, an error
4302967Seric **	message should be given using "usrerr" and FALSE should
4312967Seric **	be returned.
4322967Seric **
4334288Seric **	'NoReturn' can be set to suppress the return-to-sender
4344288Seric **	function; this should be done on huge messages.
4354288Seric **
4362967Seric **	Parameters:
4372967Seric **		to -- the person being sent to.
4382967Seric **
4392967Seric **	Returns:
4402967Seric **		TRUE -- ok to send.
4412967Seric **		FALSE -- not ok.
4422967Seric **
4432967Seric **	Side Effects:
4442967Seric **		none (unless you include the usrerr stuff)
4452967Seric */
4462967Seric 
4472967Seric bool
4482967Seric checkcompat(to)
4492967Seric 	register ADDRESS *to;
4502967Seric {
45112133Seric # ifdef lint
45212133Seric 	if (to == NULL)
45312133Seric 		to++;
45412133Seric # endif lint
45510698Seric # ifdef EXAMPLE_CODE
45610698Seric 	/* this code is intended as an example only */
4574437Seric 	register STAB *s;
4584437Seric 
4594437Seric 	s = stab("arpa", ST_MAILER, ST_FIND);
4609369Seric 	if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
4619369Seric 	    to->q_mailer == s->s_mailer)
4624437Seric 	{
4634437Seric 		usrerr("No ARPA mail through this machine: see your system administration");
46410698Seric 		/* NoReturn = TRUE; to supress return copy */
4654437Seric 		return (FALSE);
4664437Seric 	}
46710698Seric # endif EXAMPLE_CODE
4682967Seric 	return (TRUE);
4692967Seric }
4709369Seric /*
4719369Seric **  HOLDSIGS -- arrange to hold all signals
4729369Seric **
4739369Seric **	Parameters:
4749369Seric **		none.
4759369Seric **
4769369Seric **	Returns:
4779369Seric **		none.
4789369Seric **
4799369Seric **	Side Effects:
4809369Seric **		Arranges that signals are held.
4819369Seric */
4829369Seric 
4839369Seric holdsigs()
4849369Seric {
4859369Seric }
4869369Seric /*
4879369Seric **  RLSESIGS -- arrange to release all signals
4889369Seric **
4899369Seric **	This undoes the effect of holdsigs.
4909369Seric **
4919369Seric **	Parameters:
4929369Seric **		none.
4939369Seric **
4949369Seric **	Returns:
4959369Seric **		none.
4969369Seric **
4979369Seric **	Side Effects:
4989369Seric **		Arranges that signals are released.
4999369Seric */
5009369Seric 
5019369Seric rlsesigs()
5029369Seric {
5039369Seric }
50414872Seric /*
50514872Seric **  GETLA -- get the current load average
50614872Seric **
50714881Seric **	This code stolen from la.c.
50814881Seric **
50914872Seric **	Parameters:
51014872Seric **		none.
51114872Seric **
51214872Seric **	Returns:
51314872Seric **		The current load average as an integer.
51414872Seric **
51514872Seric **	Side Effects:
51614872Seric **		none.
51714872Seric */
51814872Seric 
51914872Seric #ifdef VMUNIX
52014872Seric 
52114872Seric #include <nlist.h>
52214872Seric 
52314872Seric struct	nlist Nl[] =
52414872Seric {
52514872Seric 	{ "_avenrun" },
52614872Seric #define	X_AVENRUN	0
52714872Seric 	{ 0 },
52814872Seric };
52914872Seric 
53014872Seric getla()
53114872Seric {
53214872Seric 	static int kmem = -1;
53314872Seric 	double avenrun[3];
53414872Seric 
53514872Seric 	if (kmem < 0)
53614872Seric 	{
53714872Seric 		kmem = open("/dev/kmem", 0);
53814872Seric 		if (kmem < 0)
53914872Seric 			return (-1);
54014881Seric 		(void) ioctl(kmem, FIOCLEX, 0);
54114872Seric 		nlist("/vmunix", Nl);
54214872Seric 		if (Nl[0].n_type == 0)
54314872Seric 			return (-1);
54414872Seric 	}
54519967Seric 	if (lseek(kmem, (long) Nl[X_AVENRUN].n_value, 0) < 0 ||
54619967Seric 	    read(kmem, avenrun, sizeof(avenrun)) < sizeof(avenrun))
54719967Seric 	{
54819967Seric 		/* thank you Ian */
54919967Seric 		return (-1);
55019967Seric 	}
55114872Seric 	return ((int) (avenrun[0] + 0.5));
55214872Seric }
55314872Seric 
55414872Seric #else VMUNIX
55514872Seric 
55614872Seric getla()
55714872Seric {
55814872Seric 	return (0);
55914872Seric }
56014872Seric 
56114872Seric #endif VMUNIX
56217469Seric /*
56317469Seric **  DBMCLOSE -- close the DBM file
56417469Seric **
56517469Seric **	This depends on the implementation of the DBM library.  It
56617469Seric **	seems to work for all versions that I have come across.
56717469Seric **
56817469Seric **	Parameters:
56917469Seric **		none.
57017469Seric **
57117469Seric **	Returns:
57217469Seric **		none.
57317469Seric **
57417469Seric **	Side Effects:
57517469Seric **		Closes the current DBM file; dbminit must be
57617469Seric **		called again to continue using the DBM routines.
57717469Seric */
57817469Seric 
57917469Seric dbmclose()
58017469Seric {
58117469Seric 	extern int pagf, dirf;	/* defined in the DBM package */
58217469Seric 
58317469Seric 	(void) close(pagf);
58417469Seric 	(void) close(dirf);
58517469Seric }
586