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