xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 23118)
122698Sdist /*
222698Sdist **  Sendmail
322698Sdist **  Copyright (c) 1983  Eric P. Allman
422698Sdist **  Berkeley, California
522698Sdist **
622698Sdist **  Copyright (c) 1983 Regents of the University of California.
722698Sdist **  All rights reserved.  The Berkeley software License Agreement
822698Sdist **  specifies the terms and conditions for redistribution.
922698Sdist */
1022698Sdist 
1122698Sdist #ifndef lint
12*23118Seric static char	SccsId[] = "@(#)conf.c	5.3 (Berkeley) 06/08/85";
1322698Sdist #endif not lint
1422698Sdist 
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 
514437Seric /*
522897Seric **  Header info table
533057Seric **	Final (null) entry contains the flags used for any other field.
544147Seric **
554147Seric **	Not all of these are actually handled specially by sendmail
564147Seric **	at this time.  They are included as placeholders, to let
574147Seric **	you know that "someday" I intend to have sendmail do
584147Seric **	something with them.
592897Seric */
602897Seric 
612897Seric struct hdrinfo	HdrInfo[] =
622897Seric {
638060Seric 		/* originator fields, most to least significant  */
6411417Seric 	"resent-sender",	H_FROM|H_RESENT,
6511417Seric 	"resent-from",		H_FROM|H_RESENT,
669055Seric 	"sender",		H_FROM,
679055Seric 	"from",			H_FROM,
689055Seric 	"full-name",		H_ACHECK,
699055Seric 	"return-receipt-to",	H_FROM,
709055Seric 	"errors-to",		H_FROM,
718060Seric 		/* destination fields */
729055Seric 	"to",			H_RCPT,
7311417Seric 	"resent-to",		H_RCPT|H_RESENT,
749055Seric 	"cc",			H_RCPT,
7511417Seric 	"resent-cc",		H_RCPT|H_RESENT,
769055Seric 	"bcc",			H_RCPT|H_ACHECK,
7711417Seric 	"resent-bcc",		H_RCPT|H_ACHECK|H_RESENT,
788060Seric 		/* message identification and control */
7911417Seric 	"message-id",		0,
8011417Seric 	"resent-message-id",	H_RESENT,
819055Seric 	"message",		H_EOH,
829055Seric 	"text",			H_EOH,
8311417Seric 		/* date fields */
8411417Seric 	"date",			0,
8511417Seric 	"resent-date",		H_RESENT,
868060Seric 		/* trace fields */
879055Seric 	"received",		H_TRACE|H_FORCE,
889055Seric 	"via",			H_TRACE|H_FORCE,
899055Seric 	"mail-from",		H_TRACE|H_FORCE,
908060Seric 
919055Seric 	NULL,			0,
922897Seric };
934166Seric 
944166Seric 
954166Seric /*
964166Seric **  ARPANET error message numbers.
974166Seric */
984166Seric 
997956Seric char	Arpa_Info[] =		"050";	/* arbitrary info */
1007956Seric char	Arpa_TSyserr[] =	"451";	/* some (transient) system error */
1017956Seric char	Arpa_PSyserr[] =	"554";	/* some (permanent) system error */
1027956Seric char	Arpa_Usrerr[] =		"554";	/* some (fatal) user error */
1034282Seric 
1044282Seric 
1054282Seric 
1064282Seric /*
1074282Seric **  Location of system files/databases/etc.
1084282Seric */
1094282Seric 
1104282Seric char	*ConfFile =	"/usr/lib/sendmail.cf";	/* runtime configuration */
1119064Seric char	*FreezeFile =	"/usr/lib/sendmail.fc";	/* frozen version of above */
1129039Seric 
1139064Seric 
1149064Seric 
1159039Seric /*
1169039Seric **  Some other configuration....
1179039Seric */
1189039Seric 
11916881Seric char	SpaceSub;		/* character to replace <lwsp> in addrs */
12016881Seric int	QueueLA;		/* load avg > QueueLA -> just queue */
12116881Seric int	RefuseLA;		/* load avg > RefuseLA -> refuse connections */
122294Seric 
123294Seric # ifdef V6
124294Seric /*
1254190Seric **  TTYNAME -- return name of terminal.
126294Seric **
127294Seric **	Parameters:
1284190Seric **		fd -- file descriptor to check.
129294Seric **
130294Seric **	Returns:
1314190Seric **		pointer to full path of tty.
1324190Seric **		NULL if no tty.
133294Seric **
134294Seric **	Side Effects:
135294Seric **		none.
136294Seric */
137294Seric 
138294Seric char *
1394190Seric ttyname(fd)
1404190Seric 	int fd;
141294Seric {
1424190Seric 	register char tn;
143294Seric 	static char pathn[] = "/dev/ttyx";
144294Seric 
145294Seric 	/* compute the pathname of the controlling tty */
1464190Seric 	if ((tn = ttyn(fd)) == NULL)
147294Seric 	{
148294Seric 		errno = 0;
149294Seric 		return (NULL);
150294Seric 	}
1514190Seric 	pathn[8] = tn;
152294Seric 	return (pathn);
153294Seric }
154294Seric /*
155294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
156294Seric **
157294Seric **	This is included here because it is standard in v7, but we
158294Seric **	need it in v6.
159294Seric **
160294Seric **	Algorithm:
161294Seric **		Open /dev/null to create a descriptor.
162294Seric **		Close that descriptor.
163294Seric **		Copy the existing fd into the descriptor.
164294Seric **
165294Seric **	Parameters:
166294Seric **		fd -- the open file descriptor.
167294Seric **		type -- "r", "w", or whatever.
168294Seric **
169294Seric **	Returns:
170294Seric **		The file descriptor it creates.
171294Seric **
172294Seric **	Side Effects:
173294Seric **		none
174294Seric **
175294Seric **	Called By:
176294Seric **		deliver
177294Seric **
178294Seric **	Notes:
179294Seric **		The mode of fd must match "type".
180294Seric */
181294Seric 
182294Seric FILE *
183294Seric fdopen(fd, type)
184294Seric 	int fd;
185294Seric 	char *type;
186294Seric {
187294Seric 	register FILE *f;
188294Seric 
189294Seric 	f = fopen("/dev/null", type);
1904081Seric 	(void) close(fileno(f));
191294Seric 	fileno(f) = fd;
192294Seric 	return (f);
193294Seric }
194294Seric /*
195294Seric **  INDEX -- Return pointer to character in string
196294Seric **
197294Seric **	For V7 compatibility.
198294Seric **
199294Seric **	Parameters:
200294Seric **		s -- a string to scan.
201294Seric **		c -- a character to look for.
202294Seric **
203294Seric **	Returns:
204294Seric **		If c is in s, returns the address of the first
205294Seric **			instance of c in s.
206294Seric **		NULL if c is not in s.
207294Seric **
208294Seric **	Side Effects:
209294Seric **		none.
210294Seric */
211294Seric 
2124437Seric char *
213294Seric index(s, c)
214294Seric 	register char *s;
215294Seric 	register char c;
216294Seric {
217294Seric 	while (*s != '\0')
218294Seric 	{
219294Seric 		if (*s++ == c)
220294Seric 			return (--s);
221294Seric 	}
222294Seric 	return (NULL);
223294Seric }
2244326Seric /*
2254326Seric **  UMASK -- fake the umask system call.
2264326Seric **
2274326Seric **	Since V6 always acts like the umask is zero, we will just
2284326Seric **	assume the same thing.
2294326Seric */
2304326Seric 
2314326Seric /*ARGSUSED*/
2324326Seric umask(nmask)
2334326Seric {
2344326Seric 	return (0);
2354326Seric }
2364326Seric 
2374326Seric 
2384326Seric /*
2394326Seric **  GETRUID -- get real user id.
2404326Seric */
2414326Seric 
2424326Seric getruid()
2434326Seric {
2444326Seric 	return (getuid() & 0377);
2454326Seric }
2464326Seric 
2474326Seric 
2484326Seric /*
2494326Seric **  GETRGID -- get real group id.
2504326Seric */
2514326Seric 
2524326Seric getrgid()
2534326Seric {
2544326Seric 	return (getgid() & 0377);
2554326Seric }
2564326Seric 
2574326Seric 
2584326Seric /*
2594326Seric **  GETEUID -- get effective user id.
2604326Seric */
2614326Seric 
2624326Seric geteuid()
2634326Seric {
2644326Seric 	return ((getuid() >> 8) & 0377);
2654326Seric }
2664326Seric 
2674326Seric 
2684326Seric /*
2694326Seric **  GETEGID -- get effective group id.
2704326Seric */
2714326Seric 
2724326Seric getegid()
2734326Seric {
2744326Seric 	return ((getgid() >> 8) & 0377);
2754326Seric }
2764326Seric 
277294Seric # endif V6
2784326Seric 
2794326Seric # ifndef V6
2804326Seric 
2814326Seric /*
2824326Seric **  GETRUID -- get real user id (V7)
2834326Seric */
2844326Seric 
2854326Seric getruid()
2864326Seric {
2879274Seric 	if (OpMode == MD_DAEMON)
2884536Seric 		return (RealUid);
2894536Seric 	else
2904536Seric 		return (getuid());
2914326Seric }
2924326Seric 
2934326Seric 
2944326Seric /*
2954326Seric **  GETRGID -- get real group id (V7).
2964326Seric */
2974326Seric 
2984326Seric getrgid()
2994326Seric {
3009274Seric 	if (OpMode == MD_DAEMON)
3014536Seric 		return (RealGid);
3024536Seric 	else
3034536Seric 		return (getgid());
3044326Seric }
3054326Seric 
3064326Seric # endif V6
3074190Seric /*
3089369Seric **  USERNAME -- return the user id of the logged in user.
3099369Seric **
3109369Seric **	Parameters:
3119369Seric **		none.
3129369Seric **
3139369Seric **	Returns:
3149369Seric **		The login name of the logged in user.
3159369Seric **
3169369Seric **	Side Effects:
3179369Seric **		none.
3189369Seric **
3199369Seric **	Notes:
3209369Seric **		The return value is statically allocated.
3219369Seric */
3229369Seric 
3239369Seric char *
3249369Seric username()
3259369Seric {
32617469Seric 	static char *myname = NULL;
3279369Seric 	extern char *getlogin();
32819904Smiriam 	register struct passwd *pw;
32919904Smiriam 	extern struct passwd *getpwuid();
3309369Seric 
33117469Seric 	/* cache the result */
33217469Seric 	if (myname == NULL)
33317469Seric 	{
33417469Seric 		myname = getlogin();
33517469Seric 		if (myname == NULL || myname[0] == '\0')
33617469Seric 		{
33717469Seric 
33817469Seric 			pw = getpwuid(getruid());
33917469Seric 			if (pw != NULL)
34017469Seric 				myname = pw->pw_name;
34117469Seric 		}
34219904Smiriam 		else
34319904Smiriam 		{
34419873Smiriam 
34519873Smiriam 			pw = getpwnam(myname);
34619904Smiriam 			if(getuid() != pw->pw_uid)
34719904Smiriam 			{
34819873Smiriam 				pw = getpwuid(getuid());
34919873Smiriam 				myname = pw->pw_name;
35019873Smiriam 			}
35119873Smiriam 		}
35217469Seric 		if (myname == NULL || myname[0] == '\0')
35317469Seric 		{
35417469Seric 			syserr("Who are you?");
35517469Seric 			myname = "postmaster";
35617469Seric 		}
35717469Seric 	}
35817469Seric 
35917469Seric 	return (myname);
3609369Seric }
3619369Seric /*
3624190Seric **  TTYPATH -- Get the path of the user's tty
363294Seric **
364294Seric **	Returns the pathname of the user's tty.  Returns NULL if
365294Seric **	the user is not logged in or if s/he has write permission
366294Seric **	denied.
367294Seric **
368294Seric **	Parameters:
369294Seric **		none
370294Seric **
371294Seric **	Returns:
372294Seric **		pathname of the user's tty.
373294Seric **		NULL if not logged in or write permission denied.
374294Seric **
375294Seric **	Side Effects:
376294Seric **		none.
377294Seric **
378294Seric **	WARNING:
379294Seric **		Return value is in a local buffer.
380294Seric **
381294Seric **	Called By:
382294Seric **		savemail
383294Seric */
384294Seric 
385294Seric # include <sys/stat.h>
386294Seric 
387294Seric char *
388294Seric ttypath()
389294Seric {
390294Seric 	struct stat stbuf;
391294Seric 	register char *pathn;
392294Seric 	extern char *ttyname();
3934081Seric 	extern char *getlogin();
394294Seric 
395294Seric 	/* compute the pathname of the controlling tty */
3969369Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
3979369Seric 	    (pathn = ttyname(0)) == NULL)
398294Seric 	{
399294Seric 		errno = 0;
400294Seric 		return (NULL);
401294Seric 	}
402294Seric 
403294Seric 	/* see if we have write permission */
4042967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
405294Seric 	{
406294Seric 		errno = 0;
407294Seric 		return (NULL);
408294Seric 	}
409294Seric 
410294Seric 	/* see if the user is logged in */
411294Seric 	if (getlogin() == NULL)
412294Seric 		return (NULL);
413294Seric 
414294Seric 	/* looks good */
415294Seric 	return (pathn);
416294Seric }
4172967Seric /*
4182967Seric **  CHECKCOMPAT -- check for From and To person compatible.
4192967Seric **
4202967Seric **	This routine can be supplied on a per-installation basis
4212967Seric **	to determine whether a person is allowed to send a message.
4222967Seric **	This allows restriction of certain types of internet
4232967Seric **	forwarding or registration of users.
4242967Seric **
4252967Seric **	If the hosts are found to be incompatible, an error
4262967Seric **	message should be given using "usrerr" and FALSE should
4272967Seric **	be returned.
4282967Seric **
4294288Seric **	'NoReturn' can be set to suppress the return-to-sender
4304288Seric **	function; this should be done on huge messages.
4314288Seric **
4322967Seric **	Parameters:
4332967Seric **		to -- the person being sent to.
4342967Seric **
4352967Seric **	Returns:
4362967Seric **		TRUE -- ok to send.
4372967Seric **		FALSE -- not ok.
4382967Seric **
4392967Seric **	Side Effects:
4402967Seric **		none (unless you include the usrerr stuff)
4412967Seric */
4422967Seric 
4432967Seric bool
4442967Seric checkcompat(to)
4452967Seric 	register ADDRESS *to;
4462967Seric {
44712133Seric # ifdef lint
44812133Seric 	if (to == NULL)
44912133Seric 		to++;
45012133Seric # endif lint
45110698Seric # ifdef EXAMPLE_CODE
45210698Seric 	/* this code is intended as an example only */
4534437Seric 	register STAB *s;
4544437Seric 
4554437Seric 	s = stab("arpa", ST_MAILER, ST_FIND);
4569369Seric 	if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
4579369Seric 	    to->q_mailer == s->s_mailer)
4584437Seric 	{
4594437Seric 		usrerr("No ARPA mail through this machine: see your system administration");
46010698Seric 		/* NoReturn = TRUE; to supress return copy */
4614437Seric 		return (FALSE);
4624437Seric 	}
46310698Seric # endif EXAMPLE_CODE
4642967Seric 	return (TRUE);
4652967Seric }
4669369Seric /*
4679369Seric **  HOLDSIGS -- arrange to hold all signals
4689369Seric **
4699369Seric **	Parameters:
4709369Seric **		none.
4719369Seric **
4729369Seric **	Returns:
4739369Seric **		none.
4749369Seric **
4759369Seric **	Side Effects:
4769369Seric **		Arranges that signals are held.
4779369Seric */
4789369Seric 
4799369Seric holdsigs()
4809369Seric {
4819369Seric }
4829369Seric /*
4839369Seric **  RLSESIGS -- arrange to release all signals
4849369Seric **
4859369Seric **	This undoes the effect of holdsigs.
4869369Seric **
4879369Seric **	Parameters:
4889369Seric **		none.
4899369Seric **
4909369Seric **	Returns:
4919369Seric **		none.
4929369Seric **
4939369Seric **	Side Effects:
4949369Seric **		Arranges that signals are released.
4959369Seric */
4969369Seric 
4979369Seric rlsesigs()
4989369Seric {
4999369Seric }
50014872Seric /*
50114872Seric **  GETLA -- get the current load average
50214872Seric **
50314881Seric **	This code stolen from la.c.
50414881Seric **
50514872Seric **	Parameters:
50614872Seric **		none.
50714872Seric **
50814872Seric **	Returns:
50914872Seric **		The current load average as an integer.
51014872Seric **
51114872Seric **	Side Effects:
51214872Seric **		none.
51314872Seric */
51414872Seric 
51514872Seric #ifdef VMUNIX
51614872Seric 
51714872Seric #include <nlist.h>
51814872Seric 
51914872Seric struct	nlist Nl[] =
52014872Seric {
52114872Seric 	{ "_avenrun" },
52214872Seric #define	X_AVENRUN	0
52314872Seric 	{ 0 },
52414872Seric };
52514872Seric 
52614872Seric getla()
52714872Seric {
52814872Seric 	static int kmem = -1;
52914872Seric 	double avenrun[3];
53014872Seric 
53114872Seric 	if (kmem < 0)
53214872Seric 	{
53314872Seric 		kmem = open("/dev/kmem", 0);
53414872Seric 		if (kmem < 0)
53514872Seric 			return (-1);
536*23118Seric 		(void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
53714872Seric 		nlist("/vmunix", Nl);
53814872Seric 		if (Nl[0].n_type == 0)
53914872Seric 			return (-1);
54014872Seric 	}
541*23118Seric 	if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) < 0 ||
542*23118Seric 	    read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
54319967Seric 	{
54419967Seric 		/* thank you Ian */
54519967Seric 		return (-1);
54619967Seric 	}
54714872Seric 	return ((int) (avenrun[0] + 0.5));
54814872Seric }
54914872Seric 
55014872Seric #else VMUNIX
55114872Seric 
55214872Seric getla()
55314872Seric {
55414872Seric 	return (0);
55514872Seric }
55614872Seric 
55714872Seric #endif VMUNIX
558