xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 19904)
1294Seric # include <pwd.h>
214881Seric # include <sys/ioctl.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 **		V6 -- running on a version 6 system.  This determines
121388Seric **			whether to define certain routines between
131388Seric **			the two systems.  If you are running a funny
141388Seric **			system, e.g., V6 with long tty names, this
151388Seric **			should be checked carefully.
1614872Seric **		VMUNIX -- running on a Berkeley UNIX system.
17294Seric **
181388Seric **	Configuration Variables:
192897Seric **		HdrInfo -- a table describing well-known header fields.
202897Seric **			Each entry has the field name and some flags,
214147Seric **			which are described in sendmail.h.
224093Seric **
234093Seric **	Notes:
244093Seric **		I have tried to put almost all the reasonable
254093Seric **		configuration information into the configuration
264093Seric **		file read at runtime.  My intent is that anything
274093Seric **		here is a function of the version of UNIX you
284093Seric **		are running, or is really static -- for example
294093Seric **		the headers are a superset of widely used
304093Seric **		protocols.  If you find yourself playing with
314093Seric **		this file too much, you may be making a mistake!
32294Seric */
33294Seric 
34294Seric 
35294Seric 
36294Seric 
37*19904Smiriam SCCSID(@(#)conf.c	4.8		05/01/85);
384437Seric 
394437Seric 
404437Seric 
414437Seric /*
422897Seric **  Header info table
433057Seric **	Final (null) entry contains the flags used for any other field.
444147Seric **
454147Seric **	Not all of these are actually handled specially by sendmail
464147Seric **	at this time.  They are included as placeholders, to let
474147Seric **	you know that "someday" I intend to have sendmail do
484147Seric **	something with them.
492897Seric */
502897Seric 
512897Seric struct hdrinfo	HdrInfo[] =
522897Seric {
538060Seric 		/* originator fields, most to least significant  */
5411417Seric 	"resent-sender",	H_FROM|H_RESENT,
5511417Seric 	"resent-from",		H_FROM|H_RESENT,
569055Seric 	"sender",		H_FROM,
579055Seric 	"from",			H_FROM,
589055Seric 	"full-name",		H_ACHECK,
599055Seric 	"return-receipt-to",	H_FROM,
609055Seric 	"errors-to",		H_FROM,
618060Seric 		/* destination fields */
629055Seric 	"to",			H_RCPT,
6311417Seric 	"resent-to",		H_RCPT|H_RESENT,
649055Seric 	"cc",			H_RCPT,
6511417Seric 	"resent-cc",		H_RCPT|H_RESENT,
669055Seric 	"bcc",			H_RCPT|H_ACHECK,
6711417Seric 	"resent-bcc",		H_RCPT|H_ACHECK|H_RESENT,
688060Seric 		/* message identification and control */
6911417Seric 	"message-id",		0,
7011417Seric 	"resent-message-id",	H_RESENT,
719055Seric 	"message",		H_EOH,
729055Seric 	"text",			H_EOH,
7311417Seric 		/* date fields */
7411417Seric 	"date",			0,
7511417Seric 	"resent-date",		H_RESENT,
768060Seric 		/* trace fields */
779055Seric 	"received",		H_TRACE|H_FORCE,
789055Seric 	"via",			H_TRACE|H_FORCE,
799055Seric 	"mail-from",		H_TRACE|H_FORCE,
808060Seric 
819055Seric 	NULL,			0,
822897Seric };
834166Seric 
844166Seric 
854166Seric /*
864166Seric **  ARPANET error message numbers.
874166Seric */
884166Seric 
897956Seric char	Arpa_Info[] =		"050";	/* arbitrary info */
907956Seric char	Arpa_TSyserr[] =	"451";	/* some (transient) system error */
917956Seric char	Arpa_PSyserr[] =	"554";	/* some (permanent) system error */
927956Seric char	Arpa_Usrerr[] =		"554";	/* some (fatal) user error */
934282Seric 
944282Seric 
954282Seric 
964282Seric /*
974282Seric **  Location of system files/databases/etc.
984282Seric */
994282Seric 
1004282Seric char	*ConfFile =	"/usr/lib/sendmail.cf";	/* runtime configuration */
1019064Seric char	*FreezeFile =	"/usr/lib/sendmail.fc";	/* frozen version of above */
1029039Seric 
1039064Seric 
1049064Seric 
1059039Seric /*
1069039Seric **  Some other configuration....
1079039Seric */
1089039Seric 
10916881Seric char	SpaceSub;		/* character to replace <lwsp> in addrs */
11016881Seric int	QueueLA;		/* load avg > QueueLA -> just queue */
11116881Seric int	RefuseLA;		/* load avg > RefuseLA -> refuse connections */
112294Seric 
113294Seric # ifdef V6
114294Seric /*
1154190Seric **  TTYNAME -- return name of terminal.
116294Seric **
117294Seric **	Parameters:
1184190Seric **		fd -- file descriptor to check.
119294Seric **
120294Seric **	Returns:
1214190Seric **		pointer to full path of tty.
1224190Seric **		NULL if no tty.
123294Seric **
124294Seric **	Side Effects:
125294Seric **		none.
126294Seric */
127294Seric 
128294Seric char *
1294190Seric ttyname(fd)
1304190Seric 	int fd;
131294Seric {
1324190Seric 	register char tn;
133294Seric 	static char pathn[] = "/dev/ttyx";
134294Seric 
135294Seric 	/* compute the pathname of the controlling tty */
1364190Seric 	if ((tn = ttyn(fd)) == NULL)
137294Seric 	{
138294Seric 		errno = 0;
139294Seric 		return (NULL);
140294Seric 	}
1414190Seric 	pathn[8] = tn;
142294Seric 	return (pathn);
143294Seric }
144294Seric /*
145294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
146294Seric **
147294Seric **	This is included here because it is standard in v7, but we
148294Seric **	need it in v6.
149294Seric **
150294Seric **	Algorithm:
151294Seric **		Open /dev/null to create a descriptor.
152294Seric **		Close that descriptor.
153294Seric **		Copy the existing fd into the descriptor.
154294Seric **
155294Seric **	Parameters:
156294Seric **		fd -- the open file descriptor.
157294Seric **		type -- "r", "w", or whatever.
158294Seric **
159294Seric **	Returns:
160294Seric **		The file descriptor it creates.
161294Seric **
162294Seric **	Side Effects:
163294Seric **		none
164294Seric **
165294Seric **	Called By:
166294Seric **		deliver
167294Seric **
168294Seric **	Notes:
169294Seric **		The mode of fd must match "type".
170294Seric */
171294Seric 
172294Seric FILE *
173294Seric fdopen(fd, type)
174294Seric 	int fd;
175294Seric 	char *type;
176294Seric {
177294Seric 	register FILE *f;
178294Seric 
179294Seric 	f = fopen("/dev/null", type);
1804081Seric 	(void) close(fileno(f));
181294Seric 	fileno(f) = fd;
182294Seric 	return (f);
183294Seric }
184294Seric /*
185294Seric **  INDEX -- Return pointer to character in string
186294Seric **
187294Seric **	For V7 compatibility.
188294Seric **
189294Seric **	Parameters:
190294Seric **		s -- a string to scan.
191294Seric **		c -- a character to look for.
192294Seric **
193294Seric **	Returns:
194294Seric **		If c is in s, returns the address of the first
195294Seric **			instance of c in s.
196294Seric **		NULL if c is not in s.
197294Seric **
198294Seric **	Side Effects:
199294Seric **		none.
200294Seric */
201294Seric 
2024437Seric char *
203294Seric index(s, c)
204294Seric 	register char *s;
205294Seric 	register char c;
206294Seric {
207294Seric 	while (*s != '\0')
208294Seric 	{
209294Seric 		if (*s++ == c)
210294Seric 			return (--s);
211294Seric 	}
212294Seric 	return (NULL);
213294Seric }
2144326Seric /*
2154326Seric **  UMASK -- fake the umask system call.
2164326Seric **
2174326Seric **	Since V6 always acts like the umask is zero, we will just
2184326Seric **	assume the same thing.
2194326Seric */
2204326Seric 
2214326Seric /*ARGSUSED*/
2224326Seric umask(nmask)
2234326Seric {
2244326Seric 	return (0);
2254326Seric }
2264326Seric 
2274326Seric 
2284326Seric /*
2294326Seric **  GETRUID -- get real user id.
2304326Seric */
2314326Seric 
2324326Seric getruid()
2334326Seric {
2344326Seric 	return (getuid() & 0377);
2354326Seric }
2364326Seric 
2374326Seric 
2384326Seric /*
2394326Seric **  GETRGID -- get real group id.
2404326Seric */
2414326Seric 
2424326Seric getrgid()
2434326Seric {
2444326Seric 	return (getgid() & 0377);
2454326Seric }
2464326Seric 
2474326Seric 
2484326Seric /*
2494326Seric **  GETEUID -- get effective user id.
2504326Seric */
2514326Seric 
2524326Seric geteuid()
2534326Seric {
2544326Seric 	return ((getuid() >> 8) & 0377);
2554326Seric }
2564326Seric 
2574326Seric 
2584326Seric /*
2594326Seric **  GETEGID -- get effective group id.
2604326Seric */
2614326Seric 
2624326Seric getegid()
2634326Seric {
2644326Seric 	return ((getgid() >> 8) & 0377);
2654326Seric }
2664326Seric 
267294Seric # endif V6
2684326Seric 
2694326Seric # ifndef V6
2704326Seric 
2714326Seric /*
2724326Seric **  GETRUID -- get real user id (V7)
2734326Seric */
2744326Seric 
2754326Seric getruid()
2764326Seric {
2779274Seric 	if (OpMode == MD_DAEMON)
2784536Seric 		return (RealUid);
2794536Seric 	else
2804536Seric 		return (getuid());
2814326Seric }
2824326Seric 
2834326Seric 
2844326Seric /*
2854326Seric **  GETRGID -- get real group id (V7).
2864326Seric */
2874326Seric 
2884326Seric getrgid()
2894326Seric {
2909274Seric 	if (OpMode == MD_DAEMON)
2914536Seric 		return (RealGid);
2924536Seric 	else
2934536Seric 		return (getgid());
2944326Seric }
2954326Seric 
2964326Seric # endif V6
2974190Seric /*
2989369Seric **  USERNAME -- return the user id of the logged in user.
2999369Seric **
3009369Seric **	Parameters:
3019369Seric **		none.
3029369Seric **
3039369Seric **	Returns:
3049369Seric **		The login name of the logged in user.
3059369Seric **
3069369Seric **	Side Effects:
3079369Seric **		none.
3089369Seric **
3099369Seric **	Notes:
3109369Seric **		The return value is statically allocated.
3119369Seric */
3129369Seric 
3139369Seric char *
3149369Seric username()
3159369Seric {
31617469Seric 	static char *myname = NULL;
3179369Seric 	extern char *getlogin();
318*19904Smiriam 	register struct passwd *pw;
319*19904Smiriam 	extern struct passwd *getpwuid();
3209369Seric 
32117469Seric 	/* cache the result */
32217469Seric 	if (myname == NULL)
32317469Seric 	{
32417469Seric 		myname = getlogin();
32517469Seric 		if (myname == NULL || myname[0] == '\0')
32617469Seric 		{
32717469Seric 
32817469Seric 			pw = getpwuid(getruid());
32917469Seric 			if (pw != NULL)
33017469Seric 				myname = pw->pw_name;
33117469Seric 		}
332*19904Smiriam 		else
333*19904Smiriam 		{
33419873Smiriam 
33519873Smiriam 			pw = getpwnam(myname);
336*19904Smiriam 			if(getuid() != pw->pw_uid)
337*19904Smiriam 			{
33819873Smiriam 				pw = getpwuid(getuid());
33919873Smiriam 				myname = pw->pw_name;
34019873Smiriam 			}
34119873Smiriam 		}
34217469Seric 		if (myname == NULL || myname[0] == '\0')
34317469Seric 		{
34417469Seric 			syserr("Who are you?");
34517469Seric 			myname = "postmaster";
34617469Seric 		}
34717469Seric 	}
34817469Seric 
34917469Seric 	return (myname);
3509369Seric }
3519369Seric /*
3524190Seric **  TTYPATH -- Get the path of the user's tty
353294Seric **
354294Seric **	Returns the pathname of the user's tty.  Returns NULL if
355294Seric **	the user is not logged in or if s/he has write permission
356294Seric **	denied.
357294Seric **
358294Seric **	Parameters:
359294Seric **		none
360294Seric **
361294Seric **	Returns:
362294Seric **		pathname of the user's tty.
363294Seric **		NULL if not logged in or write permission denied.
364294Seric **
365294Seric **	Side Effects:
366294Seric **		none.
367294Seric **
368294Seric **	WARNING:
369294Seric **		Return value is in a local buffer.
370294Seric **
371294Seric **	Called By:
372294Seric **		savemail
373294Seric */
374294Seric 
375294Seric # include <sys/stat.h>
376294Seric 
377294Seric char *
378294Seric ttypath()
379294Seric {
380294Seric 	struct stat stbuf;
381294Seric 	register char *pathn;
382294Seric 	extern char *ttyname();
3834081Seric 	extern char *getlogin();
384294Seric 
385294Seric 	/* compute the pathname of the controlling tty */
3869369Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
3879369Seric 	    (pathn = ttyname(0)) == NULL)
388294Seric 	{
389294Seric 		errno = 0;
390294Seric 		return (NULL);
391294Seric 	}
392294Seric 
393294Seric 	/* see if we have write permission */
3942967Seric 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
395294Seric 	{
396294Seric 		errno = 0;
397294Seric 		return (NULL);
398294Seric 	}
399294Seric 
400294Seric 	/* see if the user is logged in */
401294Seric 	if (getlogin() == NULL)
402294Seric 		return (NULL);
403294Seric 
404294Seric 	/* looks good */
405294Seric 	return (pathn);
406294Seric }
4072967Seric /*
4082967Seric **  CHECKCOMPAT -- check for From and To person compatible.
4092967Seric **
4102967Seric **	This routine can be supplied on a per-installation basis
4112967Seric **	to determine whether a person is allowed to send a message.
4122967Seric **	This allows restriction of certain types of internet
4132967Seric **	forwarding or registration of users.
4142967Seric **
4152967Seric **	If the hosts are found to be incompatible, an error
4162967Seric **	message should be given using "usrerr" and FALSE should
4172967Seric **	be returned.
4182967Seric **
4194288Seric **	'NoReturn' can be set to suppress the return-to-sender
4204288Seric **	function; this should be done on huge messages.
4214288Seric **
4222967Seric **	Parameters:
4232967Seric **		to -- the person being sent to.
4242967Seric **
4252967Seric **	Returns:
4262967Seric **		TRUE -- ok to send.
4272967Seric **		FALSE -- not ok.
4282967Seric **
4292967Seric **	Side Effects:
4302967Seric **		none (unless you include the usrerr stuff)
4312967Seric */
4322967Seric 
4332967Seric bool
4342967Seric checkcompat(to)
4352967Seric 	register ADDRESS *to;
4362967Seric {
43712133Seric # ifdef lint
43812133Seric 	if (to == NULL)
43912133Seric 		to++;
44012133Seric # endif lint
44110698Seric # ifdef EXAMPLE_CODE
44210698Seric 	/* this code is intended as an example only */
4434437Seric 	register STAB *s;
4444437Seric 
4454437Seric 	s = stab("arpa", ST_MAILER, ST_FIND);
4469369Seric 	if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
4479369Seric 	    to->q_mailer == s->s_mailer)
4484437Seric 	{
4494437Seric 		usrerr("No ARPA mail through this machine: see your system administration");
45010698Seric 		/* NoReturn = TRUE; to supress return copy */
4514437Seric 		return (FALSE);
4524437Seric 	}
45310698Seric # endif EXAMPLE_CODE
4542967Seric 	return (TRUE);
4552967Seric }
4569369Seric /*
4579369Seric **  HOLDSIGS -- arrange to hold all signals
4589369Seric **
4599369Seric **	Parameters:
4609369Seric **		none.
4619369Seric **
4629369Seric **	Returns:
4639369Seric **		none.
4649369Seric **
4659369Seric **	Side Effects:
4669369Seric **		Arranges that signals are held.
4679369Seric */
4689369Seric 
4699369Seric holdsigs()
4709369Seric {
4719369Seric }
4729369Seric /*
4739369Seric **  RLSESIGS -- arrange to release all signals
4749369Seric **
4759369Seric **	This undoes the effect of holdsigs.
4769369Seric **
4779369Seric **	Parameters:
4789369Seric **		none.
4799369Seric **
4809369Seric **	Returns:
4819369Seric **		none.
4829369Seric **
4839369Seric **	Side Effects:
4849369Seric **		Arranges that signals are released.
4859369Seric */
4869369Seric 
4879369Seric rlsesigs()
4889369Seric {
4899369Seric }
49014872Seric /*
49114872Seric **  GETLA -- get the current load average
49214872Seric **
49314881Seric **	This code stolen from la.c.
49414881Seric **
49514872Seric **	Parameters:
49614872Seric **		none.
49714872Seric **
49814872Seric **	Returns:
49914872Seric **		The current load average as an integer.
50014872Seric **
50114872Seric **	Side Effects:
50214872Seric **		none.
50314872Seric */
50414872Seric 
50514872Seric #ifdef VMUNIX
50614872Seric 
50714872Seric #include <nlist.h>
50814872Seric 
50914872Seric struct	nlist Nl[] =
51014872Seric {
51114872Seric 	{ "_avenrun" },
51214872Seric #define	X_AVENRUN	0
51314872Seric 	{ 0 },
51414872Seric };
51514872Seric 
51614872Seric getla()
51714872Seric {
51814872Seric 	static int kmem = -1;
51914872Seric 	double avenrun[3];
52014872Seric 
52114872Seric 	if (kmem < 0)
52214872Seric 	{
52314872Seric 		kmem = open("/dev/kmem", 0);
52414872Seric 		if (kmem < 0)
52514872Seric 			return (-1);
52614881Seric 		(void) ioctl(kmem, FIOCLEX, 0);
52714872Seric 		nlist("/vmunix", Nl);
52814872Seric 		if (Nl[0].n_type == 0)
52914872Seric 			return (-1);
53014872Seric 	}
53114872Seric 	(void) lseek(kmem, (long) Nl[X_AVENRUN].n_value, 0);
53214872Seric 	(void) read(kmem, avenrun, sizeof(avenrun));
53314872Seric 	return ((int) (avenrun[0] + 0.5));
53414872Seric }
53514872Seric 
53614872Seric #else VMUNIX
53714872Seric 
53814872Seric getla()
53914872Seric {
54014872Seric 	return (0);
54114872Seric }
54214872Seric 
54314872Seric #endif VMUNIX
54417469Seric /*
54517469Seric **  DBMCLOSE -- close the DBM file
54617469Seric **
54717469Seric **	This depends on the implementation of the DBM library.  It
54817469Seric **	seems to work for all versions that I have come across.
54917469Seric **
55017469Seric **	Parameters:
55117469Seric **		none.
55217469Seric **
55317469Seric **	Returns:
55417469Seric **		none.
55517469Seric **
55617469Seric **	Side Effects:
55717469Seric **		Closes the current DBM file; dbminit must be
55817469Seric **		called again to continue using the DBM routines.
55917469Seric */
56017469Seric 
56117469Seric dbmclose()
56217469Seric {
56317469Seric 	extern int pagf, dirf;	/* defined in the DBM package */
56417469Seric 
56517469Seric 	(void) close(pagf);
56617469Seric 	(void) close(dirf);
56717469Seric }
568