122698Sdist /* 2*34920Sbostic * 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 7*34920Sbostic * provided that the above copyright notice and this paragraph are 8*34920Sbostic * duplicated in all such forms and that any documentation, 9*34920Sbostic * advertising materials, and other materials related to such 10*34920Sbostic * distribution and use acknowledge that the software was developed 11*34920Sbostic * by the University of California, Berkeley. The name of the 12*34920Sbostic * University may not be used to endorse or promote products derived 13*34920Sbostic * from this software without specific prior written permission. 14*34920Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15*34920Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16*34920Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1733728Sbostic */ 1822698Sdist 1922698Sdist #ifndef lint 20*34920Sbostic static char sccsid[] = "@(#)conf.c 5.17 (Berkeley) 06/30/88"; 2133728Sbostic #endif /* not lint */ 2222698Sdist 23294Seric # include <pwd.h> 2414881Seric # include <sys/ioctl.h> 2524943Seric # ifdef sun 2624943Seric # include <sys/param.h> 2724943Seric # endif sun 283309Seric # include "sendmail.h" 29404Seric 30294Seric /* 313309Seric ** CONF.C -- Sendmail Configuration Tables. 32294Seric ** 33294Seric ** Defines the configuration of this installation. 34294Seric ** 351388Seric ** Compilation Flags: 3614872Seric ** VMUNIX -- running on a Berkeley UNIX system. 37294Seric ** 381388Seric ** Configuration Variables: 392897Seric ** HdrInfo -- a table describing well-known header fields. 402897Seric ** Each entry has the field name and some flags, 414147Seric ** which are described in sendmail.h. 424093Seric ** 434093Seric ** Notes: 444093Seric ** I have tried to put almost all the reasonable 454093Seric ** configuration information into the configuration 464093Seric ** file read at runtime. My intent is that anything 474093Seric ** here is a function of the version of UNIX you 484093Seric ** are running, or is really static -- for example 494093Seric ** the headers are a superset of widely used 504093Seric ** protocols. If you find yourself playing with 514093Seric ** this file too much, you may be making a mistake! 52294Seric */ 53294Seric 54294Seric 55294Seric 56294Seric 574437Seric /* 582897Seric ** Header info table 593057Seric ** Final (null) entry contains the flags used for any other field. 604147Seric ** 614147Seric ** Not all of these are actually handled specially by sendmail 624147Seric ** at this time. They are included as placeholders, to let 634147Seric ** you know that "someday" I intend to have sendmail do 644147Seric ** something with them. 652897Seric */ 662897Seric 672897Seric struct hdrinfo HdrInfo[] = 682897Seric { 698060Seric /* originator fields, most to least significant */ 7011417Seric "resent-sender", H_FROM|H_RESENT, 7111417Seric "resent-from", H_FROM|H_RESENT, 7225686Seric "resent-reply-to", H_FROM|H_RESENT, 739055Seric "sender", H_FROM, 749055Seric "from", H_FROM, 7525686Seric "reply-to", H_FROM, 769055Seric "full-name", H_ACHECK, 779055Seric "return-receipt-to", H_FROM, 789055Seric "errors-to", H_FROM, 798060Seric /* destination fields */ 809055Seric "to", H_RCPT, 8111417Seric "resent-to", H_RCPT|H_RESENT, 829055Seric "cc", H_RCPT, 8311417Seric "resent-cc", H_RCPT|H_RESENT, 849055Seric "bcc", H_RCPT|H_ACHECK, 8511417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 868060Seric /* message identification and control */ 8711417Seric "message-id", 0, 8811417Seric "resent-message-id", H_RESENT, 899055Seric "message", H_EOH, 909055Seric "text", H_EOH, 9111417Seric /* date fields */ 9211417Seric "date", 0, 9311417Seric "resent-date", H_RESENT, 948060Seric /* trace fields */ 959055Seric "received", H_TRACE|H_FORCE, 969055Seric "via", H_TRACE|H_FORCE, 979055Seric "mail-from", H_TRACE|H_FORCE, 988060Seric 999055Seric NULL, 0, 1002897Seric }; 1014166Seric 1024166Seric 1034166Seric /* 1044166Seric ** ARPANET error message numbers. 1054166Seric */ 1064166Seric 1077956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 1087956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 1097956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 1107956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 1114282Seric 1124282Seric 1134282Seric 1144282Seric /* 1154282Seric ** Location of system files/databases/etc. 1164282Seric */ 1174282Seric 1184282Seric char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ 1199064Seric char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */ 1209039Seric 1219064Seric 1229064Seric 1239039Seric /* 12424943Seric ** Miscellaneous stuff. 1259039Seric */ 1269039Seric 12724943Seric int DtableSize = 50; /* max open files; reset in 4.2bsd */ 12824943Seric /* 12924943Seric ** SETDEFAULTS -- set default values 13024943Seric ** 13124943Seric ** Because of the way freezing is done, these must be initialized 13224943Seric ** using direct code. 13324943Seric ** 13424943Seric ** Parameters: 13524943Seric ** none. 13624943Seric ** 13724943Seric ** Returns: 13824943Seric ** none. 13924943Seric ** 14024943Seric ** Side Effects: 14124943Seric ** Initializes a bunch of global variables to their 14224943Seric ** default values. 14324943Seric */ 14424943Seric 14524943Seric setdefaults() 14624943Seric { 14724943Seric QueueLA = 8; 14824943Seric QueueFactor = 10000; 14924943Seric RefuseLA = 12; 15024943Seric SpaceSub = ' '; 15124981Seric WkRecipFact = 1000; 15224981Seric WkClassFact = 1800; 15325812Seric WkTimeFact = 9000; 15424981Seric FileMode = 0644; 15524981Seric DefUid = 1; 15624981Seric DefGid = 1; 15724943Seric } 158294Seric 1594326Seric /* 1604326Seric ** GETRUID -- get real user id (V7) 1614326Seric */ 1624326Seric 1634326Seric getruid() 1644326Seric { 1659274Seric if (OpMode == MD_DAEMON) 1664536Seric return (RealUid); 1674536Seric else 1684536Seric return (getuid()); 1694326Seric } 1704326Seric 1714326Seric 1724326Seric /* 1734326Seric ** GETRGID -- get real group id (V7). 1744326Seric */ 1754326Seric 1764326Seric getrgid() 1774326Seric { 1789274Seric if (OpMode == MD_DAEMON) 1794536Seric return (RealGid); 1804536Seric else 1814536Seric return (getgid()); 1824326Seric } 1834326Seric 18433936Sbostic /* 1859369Seric ** USERNAME -- return the user id of the logged in user. 1869369Seric ** 1879369Seric ** Parameters: 1889369Seric ** none. 1899369Seric ** 1909369Seric ** Returns: 1919369Seric ** The login name of the logged in user. 1929369Seric ** 1939369Seric ** Side Effects: 1949369Seric ** none. 1959369Seric ** 1969369Seric ** Notes: 1979369Seric ** The return value is statically allocated. 1989369Seric */ 1999369Seric 2009369Seric char * 2019369Seric username() 2029369Seric { 20317469Seric static char *myname = NULL; 2049369Seric extern char *getlogin(); 20519904Smiriam register struct passwd *pw; 20619904Smiriam extern struct passwd *getpwuid(); 2079369Seric 20817469Seric /* cache the result */ 20917469Seric if (myname == NULL) 21017469Seric { 21117469Seric myname = getlogin(); 21217469Seric if (myname == NULL || myname[0] == '\0') 21317469Seric { 21417469Seric 21517469Seric pw = getpwuid(getruid()); 21617469Seric if (pw != NULL) 21717469Seric myname = pw->pw_name; 21817469Seric } 21919904Smiriam else 22019904Smiriam { 22119873Smiriam 22219873Smiriam pw = getpwnam(myname); 22319904Smiriam if(getuid() != pw->pw_uid) 22419904Smiriam { 22519873Smiriam pw = getpwuid(getuid()); 22624945Seric if (pw != NULL) 22724945Seric myname = pw->pw_name; 22819873Smiriam } 22919873Smiriam } 23017469Seric if (myname == NULL || myname[0] == '\0') 23117469Seric { 23217469Seric syserr("Who are you?"); 23317469Seric myname = "postmaster"; 23417469Seric } 23517469Seric } 23617469Seric 23717469Seric return (myname); 2389369Seric } 2399369Seric /* 2404190Seric ** TTYPATH -- Get the path of the user's tty 241294Seric ** 242294Seric ** Returns the pathname of the user's tty. Returns NULL if 243294Seric ** the user is not logged in or if s/he has write permission 244294Seric ** denied. 245294Seric ** 246294Seric ** Parameters: 247294Seric ** none 248294Seric ** 249294Seric ** Returns: 250294Seric ** pathname of the user's tty. 251294Seric ** NULL if not logged in or write permission denied. 252294Seric ** 253294Seric ** Side Effects: 254294Seric ** none. 255294Seric ** 256294Seric ** WARNING: 257294Seric ** Return value is in a local buffer. 258294Seric ** 259294Seric ** Called By: 260294Seric ** savemail 261294Seric */ 262294Seric 263294Seric # include <sys/stat.h> 264294Seric 265294Seric char * 266294Seric ttypath() 267294Seric { 268294Seric struct stat stbuf; 269294Seric register char *pathn; 270294Seric extern char *ttyname(); 2714081Seric extern char *getlogin(); 272294Seric 273294Seric /* compute the pathname of the controlling tty */ 2749369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 2759369Seric (pathn = ttyname(0)) == NULL) 276294Seric { 277294Seric errno = 0; 278294Seric return (NULL); 279294Seric } 280294Seric 281294Seric /* see if we have write permission */ 2822967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 283294Seric { 284294Seric errno = 0; 285294Seric return (NULL); 286294Seric } 287294Seric 288294Seric /* see if the user is logged in */ 289294Seric if (getlogin() == NULL) 290294Seric return (NULL); 291294Seric 292294Seric /* looks good */ 293294Seric return (pathn); 294294Seric } 2952967Seric /* 2962967Seric ** CHECKCOMPAT -- check for From and To person compatible. 2972967Seric ** 2982967Seric ** This routine can be supplied on a per-installation basis 2992967Seric ** to determine whether a person is allowed to send a message. 3002967Seric ** This allows restriction of certain types of internet 3012967Seric ** forwarding or registration of users. 3022967Seric ** 3032967Seric ** If the hosts are found to be incompatible, an error 3042967Seric ** message should be given using "usrerr" and FALSE should 3052967Seric ** be returned. 3062967Seric ** 3074288Seric ** 'NoReturn' can be set to suppress the return-to-sender 3084288Seric ** function; this should be done on huge messages. 3094288Seric ** 3102967Seric ** Parameters: 3112967Seric ** to -- the person being sent to. 3122967Seric ** 3132967Seric ** Returns: 3142967Seric ** TRUE -- ok to send. 3152967Seric ** FALSE -- not ok. 3162967Seric ** 3172967Seric ** Side Effects: 3182967Seric ** none (unless you include the usrerr stuff) 3192967Seric */ 3202967Seric 3212967Seric bool 3222967Seric checkcompat(to) 3232967Seric register ADDRESS *to; 3242967Seric { 32512133Seric # ifdef lint 32612133Seric if (to == NULL) 32712133Seric to++; 32812133Seric # endif lint 32910698Seric # ifdef EXAMPLE_CODE 33010698Seric /* this code is intended as an example only */ 3314437Seric register STAB *s; 3324437Seric 3334437Seric s = stab("arpa", ST_MAILER, ST_FIND); 3349369Seric if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 3359369Seric to->q_mailer == s->s_mailer) 3364437Seric { 3374437Seric usrerr("No ARPA mail through this machine: see your system administration"); 33810698Seric /* NoReturn = TRUE; to supress return copy */ 3394437Seric return (FALSE); 3404437Seric } 34110698Seric # endif EXAMPLE_CODE 3422967Seric return (TRUE); 3432967Seric } 3449369Seric /* 3459369Seric ** HOLDSIGS -- arrange to hold all signals 3469369Seric ** 3479369Seric ** Parameters: 3489369Seric ** none. 3499369Seric ** 3509369Seric ** Returns: 3519369Seric ** none. 3529369Seric ** 3539369Seric ** Side Effects: 3549369Seric ** Arranges that signals are held. 3559369Seric */ 3569369Seric 3579369Seric holdsigs() 3589369Seric { 3599369Seric } 3609369Seric /* 3619369Seric ** RLSESIGS -- arrange to release all signals 3629369Seric ** 3639369Seric ** This undoes the effect of holdsigs. 3649369Seric ** 3659369Seric ** Parameters: 3669369Seric ** none. 3679369Seric ** 3689369Seric ** Returns: 3699369Seric ** none. 3709369Seric ** 3719369Seric ** Side Effects: 3729369Seric ** Arranges that signals are released. 3739369Seric */ 3749369Seric 3759369Seric rlsesigs() 3769369Seric { 3779369Seric } 37814872Seric /* 37914872Seric ** GETLA -- get the current load average 38014872Seric ** 38114881Seric ** This code stolen from la.c. 38214881Seric ** 38314872Seric ** Parameters: 38414872Seric ** none. 38514872Seric ** 38614872Seric ** Returns: 38714872Seric ** The current load average as an integer. 38814872Seric ** 38914872Seric ** Side Effects: 39014872Seric ** none. 39114872Seric */ 39214872Seric 39314872Seric #ifdef VMUNIX 39414872Seric 39514872Seric #include <nlist.h> 39614872Seric 39714872Seric struct nlist Nl[] = 39814872Seric { 39914872Seric { "_avenrun" }, 40014872Seric #define X_AVENRUN 0 40114872Seric { 0 }, 40214872Seric }; 40314872Seric 40414872Seric getla() 40514872Seric { 40614872Seric static int kmem = -1; 40724943Seric # ifdef sun 40824943Seric long avenrun[3]; 40924943Seric # else 41014872Seric double avenrun[3]; 41124943Seric # endif 41225615Seric extern off_t lseek(); 41314872Seric 41414872Seric if (kmem < 0) 41514872Seric { 41624945Seric kmem = open("/dev/kmem", 0, 0); 41714872Seric if (kmem < 0) 41814872Seric return (-1); 41923118Seric (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); 42014872Seric nlist("/vmunix", Nl); 42114872Seric if (Nl[0].n_type == 0) 42214872Seric return (-1); 42314872Seric } 42424945Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || 42523118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 42619967Seric { 42719967Seric /* thank you Ian */ 42819967Seric return (-1); 42919967Seric } 43024943Seric # ifdef sun 43124943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 43224943Seric # else 43314872Seric return ((int) (avenrun[0] + 0.5)); 43424943Seric # endif 43514872Seric } 43614872Seric 43714872Seric #else VMUNIX 43814872Seric 43914872Seric getla() 44014872Seric { 44114872Seric return (0); 44214872Seric } 44314872Seric 44414872Seric #endif VMUNIX 44524943Seric /* 44624943Seric ** SHOULDQUEUE -- should this message be queued or sent? 44724943Seric ** 44824943Seric ** Compares the message cost to the load average to decide. 44924943Seric ** 45024943Seric ** Parameters: 45124943Seric ** pri -- the priority of the message in question. 45224943Seric ** 45324943Seric ** Returns: 45424943Seric ** TRUE -- if this message should be queued up for the 45524943Seric ** time being. 45624943Seric ** FALSE -- if the load is low enough to send this message. 45724943Seric ** 45824943Seric ** Side Effects: 45924943Seric ** none. 46024943Seric */ 46124943Seric 46224943Seric bool 46324943Seric shouldqueue(pri) 46424943Seric long pri; 46524943Seric { 46624943Seric int la; 46724943Seric 46824943Seric la = getla(); 46924943Seric if (la < QueueLA) 47024943Seric return (FALSE); 47124943Seric return (pri > (QueueFactor / (la - QueueLA + 1))); 47224943Seric } 47324943Seric /* 47424943Seric ** SETPROCTITLE -- set process title for ps 47524943Seric ** 47624943Seric ** Parameters: 47724943Seric ** fmt -- a printf style format string. 47824943Seric ** a, b, c -- possible parameters to fmt. 47924943Seric ** 48024943Seric ** Returns: 48124943Seric ** none. 48224943Seric ** 48324943Seric ** Side Effects: 48424943Seric ** Clobbers argv of our main procedure so ps(1) will 48524943Seric ** display the title. 48624943Seric */ 48724943Seric 48824943Seric /*VARARGS1*/ 48924943Seric setproctitle(fmt, a, b, c) 49024943Seric char *fmt; 49124943Seric { 49224943Seric # ifdef SETPROCTITLE 49324943Seric register char *p; 49425049Seric register int i; 49524943Seric extern char **Argv; 49624943Seric extern char *LastArgv; 49725049Seric char buf[MAXLINE]; 49824943Seric 49925049Seric (void) sprintf(buf, fmt, a, b, c); 50024943Seric 50124943Seric /* make ps print "(sendmail)" */ 50225049Seric p = Argv[0]; 50324943Seric *p++ = '-'; 50424943Seric 50525049Seric i = strlen(buf); 50625049Seric if (i > LastArgv - p - 2) 50725049Seric { 50825049Seric i = LastArgv - p - 2; 50925049Seric buf[i] = '\0'; 51025049Seric } 51125049Seric (void) strcpy(p, buf); 51225049Seric p += i; 51324943Seric while (p < LastArgv) 51424943Seric *p++ = ' '; 51524943Seric # endif SETPROCTITLE 51624943Seric } 51725698Seric /* 51825698Seric ** REAPCHILD -- pick up the body of my child, lest it become a zombie 51925698Seric ** 52025698Seric ** Parameters: 52125698Seric ** none. 52225698Seric ** 52325698Seric ** Returns: 52425698Seric ** none. 52525698Seric ** 52625698Seric ** Side Effects: 52725698Seric ** Picks up extant zombies. 52825698Seric */ 52925698Seric 53025698Seric # ifdef VMUNIX 53125698Seric # include <sys/wait.h> 53225698Seric # endif VMUNIX 53325698Seric 53425698Seric reapchild() 53525698Seric { 53625698Seric # ifdef WNOHANG 53725698Seric union wait status; 53825698Seric 53925698Seric while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0) 54025698Seric continue; 54125698Seric # else WNOHANG 54225698Seric auto int status; 54325698Seric 54425698Seric while (wait(&status) > 0) 54525698Seric continue; 54625698Seric # endif WNOHANG 54725698Seric } 548