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