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*40930Srick static char sccsid[] = "@(#)conf.c 5.21 (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 */ 12624943Seric /* 12724943Seric ** SETDEFAULTS -- set default values 12824943Seric ** 12924943Seric ** Because of the way freezing is done, these must be initialized 13024943Seric ** using direct code. 13124943Seric ** 13224943Seric ** Parameters: 13324943Seric ** none. 13424943Seric ** 13524943Seric ** Returns: 13624943Seric ** none. 13724943Seric ** 13824943Seric ** Side Effects: 13924943Seric ** Initializes a bunch of global variables to their 14024943Seric ** default values. 14124943Seric */ 14224943Seric 14324943Seric setdefaults() 14424943Seric { 14524943Seric QueueLA = 8; 14624943Seric QueueFactor = 10000; 14724943Seric RefuseLA = 12; 14824943Seric SpaceSub = ' '; 14924981Seric WkRecipFact = 1000; 15024981Seric WkClassFact = 1800; 15125812Seric WkTimeFact = 9000; 15224981Seric FileMode = 0644; 15324981Seric DefUid = 1; 15424981Seric DefGid = 1; 15524943Seric } 156294Seric 1574326Seric /* 1584326Seric ** GETRUID -- get real user id (V7) 1594326Seric */ 1604326Seric 1614326Seric getruid() 1624326Seric { 1639274Seric if (OpMode == MD_DAEMON) 1644536Seric return (RealUid); 1654536Seric else 1664536Seric return (getuid()); 1674326Seric } 1684326Seric 1694326Seric 1704326Seric /* 1714326Seric ** GETRGID -- get real group id (V7). 1724326Seric */ 1734326Seric 1744326Seric getrgid() 1754326Seric { 1769274Seric if (OpMode == MD_DAEMON) 1774536Seric return (RealGid); 1784536Seric else 1794536Seric return (getgid()); 1804326Seric } 1814326Seric 18233936Sbostic /* 1839369Seric ** USERNAME -- return the user id of the logged in user. 1849369Seric ** 1859369Seric ** Parameters: 1869369Seric ** none. 1879369Seric ** 1889369Seric ** Returns: 1899369Seric ** The login name of the logged in user. 1909369Seric ** 1919369Seric ** Side Effects: 1929369Seric ** none. 1939369Seric ** 1949369Seric ** Notes: 1959369Seric ** The return value is statically allocated. 1969369Seric */ 1979369Seric 1989369Seric char * 1999369Seric username() 2009369Seric { 20117469Seric static char *myname = NULL; 2029369Seric extern char *getlogin(); 20319904Smiriam register struct passwd *pw; 20419904Smiriam extern struct passwd *getpwuid(); 2059369Seric 20617469Seric /* cache the result */ 20717469Seric if (myname == NULL) 20817469Seric { 20917469Seric myname = getlogin(); 21017469Seric if (myname == NULL || myname[0] == '\0') 21117469Seric { 21217469Seric 21317469Seric pw = getpwuid(getruid()); 21417469Seric if (pw != NULL) 21517469Seric myname = pw->pw_name; 21617469Seric } 21719904Smiriam else 21819904Smiriam { 21919873Smiriam 22019873Smiriam pw = getpwnam(myname); 22119904Smiriam if(getuid() != pw->pw_uid) 22219904Smiriam { 22319873Smiriam pw = getpwuid(getuid()); 22424945Seric if (pw != NULL) 22524945Seric myname = pw->pw_name; 22619873Smiriam } 22719873Smiriam } 22817469Seric if (myname == NULL || myname[0] == '\0') 22917469Seric { 23017469Seric syserr("Who are you?"); 23117469Seric myname = "postmaster"; 23217469Seric } 23317469Seric } 23417469Seric 23517469Seric return (myname); 2369369Seric } 2379369Seric /* 2384190Seric ** TTYPATH -- Get the path of the user's tty 239294Seric ** 240294Seric ** Returns the pathname of the user's tty. Returns NULL if 241294Seric ** the user is not logged in or if s/he has write permission 242294Seric ** denied. 243294Seric ** 244294Seric ** Parameters: 245294Seric ** none 246294Seric ** 247294Seric ** Returns: 248294Seric ** pathname of the user's tty. 249294Seric ** NULL if not logged in or write permission denied. 250294Seric ** 251294Seric ** Side Effects: 252294Seric ** none. 253294Seric ** 254294Seric ** WARNING: 255294Seric ** Return value is in a local buffer. 256294Seric ** 257294Seric ** Called By: 258294Seric ** savemail 259294Seric */ 260294Seric 261294Seric # include <sys/stat.h> 262294Seric 263294Seric char * 264294Seric ttypath() 265294Seric { 266294Seric struct stat stbuf; 267294Seric register char *pathn; 268294Seric extern char *ttyname(); 2694081Seric extern char *getlogin(); 270294Seric 271294Seric /* compute the pathname of the controlling tty */ 2729369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 2739369Seric (pathn = ttyname(0)) == NULL) 274294Seric { 275294Seric errno = 0; 276294Seric return (NULL); 277294Seric } 278294Seric 279294Seric /* see if we have write permission */ 2802967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 281294Seric { 282294Seric errno = 0; 283294Seric return (NULL); 284294Seric } 285294Seric 286294Seric /* see if the user is logged in */ 287294Seric if (getlogin() == NULL) 288294Seric return (NULL); 289294Seric 290294Seric /* looks good */ 291294Seric return (pathn); 292294Seric } 2932967Seric /* 2942967Seric ** CHECKCOMPAT -- check for From and To person compatible. 2952967Seric ** 2962967Seric ** This routine can be supplied on a per-installation basis 2972967Seric ** to determine whether a person is allowed to send a message. 2982967Seric ** This allows restriction of certain types of internet 2992967Seric ** forwarding or registration of users. 3002967Seric ** 3012967Seric ** If the hosts are found to be incompatible, an error 3022967Seric ** message should be given using "usrerr" and FALSE should 3032967Seric ** be returned. 3042967Seric ** 3054288Seric ** 'NoReturn' can be set to suppress the return-to-sender 3064288Seric ** function; this should be done on huge messages. 3074288Seric ** 3082967Seric ** Parameters: 3092967Seric ** to -- the person being sent to. 3102967Seric ** 3112967Seric ** Returns: 3122967Seric ** TRUE -- ok to send. 3132967Seric ** FALSE -- not ok. 3142967Seric ** 3152967Seric ** Side Effects: 3162967Seric ** none (unless you include the usrerr stuff) 3172967Seric */ 3182967Seric 3192967Seric bool 3202967Seric checkcompat(to) 3212967Seric register ADDRESS *to; 3222967Seric { 32312133Seric # ifdef lint 32412133Seric if (to == NULL) 32512133Seric to++; 32612133Seric # endif lint 32710698Seric # ifdef EXAMPLE_CODE 32810698Seric /* this code is intended as an example only */ 3294437Seric register STAB *s; 3304437Seric 3314437Seric s = stab("arpa", ST_MAILER, ST_FIND); 3329369Seric if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 3339369Seric to->q_mailer == s->s_mailer) 3344437Seric { 3354437Seric usrerr("No ARPA mail through this machine: see your system administration"); 33610698Seric /* NoReturn = TRUE; to supress return copy */ 3374437Seric return (FALSE); 3384437Seric } 33910698Seric # endif EXAMPLE_CODE 3402967Seric return (TRUE); 3412967Seric } 3429369Seric /* 3439369Seric ** HOLDSIGS -- arrange to hold all signals 3449369Seric ** 3459369Seric ** Parameters: 3469369Seric ** none. 3479369Seric ** 3489369Seric ** Returns: 3499369Seric ** none. 3509369Seric ** 3519369Seric ** Side Effects: 3529369Seric ** Arranges that signals are held. 3539369Seric */ 3549369Seric 3559369Seric holdsigs() 3569369Seric { 3579369Seric } 3589369Seric /* 3599369Seric ** RLSESIGS -- arrange to release all signals 3609369Seric ** 3619369Seric ** This undoes the effect of holdsigs. 3629369Seric ** 3639369Seric ** Parameters: 3649369Seric ** none. 3659369Seric ** 3669369Seric ** Returns: 3679369Seric ** none. 3689369Seric ** 3699369Seric ** Side Effects: 3709369Seric ** Arranges that signals are released. 3719369Seric */ 3729369Seric 3739369Seric rlsesigs() 3749369Seric { 3759369Seric } 37614872Seric /* 37714872Seric ** GETLA -- get the current load average 37814872Seric ** 37914881Seric ** This code stolen from la.c. 38014881Seric ** 38114872Seric ** Parameters: 38214872Seric ** none. 38314872Seric ** 38414872Seric ** Returns: 38514872Seric ** The current load average as an integer. 38614872Seric ** 38714872Seric ** Side Effects: 38814872Seric ** none. 38914872Seric */ 39014872Seric 39138196Smckusick #ifndef sun 39214872Seric 39338196Smckusick getla() 39438196Smckusick { 39538196Smckusick double avenrun[3]; 39638196Smckusick 39738196Smckusick if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) 39838196Smckusick return (0); 39938196Smckusick return ((int) (avenrun[0] + 0.5)); 40038196Smckusick } 40138196Smckusick 40238196Smckusick #else /* sun */ 40338196Smckusick 40414872Seric #include <nlist.h> 40514872Seric 40614872Seric struct nlist Nl[] = 40714872Seric { 40814872Seric { "_avenrun" }, 40914872Seric #define X_AVENRUN 0 41014872Seric { 0 }, 41114872Seric }; 41214872Seric 413*40930Srick 414*40930Srick extern int la; 415*40930Srick 41614872Seric getla() 41714872Seric { 41814872Seric static int kmem = -1; 41924943Seric long avenrun[3]; 42025615Seric extern off_t lseek(); 42114872Seric 42214872Seric if (kmem < 0) 42314872Seric { 42424945Seric kmem = open("/dev/kmem", 0, 0); 42514872Seric if (kmem < 0) 42614872Seric return (-1); 42723118Seric (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); 42814872Seric nlist("/vmunix", Nl); 42914872Seric if (Nl[0].n_type == 0) 43014872Seric return (-1); 43114872Seric } 43224945Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || 43323118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 43419967Seric { 43519967Seric /* thank you Ian */ 43619967Seric return (-1); 43719967Seric } 43824943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 43914872Seric } 44014872Seric 44138196Smckusick #endif /* sun */ 44224943Seric /* 44324943Seric ** SHOULDQUEUE -- should this message be queued or sent? 44424943Seric ** 44524943Seric ** Compares the message cost to the load average to decide. 44624943Seric ** 44724943Seric ** Parameters: 44824943Seric ** pri -- the priority of the message in question. 44924943Seric ** 45024943Seric ** Returns: 45124943Seric ** TRUE -- if this message should be queued up for the 45224943Seric ** time being. 45324943Seric ** FALSE -- if the load is low enough to send this message. 45424943Seric ** 45524943Seric ** Side Effects: 45624943Seric ** none. 45724943Seric */ 45824943Seric 45924943Seric bool 46024943Seric shouldqueue(pri) 46124943Seric long pri; 46224943Seric { 46324943Seric if (la < QueueLA) 46424943Seric return (FALSE); 46524943Seric return (pri > (QueueFactor / (la - QueueLA + 1))); 46624943Seric } 46724943Seric /* 46824943Seric ** SETPROCTITLE -- set process title for ps 46924943Seric ** 47024943Seric ** Parameters: 47124943Seric ** fmt -- a printf style format string. 47224943Seric ** a, b, c -- possible parameters to fmt. 47324943Seric ** 47424943Seric ** Returns: 47524943Seric ** none. 47624943Seric ** 47724943Seric ** Side Effects: 47824943Seric ** Clobbers argv of our main procedure so ps(1) will 47924943Seric ** display the title. 48024943Seric */ 48124943Seric 48224943Seric /*VARARGS1*/ 48324943Seric setproctitle(fmt, a, b, c) 48424943Seric char *fmt; 48524943Seric { 48624943Seric # ifdef SETPROCTITLE 48724943Seric register char *p; 48825049Seric register int i; 48924943Seric extern char **Argv; 49024943Seric extern char *LastArgv; 49125049Seric char buf[MAXLINE]; 49224943Seric 49325049Seric (void) sprintf(buf, fmt, a, b, c); 49424943Seric 49524943Seric /* make ps print "(sendmail)" */ 49625049Seric p = Argv[0]; 49724943Seric *p++ = '-'; 49824943Seric 49925049Seric i = strlen(buf); 50025049Seric if (i > LastArgv - p - 2) 50125049Seric { 50225049Seric i = LastArgv - p - 2; 50325049Seric buf[i] = '\0'; 50425049Seric } 50525049Seric (void) strcpy(p, buf); 50625049Seric p += i; 50724943Seric while (p < LastArgv) 50824943Seric *p++ = ' '; 50924943Seric # endif SETPROCTITLE 51024943Seric } 51125698Seric /* 51225698Seric ** REAPCHILD -- pick up the body of my child, lest it become a zombie 51325698Seric ** 51425698Seric ** Parameters: 51525698Seric ** none. 51625698Seric ** 51725698Seric ** Returns: 51825698Seric ** none. 51925698Seric ** 52025698Seric ** Side Effects: 52125698Seric ** Picks up extant zombies. 52225698Seric */ 52325698Seric 52425698Seric # ifdef VMUNIX 52525698Seric # include <sys/wait.h> 52625698Seric # endif VMUNIX 52725698Seric 52825698Seric reapchild() 52925698Seric { 53025698Seric # ifdef WNOHANG 53125698Seric union wait status; 53225698Seric 53325698Seric while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0) 53425698Seric continue; 53525698Seric # else WNOHANG 53625698Seric auto int status; 53725698Seric 53825698Seric while (wait(&status) > 0) 53925698Seric continue; 54025698Seric # endif WNOHANG 54125698Seric } 542