note that _getshort used by sendmail
[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
9da8ffc8 12static char SccsId[] = "@(#)conf.c 5.14 (Berkeley) %G%";
d185cb11
DF
13#endif not lint
14
b3cbe40f 15# include <pwd.h>
d209c154 16# include <sys/ioctl.h>
2e3062fe
EA
17# ifdef sun
18# include <sys/param.h>
19# endif sun
96faada8 20# include "sendmail.h"
916b3375 21
b3cbe40f 22/*
96faada8 23** CONF.C -- Sendmail Configuration Tables.
b3cbe40f
EA
24**
25** Defines the configuration of this installation.
26**
cb590f52 27** Compilation Flags:
cb590f52
EA
28** V6 -- running on a version 6 system. This determines
29** whether to define certain routines between
30** the two systems. If you are running a funny
31** system, e.g., V6 with long tty names, this
32** should be checked carefully.
f7e74083 33** VMUNIX -- running on a Berkeley UNIX system.
b3cbe40f 34**
cb590f52 35** Configuration Variables:
1a12c7d6
EA
36** HdrInfo -- a table describing well-known header fields.
37** Each entry has the field name and some flags,
df960d9b 38** which are described in sendmail.h.
9c6d4c70
EA
39**
40** Notes:
41** I have tried to put almost all the reasonable
42** configuration information into the configuration
43** file read at runtime. My intent is that anything
44** here is a function of the version of UNIX you
45** are running, or is really static -- for example
46** the headers are a superset of widely used
47** protocols. If you find yourself playing with
48** this file too much, you may be making a mistake!
b3cbe40f
EA
49*/
50
51
52
53
b5fd168f 54\f/*
1a12c7d6 55** Header info table
355a2a04 56** Final (null) entry contains the flags used for any other field.
df960d9b
EA
57**
58** Not all of these are actually handled specially by sendmail
59** at this time. They are included as placeholders, to let
60** you know that "someday" I intend to have sendmail do
61** something with them.
1a12c7d6
EA
62*/
63
64struct hdrinfo HdrInfo[] =
65{
6144e1d1 66 /* originator fields, most to least significant */
a90807d8
EA
67 "resent-sender", H_FROM|H_RESENT,
68 "resent-from", H_FROM|H_RESENT,
4e969be0 69 "resent-reply-to", H_FROM|H_RESENT,
be2fcca9
EA
70 "sender", H_FROM,
71 "from", H_FROM,
4e969be0 72 "reply-to", H_FROM,
be2fcca9
EA
73 "full-name", H_ACHECK,
74 "return-receipt-to", H_FROM,
75 "errors-to", H_FROM,
6144e1d1 76 /* destination fields */
be2fcca9 77 "to", H_RCPT,
a90807d8 78 "resent-to", H_RCPT|H_RESENT,
be2fcca9 79 "cc", H_RCPT,
a90807d8 80 "resent-cc", H_RCPT|H_RESENT,
be2fcca9 81 "bcc", H_RCPT|H_ACHECK,
a90807d8 82 "resent-bcc", H_RCPT|H_ACHECK|H_RESENT,
6144e1d1 83 /* message identification and control */
a90807d8
EA
84 "message-id", 0,
85 "resent-message-id", H_RESENT,
be2fcca9
EA
86 "message", H_EOH,
87 "text", H_EOH,
a90807d8
EA
88 /* date fields */
89 "date", 0,
90 "resent-date", H_RESENT,
6144e1d1 91 /* trace fields */
be2fcca9
EA
92 "received", H_TRACE|H_FORCE,
93 "via", H_TRACE|H_FORCE,
94 "mail-from", H_TRACE|H_FORCE,
6144e1d1 95
be2fcca9 96 NULL, 0,
1a12c7d6 97};
15b28570
EA
98
99
100/*
101** ARPANET error message numbers.
102*/
103
314d2f52
EA
104char Arpa_Info[] = "050"; /* arbitrary info */
105char Arpa_TSyserr[] = "451"; /* some (transient) system error */
106char Arpa_PSyserr[] = "554"; /* some (permanent) system error */
107char Arpa_Usrerr[] = "554"; /* some (fatal) user error */
4e1f4d4b
EA
108
109
110
4e1f4d4b
EA
111/*
112** Location of system files/databases/etc.
113*/
114
4e1f4d4b 115char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */
acae5a9d
EA
116char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */
117
118
1744384a
EA
119
120/*
2e3062fe 121** Miscellaneous stuff.
1744384a
EA
122*/
123
2e3062fe
EA
124int DtableSize = 50; /* max open files; reset in 4.2bsd */
125\f/*
126** SETDEFAULTS -- set default values
127**
128** Because of the way freezing is done, these must be initialized
129** using direct code.
130**
131** Parameters:
132** none.
133**
134** Returns:
135** none.
136**
137** Side Effects:
138** Initializes a bunch of global variables to their
139** default values.
140*/
141
142setdefaults()
143{
144 QueueLA = 8;
145 QueueFactor = 10000;
146 RefuseLA = 12;
147 SpaceSub = ' ';
a0225d08
EA
148 WkRecipFact = 1000;
149 WkClassFact = 1800;
9da8ffc8 150 WkTimeFact = 9000;
a0225d08
EA
151 FileMode = 0644;
152 DefUid = 1;
153 DefGid = 1;
2e3062fe 154}
b3cbe40f
EA
155\f
156# ifdef V6
157/*
14e42c2b 158** TTYNAME -- return name of terminal.
b3cbe40f
EA
159**
160** Parameters:
14e42c2b 161** fd -- file descriptor to check.
b3cbe40f
EA
162**
163** Returns:
14e42c2b
EA
164** pointer to full path of tty.
165** NULL if no tty.
b3cbe40f
EA
166**
167** Side Effects:
168** none.
b3cbe40f
EA
169*/
170
b3cbe40f 171char *
14e42c2b
EA
172ttyname(fd)
173 int fd;
b3cbe40f 174{
14e42c2b 175 register char tn;
b3cbe40f 176 static char pathn[] = "/dev/ttyx";
b3cbe40f
EA
177
178 /* compute the pathname of the controlling tty */
14e42c2b 179 if ((tn = ttyn(fd)) == NULL)
b3cbe40f
EA
180 {
181 errno = 0;
182 return (NULL);
183 }
14e42c2b 184 pathn[8] = tn;
b3cbe40f
EA
185 return (pathn);
186}
187\f/*
188** FDOPEN -- Open a stdio file given an open file descriptor.
189**
190** This is included here because it is standard in v7, but we
191** need it in v6.
192**
193** Algorithm:
194** Open /dev/null to create a descriptor.
195** Close that descriptor.
196** Copy the existing fd into the descriptor.
197**
198** Parameters:
199** fd -- the open file descriptor.
200** type -- "r", "w", or whatever.
201**
202** Returns:
203** The file descriptor it creates.
204**
205** Side Effects:
206** none
207**
b3cbe40f
EA
208** Called By:
209** deliver
210**
211** Notes:
212** The mode of fd must match "type".
213*/
214
215FILE *
216fdopen(fd, type)
217 int fd;
218 char *type;
219{
220 register FILE *f;
221
222 f = fopen("/dev/null", type);
29871fef 223 (void) close(fileno(f));
b3cbe40f
EA
224 fileno(f) = fd;
225 return (f);
226}
227\f/*
228** INDEX -- Return pointer to character in string
229**
230** For V7 compatibility.
231**
232** Parameters:
233** s -- a string to scan.
234** c -- a character to look for.
235**
236** Returns:
237** If c is in s, returns the address of the first
238** instance of c in s.
239** NULL if c is not in s.
240**
241** Side Effects:
242** none.
b3cbe40f
EA
243*/
244
b14547d5 245char *
b3cbe40f
EA
246index(s, c)
247 register char *s;
248 register char c;
249{
250 while (*s != '\0')
251 {
252 if (*s++ == c)
253 return (--s);
254 }
255 return (NULL);
256}
a0554f81
EA
257\f/*
258** UMASK -- fake the umask system call.
259**
260** Since V6 always acts like the umask is zero, we will just
261** assume the same thing.
262*/
263
264/*ARGSUSED*/
265umask(nmask)
266{
267 return (0);
268}
269
270
271/*
272** GETRUID -- get real user id.
273*/
274
275getruid()
276{
277 return (getuid() & 0377);
278}
279
280
281/*
282** GETRGID -- get real group id.
283*/
284
285getrgid()
286{
287 return (getgid() & 0377);
288}
289
290
291/*
292** GETEUID -- get effective user id.
293*/
294
295geteuid()
296{
297 return ((getuid() >> 8) & 0377);
298}
299
300
301/*
302** GETEGID -- get effective group id.
303*/
304
305getegid()
306{
307 return ((getgid() >> 8) & 0377);
308}
309
310# endif V6
311\f
312# ifndef V6
313
314/*
315** GETRUID -- get real user id (V7)
316*/
317
318getruid()
319{
75f95954 320 if (OpMode == MD_DAEMON)
f6a0cc15
EA
321 return (RealUid);
322 else
323 return (getuid());
a0554f81
EA
324}
325
326
327/*
328** GETRGID -- get real group id (V7).
329*/
330
331getrgid()
332{
75f95954 333 if (OpMode == MD_DAEMON)
f6a0cc15
EA
334 return (RealGid);
335 else
336 return (getgid());
a0554f81
EA
337}
338
b3cbe40f 339# endif V6
14e42c2b 340\f/*
7338e3d4
EA
341** USERNAME -- return the user id of the logged in user.
342**
343** Parameters:
344** none.
345**
346** Returns:
347** The login name of the logged in user.
348**
349** Side Effects:
350** none.
351**
352** Notes:
353** The return value is statically allocated.
354*/
355
356char *
357username()
358{
560a80d9 359 static char *myname = NULL;
7338e3d4 360 extern char *getlogin();
19c3b81a
MAN
361 register struct passwd *pw;
362 extern struct passwd *getpwuid();
7338e3d4 363
560a80d9
EA
364 /* cache the result */
365 if (myname == NULL)
366 {
367 myname = getlogin();
368 if (myname == NULL || myname[0] == '\0')
369 {
560a80d9
EA
370
371 pw = getpwuid(getruid());
372 if (pw != NULL)
373 myname = pw->pw_name;
374 }
19c3b81a
MAN
375 else
376 {
1a626eeb
MAN
377
378 pw = getpwnam(myname);
19c3b81a
MAN
379 if(getuid() != pw->pw_uid)
380 {
1a626eeb 381 pw = getpwuid(getuid());
84f20e6d
MAN
382 if (pw != NULL)
383 myname = pw->pw_name;
1a626eeb
MAN
384 }
385 }
560a80d9
EA
386 if (myname == NULL || myname[0] == '\0')
387 {
388 syserr("Who are you?");
389 myname = "postmaster";
390 }
391 }
392
393 return (myname);
7338e3d4
EA
394}
395\f/*
14e42c2b 396** TTYPATH -- Get the path of the user's tty
b3cbe40f
EA
397**
398** Returns the pathname of the user's tty. Returns NULL if
399** the user is not logged in or if s/he has write permission
400** denied.
401**
402** Parameters:
403** none
404**
405** Returns:
406** pathname of the user's tty.
407** NULL if not logged in or write permission denied.
408**
409** Side Effects:
410** none.
411**
412** WARNING:
413** Return value is in a local buffer.
414**
b3cbe40f
EA
415** Called By:
416** savemail
b3cbe40f
EA
417*/
418
b3cbe40f
EA
419# include <sys/stat.h>
420
421char *
422ttypath()
423{
424 struct stat stbuf;
425 register char *pathn;
b3cbe40f 426 extern char *ttyname();
29871fef 427 extern char *getlogin();
b3cbe40f
EA
428
429 /* compute the pathname of the controlling tty */
7338e3d4
EA
430 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
431 (pathn = ttyname(0)) == NULL)
b3cbe40f
EA
432 {
433 errno = 0;
434 return (NULL);
435 }
436
437 /* see if we have write permission */
a530c75f 438 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
b3cbe40f
EA
439 {
440 errno = 0;
441 return (NULL);
442 }
443
444 /* see if the user is logged in */
445 if (getlogin() == NULL)
446 return (NULL);
447
448 /* looks good */
449 return (pathn);
450}
a530c75f
EA
451\f/*
452** CHECKCOMPAT -- check for From and To person compatible.
453**
454** This routine can be supplied on a per-installation basis
455** to determine whether a person is allowed to send a message.
456** This allows restriction of certain types of internet
457** forwarding or registration of users.
458**
459** If the hosts are found to be incompatible, an error
460** message should be given using "usrerr" and FALSE should
461** be returned.
462**
46b14b48
EA
463** 'NoReturn' can be set to suppress the return-to-sender
464** function; this should be done on huge messages.
465**
a530c75f
EA
466** Parameters:
467** to -- the person being sent to.
468**
469** Returns:
470** TRUE -- ok to send.
471** FALSE -- not ok.
472**
473** Side Effects:
474** none (unless you include the usrerr stuff)
475*/
476
477bool
478checkcompat(to)
479 register ADDRESS *to;
480{
22e6d6b8
EA
481# ifdef lint
482 if (to == NULL)
483 to++;
484# endif lint
97ad25b6
EA
485# ifdef EXAMPLE_CODE
486 /* this code is intended as an example only */
b14547d5
EA
487 register STAB *s;
488
b14547d5 489 s = stab("arpa", ST_MAILER, ST_FIND);
7338e3d4
EA
490 if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
491 to->q_mailer == s->s_mailer)
b14547d5
EA
492 {
493 usrerr("No ARPA mail through this machine: see your system administration");
97ad25b6 494 /* NoReturn = TRUE; to supress return copy */
b14547d5
EA
495 return (FALSE);
496 }
97ad25b6 497# endif EXAMPLE_CODE
a530c75f
EA
498 return (TRUE);
499}
7338e3d4
EA
500\f/*
501** HOLDSIGS -- arrange to hold all signals
502**
503** Parameters:
504** none.
505**
506** Returns:
507** none.
508**
509** Side Effects:
510** Arranges that signals are held.
511*/
512
513holdsigs()
514{
515}
516\f/*
517** RLSESIGS -- arrange to release all signals
518**
519** This undoes the effect of holdsigs.
520**
521** Parameters:
522** none.
523**
524** Returns:
525** none.
526**
527** Side Effects:
528** Arranges that signals are released.
529*/
530
531rlsesigs()
532{
533}
f7e74083
EA
534\f/*
535** GETLA -- get the current load average
536**
d209c154
EA
537** This code stolen from la.c.
538**
f7e74083
EA
539** Parameters:
540** none.
541**
542** Returns:
543** The current load average as an integer.
544**
545** Side Effects:
546** none.
547*/
548
549#ifdef VMUNIX
550
551#include <nlist.h>
552
553struct nlist Nl[] =
554{
555 { "_avenrun" },
556#define X_AVENRUN 0
557 { 0 },
558};
559
560getla()
561{
562 static int kmem = -1;
2e3062fe
EA
563# ifdef sun
564 long avenrun[3];
565# else
f7e74083 566 double avenrun[3];
2e3062fe 567# endif
901911f8 568 extern off_t lseek();
f7e74083
EA
569
570 if (kmem < 0)
571 {
fa483327 572 kmem = open("/dev/kmem", 0, 0);
f7e74083
EA
573 if (kmem < 0)
574 return (-1);
17a67c62 575 (void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
f7e74083
EA
576 nlist("/vmunix", Nl);
577 if (Nl[0].n_type == 0)
578 return (-1);
579 }
fa483327 580 if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
17a67c62 581 read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
fa42ff8e
EA
582 {
583 /* thank you Ian */
584 return (-1);
585 }
2e3062fe
EA
586# ifdef sun
587 return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
588# else
f7e74083 589 return ((int) (avenrun[0] + 0.5));
2e3062fe 590# endif
f7e74083
EA
591}
592
593#else VMUNIX
594
595getla()
596{
597 return (0);
598}
599
600#endif VMUNIX
2e3062fe
EA
601\f/*
602** SHOULDQUEUE -- should this message be queued or sent?
603**
604** Compares the message cost to the load average to decide.
605**
606** Parameters:
607** pri -- the priority of the message in question.
608**
609** Returns:
610** TRUE -- if this message should be queued up for the
611** time being.
612** FALSE -- if the load is low enough to send this message.
613**
614** Side Effects:
615** none.
616*/
617
618bool
619shouldqueue(pri)
620 long pri;
621{
622 int la;
623
624 la = getla();
625 if (la < QueueLA)
626 return (FALSE);
627 return (pri > (QueueFactor / (la - QueueLA + 1)));
628}
629\f/*
630** SETPROCTITLE -- set process title for ps
631**
632** Parameters:
633** fmt -- a printf style format string.
634** a, b, c -- possible parameters to fmt.
635**
636** Returns:
637** none.
638**
639** Side Effects:
640** Clobbers argv of our main procedure so ps(1) will
641** display the title.
642*/
643
644/*VARARGS1*/
645setproctitle(fmt, a, b, c)
646 char *fmt;
647{
648# ifdef SETPROCTITLE
649 register char *p;
f5ca8c6e 650 register int i;
2e3062fe
EA
651 extern char **Argv;
652 extern char *LastArgv;
f5ca8c6e 653 char buf[MAXLINE];
2e3062fe 654
f5ca8c6e 655 (void) sprintf(buf, fmt, a, b, c);
2e3062fe
EA
656
657 /* make ps print "(sendmail)" */
f5ca8c6e 658 p = Argv[0];
2e3062fe
EA
659 *p++ = '-';
660
f5ca8c6e
EA
661 i = strlen(buf);
662 if (i > LastArgv - p - 2)
663 {
664 i = LastArgv - p - 2;
665 buf[i] = '\0';
666 }
667 (void) strcpy(p, buf);
668 p += i;
2e3062fe
EA
669 while (p < LastArgv)
670 *p++ = ' ';
671# endif SETPROCTITLE
672}
8fd13041
EA
673\f/*
674** REAPCHILD -- pick up the body of my child, lest it become a zombie
675**
676** Parameters:
677** none.
678**
679** Returns:
680** none.
681**
682** Side Effects:
683** Picks up extant zombies.
684*/
685
686# ifdef VMUNIX
687# include <sys/wait.h>
688# endif VMUNIX
689
690reapchild()
691{
692# ifdef WNOHANG
693 union wait status;
694
695 while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
696 continue;
697# else WNOHANG
698 auto int status;
699
700 while (wait(&status) > 0)
701 continue;
702# endif WNOHANG
703}