xref: /csrg-svn/usr.sbin/sendmail/src/conf.c (revision 22698)
1 /*
2 **  Sendmail
3 **  Copyright (c) 1983  Eric P. Allman
4 **  Berkeley, California
5 **
6 **  Copyright (c) 1983 Regents of the University of California.
7 **  All rights reserved.  The Berkeley software License Agreement
8 **  specifies the terms and conditions for redistribution.
9 */
10 
11 #ifndef lint
12 static char	SccsId[] = "@(#)conf.c	5.1 (Berkeley) 06/07/85";
13 #endif not lint
14 
15 # include <pwd.h>
16 # include <sys/ioctl.h>
17 # include "sendmail.h"
18 
19 /*
20 **  CONF.C -- Sendmail Configuration Tables.
21 **
22 **	Defines the configuration of this installation.
23 **
24 **	Compilation Flags:
25 **		V6 -- running on a version 6 system.  This determines
26 **			whether to define certain routines between
27 **			the two systems.  If you are running a funny
28 **			system, e.g., V6 with long tty names, this
29 **			should be checked carefully.
30 **		VMUNIX -- running on a Berkeley UNIX system.
31 **
32 **	Configuration Variables:
33 **		HdrInfo -- a table describing well-known header fields.
34 **			Each entry has the field name and some flags,
35 **			which are described in sendmail.h.
36 **
37 **	Notes:
38 **		I have tried to put almost all the reasonable
39 **		configuration information into the configuration
40 **		file read at runtime.  My intent is that anything
41 **		here is a function of the version of UNIX you
42 **		are running, or is really static -- for example
43 **		the headers are a superset of widely used
44 **		protocols.  If you find yourself playing with
45 **		this file too much, you may be making a mistake!
46 */
47 
48 
49 
50 
51 SCCSID(@(#)conf.c	5.1		06/07/85);
52 
53 
54 
55 /*
56 **  Header info table
57 **	Final (null) entry contains the flags used for any other field.
58 **
59 **	Not all of these are actually handled specially by sendmail
60 **	at this time.  They are included as placeholders, to let
61 **	you know that "someday" I intend to have sendmail do
62 **	something with them.
63 */
64 
65 struct hdrinfo	HdrInfo[] =
66 {
67 		/* originator fields, most to least significant  */
68 	"resent-sender",	H_FROM|H_RESENT,
69 	"resent-from",		H_FROM|H_RESENT,
70 	"sender",		H_FROM,
71 	"from",			H_FROM,
72 	"full-name",		H_ACHECK,
73 	"return-receipt-to",	H_FROM,
74 	"errors-to",		H_FROM,
75 		/* destination fields */
76 	"to",			H_RCPT,
77 	"resent-to",		H_RCPT|H_RESENT,
78 	"cc",			H_RCPT,
79 	"resent-cc",		H_RCPT|H_RESENT,
80 	"bcc",			H_RCPT|H_ACHECK,
81 	"resent-bcc",		H_RCPT|H_ACHECK|H_RESENT,
82 		/* message identification and control */
83 	"message-id",		0,
84 	"resent-message-id",	H_RESENT,
85 	"message",		H_EOH,
86 	"text",			H_EOH,
87 		/* date fields */
88 	"date",			0,
89 	"resent-date",		H_RESENT,
90 		/* trace fields */
91 	"received",		H_TRACE|H_FORCE,
92 	"via",			H_TRACE|H_FORCE,
93 	"mail-from",		H_TRACE|H_FORCE,
94 
95 	NULL,			0,
96 };
97 
98 
99 /*
100 **  ARPANET error message numbers.
101 */
102 
103 char	Arpa_Info[] =		"050";	/* arbitrary info */
104 char	Arpa_TSyserr[] =	"451";	/* some (transient) system error */
105 char	Arpa_PSyserr[] =	"554";	/* some (permanent) system error */
106 char	Arpa_Usrerr[] =		"554";	/* some (fatal) user error */
107 
108 
109 
110 /*
111 **  Location of system files/databases/etc.
112 */
113 
114 char	*ConfFile =	"/usr/lib/sendmail.cf";	/* runtime configuration */
115 char	*FreezeFile =	"/usr/lib/sendmail.fc";	/* frozen version of above */
116 
117 
118 
119 /*
120 **  Some other configuration....
121 */
122 
123 char	SpaceSub;		/* character to replace <lwsp> in addrs */
124 int	QueueLA;		/* load avg > QueueLA -> just queue */
125 int	RefuseLA;		/* load avg > RefuseLA -> refuse connections */
126 
127 # ifdef V6
128 /*
129 **  TTYNAME -- return name of terminal.
130 **
131 **	Parameters:
132 **		fd -- file descriptor to check.
133 **
134 **	Returns:
135 **		pointer to full path of tty.
136 **		NULL if no tty.
137 **
138 **	Side Effects:
139 **		none.
140 */
141 
142 char *
143 ttyname(fd)
144 	int fd;
145 {
146 	register char tn;
147 	static char pathn[] = "/dev/ttyx";
148 
149 	/* compute the pathname of the controlling tty */
150 	if ((tn = ttyn(fd)) == NULL)
151 	{
152 		errno = 0;
153 		return (NULL);
154 	}
155 	pathn[8] = tn;
156 	return (pathn);
157 }
158 /*
159 **  FDOPEN -- Open a stdio file given an open file descriptor.
160 **
161 **	This is included here because it is standard in v7, but we
162 **	need it in v6.
163 **
164 **	Algorithm:
165 **		Open /dev/null to create a descriptor.
166 **		Close that descriptor.
167 **		Copy the existing fd into the descriptor.
168 **
169 **	Parameters:
170 **		fd -- the open file descriptor.
171 **		type -- "r", "w", or whatever.
172 **
173 **	Returns:
174 **		The file descriptor it creates.
175 **
176 **	Side Effects:
177 **		none
178 **
179 **	Called By:
180 **		deliver
181 **
182 **	Notes:
183 **		The mode of fd must match "type".
184 */
185 
186 FILE *
187 fdopen(fd, type)
188 	int fd;
189 	char *type;
190 {
191 	register FILE *f;
192 
193 	f = fopen("/dev/null", type);
194 	(void) close(fileno(f));
195 	fileno(f) = fd;
196 	return (f);
197 }
198 /*
199 **  INDEX -- Return pointer to character in string
200 **
201 **	For V7 compatibility.
202 **
203 **	Parameters:
204 **		s -- a string to scan.
205 **		c -- a character to look for.
206 **
207 **	Returns:
208 **		If c is in s, returns the address of the first
209 **			instance of c in s.
210 **		NULL if c is not in s.
211 **
212 **	Side Effects:
213 **		none.
214 */
215 
216 char *
217 index(s, c)
218 	register char *s;
219 	register char c;
220 {
221 	while (*s != '\0')
222 	{
223 		if (*s++ == c)
224 			return (--s);
225 	}
226 	return (NULL);
227 }
228 /*
229 **  UMASK -- fake the umask system call.
230 **
231 **	Since V6 always acts like the umask is zero, we will just
232 **	assume the same thing.
233 */
234 
235 /*ARGSUSED*/
236 umask(nmask)
237 {
238 	return (0);
239 }
240 
241 
242 /*
243 **  GETRUID -- get real user id.
244 */
245 
246 getruid()
247 {
248 	return (getuid() & 0377);
249 }
250 
251 
252 /*
253 **  GETRGID -- get real group id.
254 */
255 
256 getrgid()
257 {
258 	return (getgid() & 0377);
259 }
260 
261 
262 /*
263 **  GETEUID -- get effective user id.
264 */
265 
266 geteuid()
267 {
268 	return ((getuid() >> 8) & 0377);
269 }
270 
271 
272 /*
273 **  GETEGID -- get effective group id.
274 */
275 
276 getegid()
277 {
278 	return ((getgid() >> 8) & 0377);
279 }
280 
281 # endif V6
282 
283 # ifndef V6
284 
285 /*
286 **  GETRUID -- get real user id (V7)
287 */
288 
289 getruid()
290 {
291 	if (OpMode == MD_DAEMON)
292 		return (RealUid);
293 	else
294 		return (getuid());
295 }
296 
297 
298 /*
299 **  GETRGID -- get real group id (V7).
300 */
301 
302 getrgid()
303 {
304 	if (OpMode == MD_DAEMON)
305 		return (RealGid);
306 	else
307 		return (getgid());
308 }
309 
310 # endif V6
311 /*
312 **  USERNAME -- return the user id of the logged in user.
313 **
314 **	Parameters:
315 **		none.
316 **
317 **	Returns:
318 **		The login name of the logged in user.
319 **
320 **	Side Effects:
321 **		none.
322 **
323 **	Notes:
324 **		The return value is statically allocated.
325 */
326 
327 char *
328 username()
329 {
330 	static char *myname = NULL;
331 	extern char *getlogin();
332 	register struct passwd *pw;
333 	extern struct passwd *getpwuid();
334 
335 	/* cache the result */
336 	if (myname == NULL)
337 	{
338 		myname = getlogin();
339 		if (myname == NULL || myname[0] == '\0')
340 		{
341 
342 			pw = getpwuid(getruid());
343 			if (pw != NULL)
344 				myname = pw->pw_name;
345 		}
346 		else
347 		{
348 
349 			pw = getpwnam(myname);
350 			if(getuid() != pw->pw_uid)
351 			{
352 				pw = getpwuid(getuid());
353 				myname = pw->pw_name;
354 			}
355 		}
356 		if (myname == NULL || myname[0] == '\0')
357 		{
358 			syserr("Who are you?");
359 			myname = "postmaster";
360 		}
361 	}
362 
363 	return (myname);
364 }
365 /*
366 **  TTYPATH -- Get the path of the user's tty
367 **
368 **	Returns the pathname of the user's tty.  Returns NULL if
369 **	the user is not logged in or if s/he has write permission
370 **	denied.
371 **
372 **	Parameters:
373 **		none
374 **
375 **	Returns:
376 **		pathname of the user's tty.
377 **		NULL if not logged in or write permission denied.
378 **
379 **	Side Effects:
380 **		none.
381 **
382 **	WARNING:
383 **		Return value is in a local buffer.
384 **
385 **	Called By:
386 **		savemail
387 */
388 
389 # include <sys/stat.h>
390 
391 char *
392 ttypath()
393 {
394 	struct stat stbuf;
395 	register char *pathn;
396 	extern char *ttyname();
397 	extern char *getlogin();
398 
399 	/* compute the pathname of the controlling tty */
400 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
401 	    (pathn = ttyname(0)) == NULL)
402 	{
403 		errno = 0;
404 		return (NULL);
405 	}
406 
407 	/* see if we have write permission */
408 	if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
409 	{
410 		errno = 0;
411 		return (NULL);
412 	}
413 
414 	/* see if the user is logged in */
415 	if (getlogin() == NULL)
416 		return (NULL);
417 
418 	/* looks good */
419 	return (pathn);
420 }
421 /*
422 **  CHECKCOMPAT -- check for From and To person compatible.
423 **
424 **	This routine can be supplied on a per-installation basis
425 **	to determine whether a person is allowed to send a message.
426 **	This allows restriction of certain types of internet
427 **	forwarding or registration of users.
428 **
429 **	If the hosts are found to be incompatible, an error
430 **	message should be given using "usrerr" and FALSE should
431 **	be returned.
432 **
433 **	'NoReturn' can be set to suppress the return-to-sender
434 **	function; this should be done on huge messages.
435 **
436 **	Parameters:
437 **		to -- the person being sent to.
438 **
439 **	Returns:
440 **		TRUE -- ok to send.
441 **		FALSE -- not ok.
442 **
443 **	Side Effects:
444 **		none (unless you include the usrerr stuff)
445 */
446 
447 bool
448 checkcompat(to)
449 	register ADDRESS *to;
450 {
451 # ifdef lint
452 	if (to == NULL)
453 		to++;
454 # endif lint
455 # ifdef EXAMPLE_CODE
456 	/* this code is intended as an example only */
457 	register STAB *s;
458 
459 	s = stab("arpa", ST_MAILER, ST_FIND);
460 	if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
461 	    to->q_mailer == s->s_mailer)
462 	{
463 		usrerr("No ARPA mail through this machine: see your system administration");
464 		/* NoReturn = TRUE; to supress return copy */
465 		return (FALSE);
466 	}
467 # endif EXAMPLE_CODE
468 	return (TRUE);
469 }
470 /*
471 **  HOLDSIGS -- arrange to hold all signals
472 **
473 **	Parameters:
474 **		none.
475 **
476 **	Returns:
477 **		none.
478 **
479 **	Side Effects:
480 **		Arranges that signals are held.
481 */
482 
483 holdsigs()
484 {
485 }
486 /*
487 **  RLSESIGS -- arrange to release all signals
488 **
489 **	This undoes the effect of holdsigs.
490 **
491 **	Parameters:
492 **		none.
493 **
494 **	Returns:
495 **		none.
496 **
497 **	Side Effects:
498 **		Arranges that signals are released.
499 */
500 
501 rlsesigs()
502 {
503 }
504 /*
505 **  GETLA -- get the current load average
506 **
507 **	This code stolen from la.c.
508 **
509 **	Parameters:
510 **		none.
511 **
512 **	Returns:
513 **		The current load average as an integer.
514 **
515 **	Side Effects:
516 **		none.
517 */
518 
519 #ifdef VMUNIX
520 
521 #include <nlist.h>
522 
523 struct	nlist Nl[] =
524 {
525 	{ "_avenrun" },
526 #define	X_AVENRUN	0
527 	{ 0 },
528 };
529 
530 getla()
531 {
532 	static int kmem = -1;
533 	double avenrun[3];
534 
535 	if (kmem < 0)
536 	{
537 		kmem = open("/dev/kmem", 0);
538 		if (kmem < 0)
539 			return (-1);
540 		(void) ioctl(kmem, FIOCLEX, 0);
541 		nlist("/vmunix", Nl);
542 		if (Nl[0].n_type == 0)
543 			return (-1);
544 	}
545 	if (lseek(kmem, (long) Nl[X_AVENRUN].n_value, 0) < 0 ||
546 	    read(kmem, avenrun, sizeof(avenrun)) < sizeof(avenrun))
547 	{
548 		/* thank you Ian */
549 		return (-1);
550 	}
551 	return ((int) (avenrun[0] + 0.5));
552 }
553 
554 #else VMUNIX
555 
556 getla()
557 {
558 	return (0);
559 }
560 
561 #endif VMUNIX
562 /*
563 **  DBMCLOSE -- close the DBM file
564 **
565 **	This depends on the implementation of the DBM library.  It
566 **	seems to work for all versions that I have come across.
567 **
568 **	Parameters:
569 **		none.
570 **
571 **	Returns:
572 **		none.
573 **
574 **	Side Effects:
575 **		Closes the current DBM file; dbminit must be
576 **		called again to continue using the DBM routines.
577 */
578 
579 dbmclose()
580 {
581 	extern int pagf, dirf;	/* defined in the DBM package */
582 
583 	(void) close(pagf);
584 	(void) close(dirf);
585 }
586