1294Seric # include <pwd.h> 214881Seric # include <sys/ioctl.h> 33309Seric # include "sendmail.h" 4404Seric 5294Seric /* 63309Seric ** CONF.C -- Sendmail Configuration Tables. 7294Seric ** 8294Seric ** Defines the configuration of this installation. 9294Seric ** 101388Seric ** Compilation Flags: 111388Seric ** V6 -- running on a version 6 system. This determines 121388Seric ** whether to define certain routines between 131388Seric ** the two systems. If you are running a funny 141388Seric ** system, e.g., V6 with long tty names, this 151388Seric ** should be checked carefully. 1614872Seric ** VMUNIX -- running on a Berkeley UNIX system. 17294Seric ** 181388Seric ** Configuration Variables: 192897Seric ** HdrInfo -- a table describing well-known header fields. 202897Seric ** Each entry has the field name and some flags, 214147Seric ** which are described in sendmail.h. 224093Seric ** 234093Seric ** Notes: 244093Seric ** I have tried to put almost all the reasonable 254093Seric ** configuration information into the configuration 264093Seric ** file read at runtime. My intent is that anything 274093Seric ** here is a function of the version of UNIX you 284093Seric ** are running, or is really static -- for example 294093Seric ** the headers are a superset of widely used 304093Seric ** protocols. If you find yourself playing with 314093Seric ** this file too much, you may be making a mistake! 32294Seric */ 33294Seric 34294Seric 35294Seric 36294Seric 37*19904Smiriam SCCSID(@(#)conf.c 4.8 05/01/85); 384437Seric 394437Seric 404437Seric 414437Seric /* 422897Seric ** Header info table 433057Seric ** Final (null) entry contains the flags used for any other field. 444147Seric ** 454147Seric ** Not all of these are actually handled specially by sendmail 464147Seric ** at this time. They are included as placeholders, to let 474147Seric ** you know that "someday" I intend to have sendmail do 484147Seric ** something with them. 492897Seric */ 502897Seric 512897Seric struct hdrinfo HdrInfo[] = 522897Seric { 538060Seric /* originator fields, most to least significant */ 5411417Seric "resent-sender", H_FROM|H_RESENT, 5511417Seric "resent-from", H_FROM|H_RESENT, 569055Seric "sender", H_FROM, 579055Seric "from", H_FROM, 589055Seric "full-name", H_ACHECK, 599055Seric "return-receipt-to", H_FROM, 609055Seric "errors-to", H_FROM, 618060Seric /* destination fields */ 629055Seric "to", H_RCPT, 6311417Seric "resent-to", H_RCPT|H_RESENT, 649055Seric "cc", H_RCPT, 6511417Seric "resent-cc", H_RCPT|H_RESENT, 669055Seric "bcc", H_RCPT|H_ACHECK, 6711417Seric "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 688060Seric /* message identification and control */ 6911417Seric "message-id", 0, 7011417Seric "resent-message-id", H_RESENT, 719055Seric "message", H_EOH, 729055Seric "text", H_EOH, 7311417Seric /* date fields */ 7411417Seric "date", 0, 7511417Seric "resent-date", H_RESENT, 768060Seric /* trace fields */ 779055Seric "received", H_TRACE|H_FORCE, 789055Seric "via", H_TRACE|H_FORCE, 799055Seric "mail-from", H_TRACE|H_FORCE, 808060Seric 819055Seric NULL, 0, 822897Seric }; 834166Seric 844166Seric 854166Seric /* 864166Seric ** ARPANET error message numbers. 874166Seric */ 884166Seric 897956Seric char Arpa_Info[] = "050"; /* arbitrary info */ 907956Seric char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 917956Seric char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 927956Seric char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 934282Seric 944282Seric 954282Seric 964282Seric /* 974282Seric ** Location of system files/databases/etc. 984282Seric */ 994282Seric 1004282Seric char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ 1019064Seric char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */ 1029039Seric 1039064Seric 1049064Seric 1059039Seric /* 1069039Seric ** Some other configuration.... 1079039Seric */ 1089039Seric 10916881Seric char SpaceSub; /* character to replace <lwsp> in addrs */ 11016881Seric int QueueLA; /* load avg > QueueLA -> just queue */ 11116881Seric int RefuseLA; /* load avg > RefuseLA -> refuse connections */ 112294Seric 113294Seric # ifdef V6 114294Seric /* 1154190Seric ** TTYNAME -- return name of terminal. 116294Seric ** 117294Seric ** Parameters: 1184190Seric ** fd -- file descriptor to check. 119294Seric ** 120294Seric ** Returns: 1214190Seric ** pointer to full path of tty. 1224190Seric ** NULL if no tty. 123294Seric ** 124294Seric ** Side Effects: 125294Seric ** none. 126294Seric */ 127294Seric 128294Seric char * 1294190Seric ttyname(fd) 1304190Seric int fd; 131294Seric { 1324190Seric register char tn; 133294Seric static char pathn[] = "/dev/ttyx"; 134294Seric 135294Seric /* compute the pathname of the controlling tty */ 1364190Seric if ((tn = ttyn(fd)) == NULL) 137294Seric { 138294Seric errno = 0; 139294Seric return (NULL); 140294Seric } 1414190Seric pathn[8] = tn; 142294Seric return (pathn); 143294Seric } 144294Seric /* 145294Seric ** FDOPEN -- Open a stdio file given an open file descriptor. 146294Seric ** 147294Seric ** This is included here because it is standard in v7, but we 148294Seric ** need it in v6. 149294Seric ** 150294Seric ** Algorithm: 151294Seric ** Open /dev/null to create a descriptor. 152294Seric ** Close that descriptor. 153294Seric ** Copy the existing fd into the descriptor. 154294Seric ** 155294Seric ** Parameters: 156294Seric ** fd -- the open file descriptor. 157294Seric ** type -- "r", "w", or whatever. 158294Seric ** 159294Seric ** Returns: 160294Seric ** The file descriptor it creates. 161294Seric ** 162294Seric ** Side Effects: 163294Seric ** none 164294Seric ** 165294Seric ** Called By: 166294Seric ** deliver 167294Seric ** 168294Seric ** Notes: 169294Seric ** The mode of fd must match "type". 170294Seric */ 171294Seric 172294Seric FILE * 173294Seric fdopen(fd, type) 174294Seric int fd; 175294Seric char *type; 176294Seric { 177294Seric register FILE *f; 178294Seric 179294Seric f = fopen("/dev/null", type); 1804081Seric (void) close(fileno(f)); 181294Seric fileno(f) = fd; 182294Seric return (f); 183294Seric } 184294Seric /* 185294Seric ** INDEX -- Return pointer to character in string 186294Seric ** 187294Seric ** For V7 compatibility. 188294Seric ** 189294Seric ** Parameters: 190294Seric ** s -- a string to scan. 191294Seric ** c -- a character to look for. 192294Seric ** 193294Seric ** Returns: 194294Seric ** If c is in s, returns the address of the first 195294Seric ** instance of c in s. 196294Seric ** NULL if c is not in s. 197294Seric ** 198294Seric ** Side Effects: 199294Seric ** none. 200294Seric */ 201294Seric 2024437Seric char * 203294Seric index(s, c) 204294Seric register char *s; 205294Seric register char c; 206294Seric { 207294Seric while (*s != '\0') 208294Seric { 209294Seric if (*s++ == c) 210294Seric return (--s); 211294Seric } 212294Seric return (NULL); 213294Seric } 2144326Seric /* 2154326Seric ** UMASK -- fake the umask system call. 2164326Seric ** 2174326Seric ** Since V6 always acts like the umask is zero, we will just 2184326Seric ** assume the same thing. 2194326Seric */ 2204326Seric 2214326Seric /*ARGSUSED*/ 2224326Seric umask(nmask) 2234326Seric { 2244326Seric return (0); 2254326Seric } 2264326Seric 2274326Seric 2284326Seric /* 2294326Seric ** GETRUID -- get real user id. 2304326Seric */ 2314326Seric 2324326Seric getruid() 2334326Seric { 2344326Seric return (getuid() & 0377); 2354326Seric } 2364326Seric 2374326Seric 2384326Seric /* 2394326Seric ** GETRGID -- get real group id. 2404326Seric */ 2414326Seric 2424326Seric getrgid() 2434326Seric { 2444326Seric return (getgid() & 0377); 2454326Seric } 2464326Seric 2474326Seric 2484326Seric /* 2494326Seric ** GETEUID -- get effective user id. 2504326Seric */ 2514326Seric 2524326Seric geteuid() 2534326Seric { 2544326Seric return ((getuid() >> 8) & 0377); 2554326Seric } 2564326Seric 2574326Seric 2584326Seric /* 2594326Seric ** GETEGID -- get effective group id. 2604326Seric */ 2614326Seric 2624326Seric getegid() 2634326Seric { 2644326Seric return ((getgid() >> 8) & 0377); 2654326Seric } 2664326Seric 267294Seric # endif V6 2684326Seric 2694326Seric # ifndef V6 2704326Seric 2714326Seric /* 2724326Seric ** GETRUID -- get real user id (V7) 2734326Seric */ 2744326Seric 2754326Seric getruid() 2764326Seric { 2779274Seric if (OpMode == MD_DAEMON) 2784536Seric return (RealUid); 2794536Seric else 2804536Seric return (getuid()); 2814326Seric } 2824326Seric 2834326Seric 2844326Seric /* 2854326Seric ** GETRGID -- get real group id (V7). 2864326Seric */ 2874326Seric 2884326Seric getrgid() 2894326Seric { 2909274Seric if (OpMode == MD_DAEMON) 2914536Seric return (RealGid); 2924536Seric else 2934536Seric return (getgid()); 2944326Seric } 2954326Seric 2964326Seric # endif V6 2974190Seric /* 2989369Seric ** USERNAME -- return the user id of the logged in user. 2999369Seric ** 3009369Seric ** Parameters: 3019369Seric ** none. 3029369Seric ** 3039369Seric ** Returns: 3049369Seric ** The login name of the logged in user. 3059369Seric ** 3069369Seric ** Side Effects: 3079369Seric ** none. 3089369Seric ** 3099369Seric ** Notes: 3109369Seric ** The return value is statically allocated. 3119369Seric */ 3129369Seric 3139369Seric char * 3149369Seric username() 3159369Seric { 31617469Seric static char *myname = NULL; 3179369Seric extern char *getlogin(); 318*19904Smiriam register struct passwd *pw; 319*19904Smiriam extern struct passwd *getpwuid(); 3209369Seric 32117469Seric /* cache the result */ 32217469Seric if (myname == NULL) 32317469Seric { 32417469Seric myname = getlogin(); 32517469Seric if (myname == NULL || myname[0] == '\0') 32617469Seric { 32717469Seric 32817469Seric pw = getpwuid(getruid()); 32917469Seric if (pw != NULL) 33017469Seric myname = pw->pw_name; 33117469Seric } 332*19904Smiriam else 333*19904Smiriam { 33419873Smiriam 33519873Smiriam pw = getpwnam(myname); 336*19904Smiriam if(getuid() != pw->pw_uid) 337*19904Smiriam { 33819873Smiriam pw = getpwuid(getuid()); 33919873Smiriam myname = pw->pw_name; 34019873Smiriam } 34119873Smiriam } 34217469Seric if (myname == NULL || myname[0] == '\0') 34317469Seric { 34417469Seric syserr("Who are you?"); 34517469Seric myname = "postmaster"; 34617469Seric } 34717469Seric } 34817469Seric 34917469Seric return (myname); 3509369Seric } 3519369Seric /* 3524190Seric ** TTYPATH -- Get the path of the user's tty 353294Seric ** 354294Seric ** Returns the pathname of the user's tty. Returns NULL if 355294Seric ** the user is not logged in or if s/he has write permission 356294Seric ** denied. 357294Seric ** 358294Seric ** Parameters: 359294Seric ** none 360294Seric ** 361294Seric ** Returns: 362294Seric ** pathname of the user's tty. 363294Seric ** NULL if not logged in or write permission denied. 364294Seric ** 365294Seric ** Side Effects: 366294Seric ** none. 367294Seric ** 368294Seric ** WARNING: 369294Seric ** Return value is in a local buffer. 370294Seric ** 371294Seric ** Called By: 372294Seric ** savemail 373294Seric */ 374294Seric 375294Seric # include <sys/stat.h> 376294Seric 377294Seric char * 378294Seric ttypath() 379294Seric { 380294Seric struct stat stbuf; 381294Seric register char *pathn; 382294Seric extern char *ttyname(); 3834081Seric extern char *getlogin(); 384294Seric 385294Seric /* compute the pathname of the controlling tty */ 3869369Seric if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 3879369Seric (pathn = ttyname(0)) == NULL) 388294Seric { 389294Seric errno = 0; 390294Seric return (NULL); 391294Seric } 392294Seric 393294Seric /* see if we have write permission */ 3942967Seric if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 395294Seric { 396294Seric errno = 0; 397294Seric return (NULL); 398294Seric } 399294Seric 400294Seric /* see if the user is logged in */ 401294Seric if (getlogin() == NULL) 402294Seric return (NULL); 403294Seric 404294Seric /* looks good */ 405294Seric return (pathn); 406294Seric } 4072967Seric /* 4082967Seric ** CHECKCOMPAT -- check for From and To person compatible. 4092967Seric ** 4102967Seric ** This routine can be supplied on a per-installation basis 4112967Seric ** to determine whether a person is allowed to send a message. 4122967Seric ** This allows restriction of certain types of internet 4132967Seric ** forwarding or registration of users. 4142967Seric ** 4152967Seric ** If the hosts are found to be incompatible, an error 4162967Seric ** message should be given using "usrerr" and FALSE should 4172967Seric ** be returned. 4182967Seric ** 4194288Seric ** 'NoReturn' can be set to suppress the return-to-sender 4204288Seric ** function; this should be done on huge messages. 4214288Seric ** 4222967Seric ** Parameters: 4232967Seric ** to -- the person being sent to. 4242967Seric ** 4252967Seric ** Returns: 4262967Seric ** TRUE -- ok to send. 4272967Seric ** FALSE -- not ok. 4282967Seric ** 4292967Seric ** Side Effects: 4302967Seric ** none (unless you include the usrerr stuff) 4312967Seric */ 4322967Seric 4332967Seric bool 4342967Seric checkcompat(to) 4352967Seric register ADDRESS *to; 4362967Seric { 43712133Seric # ifdef lint 43812133Seric if (to == NULL) 43912133Seric to++; 44012133Seric # endif lint 44110698Seric # ifdef EXAMPLE_CODE 44210698Seric /* this code is intended as an example only */ 4434437Seric register STAB *s; 4444437Seric 4454437Seric s = stab("arpa", ST_MAILER, ST_FIND); 4469369Seric if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 4479369Seric to->q_mailer == s->s_mailer) 4484437Seric { 4494437Seric usrerr("No ARPA mail through this machine: see your system administration"); 45010698Seric /* NoReturn = TRUE; to supress return copy */ 4514437Seric return (FALSE); 4524437Seric } 45310698Seric # endif EXAMPLE_CODE 4542967Seric return (TRUE); 4552967Seric } 4569369Seric /* 4579369Seric ** HOLDSIGS -- arrange to hold all signals 4589369Seric ** 4599369Seric ** Parameters: 4609369Seric ** none. 4619369Seric ** 4629369Seric ** Returns: 4639369Seric ** none. 4649369Seric ** 4659369Seric ** Side Effects: 4669369Seric ** Arranges that signals are held. 4679369Seric */ 4689369Seric 4699369Seric holdsigs() 4709369Seric { 4719369Seric } 4729369Seric /* 4739369Seric ** RLSESIGS -- arrange to release all signals 4749369Seric ** 4759369Seric ** This undoes the effect of holdsigs. 4769369Seric ** 4779369Seric ** Parameters: 4789369Seric ** none. 4799369Seric ** 4809369Seric ** Returns: 4819369Seric ** none. 4829369Seric ** 4839369Seric ** Side Effects: 4849369Seric ** Arranges that signals are released. 4859369Seric */ 4869369Seric 4879369Seric rlsesigs() 4889369Seric { 4899369Seric } 49014872Seric /* 49114872Seric ** GETLA -- get the current load average 49214872Seric ** 49314881Seric ** This code stolen from la.c. 49414881Seric ** 49514872Seric ** Parameters: 49614872Seric ** none. 49714872Seric ** 49814872Seric ** Returns: 49914872Seric ** The current load average as an integer. 50014872Seric ** 50114872Seric ** Side Effects: 50214872Seric ** none. 50314872Seric */ 50414872Seric 50514872Seric #ifdef VMUNIX 50614872Seric 50714872Seric #include <nlist.h> 50814872Seric 50914872Seric struct nlist Nl[] = 51014872Seric { 51114872Seric { "_avenrun" }, 51214872Seric #define X_AVENRUN 0 51314872Seric { 0 }, 51414872Seric }; 51514872Seric 51614872Seric getla() 51714872Seric { 51814872Seric static int kmem = -1; 51914872Seric double avenrun[3]; 52014872Seric 52114872Seric if (kmem < 0) 52214872Seric { 52314872Seric kmem = open("/dev/kmem", 0); 52414872Seric if (kmem < 0) 52514872Seric return (-1); 52614881Seric (void) ioctl(kmem, FIOCLEX, 0); 52714872Seric nlist("/vmunix", Nl); 52814872Seric if (Nl[0].n_type == 0) 52914872Seric return (-1); 53014872Seric } 53114872Seric (void) lseek(kmem, (long) Nl[X_AVENRUN].n_value, 0); 53214872Seric (void) read(kmem, avenrun, sizeof(avenrun)); 53314872Seric return ((int) (avenrun[0] + 0.5)); 53414872Seric } 53514872Seric 53614872Seric #else VMUNIX 53714872Seric 53814872Seric getla() 53914872Seric { 54014872Seric return (0); 54114872Seric } 54214872Seric 54314872Seric #endif VMUNIX 54417469Seric /* 54517469Seric ** DBMCLOSE -- close the DBM file 54617469Seric ** 54717469Seric ** This depends on the implementation of the DBM library. It 54817469Seric ** seems to work for all versions that I have come across. 54917469Seric ** 55017469Seric ** Parameters: 55117469Seric ** none. 55217469Seric ** 55317469Seric ** Returns: 55417469Seric ** none. 55517469Seric ** 55617469Seric ** Side Effects: 55717469Seric ** Closes the current DBM file; dbminit must be 55817469Seric ** called again to continue using the DBM routines. 55917469Seric */ 56017469Seric 56117469Seric dbmclose() 56217469Seric { 56317469Seric extern int pagf, dirf; /* defined in the DBM package */ 56417469Seric 56517469Seric (void) close(pagf); 56617469Seric (void) close(dirf); 56717469Seric } 568