1: /*
   2: **  Sendmail
   3: **  Copyright (c) 1983  Eric P. Allman
   4: **  Berkeley, California
   5: **
   6: **  Copyright (c) 1983 Regents of the University of California.
   7: **  All rights reserved.  The Berkeley software License Agreement
   8: **  specifies the terms and conditions for redistribution.
   9: */
  10: 
  11: #ifndef lint
  12: static char SccsId[] = "@(#)conf.c	5.14 (Berkeley) 1/10/86";
  13: #endif not lint
  14: 
  15: # include <pwd.h>
  16: # include <sys/ioctl.h>
  17: # ifdef sun
  18: # include <sys/param.h>
  19: # endif sun
  20: # include "sendmail.h"
  21: 
  22: /*
  23: **  CONF.C -- Sendmail Configuration Tables.
  24: **
  25: **	Defines the configuration of this installation.
  26: **
  27: **	Compilation Flags:
  28: **		V6 -- running on a version 6 system.  This determines
  29: **			whether to define certain routines between
  30: **			the two systems.  If you are running a funny
  31: **			system, e.g., V6 with long tty names, this
  32: **			should be checked carefully.
  33: **		VMUNIX -- running on a Berkeley UNIX system.
  34: **
  35: **	Configuration Variables:
  36: **		HdrInfo -- a table describing well-known header fields.
  37: **			Each entry has the field name and some flags,
  38: **			which are described in sendmail.h.
  39: **
  40: **	Notes:
  41: **		I have tried to put almost all the reasonable
  42: **		configuration information into the configuration
  43: **		file read at runtime.  My intent is that anything
  44: **		here is a function of the version of UNIX you
  45: **		are running, or is really static -- for example
  46: **		the headers are a superset of widely used
  47: **		protocols.  If you find yourself playing with
  48: **		this file too much, you may be making a mistake!
  49: */
  50: 
  51: 
  52: 
  53: 
  54: /*
  55: **  Header info table
  56: **	Final (null) entry contains the flags used for any other field.
  57: **
  58: **	Not all of these are actually handled specially by sendmail
  59: **	at this time.  They are included as placeholders, to let
  60: **	you know that "someday" I intend to have sendmail do
  61: **	something with them.
  62: */
  63: 
  64: struct hdrinfo  HdrInfo[] =
  65: {
  66:         /* originator fields, most to least significant  */
  67:     "resent-sender",    H_FROM|H_RESENT,
  68:     "resent-from",      H_FROM|H_RESENT,
  69:     "resent-reply-to",  H_FROM|H_RESENT,
  70:     "sender",       H_FROM,
  71:     "from",         H_FROM,
  72:     "reply-to",     H_FROM,
  73:     "full-name",        H_ACHECK,
  74:     "return-receipt-to",    H_FROM,
  75:     "errors-to",        H_FROM,
  76:         /* destination fields */
  77:     "to",           H_RCPT,
  78:     "resent-to",        H_RCPT|H_RESENT,
  79:     "cc",           H_RCPT,
  80:     "resent-cc",        H_RCPT|H_RESENT,
  81:     "bcc",          H_RCPT|H_ACHECK,
  82:     "resent-bcc",       H_RCPT|H_ACHECK|H_RESENT,
  83:         /* message identification and control */
  84:     "message-id",       0,
  85:     "resent-message-id",    H_RESENT,
  86:     "message",      H_EOH,
  87:     "text",         H_EOH,
  88:         /* date fields */
  89:     "date",         0,
  90:     "resent-date",      H_RESENT,
  91:         /* trace fields */
  92:     "received",     H_TRACE|H_FORCE,
  93:     "via",          H_TRACE|H_FORCE,
  94:     "mail-from",        H_TRACE|H_FORCE,
  95: 
  96:     NULL,           0,
  97: };
  98: 
  99: 
 100: /*
 101: **  ARPANET error message numbers.
 102: */
 103: 
 104: char    Arpa_Info[] =       "050";  /* arbitrary info */
 105: char    Arpa_TSyserr[] =    "451";  /* some (transient) system error */
 106: char    Arpa_PSyserr[] =    "554";  /* some (permanent) system error */
 107: char    Arpa_Usrerr[] =     "554";  /* some (fatal) user error */
 108: 
 109: 
 110: 
 111: /*
 112: **  Location of system files/databases/etc.
 113: */
 114: 
 115: char    *ConfFile = "/usr/lib/sendmail.cf"; /* runtime configuration */
 116: char    *FreezeFile =   "/usr/lib/sendmail.fc"; /* frozen version of above */
 117: 
 118: 
 119: 
 120: /*
 121: **  Miscellaneous stuff.
 122: */
 123: 
 124: int DtableSize =    50;     /* max open files; reset in 4.2bsd */
 125: /*
 126: **  SETDEFAULTS -- set default values
 127: **
 128: **	Because of the way freezing is done, these must be initialized
 129: **	using direct code.
 130: **
 131: **	Parameters:
 132: **		none.
 133: **
 134: **	Returns:
 135: **		none.
 136: **
 137: **	Side Effects:
 138: **		Initializes a bunch of global variables to their
 139: **		default values.
 140: */
 141: 
 142: setdefaults()
 143: {
 144:     QueueLA = 8;
 145:     QueueFactor = 10000;
 146:     RefuseLA = 12;
 147:     SpaceSub = ' ';
 148:     WkRecipFact = 1000;
 149:     WkClassFact = 1800;
 150:     WkTimeFact = 9000;
 151:     FileMode = 0644;
 152:     DefUid = 1;
 153:     DefGid = 1;
 154: }
 155: 
 156: # ifdef V6
 157: /*
 158: **  TTYNAME -- return name of terminal.
 159: **
 160: **	Parameters:
 161: **		fd -- file descriptor to check.
 162: **
 163: **	Returns:
 164: **		pointer to full path of tty.
 165: **		NULL if no tty.
 166: **
 167: **	Side Effects:
 168: **		none.
 169: */
 170: 
 171: char *
 172: ttyname(fd)
 173:     int fd;
 174: {
 175:     register char tn;
 176:     static char pathn[] = "/dev/ttyx";
 177: 
 178:     /* compute the pathname of the controlling tty */
 179:     if ((tn = ttyn(fd)) == NULL)
 180:     {
 181:         errno = 0;
 182:         return (NULL);
 183:     }
 184:     pathn[8] = tn;
 185:     return (pathn);
 186: }
 187: /*
 188: **  FDOPEN -- Open a stdio file given an open file descriptor.
 189: **
 190: **	This is included here because it is standard in v7, but we
 191: **	need it in v6.
 192: **
 193: **	Algorithm:
 194: **		Open /dev/null to create a descriptor.
 195: **		Close that descriptor.
 196: **		Copy the existing fd into the descriptor.
 197: **
 198: **	Parameters:
 199: **		fd -- the open file descriptor.
 200: **		type -- "r", "w", or whatever.
 201: **
 202: **	Returns:
 203: **		The file descriptor it creates.
 204: **
 205: **	Side Effects:
 206: **		none
 207: **
 208: **	Called By:
 209: **		deliver
 210: **
 211: **	Notes:
 212: **		The mode of fd must match "type".
 213: */
 214: 
 215: FILE *
 216: fdopen(fd, type)
 217:     int fd;
 218:     char *type;
 219: {
 220:     register FILE *f;
 221: 
 222:     f = fopen("/dev/null", type);
 223:     (void) close(fileno(f));
 224:     fileno(f) = fd;
 225:     return (f);
 226: }
 227: /*
 228: **  INDEX -- Return pointer to character in string
 229: **
 230: **	For V7 compatibility.
 231: **
 232: **	Parameters:
 233: **		s -- a string to scan.
 234: **		c -- a character to look for.
 235: **
 236: **	Returns:
 237: **		If c is in s, returns the address of the first
 238: **			instance of c in s.
 239: **		NULL if c is not in s.
 240: **
 241: **	Side Effects:
 242: **		none.
 243: */
 244: 
 245: char *
 246: index(s, c)
 247:     register char *s;
 248:     register char c;
 249: {
 250:     while (*s != '\0')
 251:     {
 252:         if (*s++ == c)
 253:             return (--s);
 254:     }
 255:     return (NULL);
 256: }
 257: /*
 258: **  UMASK -- fake the umask system call.
 259: **
 260: **	Since V6 always acts like the umask is zero, we will just
 261: **	assume the same thing.
 262: */
 263: 
 264: /*ARGSUSED*/
 265: umask(nmask)
 266: {
 267:     return (0);
 268: }
 269: 
 270: 
 271: /*
 272: **  GETRUID -- get real user id.
 273: */
 274: 
 275: getruid()
 276: {
 277:     return (getuid() & 0377);
 278: }
 279: 
 280: 
 281: /*
 282: **  GETRGID -- get real group id.
 283: */
 284: 
 285: getrgid()
 286: {
 287:     return (getgid() & 0377);
 288: }
 289: 
 290: 
 291: /*
 292: **  GETEUID -- get effective user id.
 293: */
 294: 
 295: geteuid()
 296: {
 297:     return ((getuid() >> 8) & 0377);
 298: }
 299: 
 300: 
 301: /*
 302: **  GETEGID -- get effective group id.
 303: */
 304: 
 305: getegid()
 306: {
 307:     return ((getgid() >> 8) & 0377);
 308: }
 309: 
 310: # endif V6
 311: 
 312: # ifndef V6
 313: 
 314: /*
 315: **  GETRUID -- get real user id (V7)
 316: */
 317: 
 318: getruid()
 319: {
 320:     if (OpMode == MD_DAEMON)
 321:         return (RealUid);
 322:     else
 323:         return (getuid());
 324: }
 325: 
 326: 
 327: /*
 328: **  GETRGID -- get real group id (V7).
 329: */
 330: 
 331: getrgid()
 332: {
 333:     if (OpMode == MD_DAEMON)
 334:         return (RealGid);
 335:     else
 336:         return (getgid());
 337: }
 338: 
 339: # endif V6
 340: /*
 341: **  USERNAME -- return the user id of the logged in user.
 342: **
 343: **	Parameters:
 344: **		none.
 345: **
 346: **	Returns:
 347: **		The login name of the logged in user.
 348: **
 349: **	Side Effects:
 350: **		none.
 351: **
 352: **	Notes:
 353: **		The return value is statically allocated.
 354: */
 355: 
 356: char *
 357: username()
 358: {
 359:     static char *myname = NULL;
 360:     extern char *getlogin();
 361:     register struct passwd *pw;
 362:     extern struct passwd *getpwuid();
 363: 
 364:     /* cache the result */
 365:     if (myname == NULL)
 366:     {
 367:         myname = getlogin();
 368:         if (myname == NULL || myname[0] == '\0')
 369:         {
 370: 
 371:             pw = getpwuid(getruid());
 372:             if (pw != NULL)
 373:                 myname = pw->pw_name;
 374:         }
 375:         else
 376:         {
 377: 
 378:             pw = getpwnam(myname);
 379:             if(getuid() != pw->pw_uid)
 380:             {
 381:                 pw = getpwuid(getuid());
 382:                 if (pw != NULL)
 383:                     myname = pw->pw_name;
 384:             }
 385:         }
 386:         if (myname == NULL || myname[0] == '\0')
 387:         {
 388:             syserr("Who are you?");
 389:             myname = "postmaster";
 390:         }
 391:     }
 392: 
 393:     return (myname);
 394: }
 395: /*
 396: **  TTYPATH -- Get the path of the user's tty
 397: **
 398: **	Returns the pathname of the user's tty.  Returns NULL if
 399: **	the user is not logged in or if s/he has write permission
 400: **	denied.
 401: **
 402: **	Parameters:
 403: **		none
 404: **
 405: **	Returns:
 406: **		pathname of the user's tty.
 407: **		NULL if not logged in or write permission denied.
 408: **
 409: **	Side Effects:
 410: **		none.
 411: **
 412: **	WARNING:
 413: **		Return value is in a local buffer.
 414: **
 415: **	Called By:
 416: **		savemail
 417: */
 418: 
 419: # include <sys/stat.h>
 420: 
 421: char *
 422: ttypath()
 423: {
 424:     struct stat stbuf;
 425:     register char *pathn;
 426:     extern char *ttyname();
 427:     extern char *getlogin();
 428: 
 429:     /* compute the pathname of the controlling tty */
 430:     if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
 431:         (pathn = ttyname(0)) == NULL)
 432:     {
 433:         errno = 0;
 434:         return (NULL);
 435:     }
 436: 
 437:     /* see if we have write permission */
 438:     if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
 439:     {
 440:         errno = 0;
 441:         return (NULL);
 442:     }
 443: 
 444:     /* see if the user is logged in */
 445:     if (getlogin() == NULL)
 446:         return (NULL);
 447: 
 448:     /* looks good */
 449:     return (pathn);
 450: }
 451: /*
 452: **  CHECKCOMPAT -- check for From and To person compatible.
 453: **
 454: **	This routine can be supplied on a per-installation basis
 455: **	to determine whether a person is allowed to send a message.
 456: **	This allows restriction of certain types of internet
 457: **	forwarding or registration of users.
 458: **
 459: **	If the hosts are found to be incompatible, an error
 460: **	message should be given using "usrerr" and FALSE should
 461: **	be returned.
 462: **
 463: **	'NoReturn' can be set to suppress the return-to-sender
 464: **	function; this should be done on huge messages.
 465: **
 466: **	Parameters:
 467: **		to -- the person being sent to.
 468: **
 469: **	Returns:
 470: **		TRUE -- ok to send.
 471: **		FALSE -- not ok.
 472: **
 473: **	Side Effects:
 474: **		none (unless you include the usrerr stuff)
 475: */
 476: 
 477: bool
 478: checkcompat(to)
 479:     register ADDRESS *to;
 480: {
 481: # ifdef lint
 482:     if (to == NULL)
 483:         to++;
 484: # endif lint
 485: # ifdef EXAMPLE_CODE
 486:     /* this code is intended as an example only */
 487:     register STAB *s;
 488: 
 489:     s = stab("arpa", ST_MAILER, ST_FIND);
 490:     if (s != NULL && CurEnv->e_from.q_mailer != LocalMailer &&
 491:         to->q_mailer == s->s_mailer)
 492:     {
 493:         usrerr("No ARPA mail through this machine: see your system administration");
 494:         /* NoReturn = TRUE; to supress return copy */
 495:         return (FALSE);
 496:     }
 497: # endif EXAMPLE_CODE
 498:     return (TRUE);
 499: }
 500: /*
 501: **  HOLDSIGS -- arrange to hold all signals
 502: **
 503: **	Parameters:
 504: **		none.
 505: **
 506: **	Returns:
 507: **		none.
 508: **
 509: **	Side Effects:
 510: **		Arranges that signals are held.
 511: */
 512: 
 513: holdsigs()
 514: {
 515: }
 516: /*
 517: **  RLSESIGS -- arrange to release all signals
 518: **
 519: **	This undoes the effect of holdsigs.
 520: **
 521: **	Parameters:
 522: **		none.
 523: **
 524: **	Returns:
 525: **		none.
 526: **
 527: **	Side Effects:
 528: **		Arranges that signals are released.
 529: */
 530: 
 531: rlsesigs()
 532: {
 533: }
 534: /*
 535: **  GETLA -- get the current load average
 536: **
 537: **	This code stolen from la.c.
 538: **
 539: **	Parameters:
 540: **		none.
 541: **
 542: **	Returns:
 543: **		The current load average as an integer.
 544: **
 545: **	Side Effects:
 546: **		none.
 547: */
 548: 
 549: #ifdef VMUNIX
 550: 
 551: #include <nlist.h>
 552: 
 553: struct  nlist Nl[] =
 554: {
 555:     { "_avenrun" },
 556: #define X_AVENRUN   0
 557:     { 0 },
 558: };
 559: 
 560: getla()
 561: {
 562:     static int kmem = -1;
 563: # ifdef sun
 564:     long avenrun[3];
 565: # else
 566:     double avenrun[3];
 567: # endif
 568:     extern off_t lseek();
 569: 
 570:     if (kmem < 0)
 571:     {
 572:         kmem = open("/dev/kmem", 0, 0);
 573:         if (kmem < 0)
 574:             return (-1);
 575:         (void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
 576:         nlist("/vmunix", Nl);
 577:         if (Nl[0].n_type == 0)
 578:             return (-1);
 579:     }
 580:     if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
 581:         read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
 582:     {
 583:         /* thank you Ian */
 584:         return (-1);
 585:     }
 586: # ifdef sun
 587:     return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
 588: # else
 589:     return ((int) (avenrun[0] + 0.5));
 590: # endif
 591: }
 592: 
 593: #else VMUNIX
 594: 
 595: getla()
 596: {
 597:     return (0);
 598: }
 599: 
 600: #endif VMUNIX
 601: /*
 602: **  SHOULDQUEUE -- should this message be queued or sent?
 603: **
 604: **	Compares the message cost to the load average to decide.
 605: **
 606: **	Parameters:
 607: **		pri -- the priority of the message in question.
 608: **
 609: **	Returns:
 610: **		TRUE -- if this message should be queued up for the
 611: **			time being.
 612: **		FALSE -- if the load is low enough to send this message.
 613: **
 614: **	Side Effects:
 615: **		none.
 616: */
 617: 
 618: bool
 619: shouldqueue(pri)
 620:     long pri;
 621: {
 622:     int la;
 623: 
 624:     la = getla();
 625:     if (la < QueueLA)
 626:         return (FALSE);
 627:     return (pri > (QueueFactor / (la - QueueLA + 1)));
 628: }
 629: /*
 630: **  SETPROCTITLE -- set process title for ps
 631: **
 632: **	Parameters:
 633: **		fmt -- a printf style format string.
 634: **		a, b, c -- possible parameters to fmt.
 635: **
 636: **	Returns:
 637: **		none.
 638: **
 639: **	Side Effects:
 640: **		Clobbers argv of our main procedure so ps(1) will
 641: **		display the title.
 642: */
 643: 
 644: /*VARARGS1*/
 645: setproctitle(fmt, a, b, c)
 646:     char *fmt;
 647: {
 648: # ifdef SETPROCTITLE
 649:     register char *p;
 650:     register int i;
 651:     extern char **Argv;
 652:     extern char *LastArgv;
 653:     char buf[MAXLINE];
 654: 
 655:     (void) sprintf(buf, fmt, a, b, c);
 656: 
 657:     /* make ps print "(sendmail)" */
 658:     p = Argv[0];
 659:     *p++ = '-';
 660: 
 661:     i = strlen(buf);
 662:     if (i > LastArgv - p - 2)
 663:     {
 664:         i = LastArgv - p - 2;
 665:         buf[i] = '\0';
 666:     }
 667:     (void) strcpy(p, buf);
 668:     p += i;
 669:     while (p < LastArgv)
 670:         *p++ = ' ';
 671: # endif SETPROCTITLE
 672: }
 673: /*
 674: **  REAPCHILD -- pick up the body of my child, lest it become a zombie
 675: **
 676: **	Parameters:
 677: **		none.
 678: **
 679: **	Returns:
 680: **		none.
 681: **
 682: **	Side Effects:
 683: **		Picks up extant zombies.
 684: */
 685: 
 686: # ifdef VMUNIX
 687: # include <sys/wait.h>
 688: # endif VMUNIX
 689: 
 690: reapchild()
 691: {
 692: # ifdef WNOHANG
 693:     union wait status;
 694: 
 695:     while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
 696:         continue;
 697: # else WNOHANG
 698:     auto int status;
 699: 
 700:     while (wait(&status) > 0)
 701:         continue;
 702: # endif WNOHANG
 703: }

Defined functions

checkcompat defined in line 477; used 2 times
geteuid defined in line 295; used 50 times
getla defined in line 595; used 2 times
holdsigs defined in line 513; never used
rlsesigs defined in line 531; never used
setdefaults defined in line 142; used 1 times
ttyname defined in line 171; used 6 times
ttypath defined in line 421; used 2 times
umask defined in line 265; used 82 times

Defined variables

Arpa_Info defined in line 104; used 3 times
Arpa_PSyserr defined in line 106; never used
Arpa_TSyserr defined in line 105; never used
Arpa_Usrerr defined in line 107; never used
ConfFile defined in line 115; never used
DtableSize defined in line 124; never used
FreezeFile defined in line 116; never used
HdrInfo defined in line 64; never used
Nl defined in line 553; used 3 times
SccsId defined in line 12; never used
bool defined in line 477; used 1 times

Defined macros

X_AVENRUN defined in line 556; used 1 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2551
Valid CSS Valid XHTML 1.0 Strict