1*22698Sdist /* 2*22698Sdist ** Sendmail 3*22698Sdist ** Copyright (c) 1983 Eric P. Allman 4*22698Sdist ** Berkeley, California 5*22698Sdist ** 6*22698Sdist ** Copyright (c) 1983 Regents of the University of California. 7*22698Sdist ** All rights reserved. The Berkeley software License Agreement 8*22698Sdist ** specifies the terms and conditions for redistribution. 9*22698Sdist */ 10*22698Sdist 11*22698Sdist #ifndef lint 12*22698Sdist static char SccsId[] = "@(#)conf.c 5.1 (Berkeley) 06/07/85"; 13*22698Sdist #endif not lint 14*22698Sdist 15294Seric # include <pwd.h> 1614881Seric # include <sys/ioctl.h> 173309Seric # include "sendmail.h" 18404Seric 19294Seric /* 203309Seric ** CONF.C -- Sendmail Configuration Tables. 21294Seric ** 22294Seric ** Defines the configuration of this installation. 23294Seric ** 241388Seric ** Compilation Flags: 251388Seric ** V6 -- running on a version 6 system. This determines 261388Seric ** whether to define certain routines between 271388Seric ** the two systems. If you are running a funny 281388Seric ** system, e.g., V6 with long tty names, this 291388Seric ** should be checked carefully. 3014872Seric ** VMUNIX -- running on a Berkeley UNIX system. 31294Seric ** 321388Seric ** Configuration Variables: 332897Seric ** HdrInfo -- a table describing well-known header fields. 342897Seric ** Each entry has the field name and some flags, 354147Seric ** which are described in sendmail.h. 364093Seric ** 374093Seric ** Notes: 384093Seric ** I have tried to put almost all the reasonable 394093Seric ** configuration information into the configuration 404093Seric ** file read at runtime. My intent is that anything 414093Seric ** here is a function of the version of UNIX you 424093Seric ** are running, or is really static -- for example 434093Seric ** the headers are a superset of widely used 444093Seric ** protocols. If you find yourself playing with 454093Seric ** this file too much, you may be making a mistake! 46294Seric */ 47294Seric 48294Seric 49294Seric 50294Seric 51*22698Sdist SCCSID(@(#)conf.c 5.1 06/07/85); 524437Seric 534437Seric 544437Seric 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, 709055Seric "sender", H_FROM, 719055Seric "from", H_FROM, 729055Seric "full-name", H_ACHECK, 739055Seric "return-receipt-to", H_FROM, 749055Seric "errors-to", H_FROM, 758060Seric /* destination fields */ 769055Seric "to", H_RCPT, 7711417Seric "resent-to", H_RCPT|H_RESENT, 789055Seric "cc", H_RCPT, 7911417Seric "resent-cc", H_RCPT|H_RESENT, 809055Seric "bcc", H_RCPT|H_ACHECK, 8111417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 828060Seric /* message identification and control */ 8311417Seric "message-id", 0, 8411417Seric "resent-message-id", H_RESENT, 859055Seric "message", H_EOH, 869055Seric "text", H_EOH, 8711417Seric /* date fields */ 8811417Seric "date", 0, 8911417Seric "resent-date", H_RESENT, 908060Seric /* trace fields */ 919055Seric "received", H_TRACE|H_FORCE, 929055Seric "via", H_TRACE|H_FORCE, 939055Seric "mail-from", H_TRACE|H_FORCE, 948060Seric 959055Seric NULL, 0, 962897Seric }; 974166Seric 984166Seric 994166Seric /* 1004166Seric ** ARPANET error message numbers. 1014166Seric */ 1024166Seric 1037956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 1047956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 1057956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 1067956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 1074282Seric 1084282Seric 1094282Seric 1104282Seric /* 1114282Seric ** Location of system files/databases/etc. 1124282Seric */ 1134282Seric 1144282Seric char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ 1159064Seric char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */ 1169039Seric 1179064Seric 1189064Seric 1199039Seric /* 1209039Seric ** Some other configuration.... 1219039Seric */ 1229039Seric 12316881Seric char SpaceSub; /* character to replace <lwsp> in addrs */ 12416881Seric int QueueLA; /* load avg > QueueLA -> just queue */ 12516881Seric int RefuseLA; /* load avg > RefuseLA -> refuse connections */ 126294Seric 127294Seric # ifdef V6 128294Seric /* 1294190Seric ** TTYNAME -- return name of terminal. 130294Seric ** 131294Seric ** Parameters: 1324190Seric ** fd -- file descriptor to check. 133294Seric ** 134294Seric ** Returns: 1354190Seric ** pointer to full path of tty. 1364190Seric ** NULL if no tty. 137294Seric ** 138294Seric ** Side Effects: 139294Seric ** none. 140294Seric */ 141294Seric 142294Seric char * 1434190Seric ttyname(fd) 1444190Seric int fd; 145294Seric { 1464190Seric register char tn; 147294Seric static char pathn[] = "/dev/ttyx"; 148294Seric 149294Seric /* compute the pathname of the controlling tty */ 1504190Seric if ((tn = ttyn(fd)) == NULL) 151294Seric { 152294Seric errno = 0; 153294Seric return (NULL); 154294Seric } 1554190Seric pathn[8] = tn; 156294Seric return (pathn); 157294Seric } 158294Seric /* 159294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 160294Seric ** 161294Seric ** This is included here because it is standard in v7, but we 162294Seric ** need it in v6. 163294Seric ** 164294Seric ** Algorithm: 165294Seric ** Open /dev/null to create a descriptor. 166294Seric ** Close that descriptor. 167294Seric ** Copy the existing fd into the descriptor. 168294Seric ** 169294Seric ** Parameters: 170294Seric ** fd -- the open file descriptor. 171294Seric ** type -- "r", "w", or whatever. 172294Seric ** 173294Seric ** Returns: 174294Seric ** The file descriptor it creates. 175294Seric ** 176294Seric ** Side Effects: 177294Seric ** none 178294Seric ** 179294Seric ** Called By: 180294Seric ** deliver 181294Seric ** 182294Seric ** Notes: 183294Seric ** The mode of fd must match "type". 184294Seric */ 185294Seric 186294Seric FILE * 187294Seric fdopen(fd, type) 188294Seric int fd; 189294Seric char *type; 190294Seric { 191294Seric register FILE *f; 192294Seric 193294Seric f = fopen("/dev/null", type); 1944081Seric (void) close(fileno(f)); 195294Seric fileno(f) = fd; 196294Seric return (f); 197294Seric } 198294Seric /* 199294Seric ** INDEX -- Return pointer to character in string 200294Seric ** 201294Seric ** For V7 compatibility. 202294Seric ** 203294Seric ** Parameters: 204294Seric ** s -- a string to scan. 205294Seric ** c -- a character to look for. 206294Seric ** 207294Seric ** Returns: 208294Seric ** If c is in s, returns the address of the first 209294Seric ** instance of c in s. 210294Seric ** NULL if c is not in s. 211294Seric ** 212294Seric ** Side Effects: 213294Seric ** none. 214294Seric */ 215294Seric 2164437Seric char * 217294Seric index(s, c) 218294Seric register char *s; 219294Seric register char c; 220294Seric { 221294Seric while (*s != '\0') 222294Seric { 223294Seric if (*s++ == c) 224294Seric return (--s); 225294Seric } 226294Seric return (NULL); 227294Seric } 2284326Seric /* 2294326Seric ** UMASK -- fake the umask system call. 2304326Seric ** 2314326Seric ** Since V6 always acts like the umask is zero, we will just 2324326Seric ** assume the same thing. 2334326Seric */ 2344326Seric 2354326Seric /*ARGSUSED*/ 2364326Seric umask(nmask) 2374326Seric { 2384326Seric return (0); 2394326Seric } 2404326Seric 2414326Seric 2424326Seric /* 2434326Seric ** GETRUID -- get real user id. 2444326Seric */ 2454326Seric 2464326Seric getruid() 2474326Seric { 2484326Seric return (getuid() & 0377); 2494326Seric } 2504326Seric 2514326Seric 2524326Seric /* 2534326Seric ** GETRGID -- get real group id. 2544326Seric */ 2554326Seric 2564326Seric getrgid() 2574326Seric { 2584326Seric return (getgid() & 0377); 2594326Seric } 2604326Seric 2614326Seric 2624326Seric /* 2634326Seric ** GETEUID -- get effective user id. 2644326Seric */ 2654326Seric 2664326Seric geteuid() 2674326Seric { 2684326Seric return ((getuid() >> 8) & 0377); 2694326Seric } 2704326Seric 2714326Seric 2724326Seric /* 2734326Seric ** GETEGID -- get effective group id. 2744326Seric */ 2754326Seric 2764326Seric getegid() 2774326Seric { 2784326Seric return ((getgid() >> 8) & 0377); 2794326Seric } 2804326Seric 281294Seric # endif V6 2824326Seric 2834326Seric # ifndef V6 2844326Seric 2854326Seric /* 2864326Seric ** GETRUID -- get real user id (V7) 2874326Seric */ 2884326Seric 2894326Seric getruid() 2904326Seric { 2919274Seric if (OpMode == MD_DAEMON) 2924536Seric return (RealUid); 2934536Seric else 2944536Seric return (getuid()); 2954326Seric } 2964326Seric 2974326Seric 2984326Seric /* 2994326Seric ** GETRGID -- get real group id (V7). 3004326Seric */ 3014326Seric 3024326Seric getrgid() 3034326Seric { 3049274Seric if (OpMode == MD_DAEMON) 3054536Seric return (RealGid); 3064536Seric else 3074536Seric return (getgid()); 3084326Seric } 3094326Seric 3104326Seric # endif V6 3114190Seric /* 3129369Seric ** USERNAME -- return the user id of the logged in user. 3139369Seric ** 3149369Seric ** Parameters: 3159369Seric ** none. 3169369Seric ** 3179369Seric ** Returns: 3189369Seric ** The login name of the logged in user. 3199369Seric ** 3209369Seric ** Side Effects: 3219369Seric ** none. 3229369Seric ** 3239369Seric ** Notes: 3249369Seric ** The return value is statically allocated. 3259369Seric */ 3269369Seric 3279369Seric char * 3289369Seric username() 3299369Seric { 33017469Seric static char *myname = NULL; 3319369Seric extern char *getlogin(); 33219904Smiriam register struct passwd *pw; 33319904Smiriam extern struct passwd *getpwuid(); 3349369Seric 33517469Seric /* cache the result */ 33617469Seric if (myname == NULL) 33717469Seric { 33817469Seric myname = getlogin(); 33917469Seric if (myname == NULL || myname[0] == '\0') 34017469Seric { 34117469Seric 34217469Seric pw = getpwuid(getruid()); 34317469Seric if (pw != NULL) 34417469Seric myname = pw->pw_name; 34517469Seric } 34619904Smiriam else 34719904Smiriam { 34819873Smiriam 34919873Smiriam pw = getpwnam(myname); 35019904Smiriam if(getuid() != pw->pw_uid) 35119904Smiriam { 35219873Smiriam pw = getpwuid(getuid()); 35319873Smiriam myname = pw->pw_name; 35419873Smiriam } 35519873Smiriam } 35617469Seric if (myname == NULL || myname[0] == '\0') 35717469Seric { 35817469Seric syserr("Who are you?"); 35917469Seric myname = "postmaster"; 36017469Seric } 36117469Seric } 36217469Seric 36317469Seric return (myname); 3649369Seric } 3659369Seric /* 3664190Seric ** TTYPATH -- Get the path of the user's tty 367294Seric ** 368294Seric ** Returns the pathname of the user's tty. Returns NULL if 369294Seric ** the user is not logged in or if s/he has write permission 370294Seric ** denied. 371294Seric ** 372294Seric ** Parameters: 373294Seric ** none 374294Seric ** 375294Seric ** Returns: 376294Seric ** pathname of the user's tty. 377294Seric ** NULL if not logged in or write permission denied. 378294Seric ** 379294Seric ** Side Effects: 380294Seric ** none. 381294Seric ** 382294Seric ** WARNING: 383294Seric ** Return value is in a local buffer. 384294Seric ** 385294Seric ** Called By: 386294Seric ** savemail 387294Seric */ 388294Seric 389294Seric # include <sys/stat.h> 390294Seric 391294Seric char * 392294Seric ttypath() 393294Seric { 394294Seric struct stat stbuf; 395294Seric register char *pathn; 396294Seric extern char *ttyname(); 3974081Seric extern char *getlogin(); 398294Seric 399294Seric /* compute the pathname of the controlling tty */ 4009369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 4019369Seric (pathn = ttyname(0)) == NULL) 402294Seric { 403294Seric errno = 0; 404294Seric return (NULL); 405294Seric } 406294Seric 407294Seric /* see if we have write permission */ 4082967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 409294Seric { 410294Seric errno = 0; 411294Seric return (NULL); 412294Seric } 413294Seric 414294Seric /* see if the user is logged in */ 415294Seric if (getlogin() == NULL) 416294Seric return (NULL); 417294Seric 418294Seric /* looks good */ 419294Seric return (pathn); 420294Seric } 4212967Seric /* 4222967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4232967Seric ** 4242967Seric ** This routine can be supplied on a per-installation basis 4252967Seric ** to determine whether a person is allowed to send a message. 4262967Seric ** This allows restriction of certain types of internet 4272967Seric ** forwarding or registration of users. 4282967Seric ** 4292967Seric ** If the hosts are found to be incompatible, an error 4302967Seric ** message should be given using "usrerr" and FALSE should 4312967Seric ** be returned. 4322967Seric ** 4334288Seric ** 'NoReturn' can be set to suppress the return-to-sender 4344288Seric ** function; this should be done on huge messages. 4354288Seric ** 4362967Seric ** Parameters: 4372967Seric ** to -- the person being sent to. 4382967Seric ** 4392967Seric ** Returns: 4402967Seric ** TRUE -- ok to send. 4412967Seric ** FALSE -- not ok. 4422967Seric ** 4432967Seric ** Side Effects: 4442967Seric ** none (unless you include the usrerr stuff) 4452967Seric */ 4462967Seric 4472967Seric bool 4482967Seric checkcompat(to) 4492967Seric register ADDRESS *to; 4502967Seric { 45112133Seric # ifdef lint 45212133Seric if (to == NULL) 45312133Seric to++; 45412133Seric # endif lint 45510698Seric # ifdef EXAMPLE_CODE 45610698Seric /* this code is intended as an example only */ 4574437Seric register STAB *s; 4584437Seric 4594437Seric s = stab("arpa", ST_MAILER, ST_FIND); 4609369Seric if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 4619369Seric to->q_mailer == s->s_mailer) 4624437Seric { 4634437Seric usrerr("No ARPA mail through this machine: see your system administration"); 46410698Seric /* NoReturn = TRUE; to supress return copy */ 4654437Seric return (FALSE); 4664437Seric } 46710698Seric # endif EXAMPLE_CODE 4682967Seric return (TRUE); 4692967Seric } 4709369Seric /* 4719369Seric ** HOLDSIGS -- arrange to hold all signals 4729369Seric ** 4739369Seric ** Parameters: 4749369Seric ** none. 4759369Seric ** 4769369Seric ** Returns: 4779369Seric ** none. 4789369Seric ** 4799369Seric ** Side Effects: 4809369Seric ** Arranges that signals are held. 4819369Seric */ 4829369Seric 4839369Seric holdsigs() 4849369Seric { 4859369Seric } 4869369Seric /* 4879369Seric ** RLSESIGS -- arrange to release all signals 4889369Seric ** 4899369Seric ** This undoes the effect of holdsigs. 4909369Seric ** 4919369Seric ** Parameters: 4929369Seric ** none. 4939369Seric ** 4949369Seric ** Returns: 4959369Seric ** none. 4969369Seric ** 4979369Seric ** Side Effects: 4989369Seric ** Arranges that signals are released. 4999369Seric */ 5009369Seric 5019369Seric rlsesigs() 5029369Seric { 5039369Seric } 50414872Seric /* 50514872Seric ** GETLA -- get the current load average 50614872Seric ** 50714881Seric ** This code stolen from la.c. 50814881Seric ** 50914872Seric ** Parameters: 51014872Seric ** none. 51114872Seric ** 51214872Seric ** Returns: 51314872Seric ** The current load average as an integer. 51414872Seric ** 51514872Seric ** Side Effects: 51614872Seric ** none. 51714872Seric */ 51814872Seric 51914872Seric #ifdef VMUNIX 52014872Seric 52114872Seric #include <nlist.h> 52214872Seric 52314872Seric struct nlist Nl[] = 52414872Seric { 52514872Seric { "_avenrun" }, 52614872Seric #define X_AVENRUN 0 52714872Seric { 0 }, 52814872Seric }; 52914872Seric 53014872Seric getla() 53114872Seric { 53214872Seric static int kmem = -1; 53314872Seric double avenrun[3]; 53414872Seric 53514872Seric if (kmem < 0) 53614872Seric { 53714872Seric kmem = open("/dev/kmem", 0); 53814872Seric if (kmem < 0) 53914872Seric return (-1); 54014881Seric (void) ioctl(kmem, FIOCLEX, 0); 54114872Seric nlist("/vmunix", Nl); 54214872Seric if (Nl[0].n_type == 0) 54314872Seric return (-1); 54414872Seric } 54519967Seric if (lseek(kmem, (long) Nl[X_AVENRUN].n_value, 0) < 0 || 54619967Seric read(kmem, avenrun, sizeof(avenrun)) < sizeof(avenrun)) 54719967Seric { 54819967Seric /* thank you Ian */ 54919967Seric return (-1); 55019967Seric } 55114872Seric return ((int) (avenrun[0] + 0.5)); 55214872Seric } 55314872Seric 55414872Seric #else VMUNIX 55514872Seric 55614872Seric getla() 55714872Seric { 55814872Seric return (0); 55914872Seric } 56014872Seric 56114872Seric #endif VMUNIX 56217469Seric /* 56317469Seric ** DBMCLOSE -- close the DBM file 56417469Seric ** 56517469Seric ** This depends on the implementation of the DBM library. It 56617469Seric ** seems to work for all versions that I have come across. 56717469Seric ** 56817469Seric ** Parameters: 56917469Seric ** none. 57017469Seric ** 57117469Seric ** Returns: 57217469Seric ** none. 57317469Seric ** 57417469Seric ** Side Effects: 57517469Seric ** Closes the current DBM file; dbminit must be 57617469Seric ** called again to continue using the DBM routines. 57717469Seric */ 57817469Seric 57917469Seric dbmclose() 58017469Seric { 58117469Seric extern int pagf, dirf; /* defined in the DBM package */ 58217469Seric 58317469Seric (void) close(pagf); 58417469Seric (void) close(dirf); 58517469Seric } 586