122698Sdist /* 222698Sdist ** Sendmail 322698Sdist ** Copyright (c) 1983 Eric P. Allman 422698Sdist ** Berkeley, California 522698Sdist ** 622698Sdist ** Copyright (c) 1983 Regents of the University of California. 722698Sdist ** All rights reserved. The Berkeley software License Agreement 822698Sdist ** specifies the terms and conditions for redistribution. 922698Sdist */ 1022698Sdist 1122698Sdist #ifndef lint 12*24943Seric static char SccsId[] = "@(#)conf.c 5.3.1.1 (Berkeley) 09/19/85"; 1322698Sdist #endif not lint 1422698Sdist 15294Seric # include <pwd.h> 1614881Seric # include <sys/ioctl.h> 17*24943Seric # ifdef sun 18*24943Seric # include <sys/param.h> 19*24943Seric # endif sun 203309Seric # include "sendmail.h" 21404Seric 22294Seric /* 233309Seric ** CONF.C -- Sendmail Configuration Tables. 24294Seric ** 25294Seric ** Defines the configuration of this installation. 26294Seric ** 271388Seric ** Compilation Flags: 281388Seric ** V6 -- running on a version 6 system. This determines 291388Seric ** whether to define certain routines between 301388Seric ** the two systems. If you are running a funny 311388Seric ** system, e.g., V6 with long tty names, this 321388Seric ** should be checked carefully. 3314872Seric ** VMUNIX -- running on a Berkeley UNIX system. 34294Seric ** 351388Seric ** Configuration Variables: 362897Seric ** HdrInfo -- a table describing well-known header fields. 372897Seric ** Each entry has the field name and some flags, 384147Seric ** which are described in sendmail.h. 394093Seric ** 404093Seric ** Notes: 414093Seric ** I have tried to put almost all the reasonable 424093Seric ** configuration information into the configuration 434093Seric ** file read at runtime. My intent is that anything 444093Seric ** here is a function of the version of UNIX you 454093Seric ** are running, or is really static -- for example 464093Seric ** the headers are a superset of widely used 474093Seric ** protocols. If you find yourself playing with 484093Seric ** this file too much, you may be making a mistake! 49294Seric */ 50294Seric 51294Seric 52294Seric 53294Seric 544437Seric /* 552897Seric ** Header info table 563057Seric ** Final (null) entry contains the flags used for any other field. 574147Seric ** 584147Seric ** Not all of these are actually handled specially by sendmail 594147Seric ** at this time. They are included as placeholders, to let 604147Seric ** you know that "someday" I intend to have sendmail do 614147Seric ** something with them. 622897Seric */ 632897Seric 642897Seric struct hdrinfo HdrInfo[] = 652897Seric { 668060Seric /* originator fields, most to least significant */ 6711417Seric "resent-sender", H_FROM|H_RESENT, 6811417Seric "resent-from", H_FROM|H_RESENT, 699055Seric "sender", H_FROM, 709055Seric "from", H_FROM, 719055Seric "full-name", H_ACHECK, 729055Seric "return-receipt-to", H_FROM, 739055Seric "errors-to", H_FROM, 748060Seric /* destination fields */ 759055Seric "to", H_RCPT, 7611417Seric "resent-to", H_RCPT|H_RESENT, 779055Seric "cc", H_RCPT, 7811417Seric "resent-cc", H_RCPT|H_RESENT, 799055Seric "bcc", H_RCPT|H_ACHECK, 8011417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 818060Seric /* message identification and control */ 8211417Seric "message-id", 0, 8311417Seric "resent-message-id", H_RESENT, 849055Seric "message", H_EOH, 859055Seric "text", H_EOH, 8611417Seric /* date fields */ 8711417Seric "date", 0, 8811417Seric "resent-date", H_RESENT, 898060Seric /* trace fields */ 909055Seric "received", H_TRACE|H_FORCE, 919055Seric "via", H_TRACE|H_FORCE, 929055Seric "mail-from", H_TRACE|H_FORCE, 938060Seric 949055Seric NULL, 0, 952897Seric }; 964166Seric 974166Seric 984166Seric /* 994166Seric ** ARPANET error message numbers. 1004166Seric */ 1014166Seric 1027956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 1037956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 1047956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 1057956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 1064282Seric 1074282Seric 1084282Seric 1094282Seric /* 1104282Seric ** Location of system files/databases/etc. 1114282Seric */ 1124282Seric 1134282Seric char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ 1149064Seric char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */ 1159039Seric 1169064Seric 1179064Seric 1189039Seric /* 119*24943Seric ** Miscellaneous stuff. 1209039Seric */ 1219039Seric 122*24943Seric int DtableSize = 50; /* max open files; reset in 4.2bsd */ 123*24943Seric /* 124*24943Seric ** SETDEFAULTS -- set default values 125*24943Seric ** 126*24943Seric ** Because of the way freezing is done, these must be initialized 127*24943Seric ** using direct code. 128*24943Seric ** 129*24943Seric ** Parameters: 130*24943Seric ** none. 131*24943Seric ** 132*24943Seric ** Returns: 133*24943Seric ** none. 134*24943Seric ** 135*24943Seric ** Side Effects: 136*24943Seric ** Initializes a bunch of global variables to their 137*24943Seric ** default values. 138*24943Seric */ 139*24943Seric 140*24943Seric setdefaults() 141*24943Seric { 142*24943Seric QueueLA = 8; 143*24943Seric QueueFactor = 10000; 144*24943Seric RefuseLA = 12; 145*24943Seric SpaceSub = ' '; 146*24943Seric } 147294Seric 148294Seric # ifdef V6 149294Seric /* 1504190Seric ** TTYNAME -- return name of terminal. 151294Seric ** 152294Seric ** Parameters: 1534190Seric ** fd -- file descriptor to check. 154294Seric ** 155294Seric ** Returns: 1564190Seric ** pointer to full path of tty. 1574190Seric ** NULL if no tty. 158294Seric ** 159294Seric ** Side Effects: 160294Seric ** none. 161294Seric */ 162294Seric 163294Seric char * 1644190Seric ttyname(fd) 1654190Seric int fd; 166294Seric { 1674190Seric register char tn; 168294Seric static char pathn[] = "/dev/ttyx"; 169294Seric 170294Seric /* compute the pathname of the controlling tty */ 1714190Seric if ((tn = ttyn(fd)) == NULL) 172294Seric { 173294Seric errno = 0; 174294Seric return (NULL); 175294Seric } 1764190Seric pathn[8] = tn; 177294Seric return (pathn); 178294Seric } 179294Seric /* 180294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 181294Seric ** 182294Seric ** This is included here because it is standard in v7, but we 183294Seric ** need it in v6. 184294Seric ** 185294Seric ** Algorithm: 186294Seric ** Open /dev/null to create a descriptor. 187294Seric ** Close that descriptor. 188294Seric ** Copy the existing fd into the descriptor. 189294Seric ** 190294Seric ** Parameters: 191294Seric ** fd -- the open file descriptor. 192294Seric ** type -- "r", "w", or whatever. 193294Seric ** 194294Seric ** Returns: 195294Seric ** The file descriptor it creates. 196294Seric ** 197294Seric ** Side Effects: 198294Seric ** none 199294Seric ** 200294Seric ** Called By: 201294Seric ** deliver 202294Seric ** 203294Seric ** Notes: 204294Seric ** The mode of fd must match "type". 205294Seric */ 206294Seric 207294Seric FILE * 208294Seric fdopen(fd, type) 209294Seric int fd; 210294Seric char *type; 211294Seric { 212294Seric register FILE *f; 213294Seric 214294Seric f = fopen("/dev/null", type); 2154081Seric (void) close(fileno(f)); 216294Seric fileno(f) = fd; 217294Seric return (f); 218294Seric } 219294Seric /* 220294Seric ** INDEX -- Return pointer to character in string 221294Seric ** 222294Seric ** For V7 compatibility. 223294Seric ** 224294Seric ** Parameters: 225294Seric ** s -- a string to scan. 226294Seric ** c -- a character to look for. 227294Seric ** 228294Seric ** Returns: 229294Seric ** If c is in s, returns the address of the first 230294Seric ** instance of c in s. 231294Seric ** NULL if c is not in s. 232294Seric ** 233294Seric ** Side Effects: 234294Seric ** none. 235294Seric */ 236294Seric 2374437Seric char * 238294Seric index(s, c) 239294Seric register char *s; 240294Seric register char c; 241294Seric { 242294Seric while (*s != '\0') 243294Seric { 244294Seric if (*s++ == c) 245294Seric return (--s); 246294Seric } 247294Seric return (NULL); 248294Seric } 2494326Seric /* 2504326Seric ** UMASK -- fake the umask system call. 2514326Seric ** 2524326Seric ** Since V6 always acts like the umask is zero, we will just 2534326Seric ** assume the same thing. 2544326Seric */ 2554326Seric 2564326Seric /*ARGSUSED*/ 2574326Seric umask(nmask) 2584326Seric { 2594326Seric return (0); 2604326Seric } 2614326Seric 2624326Seric 2634326Seric /* 2644326Seric ** GETRUID -- get real user id. 2654326Seric */ 2664326Seric 2674326Seric getruid() 2684326Seric { 2694326Seric return (getuid() & 0377); 2704326Seric } 2714326Seric 2724326Seric 2734326Seric /* 2744326Seric ** GETRGID -- get real group id. 2754326Seric */ 2764326Seric 2774326Seric getrgid() 2784326Seric { 2794326Seric return (getgid() & 0377); 2804326Seric } 2814326Seric 2824326Seric 2834326Seric /* 2844326Seric ** GETEUID -- get effective user id. 2854326Seric */ 2864326Seric 2874326Seric geteuid() 2884326Seric { 2894326Seric return ((getuid() >> 8) & 0377); 2904326Seric } 2914326Seric 2924326Seric 2934326Seric /* 2944326Seric ** GETEGID -- get effective group id. 2954326Seric */ 2964326Seric 2974326Seric getegid() 2984326Seric { 2994326Seric return ((getgid() >> 8) & 0377); 3004326Seric } 3014326Seric 302294Seric # endif V6 3034326Seric 3044326Seric # ifndef V6 3054326Seric 3064326Seric /* 3074326Seric ** GETRUID -- get real user id (V7) 3084326Seric */ 3094326Seric 3104326Seric getruid() 3114326Seric { 3129274Seric if (OpMode == MD_DAEMON) 3134536Seric return (RealUid); 3144536Seric else 3154536Seric return (getuid()); 3164326Seric } 3174326Seric 3184326Seric 3194326Seric /* 3204326Seric ** GETRGID -- get real group id (V7). 3214326Seric */ 3224326Seric 3234326Seric getrgid() 3244326Seric { 3259274Seric if (OpMode == MD_DAEMON) 3264536Seric return (RealGid); 3274536Seric else 3284536Seric return (getgid()); 3294326Seric } 3304326Seric 3314326Seric # endif V6 3324190Seric /* 3339369Seric ** USERNAME -- return the user id of the logged in user. 3349369Seric ** 3359369Seric ** Parameters: 3369369Seric ** none. 3379369Seric ** 3389369Seric ** Returns: 3399369Seric ** The login name of the logged in user. 3409369Seric ** 3419369Seric ** Side Effects: 3429369Seric ** none. 3439369Seric ** 3449369Seric ** Notes: 3459369Seric ** The return value is statically allocated. 3469369Seric */ 3479369Seric 3489369Seric char * 3499369Seric username() 3509369Seric { 35117469Seric static char *myname = NULL; 3529369Seric extern char *getlogin(); 35319904Smiriam register struct passwd *pw; 35419904Smiriam extern struct passwd *getpwuid(); 3559369Seric 35617469Seric /* cache the result */ 35717469Seric if (myname == NULL) 35817469Seric { 35917469Seric myname = getlogin(); 36017469Seric if (myname == NULL || myname[0] == '\0') 36117469Seric { 36217469Seric 36317469Seric pw = getpwuid(getruid()); 36417469Seric if (pw != NULL) 36517469Seric myname = pw->pw_name; 36617469Seric } 36719904Smiriam else 36819904Smiriam { 36919873Smiriam 37019873Smiriam pw = getpwnam(myname); 37119904Smiriam if(getuid() != pw->pw_uid) 37219904Smiriam { 37319873Smiriam pw = getpwuid(getuid()); 374*24943Seric myname = pw->pw_name; 37519873Smiriam } 37619873Smiriam } 37717469Seric if (myname == NULL || myname[0] == '\0') 37817469Seric { 37917469Seric syserr("Who are you?"); 38017469Seric myname = "postmaster"; 38117469Seric } 38217469Seric } 38317469Seric 38417469Seric return (myname); 3859369Seric } 3869369Seric /* 3874190Seric ** TTYPATH -- Get the path of the user's tty 388294Seric ** 389294Seric ** Returns the pathname of the user's tty. Returns NULL if 390294Seric ** the user is not logged in or if s/he has write permission 391294Seric ** denied. 392294Seric ** 393294Seric ** Parameters: 394294Seric ** none 395294Seric ** 396294Seric ** Returns: 397294Seric ** pathname of the user's tty. 398294Seric ** NULL if not logged in or write permission denied. 399294Seric ** 400294Seric ** Side Effects: 401294Seric ** none. 402294Seric ** 403294Seric ** WARNING: 404294Seric ** Return value is in a local buffer. 405294Seric ** 406294Seric ** Called By: 407294Seric ** savemail 408294Seric */ 409294Seric 410294Seric # include <sys/stat.h> 411294Seric 412294Seric char * 413294Seric ttypath() 414294Seric { 415294Seric struct stat stbuf; 416294Seric register char *pathn; 417294Seric extern char *ttyname(); 4184081Seric extern char *getlogin(); 419294Seric 420294Seric /* compute the pathname of the controlling tty */ 4219369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 4229369Seric (pathn = ttyname(0)) == NULL) 423294Seric { 424294Seric errno = 0; 425294Seric return (NULL); 426294Seric } 427294Seric 428294Seric /* see if we have write permission */ 4292967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 430294Seric { 431294Seric errno = 0; 432294Seric return (NULL); 433294Seric } 434294Seric 435294Seric /* see if the user is logged in */ 436294Seric if (getlogin() == NULL) 437294Seric return (NULL); 438294Seric 439294Seric /* looks good */ 440294Seric return (pathn); 441294Seric } 4422967Seric /* 4432967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4442967Seric ** 4452967Seric ** This routine can be supplied on a per-installation basis 4462967Seric ** to determine whether a person is allowed to send a message. 4472967Seric ** This allows restriction of certain types of internet 4482967Seric ** forwarding or registration of users. 4492967Seric ** 4502967Seric ** If the hosts are found to be incompatible, an error 4512967Seric ** message should be given using "usrerr" and FALSE should 4522967Seric ** be returned. 4532967Seric ** 4544288Seric ** 'NoReturn' can be set to suppress the return-to-sender 4554288Seric ** function; this should be done on huge messages. 4564288Seric ** 4572967Seric ** Parameters: 4582967Seric ** to -- the person being sent to. 4592967Seric ** 4602967Seric ** Returns: 4612967Seric ** TRUE -- ok to send. 4622967Seric ** FALSE -- not ok. 4632967Seric ** 4642967Seric ** Side Effects: 4652967Seric ** none (unless you include the usrerr stuff) 4662967Seric */ 4672967Seric 4682967Seric bool 4692967Seric checkcompat(to) 4702967Seric register ADDRESS *to; 4712967Seric { 47212133Seric # ifdef lint 47312133Seric if (to == NULL) 47412133Seric to++; 47512133Seric # endif lint 47610698Seric # ifdef EXAMPLE_CODE 47710698Seric /* this code is intended as an example only */ 4784437Seric register STAB *s; 4794437Seric 4804437Seric s = stab("arpa", ST_MAILER, ST_FIND); 4819369Seric if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 4829369Seric to->q_mailer == s->s_mailer) 4834437Seric { 4844437Seric usrerr("No ARPA mail through this machine: see your system administration"); 48510698Seric /* NoReturn = TRUE; to supress return copy */ 4864437Seric return (FALSE); 4874437Seric } 48810698Seric # endif EXAMPLE_CODE 4892967Seric return (TRUE); 4902967Seric } 4919369Seric /* 4929369Seric ** HOLDSIGS -- arrange to hold all signals 4939369Seric ** 4949369Seric ** Parameters: 4959369Seric ** none. 4969369Seric ** 4979369Seric ** Returns: 4989369Seric ** none. 4999369Seric ** 5009369Seric ** Side Effects: 5019369Seric ** Arranges that signals are held. 5029369Seric */ 5039369Seric 5049369Seric holdsigs() 5059369Seric { 5069369Seric } 5079369Seric /* 5089369Seric ** RLSESIGS -- arrange to release all signals 5099369Seric ** 5109369Seric ** This undoes the effect of holdsigs. 5119369Seric ** 5129369Seric ** Parameters: 5139369Seric ** none. 5149369Seric ** 5159369Seric ** Returns: 5169369Seric ** none. 5179369Seric ** 5189369Seric ** Side Effects: 5199369Seric ** Arranges that signals are released. 5209369Seric */ 5219369Seric 5229369Seric rlsesigs() 5239369Seric { 5249369Seric } 52514872Seric /* 52614872Seric ** GETLA -- get the current load average 52714872Seric ** 52814881Seric ** This code stolen from la.c. 52914881Seric ** 53014872Seric ** Parameters: 53114872Seric ** none. 53214872Seric ** 53314872Seric ** Returns: 53414872Seric ** The current load average as an integer. 53514872Seric ** 53614872Seric ** Side Effects: 53714872Seric ** none. 53814872Seric */ 53914872Seric 54014872Seric #ifdef VMUNIX 54114872Seric 54214872Seric #include <nlist.h> 54314872Seric 54414872Seric struct nlist Nl[] = 54514872Seric { 54614872Seric { "_avenrun" }, 54714872Seric #define X_AVENRUN 0 54814872Seric { 0 }, 54914872Seric }; 55014872Seric 55114872Seric getla() 55214872Seric { 55314872Seric static int kmem = -1; 554*24943Seric # ifdef sun 555*24943Seric long avenrun[3]; 556*24943Seric # else 55714872Seric double avenrun[3]; 558*24943Seric # endif 55914872Seric 56014872Seric if (kmem < 0) 56114872Seric { 562*24943Seric kmem = open("/dev/kmem", 0); 56314872Seric if (kmem < 0) 56414872Seric return (-1); 56523118Seric (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); 56614872Seric nlist("/vmunix", Nl); 56714872Seric if (Nl[0].n_type == 0) 56814872Seric return (-1); 56914872Seric } 570*24943Seric if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) < 0 || 57123118Seric read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) 57219967Seric { 57319967Seric /* thank you Ian */ 57419967Seric return (-1); 57519967Seric } 576*24943Seric # ifdef sun 577*24943Seric return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); 578*24943Seric # else 57914872Seric return ((int) (avenrun[0] + 0.5)); 580*24943Seric # endif 58114872Seric } 58214872Seric 58314872Seric #else VMUNIX 58414872Seric 58514872Seric getla() 58614872Seric { 58714872Seric return (0); 58814872Seric } 58914872Seric 59014872Seric #endif VMUNIX 591*24943Seric /* 592*24943Seric ** SHOULDQUEUE -- should this message be queued or sent? 593*24943Seric ** 594*24943Seric ** Compares the message cost to the load average to decide. 595*24943Seric ** 596*24943Seric ** Parameters: 597*24943Seric ** pri -- the priority of the message in question. 598*24943Seric ** 599*24943Seric ** Returns: 600*24943Seric ** TRUE -- if this message should be queued up for the 601*24943Seric ** time being. 602*24943Seric ** FALSE -- if the load is low enough to send this message. 603*24943Seric ** 604*24943Seric ** Side Effects: 605*24943Seric ** none. 606*24943Seric */ 607*24943Seric 608*24943Seric bool 609*24943Seric shouldqueue(pri) 610*24943Seric long pri; 611*24943Seric { 612*24943Seric int la; 613*24943Seric 614*24943Seric la = getla(); 615*24943Seric if (la < QueueLA) 616*24943Seric return (FALSE); 617*24943Seric return (pri > (QueueFactor / (la - QueueLA + 1))); 618*24943Seric } 619*24943Seric /* 620*24943Seric ** SETPROCTITLE -- set process title for ps 621*24943Seric ** 622*24943Seric ** Parameters: 623*24943Seric ** fmt -- a printf style format string. 624*24943Seric ** a, b, c -- possible parameters to fmt. 625*24943Seric ** 626*24943Seric ** Returns: 627*24943Seric ** none. 628*24943Seric ** 629*24943Seric ** Side Effects: 630*24943Seric ** Clobbers argv of our main procedure so ps(1) will 631*24943Seric ** display the title. 632*24943Seric */ 633*24943Seric 634*24943Seric /*VARARGS1*/ 635*24943Seric setproctitle(fmt, a, b, c) 636*24943Seric char *fmt; 637*24943Seric { 638*24943Seric # ifdef SETPROCTITLE 639*24943Seric register char *p; 640*24943Seric extern char **Argv; 641*24943Seric extern char *LastArgv; 642*24943Seric 643*24943Seric p = Argv[0]; 644*24943Seric 645*24943Seric /* make ps print "(sendmail)" */ 646*24943Seric *p++ = '-'; 647*24943Seric 648*24943Seric (void) sprintf(p, fmt, a, b, c); 649*24943Seric p += strlen(p); 650*24943Seric 651*24943Seric /* avoid confusing ps */ 652*24943Seric while (p < LastArgv) 653*24943Seric *p++ = ' '; 654*24943Seric # endif SETPROCTITLE 655*24943Seric } 656