1: # include <pwd.h> 2: # include <sys/ioctl.h> 3: # include "sendmail.h" 4: 5: /* 6: ** CONF.C -- Sendmail Configuration Tables. 7: ** 8: ** Defines the configuration of this installation. 9: ** 10: ** Compilation Flags: 11: ** V6 -- running on a version 6 system. This determines 12: ** whether to define certain routines between 13: ** the two systems. If you are running a funny 14: ** system, e.g., V6 with long tty names, this 15: ** should be checked carefully. 16: ** VMUNIX -- running on a Berkeley UNIX system. 17: ** 18: ** Configuration Variables: 19: ** HdrInfo -- a table describing well-known header fields. 20: ** Each entry has the field name and some flags, 21: ** which are described in sendmail.h. 22: ** 23: ** Notes: 24: ** I have tried to put almost all the reasonable 25: ** configuration information into the configuration 26: ** file read at runtime. My intent is that anything 27: ** here is a function of the version of UNIX you 28: ** are running, or is really static -- for example 29: ** the headers are a superset of widely used 30: ** protocols. If you find yourself playing with 31: ** this file too much, you may be making a mistake! 32: */ 33: 34: 35: 36: 37: SCCSID(@(#)conf.c 4.4 8/28/83); 38: 39: 40: 41: /* 42: ** Header info table 43: ** Final (null) entry contains the flags used for any other field. 44: ** 45: ** Not all of these are actually handled specially by sendmail 46: ** at this time. They are included as placeholders, to let 47: ** you know that "someday" I intend to have sendmail do 48: ** something with them. 49: */ 50: 51: struct hdrinfo HdrInfo[] = 52: { 53: /* originator fields, most to least significant */ 54: "resent-sender", H_FROM|H_RESENT, 55: "resent-from", H_FROM|H_RESENT, 56: "sender", H_FROM, 57: "from", H_FROM, 58: "full-name", H_ACHECK, 59: "return-receipt-to", H_FROM, 60: "errors-to", H_FROM, 61: /* destination fields */ 62: "to", H_RCPT, 63: "resent-to", H_RCPT|H_RESENT, 64: "cc", H_RCPT, 65: "resent-cc", H_RCPT|H_RESENT, 66: "bcc", H_RCPT|H_ACHECK, 67: "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, 68: /* message identification and control */ 69: "message-id", 0, 70: "resent-message-id", H_RESENT, 71: "message", H_EOH, 72: "text", H_EOH, 73: /* date fields */ 74: "date", 0, 75: "resent-date", H_RESENT, 76: /* trace fields */ 77: "received", H_TRACE|H_FORCE, 78: "via", H_TRACE|H_FORCE, 79: "mail-from", H_TRACE|H_FORCE, 80: 81: NULL, 0, 82: }; 83: 84: 85: /* 86: ** ARPANET error message numbers. 87: */ 88: 89: char Arpa_Info[] = "050"; /* arbitrary info */ 90: char Arpa_TSyserr[] = "451"; /* some (transient) system error */ 91: char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ 92: char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ 93: 94: 95: 96: /* 97: ** Location of system files/databases/etc. 98: */ 99: 100: char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ 101: char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */ 102: 103: 104: 105: /* 106: ** Some other configuration.... 107: */ 108: 109: char SpaceSub = '.'; /* character to replace <lwsp> in addrs */ 110: int QueueLA = 8; /* load avg > QueueLA -> just queue */ 111: int RefuseLA = 12; /* load avg > RefuseLA -> refuse connections */ 112: 113: # ifdef V6 114: /* 115: ** TTYNAME -- return name of terminal. 116: ** 117: ** Parameters: 118: ** fd -- file descriptor to check. 119: ** 120: ** Returns: 121: ** pointer to full path of tty. 122: ** NULL if no tty. 123: ** 124: ** Side Effects: 125: ** none. 126: */ 127: 128: char * 129: ttyname(fd) 130: int fd; 131: { 132: register char tn; 133: static char pathn[] = "/dev/ttyx"; 134: 135: /* compute the pathname of the controlling tty */ 136: if ((tn = ttyn(fd)) == NULL) 137: { 138: errno = 0; 139: return (NULL); 140: } 141: pathn[8] = tn; 142: return (pathn); 143: } 144: /* 145: ** FDOPEN -- Open a stdio file given an open file descriptor. 146: ** 147: ** This is included here because it is standard in v7, but we 148: ** need it in v6. 149: ** 150: ** Algorithm: 151: ** Open /dev/null to create a descriptor. 152: ** Close that descriptor. 153: ** Copy the existing fd into the descriptor. 154: ** 155: ** Parameters: 156: ** fd -- the open file descriptor. 157: ** type -- "r", "w", or whatever. 158: ** 159: ** Returns: 160: ** The file descriptor it creates. 161: ** 162: ** Side Effects: 163: ** none 164: ** 165: ** Called By: 166: ** deliver 167: ** 168: ** Notes: 169: ** The mode of fd must match "type". 170: */ 171: 172: FILE * 173: fdopen(fd, type) 174: int fd; 175: char *type; 176: { 177: register FILE *f; 178: 179: f = fopen("/dev/null", type); 180: (void) close(fileno(f)); 181: fileno(f) = fd; 182: return (f); 183: } 184: /* 185: ** INDEX -- Return pointer to character in string 186: ** 187: ** For V7 compatibility. 188: ** 189: ** Parameters: 190: ** s -- a string to scan. 191: ** c -- a character to look for. 192: ** 193: ** Returns: 194: ** If c is in s, returns the address of the first 195: ** instance of c in s. 196: ** NULL if c is not in s. 197: ** 198: ** Side Effects: 199: ** none. 200: */ 201: 202: char * 203: index(s, c) 204: register char *s; 205: register char c; 206: { 207: while (*s != '\0') 208: { 209: if (*s++ == c) 210: return (--s); 211: } 212: return (NULL); 213: } 214: /* 215: ** UMASK -- fake the umask system call. 216: ** 217: ** Since V6 always acts like the umask is zero, we will just 218: ** assume the same thing. 219: */ 220: 221: /*ARGSUSED*/ 222: umask(nmask) 223: { 224: return (0); 225: } 226: 227: 228: /* 229: ** GETRUID -- get real user id. 230: */ 231: 232: getruid() 233: { 234: return (getuid() & 0377); 235: } 236: 237: 238: /* 239: ** GETRGID -- get real group id. 240: */ 241: 242: getrgid() 243: { 244: return (getgid() & 0377); 245: } 246: 247: 248: /* 249: ** GETEUID -- get effective user id. 250: */ 251: 252: geteuid() 253: { 254: return ((getuid() >> 8) & 0377); 255: } 256: 257: 258: /* 259: ** GETEGID -- get effective group id. 260: */ 261: 262: getegid() 263: { 264: return ((getgid() >> 8) & 0377); 265: } 266: 267: # endif V6 268: 269: # ifndef V6 270: 271: /* 272: ** GETRUID -- get real user id (V7) 273: */ 274: 275: getruid() 276: { 277: if (OpMode == MD_DAEMON) 278: return (RealUid); 279: else 280: return (getuid()); 281: } 282: 283: 284: /* 285: ** GETRGID -- get real group id (V7). 286: */ 287: 288: getrgid() 289: { 290: if (OpMode == MD_DAEMON) 291: return (RealGid); 292: else 293: return (getgid()); 294: } 295: 296: # endif V6 297: /* 298: ** USERNAME -- return the user id of the logged in user. 299: ** 300: ** Parameters: 301: ** none. 302: ** 303: ** Returns: 304: ** The login name of the logged in user. 305: ** 306: ** Side Effects: 307: ** none. 308: ** 309: ** Notes: 310: ** The return value is statically allocated. 311: */ 312: 313: char * 314: username() 315: { 316: extern char *getlogin(); 317: 318: return (getlogin()); 319: } 320: /* 321: ** TTYPATH -- Get the path of the user's tty 322: ** 323: ** Returns the pathname of the user's tty. Returns NULL if 324: ** the user is not logged in or if s/he has write permission 325: ** denied. 326: ** 327: ** Parameters: 328: ** none 329: ** 330: ** Returns: 331: ** pathname of the user's tty. 332: ** NULL if not logged in or write permission denied. 333: ** 334: ** Side Effects: 335: ** none. 336: ** 337: ** WARNING: 338: ** Return value is in a local buffer. 339: ** 340: ** Called By: 341: ** savemail 342: */ 343: 344: # include <sys/stat.h> 345: 346: char * 347: ttypath() 348: { 349: struct stat stbuf; 350: register char *pathn; 351: extern char *ttyname(); 352: extern char *getlogin(); 353: 354: /* compute the pathname of the controlling tty */ 355: if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && 356: (pathn = ttyname(0)) == NULL) 357: { 358: errno = 0; 359: return (NULL); 360: } 361: 362: /* see if we have write permission */ 363: if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) 364: { 365: errno = 0; 366: return (NULL); 367: } 368: 369: /* see if the user is logged in */ 370: if (getlogin() == NULL) 371: return (NULL); 372: 373: /* looks good */ 374: return (pathn); 375: } 376: /* 377: ** CHECKCOMPAT -- check for From and To person compatible. 378: ** 379: ** This routine can be supplied on a per-installation basis 380: ** to determine whether a person is allowed to send a message. 381: ** This allows restriction of certain types of internet 382: ** forwarding or registration of users. 383: ** 384: ** If the hosts are found to be incompatible, an error 385: ** message should be given using "usrerr" and FALSE should 386: ** be returned. 387: ** 388: ** 'NoReturn' can be set to suppress the return-to-sender 389: ** function; this should be done on huge messages. 390: ** 391: ** Parameters: 392: ** to -- the person being sent to. 393: ** 394: ** Returns: 395: ** TRUE -- ok to send. 396: ** FALSE -- not ok. 397: ** 398: ** Side Effects: 399: ** none (unless you include the usrerr stuff) 400: */ 401: 402: bool 403: checkcompat(to) 404: register ADDRESS *to; 405: { 406: # ifdef lint 407: if (to == NULL) 408: to++; 409: # endif lint 410: # ifdef EXAMPLE_CODE 411: /* this code is intended as an example only */ 412: register STAB *s; 413: 414: s = stab("arpa", ST_MAILER, ST_FIND); 415: if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && 416: to->q_mailer == s->s_mailer) 417: { 418: usrerr("No ARPA mail through this machine: see your system administration"); 419: /* NoReturn = TRUE; to supress return copy */ 420: return (FALSE); 421: } 422: # endif EXAMPLE_CODE 423: return (TRUE); 424: } 425: /* 426: ** HOLDSIGS -- arrange to hold all signals 427: ** 428: ** Parameters: 429: ** none. 430: ** 431: ** Returns: 432: ** none. 433: ** 434: ** Side Effects: 435: ** Arranges that signals are held. 436: */ 437: 438: holdsigs() 439: { 440: } 441: /* 442: ** RLSESIGS -- arrange to release all signals 443: ** 444: ** This undoes the effect of holdsigs. 445: ** 446: ** Parameters: 447: ** none. 448: ** 449: ** Returns: 450: ** none. 451: ** 452: ** Side Effects: 453: ** Arranges that signals are released. 454: */ 455: 456: rlsesigs() 457: { 458: } 459: /* 460: ** GETLA -- get the current load average 461: ** 462: ** This code stolen from la.c. 463: ** 464: ** Parameters: 465: ** none. 466: ** 467: ** Returns: 468: ** The current load average as an integer. 469: ** 470: ** Side Effects: 471: ** none. 472: */ 473: 474: #ifdef VMUNIX 475: 476: #include <nlist.h> 477: 478: struct nlist Nl[] = 479: { 480: { "_avenrun" }, 481: #define X_AVENRUN 0 482: { 0 }, 483: }; 484: 485: getla() 486: { 487: static int kmem = -1; 488: double avenrun[3]; 489: 490: if (kmem < 0) 491: { 492: kmem = open("/dev/kmem", 0); 493: if (kmem < 0) 494: return (-1); 495: (void) ioctl(kmem, FIOCLEX, 0); 496: nlist("/unix", Nl); 497: if (Nl[0].n_type == 0) 498: return (-1); 499: } 500: (void) lseek(kmem, (long) Nl[X_AVENRUN].n_value, 0); 501: (void) read(kmem, avenrun, sizeof(avenrun)); 502: return ((int) (avenrun[0] + 0.5)); 503: } 504: 505: #else VMUNIX 506: 507: getla() 508: { 509: return (0); 510: } 511: 512: #endif VMUNIX