122698Sdist /* 234920Sbostic * Copyright (c) 1983 Eric P. Allman 333728Sbostic * Copyright (c) 1988 Regents of the University of California. 433728Sbostic * All rights reserved. 533728Sbostic * 642825Sbostic * %sccs.include.redist.c% 733728Sbostic */ 822698Sdist 922698Sdist #ifndef lint 10*51773Seric static char sccsid[] = "@(#)conf.c 5.30 (Berkeley) 11/20/91"; 1133728Sbostic #endif /* not lint */ 1222698Sdist 1314881Seric # include <sys/ioctl.h> 1424943Seric # include <sys/param.h> 1536928Sbostic # include <pwd.h> 163309Seric # include "sendmail.h" 1740980Sbostic # include "pathnames.h" 18404Seric 19294Seric /* 203309Seric ** CONF.C -- Sendmail Configuration Tables. 21294Seric ** 22294Seric ** Defines the configuration of this installation. 23294Seric ** 241388Seric ** Compilation Flags: 2514872Seric ** VMUNIX -- running on a Berkeley UNIX system. 26294Seric ** 271388Seric ** Configuration Variables: 282897Seric ** HdrInfo -- a table describing well-known header fields. 292897Seric ** Each entry has the field name and some flags, 304147Seric ** which are described in sendmail.h. 314093Seric ** 324093Seric ** Notes: 334093Seric ** I have tried to put almost all the reasonable 344093Seric ** configuration information into the configuration 354093Seric ** file read at runtime. My intent is that anything 364093Seric ** here is a function of the version of UNIX you 374093Seric ** are running, or is really static -- for example 384093Seric ** the headers are a superset of widely used 394093Seric ** protocols. If you find yourself playing with 404093Seric ** this file too much, you may be making a mistake! 41294Seric */ 42294Seric 43294Seric 44294Seric 45294Seric 464437Seric /* 472897Seric ** Header info table 483057Seric ** Final (null) entry contains the flags used for any other field. 494147Seric ** 504147Seric ** Not all of these are actually handled specially by sendmail 514147Seric ** at this time. They are included as placeholders, to let 524147Seric ** you know that "someday" I intend to have sendmail do 534147Seric ** something with them. 542897Seric */ 552897Seric 562897Seric struct hdrinfo HdrInfo[] = 572897Seric { 588060Seric /* originator fields, most to least significant */ 5911417Seric "resent-sender", H_FROM|H_RESENT, 6011417Seric "resent-from", H_FROM|H_RESENT, 6125686Seric "resent-reply-to", H_FROM|H_RESENT, 629055Seric "sender", H_FROM, 639055Seric "from", H_FROM, 6425686Seric "reply-to", H_FROM, 659055Seric "full-name", H_ACHECK, 669055Seric "return-receipt-to", H_FROM, 679055Seric "errors-to", H_FROM, 688060Seric /* destination fields */ 699055Seric "to", H_RCPT, 7011417Seric "resent-to", H_RCPT|H_RESENT, 719055Seric "cc", H_RCPT, 7211417Seric "resent-cc", H_RCPT|H_RESENT, 739055Seric "bcc", H_RCPT|H_ACHECK, 7411417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 758060Seric /* message identification and control */ 7611417Seric "message-id", 0, 7711417Seric "resent-message-id", H_RESENT, 789055Seric "message", H_EOH, 799055Seric "text", H_EOH, 8011417Seric /* date fields */ 8111417Seric "date", 0, 8211417Seric "resent-date", H_RESENT, 838060Seric /* trace fields */ 849055Seric "received", H_TRACE|H_FORCE, 859055Seric "via", H_TRACE|H_FORCE, 869055Seric "mail-from", H_TRACE|H_FORCE, 878060Seric 889055Seric NULL, 0, 892897Seric }; 904166Seric 914166Seric 924166Seric /* 934166Seric ** ARPANET error message numbers. 944166Seric */ 954166Seric 967956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 977956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 987956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 997956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 1004282Seric 1014282Seric 1024282Seric 1034282Seric /* 1044282Seric ** Location of system files/databases/etc. 1054282Seric */ 1064282Seric 10740980Sbostic char *ConfFile = _PATH_SENDMAILCF; /* runtime configuration */ 10840980Sbostic char *FreezeFile = _PATH_SENDMAILFC; /* frozen version of above */ 1099039Seric 1109064Seric 1119064Seric 1129039Seric /* 11324943Seric ** Miscellaneous stuff. 1149039Seric */ 1159039Seric 11624943Seric int DtableSize = 50; /* max open files; reset in 4.2bsd */ 11740938Srick extern int la; /* load average */ 11824943Seric /* 11924943Seric ** SETDEFAULTS -- set default values 12024943Seric ** 12124943Seric ** Because of the way freezing is done, these must be initialized 12224943Seric ** using direct code. 12324943Seric ** 12424943Seric ** Parameters: 12524943Seric ** none. 12624943Seric ** 12724943Seric ** Returns: 12824943Seric ** none. 12924943Seric ** 13024943Seric ** Side Effects: 13124943Seric ** Initializes a bunch of global variables to their 13224943Seric ** default values. 13324943Seric */ 13424943Seric 13524943Seric setdefaults() 13624943Seric { 13724943Seric QueueLA = 8; 13824943Seric QueueFactor = 10000; 13924943Seric RefuseLA = 12; 14024943Seric SpaceSub = ' '; 14124981Seric WkRecipFact = 1000; 14224981Seric WkClassFact = 1800; 14325812Seric WkTimeFact = 9000; 14424981Seric FileMode = 0644; 14524981Seric DefUid = 1; 14624981Seric DefGid = 1; 14747284Seric CheckpointInterval = 10; 14851305Seric MaxHopCount = MAXHOP; 14940973Sbostic setdefuser(); 15024943Seric } 151294Seric 15240973Sbostic 1534326Seric /* 15440973Sbostic ** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups()) 15540973Sbostic */ 15640973Sbostic 15740973Sbostic setdefuser() 15840973Sbostic { 15940973Sbostic struct passwd *defpwent; 16040973Sbostic 16140973Sbostic if (DefUser != NULL) 16240973Sbostic free(DefUser); 16340973Sbostic if ((defpwent = getpwuid(DefUid)) != NULL) 16440973Sbostic DefUser = newstr(defpwent->pw_name); 16540973Sbostic else 16640973Sbostic DefUser = newstr("nobody"); 16740973Sbostic } 16840973Sbostic 16940973Sbostic 17040973Sbostic /* 1714326Seric ** GETRUID -- get real user id (V7) 1724326Seric */ 1734326Seric 1744326Seric getruid() 1754326Seric { 1769274Seric if (OpMode == MD_DAEMON) 1774536Seric return (RealUid); 1784536Seric else 1794536Seric return (getuid()); 1804326Seric } 1814326Seric 1824326Seric 1834326Seric /* 1844326Seric ** GETRGID -- get real group id (V7). 1854326Seric */ 1864326Seric 1874326Seric getrgid() 1884326Seric { 1899274Seric if (OpMode == MD_DAEMON) 1904536Seric return (RealGid); 1914536Seric else 1924536Seric return (getgid()); 1934326Seric } 1944326Seric 19533936Sbostic /* 1969369Seric ** USERNAME -- return the user id of the logged in user. 1979369Seric ** 1989369Seric ** Parameters: 1999369Seric ** none. 2009369Seric ** 2019369Seric ** Returns: 2029369Seric ** The login name of the logged in user. 2039369Seric ** 2049369Seric ** Side Effects: 2059369Seric ** none. 2069369Seric ** 2079369Seric ** Notes: 2089369Seric ** The return value is statically allocated. 2099369Seric */ 2109369Seric 2119369Seric char * 2129369Seric username() 2139369Seric { 21417469Seric static char *myname = NULL; 2159369Seric extern char *getlogin(); 21619904Smiriam register struct passwd *pw; 2179369Seric 21817469Seric /* cache the result */ 21917469Seric if (myname == NULL) 22017469Seric { 22117469Seric myname = getlogin(); 22217469Seric if (myname == NULL || myname[0] == '\0') 22317469Seric { 22417469Seric 22517469Seric pw = getpwuid(getruid()); 22617469Seric if (pw != NULL) 22740993Sbostic myname = newstr(pw->pw_name); 22817469Seric } 22919904Smiriam else 23019904Smiriam { 23119873Smiriam 23240993Sbostic myname = newstr(myname); 23340993Sbostic if ((pw = getpwnam(myname)) == NULL || 23440993Sbostic getuid() != pw->pw_uid) 23519904Smiriam { 23619873Smiriam pw = getpwuid(getuid()); 23724945Seric if (pw != NULL) 23840993Sbostic myname = newstr(pw->pw_name); 23919873Smiriam } 24019873Smiriam } 24117469Seric if (myname == NULL || myname[0] == '\0') 24217469Seric { 24317469Seric syserr("Who are you?"); 24417469Seric myname = "postmaster"; 24517469Seric } 24617469Seric } 24717469Seric 24817469Seric return (myname); 2499369Seric } 2509369Seric /* 2514190Seric ** TTYPATH -- Get the path of the user's tty 252294Seric ** 253294Seric ** Returns the pathname of the user's tty. Returns NULL if 254294Seric ** the user is not logged in or if s/he has write permission 255294Seric ** denied. 256294Seric ** 257294Seric ** Parameters: 258294Seric ** none 259294Seric ** 260294Seric ** Returns: 261294Seric ** pathname of the user's tty. 262294Seric ** NULL if not logged in or write permission denied. 263294Seric ** 264294Seric ** Side Effects: 265294Seric ** none. 266294Seric ** 267294Seric ** WARNING: 268294Seric ** Return value is in a local buffer. 269294Seric ** 270294Seric ** Called By: 271294Seric ** savemail 272294Seric */ 273294Seric 274294Seric # include <sys/stat.h> 275294Seric 276294Seric char * 277294Seric ttypath() 278294Seric { 279294Seric struct stat stbuf; 280294Seric register char *pathn; 281294Seric extern char *ttyname(); 2824081Seric extern char *getlogin(); 283294Seric 284294Seric /* compute the pathname of the controlling tty */ 2859369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 2869369Seric (pathn = ttyname(0)) == NULL) 287294Seric { 288294Seric errno = 0; 289294Seric return (NULL); 290294Seric } 291294Seric 292294Seric /* see if we have write permission */ 2932967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 294294Seric { 295294Seric errno = 0; 296294Seric return (NULL); 297294Seric } 298294Seric 299294Seric /* see if the user is logged in */ 300294Seric if (getlogin() == NULL) 301294Seric return (NULL); 302294Seric 303294Seric /* looks good */ 304294Seric return (pathn); 305294Seric } 3062967Seric /* 3072967Seric ** CHECKCOMPAT -- check for From and To person compatible. 3082967Seric ** 3092967Seric ** This routine can be supplied on a per-installation basis 3102967Seric ** to determine whether a person is allowed to send a message. 3112967Seric ** This allows restriction of certain types of internet 3122967Seric ** forwarding or registration of users. 3132967Seric ** 3142967Seric ** If the hosts are found to be incompatible, an error 3152967Seric ** message should be given using "usrerr" and FALSE should 3162967Seric ** be returned. 3172967Seric ** 3184288Seric ** 'NoReturn' can be set to suppress the return-to-sender 3194288Seric ** function; this should be done on huge messages. 3204288Seric ** 3212967Seric ** Parameters: 3222967Seric ** to -- the person being sent to. 3232967Seric ** 3242967Seric ** Returns: 3252967Seric ** TRUE -- ok to send. 3262967Seric ** FALSE -- not ok. 3272967Seric ** 3282967Seric ** Side Effects: 3292967Seric ** none (unless you include the usrerr stuff) 3302967Seric */ 3312967Seric 3322967Seric bool 3332967Seric checkcompat(to) 3342967Seric register ADDRESS *to; 3352967Seric { 33612133Seric # ifdef lint 33712133Seric if (to == NULL) 33812133Seric to++; 33912133Seric # endif lint 34010698Seric # ifdef EXAMPLE_CODE 34110698Seric /* this code is intended as an example only */ 3424437Seric register STAB *s; 3434437Seric 3444437Seric s = stab("arpa", ST_MAILER, ST_FIND); 3459369Seric if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 3469369Seric to->q_mailer == s->s_mailer) 3474437Seric { 3484437Seric usrerr("No ARPA mail through this machine: see your system administration"); 34910698Seric /* NoReturn = TRUE; to supress return copy */ 3504437Seric return (FALSE); 3514437Seric } 35210698Seric # endif EXAMPLE_CODE 3532967Seric return (TRUE); 3542967Seric } 3559369Seric /* 3569369Seric ** HOLDSIGS -- arrange to hold all signals 3579369Seric ** 3589369Seric ** Parameters: 3599369Seric ** none. 3609369Seric ** 3619369Seric ** Returns: 3629369Seric ** none. 3639369Seric ** 3649369Seric ** Side Effects: 3659369Seric ** Arranges that signals are held. 3669369Seric */ 3679369Seric 3689369Seric holdsigs() 3699369Seric { 3709369Seric } 3719369Seric /* 3729369Seric ** RLSESIGS -- arrange to release all signals 3739369Seric ** 3749369Seric ** This undoes the effect of holdsigs. 3759369Seric ** 3769369Seric ** Parameters: 3779369Seric ** none. 3789369Seric ** 3799369Seric ** Returns: 3809369Seric ** none. 3819369Seric ** 3829369Seric ** Side Effects: 3839369Seric ** Arranges that signals are released. 3849369Seric */ 3859369Seric 3869369Seric rlsesigs() 3879369Seric { 3889369Seric } 38914872Seric /* 39014872Seric ** GETLA -- get the current load average 39114872Seric ** 39214881Seric ** This code stolen from la.c. 39314881Seric ** 39414872Seric ** Parameters: 39514872Seric ** none. 39614872Seric ** 39714872Seric ** Returns: 39814872Seric ** The current load average as an integer. 39914872Seric ** 40014872Seric ** Side Effects: 40114872Seric ** none. 40214872Seric */ 40314872Seric 404*51773Seric #ifdef sun 40514872Seric 40614872Seric #include <nlist.h> 40714872Seric 40814872Seric struct nlist Nl[] = 40914872Seric { 41014872Seric { "_avenrun" }, 41114872Seric #define X_AVENRUN 0 41214872Seric { 0 }, 41314872Seric }; 41414872Seric 41540930Srick 41640930Srick extern int la; 41740930Srick 41814872Seric getla() 41914872Seric { 42014872Seric static int kmem = -1; 42124943Seric long avenrun[3]; 42225615Seric extern off_t lseek(); 42314872Seric 42414872Seric if (kmem < 0) 42514872Seric { 42624945Seric kmem = open("/dev/kmem", 0, 0); 42714872Seric if (kmem < 0) 42814872Seric return (-1); 42923118Seric (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); 43014872Seric nlist("/vmunix", Nl); 43114872Seric if (Nl[0].n_type == 0) 43214872Seric return (-1); 43314872Seric } 43424945Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || 43523118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 43619967Seric { 43719967Seric /* thank you Ian */ 43819967Seric return (-1); 43919967Seric } 44024943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 44114872Seric } 44214872Seric 443*51773Seric #else 444*51773Seric #ifdef ultrix 445*51773Seric 446*51773Seric getla() 447*51773Seric { 448*51773Seric return (0); 449*51773Seric } 450*51773Seric 451*51773Seric #else 452*51773Seric 453*51773Seric getla() 454*51773Seric { 455*51773Seric double avenrun[3]; 456*51773Seric 457*51773Seric if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 458*51773Seric return (0); 459*51773Seric return ((int) (avenrun[0] + 0.5)); 460*51773Seric } 461*51773Seric 462*51773Seric #endif 463*51773Seric #endif 46424943Seric /* 46524943Seric ** SHOULDQUEUE -- should this message be queued or sent? 46624943Seric ** 46724943Seric ** Compares the message cost to the load average to decide. 46824943Seric ** 46924943Seric ** Parameters: 47024943Seric ** pri -- the priority of the message in question. 47124943Seric ** 47224943Seric ** Returns: 47324943Seric ** TRUE -- if this message should be queued up for the 47424943Seric ** time being. 47524943Seric ** FALSE -- if the load is low enough to send this message. 47624943Seric ** 47724943Seric ** Side Effects: 47824943Seric ** none. 47924943Seric */ 48024943Seric 48124943Seric bool 48224943Seric shouldqueue(pri) 48324943Seric long pri; 48424943Seric { 48524943Seric if (la < QueueLA) 48624943Seric return (FALSE); 48724943Seric return (pri > (QueueFactor / (la - QueueLA + 1))); 48824943Seric } 48924943Seric /* 49024943Seric ** SETPROCTITLE -- set process title for ps 49124943Seric ** 49224943Seric ** Parameters: 49324943Seric ** fmt -- a printf style format string. 49424943Seric ** a, b, c -- possible parameters to fmt. 49524943Seric ** 49624943Seric ** Returns: 49724943Seric ** none. 49824943Seric ** 49924943Seric ** Side Effects: 50024943Seric ** Clobbers argv of our main procedure so ps(1) will 50124943Seric ** display the title. 50224943Seric */ 50324943Seric 50424943Seric /*VARARGS1*/ 50524943Seric setproctitle(fmt, a, b, c) 50624943Seric char *fmt; 50724943Seric { 50824943Seric # ifdef SETPROCTITLE 50924943Seric register char *p; 51025049Seric register int i; 51124943Seric extern char **Argv; 51224943Seric extern char *LastArgv; 51325049Seric char buf[MAXLINE]; 51424943Seric 51525049Seric (void) sprintf(buf, fmt, a, b, c); 51624943Seric 51724943Seric /* make ps print "(sendmail)" */ 51825049Seric p = Argv[0]; 51924943Seric *p++ = '-'; 52024943Seric 52125049Seric i = strlen(buf); 52225049Seric if (i > LastArgv - p - 2) 52325049Seric { 52425049Seric i = LastArgv - p - 2; 52525049Seric buf[i] = '\0'; 52625049Seric } 52725049Seric (void) strcpy(p, buf); 52825049Seric p += i; 52924943Seric while (p < LastArgv) 53024943Seric *p++ = ' '; 53124943Seric # endif SETPROCTITLE 53224943Seric } 53325698Seric /* 53425698Seric ** REAPCHILD -- pick up the body of my child, lest it become a zombie 53525698Seric ** 53625698Seric ** Parameters: 53725698Seric ** none. 53825698Seric ** 53925698Seric ** Returns: 54025698Seric ** none. 54125698Seric ** 54225698Seric ** Side Effects: 54325698Seric ** Picks up extant zombies. 54425698Seric */ 54525698Seric 54625698Seric # ifdef VMUNIX 54725698Seric # include <sys/wait.h> 54825698Seric # endif VMUNIX 54925698Seric 55046928Sbostic void 55125698Seric reapchild() 55225698Seric { 55325698Seric # ifdef WNOHANG 55425698Seric union wait status; 55525698Seric 55646928Sbostic while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0) 55725698Seric continue; 55825698Seric # else WNOHANG 55925698Seric auto int status; 56025698Seric 56146928Sbostic while (wait((int *)&status) > 0) 56225698Seric continue; 56325698Seric # endif WNOHANG 56425698Seric } 565