|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Eric P. Allman ! 3: * Copyright (c) 1988 Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * Redistribution and use in source and binary forms are permitted ! 7: * provided that the above copyright notice and this paragraph are ! 8: * duplicated in all such forms and that any documentation, ! 9: * advertising materials, and other materials related to such ! 10: * distribution and use acknowledge that the software was developed ! 11: * by the University of California, Berkeley. The name of the ! 12: * University may not be used to endorse or promote products derived ! 13: * from this software without specific prior written permission. ! 14: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 15: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 16: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 17: */ ! 18: ! 19: #ifndef lint ! 20: static char sccsid[] = "@(#)conf.c 5.17 (Berkeley) 6/30/88"; ! 21: #endif /* not lint */ ! 22: ! 23: # include <pwd.h> ! 24: # include <sys/ioctl.h> ! 25: # ifdef sun ! 26: # include <sys/param.h> ! 27: # endif sun ! 28: # include "sendmail.h" ! 29: ! 30: /* ! 31: ** CONF.C -- Sendmail Configuration Tables. ! 32: ** ! 33: ** Defines the configuration of this installation. ! 34: ** ! 35: ** Compilation Flags: ! 36: ** VMUNIX -- running on a Berkeley UNIX system. ! 37: ** ! 38: ** Configuration Variables: ! 39: ** HdrInfo -- a table describing well-known header fields. ! 40: ** Each entry has the field name and some flags, ! 41: ** which are described in sendmail.h. ! 42: ** ! 43: ** Notes: ! 44: ** I have tried to put almost all the reasonable ! 45: ** configuration information into the configuration ! 46: ** file read at runtime. My intent is that anything ! 47: ** here is a function of the version of UNIX you ! 48: ** are running, or is really static -- for example ! 49: ** the headers are a superset of widely used ! 50: ** protocols. If you find yourself playing with ! 51: ** this file too much, you may be making a mistake! ! 52: */ ! 53: ! 54: ! 55: ! 56: ! 57: /* ! 58: ** Header info table ! 59: ** Final (null) entry contains the flags used for any other field. ! 60: ** ! 61: ** Not all of these are actually handled specially by sendmail ! 62: ** at this time. They are included as placeholders, to let ! 63: ** you know that "someday" I intend to have sendmail do ! 64: ** something with them. ! 65: */ ! 66: ! 67: struct hdrinfo HdrInfo[] = ! 68: { ! 69: /* originator fields, most to least significant */ ! 70: "resent-sender", H_FROM|H_RESENT, ! 71: "resent-from", H_FROM|H_RESENT, ! 72: "resent-reply-to", H_FROM|H_RESENT, ! 73: "sender", H_FROM, ! 74: "from", H_FROM, ! 75: "reply-to", H_FROM, ! 76: "full-name", H_ACHECK, ! 77: "return-receipt-to", H_FROM, ! 78: "errors-to", H_FROM, ! 79: /* destination fields */ ! 80: "to", H_RCPT, ! 81: "resent-to", H_RCPT|H_RESENT, ! 82: "cc", H_RCPT, ! 83: "resent-cc", H_RCPT|H_RESENT, ! 84: "bcc", H_RCPT|H_ACHECK, ! 85: "resent-bcc", H_RCPT|H_ACHECK|H_RESENT, ! 86: /* message identification and control */ ! 87: "message-id", 0, ! 88: "resent-message-id", H_RESENT, ! 89: "message", H_EOH, ! 90: "text", H_EOH, ! 91: /* date fields */ ! 92: "date", 0, ! 93: "resent-date", H_RESENT, ! 94: /* trace fields */ ! 95: "received", H_TRACE|H_FORCE, ! 96: "via", H_TRACE|H_FORCE, ! 97: "mail-from", H_TRACE|H_FORCE, ! 98: ! 99: NULL, 0, ! 100: }; ! 101: ! 102: ! 103: /* ! 104: ** ARPANET error message numbers. ! 105: */ ! 106: ! 107: char Arpa_Info[] = "050"; /* arbitrary info */ ! 108: char Arpa_TSyserr[] = "451"; /* some (transient) system error */ ! 109: char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ ! 110: char Arpa_Usrerr[] = "554"; /* some (fatal) user error */ ! 111: ! 112: ! 113: ! 114: /* ! 115: ** Location of system files/databases/etc. ! 116: */ ! 117: ! 118: char *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */ ! 119: char *FreezeFile = "/usr/lib/sendmail.fc"; /* frozen version of above */ ! 120: ! 121: ! 122: ! 123: /* ! 124: ** Miscellaneous stuff. ! 125: */ ! 126: ! 127: int DtableSize = 50; /* max open files; reset in 4.2bsd */ ! 128: /* ! 129: ** SETDEFAULTS -- set default values ! 130: ** ! 131: ** Because of the way freezing is done, these must be initialized ! 132: ** using direct code. ! 133: ** ! 134: ** Parameters: ! 135: ** none. ! 136: ** ! 137: ** Returns: ! 138: ** none. ! 139: ** ! 140: ** Side Effects: ! 141: ** Initializes a bunch of global variables to their ! 142: ** default values. ! 143: */ ! 144: ! 145: setdefaults() ! 146: { ! 147: QueueLA = 8; ! 148: QueueFactor = 10000; ! 149: RefuseLA = 12; ! 150: SpaceSub = ' '; ! 151: WkRecipFact = 1000; ! 152: WkClassFact = 1800; ! 153: WkTimeFact = 9000; ! 154: FileMode = 0644; ! 155: DefUid = 1; ! 156: DefGid = 1; ! 157: } ! 158: ! 159: /* ! 160: ** GETRUID -- get real user id (V7) ! 161: */ ! 162: ! 163: getruid() ! 164: { ! 165: if (OpMode == MD_DAEMON) ! 166: return (RealUid); ! 167: else ! 168: return (getuid()); ! 169: } ! 170: ! 171: ! 172: /* ! 173: ** GETRGID -- get real group id (V7). ! 174: */ ! 175: ! 176: getrgid() ! 177: { ! 178: if (OpMode == MD_DAEMON) ! 179: return (RealGid); ! 180: else ! 181: return (getgid()); ! 182: } ! 183: ! 184: /* ! 185: ** USERNAME -- return the user id of the logged in user. ! 186: ** ! 187: ** Parameters: ! 188: ** none. ! 189: ** ! 190: ** Returns: ! 191: ** The login name of the logged in user. ! 192: ** ! 193: ** Side Effects: ! 194: ** none. ! 195: ** ! 196: ** Notes: ! 197: ** The return value is statically allocated. ! 198: */ ! 199: ! 200: char * ! 201: username() ! 202: { ! 203: static char *myname = NULL; ! 204: extern char *getlogin(); ! 205: register struct passwd *pw; ! 206: extern struct passwd *getpwuid(); ! 207: ! 208: /* cache the result */ ! 209: if (myname == NULL) ! 210: { ! 211: myname = getlogin(); ! 212: if (myname == NULL || myname[0] == '\0') ! 213: { ! 214: ! 215: pw = getpwuid(getruid()); ! 216: if (pw != NULL) ! 217: myname = pw->pw_name; ! 218: } ! 219: else ! 220: { ! 221: ! 222: pw = getpwnam(myname); ! 223: if(getuid() != pw->pw_uid) ! 224: { ! 225: pw = getpwuid(getuid()); ! 226: if (pw != NULL) ! 227: myname = pw->pw_name; ! 228: } ! 229: } ! 230: if (myname == NULL || myname[0] == '\0') ! 231: { ! 232: syserr("Who are you?"); ! 233: myname = "postmaster"; ! 234: } ! 235: } ! 236: ! 237: return (myname); ! 238: } ! 239: /* ! 240: ** TTYPATH -- Get the path of the user's tty ! 241: ** ! 242: ** Returns the pathname of the user's tty. Returns NULL if ! 243: ** the user is not logged in or if s/he has write permission ! 244: ** denied. ! 245: ** ! 246: ** Parameters: ! 247: ** none ! 248: ** ! 249: ** Returns: ! 250: ** pathname of the user's tty. ! 251: ** NULL if not logged in or write permission denied. ! 252: ** ! 253: ** Side Effects: ! 254: ** none. ! 255: ** ! 256: ** WARNING: ! 257: ** Return value is in a local buffer. ! 258: ** ! 259: ** Called By: ! 260: ** savemail ! 261: */ ! 262: ! 263: # include <sys/stat.h> ! 264: ! 265: char * ! 266: ttypath() ! 267: { ! 268: struct stat stbuf; ! 269: register char *pathn; ! 270: extern char *ttyname(); ! 271: extern char *getlogin(); ! 272: ! 273: /* compute the pathname of the controlling tty */ ! 274: if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && ! 275: (pathn = ttyname(0)) == NULL) ! 276: { ! 277: errno = 0; ! 278: return (NULL); ! 279: } ! 280: ! 281: /* see if we have write permission */ ! 282: if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode)) ! 283: { ! 284: errno = 0; ! 285: return (NULL); ! 286: } ! 287: ! 288: /* see if the user is logged in */ ! 289: if (getlogin() == NULL) ! 290: return (NULL); ! 291: ! 292: /* looks good */ ! 293: return (pathn); ! 294: } ! 295: /* ! 296: ** CHECKCOMPAT -- check for From and To person compatible. ! 297: ** ! 298: ** This routine can be supplied on a per-installation basis ! 299: ** to determine whether a person is allowed to send a message. ! 300: ** This allows restriction of certain types of internet ! 301: ** forwarding or registration of users. ! 302: ** ! 303: ** If the hosts are found to be incompatible, an error ! 304: ** message should be given using "usrerr" and FALSE should ! 305: ** be returned. ! 306: ** ! 307: ** 'NoReturn' can be set to suppress the return-to-sender ! 308: ** function; this should be done on huge messages. ! 309: ** ! 310: ** Parameters: ! 311: ** to -- the person being sent to. ! 312: ** ! 313: ** Returns: ! 314: ** TRUE -- ok to send. ! 315: ** FALSE -- not ok. ! 316: ** ! 317: ** Side Effects: ! 318: ** none (unless you include the usrerr stuff) ! 319: */ ! 320: ! 321: bool ! 322: checkcompat(to) ! 323: register ADDRESS *to; ! 324: { ! 325: # ifdef lint ! 326: if (to == NULL) ! 327: to++; ! 328: # endif lint ! 329: # ifdef EXAMPLE_CODE ! 330: /* this code is intended as an example only */ ! 331: register STAB *s; ! 332: ! 333: s = stab("arpa", ST_MAILER, ST_FIND); ! 334: if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer && ! 335: to->q_mailer == s->s_mailer) ! 336: { ! 337: usrerr("No ARPA mail through this machine: see your system administration"); ! 338: /* NoReturn = TRUE; to supress return copy */ ! 339: return (FALSE); ! 340: } ! 341: # endif EXAMPLE_CODE ! 342: return (TRUE); ! 343: } ! 344: /* ! 345: ** HOLDSIGS -- arrange to hold all signals ! 346: ** ! 347: ** Parameters: ! 348: ** none. ! 349: ** ! 350: ** Returns: ! 351: ** none. ! 352: ** ! 353: ** Side Effects: ! 354: ** Arranges that signals are held. ! 355: */ ! 356: ! 357: holdsigs() ! 358: { ! 359: } ! 360: /* ! 361: ** RLSESIGS -- arrange to release all signals ! 362: ** ! 363: ** This undoes the effect of holdsigs. ! 364: ** ! 365: ** Parameters: ! 366: ** none. ! 367: ** ! 368: ** Returns: ! 369: ** none. ! 370: ** ! 371: ** Side Effects: ! 372: ** Arranges that signals are released. ! 373: */ ! 374: ! 375: rlsesigs() ! 376: { ! 377: } ! 378: /* ! 379: ** GETLA -- get the current load average ! 380: ** ! 381: ** This code stolen from la.c. ! 382: ** ! 383: ** Parameters: ! 384: ** none. ! 385: ** ! 386: ** Returns: ! 387: ** The current load average as an integer. ! 388: ** ! 389: ** Side Effects: ! 390: ** none. ! 391: */ ! 392: ! 393: #ifdef VMUNIX ! 394: ! 395: #include <nlist.h> ! 396: ! 397: struct nlist Nl[] = ! 398: { ! 399: { "_avenrun" }, ! 400: #define X_AVENRUN 0 ! 401: { 0 }, ! 402: }; ! 403: ! 404: getla() ! 405: { ! 406: static int kmem = -1; ! 407: # ifdef sun ! 408: long avenrun[3]; ! 409: # else ! 410: double avenrun[3]; ! 411: # endif ! 412: extern off_t lseek(); ! 413: ! 414: if (kmem < 0) ! 415: { ! 416: kmem = open("/dev/kmem", 0, 0); ! 417: if (kmem < 0) ! 418: return (-1); ! 419: (void) ioctl(kmem, (int) FIOCLEX, (char *) 0); ! 420: nlist("/vmunix", Nl); ! 421: if (Nl[0].n_type == 0) ! 422: return (-1); ! 423: } ! 424: if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 || ! 425: read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) ! 426: { ! 427: /* thank you Ian */ ! 428: return (-1); ! 429: } ! 430: # ifdef sun ! 431: return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); ! 432: # else ! 433: return ((int) (avenrun[0] + 0.5)); ! 434: # endif ! 435: } ! 436: ! 437: #else VMUNIX ! 438: ! 439: getla() ! 440: { ! 441: return (0); ! 442: } ! 443: ! 444: #endif VMUNIX ! 445: /* ! 446: ** SHOULDQUEUE -- should this message be queued or sent? ! 447: ** ! 448: ** Compares the message cost to the load average to decide. ! 449: ** ! 450: ** Parameters: ! 451: ** pri -- the priority of the message in question. ! 452: ** ! 453: ** Returns: ! 454: ** TRUE -- if this message should be queued up for the ! 455: ** time being. ! 456: ** FALSE -- if the load is low enough to send this message. ! 457: ** ! 458: ** Side Effects: ! 459: ** none. ! 460: */ ! 461: ! 462: bool ! 463: shouldqueue(pri) ! 464: long pri; ! 465: { ! 466: int la; ! 467: ! 468: la = getla(); ! 469: if (la < QueueLA) ! 470: return (FALSE); ! 471: return (pri > (QueueFactor / (la - QueueLA + 1))); ! 472: } ! 473: /* ! 474: ** SETPROCTITLE -- set process title for ps ! 475: ** ! 476: ** Parameters: ! 477: ** fmt -- a printf style format string. ! 478: ** a, b, c -- possible parameters to fmt. ! 479: ** ! 480: ** Returns: ! 481: ** none. ! 482: ** ! 483: ** Side Effects: ! 484: ** Clobbers argv of our main procedure so ps(1) will ! 485: ** display the title. ! 486: */ ! 487: ! 488: /*VARARGS1*/ ! 489: setproctitle(fmt, a, b, c) ! 490: char *fmt; ! 491: { ! 492: # ifdef SETPROCTITLE ! 493: register char *p; ! 494: register int i; ! 495: extern char **Argv; ! 496: extern char *LastArgv; ! 497: char buf[MAXLINE]; ! 498: ! 499: (void) sprintf(buf, fmt, a, b, c); ! 500: ! 501: /* make ps print "(sendmail)" */ ! 502: p = Argv[0]; ! 503: *p++ = '-'; ! 504: ! 505: i = strlen(buf); ! 506: if (i > LastArgv - p - 2) ! 507: { ! 508: i = LastArgv - p - 2; ! 509: buf[i] = '\0'; ! 510: } ! 511: (void) strcpy(p, buf); ! 512: p += i; ! 513: while (p < LastArgv) ! 514: *p++ = ' '; ! 515: # endif SETPROCTITLE ! 516: } ! 517: /* ! 518: ** REAPCHILD -- pick up the body of my child, lest it become a zombie ! 519: ** ! 520: ** Parameters: ! 521: ** none. ! 522: ** ! 523: ** Returns: ! 524: ** none. ! 525: ** ! 526: ** Side Effects: ! 527: ** Picks up extant zombies. ! 528: */ ! 529: ! 530: # ifdef VMUNIX ! 531: # include <sys/wait.h> ! 532: # endif VMUNIX ! 533: ! 534: reapchild() ! 535: { ! 536: # ifdef WNOHANG ! 537: union wait status; ! 538: ! 539: while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0) ! 540: continue; ! 541: # else WNOHANG ! 542: auto int status; ! 543: ! 544: while (wait(&status) > 0) ! 545: continue; ! 546: # endif WNOHANG ! 547: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.