122698Sdist /* 234920Sbostic * Copyright (c) 1983 Eric P. Allman 333728Sbostic * Copyright (c) 1988 Regents of the University of California. 433728Sbostic * All rights reserved. 533728Sbostic * 633728Sbostic * Redistribution and use in source and binary forms are permitted 734920Sbostic * provided that the above copyright notice and this paragraph are 834920Sbostic * duplicated in all such forms and that any documentation, 934920Sbostic * advertising materials, and other materials related to such 1034920Sbostic * distribution and use acknowledge that the software was developed 1134920Sbostic * by the University of California, Berkeley. The name of the 1234920Sbostic * University may not be used to endorse or promote products derived 1334920Sbostic * from this software without specific prior written permission. 1434920Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1534920Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1634920Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1733728Sbostic */ 1822698Sdist 1922698Sdist #ifndef lint 20*40938Srick static char sccsid[] = "@(#)conf.c 5.22 (Berkeley) 04/16/90"; 2133728Sbostic #endif /* not lint */ 2222698Sdist 2314881Seric # include <sys/ioctl.h> 2424943Seric # include <sys/param.h> 2536928Sbostic # include <pwd.h> 263309Seric # include "sendmail.h" 27404Seric 28294Seric /* 293309Seric ** CONF.C -- Sendmail Configuration Tables. 30294Seric ** 31294Seric ** Defines the configuration of this installation. 32294Seric ** 331388Seric ** Compilation Flags: 3414872Seric ** VMUNIX -- running on a Berkeley UNIX system. 35294Seric ** 361388Seric ** Configuration Variables: 372897Seric ** HdrInfo -- a table describing well-known header fields. 382897Seric ** Each entry has the field name and some flags, 394147Seric ** which are described in sendmail.h. 404093Seric ** 414093Seric ** Notes: 424093Seric ** I have tried to put almost all the reasonable 434093Seric ** configuration information into the configuration 444093Seric ** file read at runtime. My intent is that anything 454093Seric ** here is a function of the version of UNIX you 464093Seric ** are running, or is really static -- for example 474093Seric ** the headers are a superset of widely used 484093Seric ** protocols. If you find yourself playing with 494093Seric ** this file too much, you may be making a mistake! 50294Seric */ 51294Seric 52294Seric 53294Seric 54294Seric 554437Seric /* 562897Seric ** Header info table 573057Seric ** Final (null) entry contains the flags used for any other field. 584147Seric ** 594147Seric ** Not all of these are actually handled specially by sendmail 604147Seric ** at this time. They are included as placeholders, to let 614147Seric ** you know that "someday" I intend to have sendmail do 624147Seric ** something with them. 632897Seric */ 642897Seric 652897Seric struct hdrinfo HdrInfo[] = 662897Seric { 678060Seric /* originator fields, most to least significant */ 6811417Seric "resent-sender", H_FROM|H_RESENT, 6911417Seric "resent-from", H_FROM|H_RESENT, 7025686Seric "resent-reply-to", H_FROM|H_RESENT, 719055Seric "sender", H_FROM, 729055Seric "from", H_FROM, 7325686Seric "reply-to", H_FROM, 749055Seric "full-name", H_ACHECK, 759055Seric "return-receipt-to", H_FROM, 769055Seric "errors-to", H_FROM, 778060Seric /* destination fields */ 789055Seric "to", H_RCPT, 7911417Seric "resent-to", H_RCPT|H_RESENT, 809055Seric "cc", H_RCPT, 8111417Seric "resent-cc", H_RCPT|H_RESENT, 829055Seric "bcc", H_RCPT|H_ACHECK, 8311417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 848060Seric /* message identification and control */ 8511417Seric "message-id", 0, 8611417Seric "resent-message-id", H_RESENT, 879055Seric "message", H_EOH, 889055Seric "text", H_EOH, 8911417Seric /* date fields */ 9011417Seric "date", 0, 9111417Seric "resent-date", H_RESENT, 928060Seric /* trace fields */ 939055Seric "received", H_TRACE|H_FORCE, 949055Seric "via", H_TRACE|H_FORCE, 959055Seric "mail-from", H_TRACE|H_FORCE, 968060Seric 979055Seric NULL, 0, 982897Seric }; 994166Seric 1004166Seric 1014166Seric /* 1024166Seric ** ARPANET error message numbers. 1034166Seric */ 1044166Seric 1057956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 1067956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 1077956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 1087956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 1094282Seric 1104282Seric 1114282Seric 1124282Seric /* 1134282Seric ** Location of system files/databases/etc. 1144282Seric */ 1154282Seric 11637972Sbostic char *ConfFile = "/etc/sendmail.cf"; /* runtime configuration */ 11737972Sbostic char *FreezeFile = "/etc/sendmail.fc"; /* frozen version of above */ 1189039Seric 1199064Seric 1209064Seric 1219039Seric /* 12224943Seric ** Miscellaneous stuff. 1239039Seric */ 1249039Seric 12524943Seric int DtableSize = 50; /* max open files; reset in 4.2bsd */ 126*40938Srick extern int la; /* load average */ 12724943Seric /* 12824943Seric ** SETDEFAULTS -- set default values 12924943Seric ** 13024943Seric ** Because of the way freezing is done, these must be initialized 13124943Seric ** using direct code. 13224943Seric ** 13324943Seric ** Parameters: 13424943Seric ** none. 13524943Seric ** 13624943Seric ** Returns: 13724943Seric ** none. 13824943Seric ** 13924943Seric ** Side Effects: 14024943Seric ** Initializes a bunch of global variables to their 14124943Seric ** default values. 14224943Seric */ 14324943Seric 14424943Seric setdefaults() 14524943Seric { 14624943Seric QueueLA = 8; 14724943Seric QueueFactor = 10000; 14824943Seric RefuseLA = 12; 14924943Seric SpaceSub = ' '; 15024981Seric WkRecipFact = 1000; 15124981Seric WkClassFact = 1800; 15225812Seric WkTimeFact = 9000; 15324981Seric FileMode = 0644; 15424981Seric DefUid = 1; 15524981Seric DefGid = 1; 15624943Seric } 157294Seric 1584326Seric /* 1594326Seric ** GETRUID -- get real user id (V7) 1604326Seric */ 1614326Seric 1624326Seric getruid() 1634326Seric { 1649274Seric if (OpMode == MD_DAEMON) 1654536Seric return (RealUid); 1664536Seric else 1674536Seric return (getuid()); 1684326Seric } 1694326Seric 1704326Seric 1714326Seric /* 1724326Seric ** GETRGID -- get real group id (V7). 1734326Seric */ 1744326Seric 1754326Seric getrgid() 1764326Seric { 1779274Seric if (OpMode == MD_DAEMON) 1784536Seric return (RealGid); 1794536Seric else 1804536Seric return (getgid()); 1814326Seric } 1824326Seric 18333936Sbostic /* 1849369Seric ** USERNAME -- return the user id of the logged in user. 1859369Seric ** 1869369Seric ** Parameters: 1879369Seric ** none. 1889369Seric ** 1899369Seric ** Returns: 1909369Seric ** The login name of the logged in user. 1919369Seric ** 1929369Seric ** Side Effects: 1939369Seric ** none. 1949369Seric ** 1959369Seric ** Notes: 1969369Seric ** The return value is statically allocated. 1979369Seric */ 1989369Seric 1999369Seric char * 2009369Seric username() 2019369Seric { 20217469Seric static char *myname = NULL; 2039369Seric extern char *getlogin(); 20419904Smiriam register struct passwd *pw; 20519904Smiriam extern struct passwd *getpwuid(); 2069369Seric 20717469Seric /* cache the result */ 20817469Seric if (myname == NULL) 20917469Seric { 21017469Seric myname = getlogin(); 21117469Seric if (myname == NULL || myname[0] == '\0') 21217469Seric { 21317469Seric 21417469Seric pw = getpwuid(getruid()); 21517469Seric if (pw != NULL) 21617469Seric myname = pw->pw_name; 21717469Seric } 21819904Smiriam else 21919904Smiriam { 22019873Smiriam 22119873Smiriam pw = getpwnam(myname); 22219904Smiriam if(getuid() != pw->pw_uid) 22319904Smiriam { 22419873Smiriam pw = getpwuid(getuid()); 22524945Seric if (pw != NULL) 22624945Seric myname = pw->pw_name; 22719873Smiriam } 22819873Smiriam } 22917469Seric if (myname == NULL || myname[0] == '\0') 23017469Seric { 23117469Seric syserr("Who are you?"); 23217469Seric myname = "postmaster"; 23317469Seric } 23417469Seric } 23517469Seric 23617469Seric return (myname); 2379369Seric } 2389369Seric /* 2394190Seric ** TTYPATH -- Get the path of the user's tty 240294Seric ** 241294Seric ** Returns the pathname of the user's tty. Returns NULL if 242294Seric ** the user is not logged in or if s/he has write permission 243294Seric ** denied. 244294Seric ** 245294Seric ** Parameters: 246294Seric ** none 247294Seric ** 248294Seric ** Returns: 249294Seric ** pathname of the user's tty. 250294Seric ** NULL if not logged in or write permission denied. 251294Seric ** 252294Seric ** Side Effects: 253294Seric ** none. 254294Seric ** 255294Seric ** WARNING: 256294Seric ** Return value is in a local buffer. 257294Seric ** 258294Seric ** Called By: 259294Seric ** savemail 260294Seric */ 261294Seric 262294Seric # include <sys/stat.h> 263294Seric 264294Seric char * 265294Seric ttypath() 266294Seric { 267294Seric struct stat stbuf; 268294Seric register char *pathn; 269294Seric extern char *ttyname(); 2704081Seric extern char *getlogin(); 271294Seric 272294Seric /* compute the pathname of the controlling tty */ 2739369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 2749369Seric (pathn = ttyname(0)) == NULL) 275294Seric { 276294Seric errno = 0; 277294Seric return (NULL); 278294Seric } 279294Seric 280294Seric /* see if we have write permission */ 2812967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 282294Seric { 283294Seric errno = 0; 284294Seric return (NULL); 285294Seric } 286294Seric 287294Seric /* see if the user is logged in */ 288294Seric if (getlogin() == NULL) 289294Seric return (NULL); 290294Seric 291294Seric /* looks good */ 292294Seric return (pathn); 293294Seric } 2942967Seric /* 2952967Seric ** CHECKCOMPAT -- check for From and To person compatible. 2962967Seric ** 2972967Seric ** This routine can be supplied on a per-installation basis 2982967Seric ** to determine whether a person is allowed to send a message. 2992967Seric ** This allows restriction of certain types of internet 3002967Seric ** forwarding or registration of users. 3012967Seric ** 3022967Seric ** If the hosts are found to be incompatible, an error 3032967Seric ** message should be given using "usrerr" and FALSE should 3042967Seric ** be returned. 3052967Seric ** 3064288Seric ** 'NoReturn' can be set to suppress the return-to-sender 3074288Seric ** function; this should be done on huge messages. 3084288Seric ** 3092967Seric ** Parameters: 3102967Seric ** to -- the person being sent to. 3112967Seric ** 3122967Seric ** Returns: 3132967Seric ** TRUE -- ok to send. 3142967Seric ** FALSE -- not ok. 3152967Seric ** 3162967Seric ** Side Effects: 3172967Seric ** none (unless you include the usrerr stuff) 3182967Seric */ 3192967Seric 3202967Seric bool 3212967Seric checkcompat(to) 3222967Seric register ADDRESS *to; 3232967Seric { 32412133Seric # ifdef lint 32512133Seric if (to == NULL) 32612133Seric to++; 32712133Seric # endif lint 32810698Seric # ifdef EXAMPLE_CODE 32910698Seric /* this code is intended as an example only */ 3304437Seric register STAB *s; 3314437Seric 3324437Seric s = stab("arpa", ST_MAILER, ST_FIND); 3339369Seric if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 3349369Seric to->q_mailer == s->s_mailer) 3354437Seric { 3364437Seric usrerr("No ARPA mail through this machine: see your system administration"); 33710698Seric /* NoReturn = TRUE; to supress return copy */ 3384437Seric return (FALSE); 3394437Seric } 34010698Seric # endif EXAMPLE_CODE 3412967Seric return (TRUE); 3422967Seric } 3439369Seric /* 3449369Seric ** HOLDSIGS -- arrange to hold all signals 3459369Seric ** 3469369Seric ** Parameters: 3479369Seric ** none. 3489369Seric ** 3499369Seric ** Returns: 3509369Seric ** none. 3519369Seric ** 3529369Seric ** Side Effects: 3539369Seric ** Arranges that signals are held. 3549369Seric */ 3559369Seric 3569369Seric holdsigs() 3579369Seric { 3589369Seric } 3599369Seric /* 3609369Seric ** RLSESIGS -- arrange to release all signals 3619369Seric ** 3629369Seric ** This undoes the effect of holdsigs. 3639369Seric ** 3649369Seric ** Parameters: 3659369Seric ** none. 3669369Seric ** 3679369Seric ** Returns: 3689369Seric ** none. 3699369Seric ** 3709369Seric ** Side Effects: 3719369Seric ** Arranges that signals are released. 3729369Seric */ 3739369Seric 3749369Seric rlsesigs() 3759369Seric { 3769369Seric } 37714872Seric /* 37814872Seric ** GETLA -- get the current load average 37914872Seric ** 38014881Seric ** This code stolen from la.c. 38114881Seric ** 38214872Seric ** Parameters: 38314872Seric ** none. 38414872Seric ** 38514872Seric ** Returns: 38614872Seric ** The current load average as an integer. 38714872Seric ** 38814872Seric ** Side Effects: 38914872Seric ** none. 39014872Seric */ 39114872Seric 39238196Smckusick #ifndef sun 39314872Seric 39438196Smckusick getla() 39538196Smckusick { 39638196Smckusick double avenrun[3]; 39738196Smckusick 39838196Smckusick if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 39938196Smckusick return (0); 40038196Smckusick return ((int) (avenrun[0] + 0.5)); 40138196Smckusick } 40238196Smckusick 40338196Smckusick #else /* sun */ 40438196Smckusick 40514872Seric #include <nlist.h> 40614872Seric 40714872Seric struct nlist Nl[] = 40814872Seric { 40914872Seric { "_avenrun" }, 41014872Seric #define X_AVENRUN 0 41114872Seric { 0 }, 41214872Seric }; 41314872Seric 41440930Srick 41540930Srick extern int la; 41640930Srick 41714872Seric getla() 41814872Seric { 41914872Seric static int kmem = -1; 42024943Seric long avenrun[3]; 42125615Seric extern off_t lseek(); 42214872Seric 42314872Seric if (kmem < 0) 42414872Seric { 42524945Seric kmem = open("/dev/kmem", 0, 0); 42614872Seric if (kmem < 0) 42714872Seric return (-1); 42823118Seric (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); 42914872Seric nlist("/vmunix", Nl); 43014872Seric if (Nl[0].n_type == 0) 43114872Seric return (-1); 43214872Seric } 43324945Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || 43423118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 43519967Seric { 43619967Seric /* thank you Ian */ 43719967Seric return (-1); 43819967Seric } 43924943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 44014872Seric } 44114872Seric 44238196Smckusick #endif /* sun */ 44324943Seric /* 44424943Seric ** SHOULDQUEUE -- should this message be queued or sent? 44524943Seric ** 44624943Seric ** Compares the message cost to the load average to decide. 44724943Seric ** 44824943Seric ** Parameters: 44924943Seric ** pri -- the priority of the message in question. 45024943Seric ** 45124943Seric ** Returns: 45224943Seric ** TRUE -- if this message should be queued up for the 45324943Seric ** time being. 45424943Seric ** FALSE -- if the load is low enough to send this message. 45524943Seric ** 45624943Seric ** Side Effects: 45724943Seric ** none. 45824943Seric */ 45924943Seric 46024943Seric bool 46124943Seric shouldqueue(pri) 46224943Seric long pri; 46324943Seric { 46424943Seric if (la < QueueLA) 46524943Seric return (FALSE); 46624943Seric return (pri > (QueueFactor / (la - QueueLA + 1))); 46724943Seric } 46824943Seric /* 46924943Seric ** SETPROCTITLE -- set process title for ps 47024943Seric ** 47124943Seric ** Parameters: 47224943Seric ** fmt -- a printf style format string. 47324943Seric ** a, b, c -- possible parameters to fmt. 47424943Seric ** 47524943Seric ** Returns: 47624943Seric ** none. 47724943Seric ** 47824943Seric ** Side Effects: 47924943Seric ** Clobbers argv of our main procedure so ps(1) will 48024943Seric ** display the title. 48124943Seric */ 48224943Seric 48324943Seric /*VARARGS1*/ 48424943Seric setproctitle(fmt, a, b, c) 48524943Seric char *fmt; 48624943Seric { 48724943Seric # ifdef SETPROCTITLE 48824943Seric register char *p; 48925049Seric register int i; 49024943Seric extern char **Argv; 49124943Seric extern char *LastArgv; 49225049Seric char buf[MAXLINE]; 49324943Seric 49425049Seric (void) sprintf(buf, fmt, a, b, c); 49524943Seric 49624943Seric /* make ps print "(sendmail)" */ 49725049Seric p = Argv[0]; 49824943Seric *p++ = '-'; 49924943Seric 50025049Seric i = strlen(buf); 50125049Seric if (i > LastArgv - p - 2) 50225049Seric { 50325049Seric i = LastArgv - p - 2; 50425049Seric buf[i] = '\0'; 50525049Seric } 50625049Seric (void) strcpy(p, buf); 50725049Seric p += i; 50824943Seric while (p < LastArgv) 50924943Seric *p++ = ' '; 51024943Seric # endif SETPROCTITLE 51124943Seric } 51225698Seric /* 51325698Seric ** REAPCHILD -- pick up the body of my child, lest it become a zombie 51425698Seric ** 51525698Seric ** Parameters: 51625698Seric ** none. 51725698Seric ** 51825698Seric ** Returns: 51925698Seric ** none. 52025698Seric ** 52125698Seric ** Side Effects: 52225698Seric ** Picks up extant zombies. 52325698Seric */ 52425698Seric 52525698Seric # ifdef VMUNIX 52625698Seric # include <sys/wait.h> 52725698Seric # endif VMUNIX 52825698Seric 52925698Seric reapchild() 53025698Seric { 53125698Seric # ifdef WNOHANG 53225698Seric union wait status; 53325698Seric 53425698Seric while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0) 53525698Seric continue; 53625698Seric # else WNOHANG 53725698Seric auto int status; 53825698Seric 53925698Seric while (wait(&status) > 0) 54025698Seric continue; 54125698Seric # endif WNOHANG 54225698Seric } 543