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[] = "@(#)envelope.c	5.12 (Berkeley) 12/17/85";
  13: #endif not lint
  14: 
  15: #include <pwd.h>
  16: #include <sys/time.h>
  17: #include "sendmail.h"
  18: #include <sys/stat.h>
  19: 
  20: /*
  21: **  NEWENVELOPE -- allocate a new envelope
  22: **
  23: **	Supports inheritance.
  24: **
  25: **	Parameters:
  26: **		e -- the new envelope to fill in.
  27: **
  28: **	Returns:
  29: **		e.
  30: **
  31: **	Side Effects:
  32: **		none.
  33: */
  34: 
  35: ENVELOPE *
  36: newenvelope(e)
  37:     register ENVELOPE *e;
  38: {
  39:     register ENVELOPE *parent;
  40:     extern putheader(), putbody();
  41:     extern ENVELOPE BlankEnvelope;
  42: 
  43:     parent = CurEnv;
  44:     if (e == CurEnv)
  45:         parent = e->e_parent;
  46:     clearenvelope(e, TRUE);
  47:     if (e == CurEnv)
  48:         bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from);
  49:     else
  50:         bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from);
  51:     e->e_parent = parent;
  52:     e->e_ctime = curtime();
  53:     e->e_msgpriority = parent->e_msgsize;
  54:     e->e_puthdr = putheader;
  55:     e->e_putbody = putbody;
  56:     if (CurEnv->e_xfp != NULL)
  57:         (void) fflush(CurEnv->e_xfp);
  58: 
  59:     return (e);
  60: }
  61: /*
  62: **  DROPENVELOPE -- deallocate an envelope.
  63: **
  64: **	Parameters:
  65: **		e -- the envelope to deallocate.
  66: **
  67: **	Returns:
  68: **		none.
  69: **
  70: **	Side Effects:
  71: **		housekeeping necessary to dispose of an envelope.
  72: **		Unlocks this queue file.
  73: */
  74: 
  75: dropenvelope(e)
  76:     register ENVELOPE *e;
  77: {
  78:     bool queueit = FALSE;
  79:     register ADDRESS *q;
  80: 
  81: #ifdef DEBUG
  82:     if (tTd(50, 1))
  83:     {
  84:         printf("dropenvelope %x id=", e);
  85:         xputs(e->e_id);
  86:         printf(" flags=%o\n", e->e_flags);
  87:     }
  88: #endif DEBUG
  89: #ifdef LOG
  90:     if (LogLevel > 10)
  91:         syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d",
  92:                   e->e_id == NULL ? "(none)" : e->e_id,
  93:                   e->e_flags, getpid());
  94: #endif LOG
  95: 
  96:     /* we must have an id to remove disk files */
  97:     if (e->e_id == NULL)
  98:         return;
  99: 
 100:     /*
 101: 	**  Extract state information from dregs of send list.
 102: 	*/
 103: 
 104:     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
 105:     {
 106:         if (bitset(QQUEUEUP, q->q_flags))
 107:             queueit = TRUE;
 108:     }
 109: 
 110:     /*
 111: 	**  Send back return receipts as requested.
 112: 	*/
 113: 
 114:     if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags))
 115:     {
 116:         auto ADDRESS *rlist = NULL;
 117: 
 118:         sendtolist(CurEnv->e_receiptto, (ADDRESS *) NULL, &rlist);
 119:         (void) returntosender("Return receipt", rlist, FALSE);
 120:     }
 121: 
 122:     /*
 123: 	**  Arrange to send error messages if there are fatal errors.
 124: 	*/
 125: 
 126:     if (bitset(EF_FATALERRS|EF_TIMEOUT, e->e_flags) && ErrorMode != EM_QUIET)
 127:         savemail(e);
 128: 
 129:     /*
 130: 	**  Instantiate or deinstantiate the queue.
 131: 	*/
 132: 
 133:     if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) ||
 134:         bitset(EF_CLRQUEUE, e->e_flags))
 135:     {
 136:         if (e->e_df != NULL)
 137:             xunlink(e->e_df);
 138:         xunlink(queuename(e, 'q'));
 139:     }
 140:     else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
 141:     {
 142: #ifdef QUEUE
 143:         queueup(e, FALSE, FALSE);
 144: #else QUEUE
 145:         syserr("dropenvelope: queueup");
 146: #endif QUEUE
 147:     }
 148: 
 149:     /* now unlock the job */
 150:     closexscript(e);
 151:     unlockqueue(e);
 152: 
 153:     /* make sure that this envelope is marked unused */
 154:     e->e_id = e->e_df = NULL;
 155:     if (e->e_dfp != NULL)
 156:         (void) fclose(e->e_dfp);
 157:     e->e_dfp = NULL;
 158: }
 159: /*
 160: **  CLEARENVELOPE -- clear an envelope without unlocking
 161: **
 162: **	This is normally used by a child process to get a clean
 163: **	envelope without disturbing the parent.
 164: **
 165: **	Parameters:
 166: **		e -- the envelope to clear.
 167: **		fullclear - if set, the current envelope is total
 168: **			garbage and should be ignored; otherwise,
 169: **			release any resources it may indicate.
 170: **
 171: **	Returns:
 172: **		none.
 173: **
 174: **	Side Effects:
 175: **		Closes files associated with the envelope.
 176: **		Marks the envelope as unallocated.
 177: */
 178: 
 179: clearenvelope(e, fullclear)
 180:     register ENVELOPE *e;
 181:     bool fullclear;
 182: {
 183:     register HDR *bh;
 184:     register HDR **nhp;
 185:     extern ENVELOPE BlankEnvelope;
 186: 
 187:     if (!fullclear)
 188:     {
 189:         /* clear out any file information */
 190:         if (e->e_xfp != NULL)
 191:             (void) fclose(e->e_xfp);
 192:         if (e->e_dfp != NULL)
 193:             (void) fclose(e->e_dfp);
 194:     }
 195: 
 196:     /* now clear out the data */
 197:     STRUCTCOPY(BlankEnvelope, *e);
 198:     bh = BlankEnvelope.e_header;
 199:     nhp = &e->e_header;
 200:     while (bh != NULL)
 201:     {
 202:         *nhp = (HDR *) xalloc(sizeof *bh);
 203:         bcopy((char *) bh, (char *) *nhp, sizeof *bh);
 204:         bh = bh->h_link;
 205:         nhp = &(*nhp)->h_link;
 206:     }
 207: }
 208: /*
 209: **  INITSYS -- initialize instantiation of system
 210: **
 211: **	In Daemon mode, this is done in the child.
 212: **
 213: **	Parameters:
 214: **		none.
 215: **
 216: **	Returns:
 217: **		none.
 218: **
 219: **	Side Effects:
 220: **		Initializes the system macros, some global variables,
 221: **		etc.  In particular, the current time in various
 222: **		forms is set.
 223: */
 224: 
 225: initsys()
 226: {
 227:     static char cbuf[5];            /* holds hop count */
 228:     static char pbuf[10];           /* holds pid */
 229: #ifdef TTYNAME
 230:     static char ybuf[10];           /* holds tty id */
 231:     register char *p;
 232: #endif TTYNAME
 233:     extern char *ttyname();
 234:     extern char *macvalue();
 235:     extern char Version[];
 236: 
 237:     /*
 238: 	**  Give this envelope a reality.
 239: 	**	I.e., an id, a transcript, and a creation time.
 240: 	*/
 241: 
 242:     openxscript(CurEnv);
 243:     CurEnv->e_ctime = curtime();
 244: 
 245:     /*
 246: 	**  Set OutChannel to something useful if stdout isn't it.
 247: 	**	This arranges that any extra stuff the mailer produces
 248: 	**	gets sent back to the user on error (because it is
 249: 	**	tucked away in the transcript).
 250: 	*/
 251: 
 252:     if (OpMode == MD_DAEMON && QueueRun)
 253:         OutChannel = CurEnv->e_xfp;
 254: 
 255:     /*
 256: 	**  Set up some basic system macros.
 257: 	*/
 258: 
 259:     /* process id */
 260:     (void) sprintf(pbuf, "%d", getpid());
 261:     define('p', pbuf, CurEnv);
 262: 
 263:     /* hop count */
 264:     (void) sprintf(cbuf, "%d", CurEnv->e_hopcount);
 265:     define('c', cbuf, CurEnv);
 266: 
 267:     /* time as integer, unix time, arpa time */
 268:     settime();
 269: 
 270: #ifdef TTYNAME
 271:     /* tty name */
 272:     if (macvalue('y', CurEnv) == NULL)
 273:     {
 274:         p = ttyname(2);
 275:         if (p != NULL)
 276:         {
 277:             if (rindex(p, '/') != NULL)
 278:                 p = rindex(p, '/') + 1;
 279:             (void) strcpy(ybuf, p);
 280:             define('y', ybuf, CurEnv);
 281:         }
 282:     }
 283: #endif TTYNAME
 284: }
 285: /*
 286: **  SETTIME -- set the current time.
 287: **
 288: **	Parameters:
 289: **		none.
 290: **
 291: **	Returns:
 292: **		none.
 293: **
 294: **	Side Effects:
 295: **		Sets the various time macros -- $a, $b, $d, $t.
 296: */
 297: 
 298: settime()
 299: {
 300:     register char *p;
 301:     auto time_t now;
 302:     static char tbuf[20];           /* holds "current" time */
 303:     static char dbuf[30];           /* holds ctime(tbuf) */
 304:     register struct tm *tm;
 305:     extern char *arpadate();
 306:     extern struct tm *gmtime();
 307:     extern char *macvalue();
 308: 
 309:     now = curtime();
 310:     tm = gmtime(&now);
 311:     (void) sprintf(tbuf, "%02d%02d%02d%02d%02d", tm->tm_year, tm->tm_mon+1,
 312:             tm->tm_mday, tm->tm_hour, tm->tm_min);
 313:     define('t', tbuf, CurEnv);
 314:     (void) strcpy(dbuf, ctime(&now));
 315:     *index(dbuf, '\n') = '\0';
 316:     if (macvalue('d', CurEnv) == NULL)
 317:         define('d', dbuf, CurEnv);
 318:     p = newstr(arpadate(dbuf));
 319:     if (macvalue('a', CurEnv) == NULL)
 320:         define('a', p, CurEnv);
 321:     define('b', p, CurEnv);
 322: }
 323: /*
 324: **  OPENXSCRIPT -- Open transcript file
 325: **
 326: **	Creates a transcript file for possible eventual mailing or
 327: **	sending back.
 328: **
 329: **	Parameters:
 330: **		e -- the envelope to create the transcript in/for.
 331: **
 332: **	Returns:
 333: **		none
 334: **
 335: **	Side Effects:
 336: **		Creates the transcript file.
 337: */
 338: 
 339: openxscript(e)
 340:     register ENVELOPE *e;
 341: {
 342:     register char *p;
 343: 
 344: # ifdef LOG
 345:     if (LogLevel > 19)
 346:         syslog(LOG_DEBUG, "%s: openx%s", e->e_id, e->e_xfp == NULL ? "" : " (no)");
 347: # endif LOG
 348:     if (e->e_xfp != NULL)
 349:         return;
 350:     p = queuename(e, 'x');
 351:     e->e_xfp = fopen(p, "w");
 352:     if (e->e_xfp == NULL)
 353:         syserr("Can't create %s", p);
 354:     else
 355:         (void) chmod(p, 0644);
 356: }
 357: /*
 358: **  CLOSEXSCRIPT -- close the transcript file.
 359: **
 360: **	Parameters:
 361: **		e -- the envelope containing the transcript to close.
 362: **
 363: **	Returns:
 364: **		none.
 365: **
 366: **	Side Effects:
 367: **		none.
 368: */
 369: 
 370: closexscript(e)
 371:     register ENVELOPE *e;
 372: {
 373:     if (e->e_xfp == NULL)
 374:         return;
 375:     (void) fclose(e->e_xfp);
 376:     e->e_xfp = NULL;
 377: }
 378: /*
 379: **  SETSENDER -- set the person who this message is from
 380: **
 381: **	Under certain circumstances allow the user to say who
 382: **	s/he is (using -f or -r).  These are:
 383: **	1.  The user's uid is zero (root).
 384: **	2.  The user's login name is in an approved list (typically
 385: **	    from a network server).
 386: **	3.  The address the user is trying to claim has a
 387: **	    "!" character in it (since #2 doesn't do it for
 388: **	    us if we are dialing out for UUCP).
 389: **	A better check to replace #3 would be if the
 390: **	effective uid is "UUCP" -- this would require me
 391: **	to rewrite getpwent to "grab" uucp as it went by,
 392: **	make getname more nasty, do another passwd file
 393: **	scan, or compile the UID of "UUCP" into the code,
 394: **	all of which are reprehensible.
 395: **
 396: **	Assuming all of these fail, we figure out something
 397: **	ourselves.
 398: **
 399: **	Parameters:
 400: **		from -- the person we would like to believe this message
 401: **			is from, as specified on the command line.
 402: **
 403: **	Returns:
 404: **		none.
 405: **
 406: **	Side Effects:
 407: **		sets sendmail's notion of who the from person is.
 408: */
 409: 
 410: setsender(from)
 411:     char *from;
 412: {
 413:     register char **pvp;
 414:     char *realname = NULL;
 415:     register struct passwd *pw;
 416:     char buf[MAXNAME];
 417:     char pvpbuf[PSBUFSIZE];
 418:     extern struct passwd *getpwnam();
 419:     extern char *macvalue();
 420:     extern char **prescan();
 421:     extern bool safefile();
 422:     extern char *FullName;
 423: 
 424: # ifdef DEBUG
 425:     if (tTd(45, 1))
 426:         printf("setsender(%s)\n", from == NULL ? "" : from);
 427: # endif DEBUG
 428: 
 429:     /*
 430: 	**  Figure out the real user executing us.
 431: 	**	Username can return errno != 0 on non-errors.
 432: 	*/
 433: 
 434:     if (QueueRun || OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
 435:         realname = from;
 436:     if (realname == NULL || realname[0] == '\0')
 437:     {
 438:         extern char *username();
 439: 
 440:         realname = username();
 441:     }
 442: 
 443:     /*
 444: 	**  Determine if this real person is allowed to alias themselves.
 445: 	*/
 446: 
 447:     if (from != NULL)
 448:     {
 449:         extern bool trusteduser();
 450: 
 451:         if (!trusteduser(realname) &&
 452: # ifdef DEBUG
 453:             (!tTd(1, 9) || getuid() != geteuid()) &&
 454: # endif DEBUG
 455:             index(from, '!') == NULL && getuid() != 0)
 456:         {
 457:             /* network sends -r regardless (why why why?) */
 458:             /* syserr("%s, you cannot use the -f flag", realname); */
 459:             from = NULL;
 460:         }
 461:     }
 462: 
 463:     SuprErrs = TRUE;
 464:     if (from == NULL || parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL)
 465:     {
 466:         /* log garbage addresses for traceback */
 467:         if (from != NULL)
 468:         {
 469: # ifdef LOG
 470:             if (LogLevel >= 1)
 471:                 syslog(LOG_ERR, "Unparseable user %s wants to be %s",
 472:                         realname, from);
 473: # endif LOG
 474:         }
 475:         from = newstr(realname);
 476:         if (parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL &&
 477:             parseaddr("postmaster", &CurEnv->e_from, 1, '\0') == NULL)
 478:         {
 479:             syserr("setsender: can't even parse postmaster!");
 480:         }
 481:     }
 482:     else
 483:         FromFlag = TRUE;
 484:     CurEnv->e_from.q_flags |= QDONTSEND;
 485:     loweraddr(&CurEnv->e_from);
 486:     SuprErrs = FALSE;
 487: 
 488:     if (CurEnv->e_from.q_mailer == LocalMailer &&
 489:         (pw = getpwnam(CurEnv->e_from.q_user)) != NULL)
 490:     {
 491:         /*
 492: 		**  Process passwd file entry.
 493: 		*/
 494: 
 495: 
 496:         /* extract home directory */
 497:         CurEnv->e_from.q_home = newstr(pw->pw_dir);
 498:         define('z', CurEnv->e_from.q_home, CurEnv);
 499: 
 500:         /* extract user and group id */
 501:         CurEnv->e_from.q_uid = pw->pw_uid;
 502:         CurEnv->e_from.q_gid = pw->pw_gid;
 503: 
 504:         /* if the user has given fullname already, don't redefine */
 505:         if (FullName == NULL)
 506:             FullName = macvalue('x', CurEnv);
 507:         if (FullName != NULL && FullName[0] == '\0')
 508:             FullName = NULL;
 509: 
 510:         /* extract full name from passwd file */
 511:         if (FullName == NULL && pw->pw_gecos != NULL &&
 512:             strcmp(pw->pw_name, CurEnv->e_from.q_user) == 0)
 513:         {
 514:             buildfname(pw->pw_gecos, CurEnv->e_from.q_user, buf);
 515:             if (buf[0] != '\0')
 516:                 FullName = newstr(buf);
 517:         }
 518:         if (FullName != NULL)
 519:             define('x', FullName, CurEnv);
 520:     }
 521:     else
 522:     {
 523: #ifndef V6
 524:         if (CurEnv->e_from.q_home == NULL)
 525:             CurEnv->e_from.q_home = getenv("HOME");
 526: #endif V6
 527:         CurEnv->e_from.q_uid = getuid();
 528:         CurEnv->e_from.q_gid = getgid();
 529:     }
 530: 
 531:     if (CurEnv->e_from.q_uid != 0)
 532:     {
 533:         DefUid = CurEnv->e_from.q_uid;
 534:         DefGid = CurEnv->e_from.q_gid;
 535:     }
 536: 
 537:     /*
 538: 	**  Rewrite the from person to dispose of possible implicit
 539: 	**	links in the net.
 540: 	*/
 541: 
 542:     pvp = prescan(from, '\0', pvpbuf);
 543:     if (pvp == NULL)
 544:     {
 545:         syserr("cannot prescan from (%s)", from);
 546:         finis();
 547:     }
 548:     rewrite(pvp, 3);
 549:     rewrite(pvp, 1);
 550:     rewrite(pvp, 4);
 551:     cataddr(pvp, buf, sizeof buf);
 552:     define('f', newstr(buf), CurEnv);
 553: 
 554:     /* save the domain spec if this mailer wants it */
 555:     if (CurEnv->e_from.q_mailer != NULL &&
 556:         bitnset(M_CANONICAL, CurEnv->e_from.q_mailer->m_flags))
 557:     {
 558:         extern char **copyplist();
 559: 
 560:         while (*pvp != NULL && strcmp(*pvp, "@") != 0)
 561:             pvp++;
 562:         if (*pvp != NULL)
 563:             CurEnv->e_fromdomain = copyplist(pvp, TRUE);
 564:     }
 565: }
 566: /*
 567: **  TRUSTEDUSER -- tell us if this user is to be trusted.
 568: **
 569: **	Parameters:
 570: **		user -- the user to be checked.
 571: **
 572: **	Returns:
 573: **		TRUE if the user is in an approved list.
 574: **		FALSE otherwise.
 575: **
 576: **	Side Effects:
 577: **		none.
 578: */
 579: 
 580: bool
 581: trusteduser(user)
 582:     char *user;
 583: {
 584:     register char **ulist;
 585:     extern char *TrustedUsers[];
 586: 
 587:     for (ulist = TrustedUsers; *ulist != NULL; ulist++)
 588:         if (strcmp(*ulist, user) == 0)
 589:             return (TRUE);
 590:     return (FALSE);
 591: }

Defined functions

closexscript defined in line 370; used 1 times
settime defined in line 298; used 2 times
trusteduser defined in line 580; used 3 times

Defined variables

SccsId defined in line 12; never used
Last modified: 1985-12-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1662
Valid CSS Valid XHTML 1.0 Strict