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