# 2.11BSD#431 - /usr/src/usr.sbin/sendmail/src/envelope.c

##### Functions

    clearenvelope     X
    closexscript      X
    dropenvelope      X
    initsys           X
    newenvelope       X
    openxscript       X
    setsender         X
    settime           X
    trusteduser       X

       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: #if !defined(lint) && !defined(NOSCCS)
      12: static char SccsId[] = "@(#)envelope.c	5.12.1 (2.11BSD GTE) 7/15/94";
      13: #endif
      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:
     236:     /*
     237: 	**  Give this envelope a reality.
     238: 	**	I.e., an id, a transcript, and a creation time.
     239: 	*/
     240:
     241:     openxscript(CurEnv);
     242:     CurEnv->e_ctime = curtime();
     243:
     244:     /*
     245: 	**  Set OutChannel to something useful if stdout isn't it.
     246: 	**	This arranges that any extra stuff the mailer produces
     247: 	**	gets sent back to the user on error (because it is
     248: 	**	tucked away in the transcript).
     249: 	*/
     250:
     251:     if (OpMode == MD_DAEMON && QueueRun)
     252:         OutChannel = CurEnv->e_xfp;
     253:
     254:     /*
     255: 	**  Set up some basic system macros.
     256: 	*/
     257:
     258:     /* process id */
     259:     (void) sprintf(pbuf, "%d", getpid());
     260:     define('p', pbuf, CurEnv);
     261:
     262:     /* hop count */
     263:     (void) sprintf(cbuf, "%d", CurEnv->e_hopcount);
     264:     define('c', cbuf, CurEnv);
     265:
     266:     /* time as integer, unix time, arpa time */
     267:     settime();
     268:
     269: #ifdef TTYNAME
     270:     /* tty name */
     271:     if (macvalue('y', CurEnv) == NULL)
     272:     {
     273:         p = ttyname(2);
     274:         if (p != NULL)
     275:         {
     276:             if (rindex(p, '/') != NULL)
     277:                 p = rindex(p, '/') + 1;
     278:             (void) strcpy(ybuf, p);
     279:             define('y', ybuf, CurEnv);
     280:         }
     281:     }
     282: #endif TTYNAME
     283: }
     284: /*
     285: **  SETTIME -- set the current time.
     286: **
     287: **	Parameters:
     288: **		none.
     289: **
     290: **	Returns:
     291: **		none.
     292: **
     293: **	Side Effects:
     294: **		Sets the various time macros -- $a, $b, $d, $t.
     295: */
     296:
     297: settime()
     298: {
     299:     register char *p;
     300:     auto time_t now;
     301:     static char tbuf[20];           /* holds "current" time */
     302:     static char dbuf[30];           /* holds ctime(tbuf) */
     303:     register struct tm *tm;
     304:     extern char *arpadate();
     305:     extern struct tm *gmtime();
     306:     extern char *macvalue();
     307:
     308:     now = curtime();
     309:     tm = gmtime(&now);
     310:     (void) sprintf(tbuf, "%02d%02d%02d%02d%02d", tm->tm_year, tm->tm_mon+1,
     311:             tm->tm_mday, tm->tm_hour, tm->tm_min);
     312:     define('t', tbuf, CurEnv);
     313:     (void) strcpy(dbuf, ctime(&now));
     314:     *index(dbuf, '\n') = '\0';
     315:     if (macvalue('d', CurEnv) == NULL)
     316:         define('d', dbuf, CurEnv);
     317:     p = newstr(arpadate(dbuf));
     318:     if (macvalue('a', CurEnv) == NULL)
     319:         define('a', p, CurEnv);
     320:     define('b', p, CurEnv);
     321: }
     322: /*
     323: **  OPENXSCRIPT -- Open transcript file
     324: **
     325: **	Creates a transcript file for possible eventual mailing or
     326: **	sending back.
     327: **
     328: **	Parameters:
     329: **		e -- the envelope to create the transcript in/for.
     330: **
     331: **	Returns:
     332: **		none
     333: **
     334: **	Side Effects:
     335: **		Creates the transcript file.
     336: */
     337:
     338: openxscript(e)
     339:     register ENVELOPE *e;
     340: {
     341:     register char *p;
     342:
     343: # ifdef LOG
     344:     if (LogLevel > 19)
     345:         syslog(LOG_DEBUG, "%s: openx%s", e->e_id, e->e_xfp == NULL ? "" : " (no)");
     346: # endif LOG
     347:     if (e->e_xfp != NULL)
     348:         return;
     349:     p = queuename(e, 'x');
     350:     e->e_xfp = fopen(p, "w");
     351:     if (e->e_xfp == NULL)
     352:         syserr("Can't create %s", p);
     353:     else
     354:         (void) chmod(p, 0644);
     355: }
     356: /*
     357: **  CLOSEXSCRIPT -- close the transcript file.
     358: **
     359: **	Parameters:
     360: **		e -- the envelope containing the transcript to close.
     361: **
     362: **	Returns:
     363: **		none.
     364: **
     365: **	Side Effects:
     366: **		none.
     367: */
     368:
     369: closexscript(e)
     370:     register ENVELOPE *e;
     371: {
     372:     if (e->e_xfp == NULL)
     373:         return;
     374:     (void) fclose(e->e_xfp);
     375:     e->e_xfp = NULL;
     376: }
     377: /*
     378: **  SETSENDER -- set the person who this message is from
     379: **
     380: **	Under certain circumstances allow the user to say who
     381: **	s/he is (using -f or -r).  These are:
     382: **	1.  The user's uid is zero (root).
     383: **	2.  The user's login name is in an approved list (typically
     384: **	    from a network server).
     385: **	3.  The address the user is trying to claim has a
     386: **	    "!" character in it (since #2 doesn't do it for
     387: **	    us if we are dialing out for UUCP).
     388: **	A better check to replace #3 would be if the
     389: **	effective uid is "UUCP" -- this would require me
     390: **	to rewrite getpwent to "grab" uucp as it went by,
     391: **	make getname more nasty, do another passwd file
     392: **	scan, or compile the UID of "UUCP" into the code,
     393: **	all of which are reprehensible.
     394: **
     395: **	Assuming all of these fail, we figure out something
     396: **	ourselves.
     397: **
     398: **	Parameters:
     399: **		from -- the person we would like to believe this message
     400: **			is from, as specified on the command line.
     401: **
     402: **	Returns:
     403: **		none.
     404: **
     405: **	Side Effects:
     406: **		sets sendmail's notion of who the from person is.
     407: */
     408:
     409: setsender(from)
     410:     char *from;
     411: {
     412:     register char **pvp;
     413:     char *realname = NULL;
     414:     register struct passwd *pw;
     415:     char buf[MAXNAME];
     416:     char pvpbuf[PSBUFSIZE];
     417:     extern struct passwd *getpwnam();
     418:     extern char *macvalue();
     419:     extern char **prescan();
     420:     extern bool safefile();
     421:     extern char *FullName;
     422:
     423: # ifdef DEBUG
     424:     if (tTd(45, 1))
     425:         printf("setsender(%s)\n", from == NULL ? "" : from);
     426: # endif DEBUG
     427:
     428:     /*
     429: 	**  Figure out the real user executing us.
     430: 	**	Username can return errno != 0 on non-errors.
     431: 	*/
     432:
     433:     if (QueueRun || OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
     434:         realname = from;
     435:     if (realname == NULL || realname[0] == '\0')
     436:     {
     437:         extern char *username();
     438:
     439:         realname = username();
     440:     }
     441:
     442:     /*
     443: 	**  Determine if this real person is allowed to alias themselves.
     444: 	*/
     445:
     446:     if (from != NULL)
     447:     {
     448:         extern bool trusteduser();
     449:
     450:         if (!trusteduser(realname) &&
     451: # ifdef DEBUG
     452:             (!tTd(1, 9) || getuid() != geteuid()) &&
     453: # endif DEBUG
     454:             index(from, '!') == NULL && getuid() != 0)
     455:         {
     456:             /* network sends -r regardless (why why why?) */
     457:             /* syserr("%s, you cannot use the -f flag", realname); */
     458:             from = NULL;
     459:         }
     460:     }
     461:
     462:     SuprErrs = TRUE;
     463:     if (from == NULL || parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL)
     464:     {
     465:         /* log garbage addresses for traceback */
     466:         if (from != NULL)
     467:         {
     468: # ifdef LOG
     469:             if (LogLevel >= 1)
     470:                 syslog(LOG_ERR, "Unparseable user %s wants to be %s",
     471:                         realname, from);
     472: # endif LOG
     473:         }
     474:         from = newstr(realname);
     475:         if (parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL &&
     476:             parseaddr("postmaster", &CurEnv->e_from, 1, '\0') == NULL)
     477:         {
     478:             syserr("setsender: can't even parse postmaster!");
     479:         }
     480:     }
     481:     else
     482:         FromFlag = TRUE;
     483:     CurEnv->e_from.q_flags |= QDONTSEND;
     484:     loweraddr(&CurEnv->e_from);
     485:     SuprErrs = FALSE;
     486:
     487:     if (CurEnv->e_from.q_mailer == LocalMailer &&
     488:         (pw = getpwnam(CurEnv->e_from.q_user)) != NULL)
     489:     {
     490:         /*
     491: 		**  Process passwd file entry.
     492: 		*/
     493:
     494:
     495:         /* extract home directory */
     496:         CurEnv->e_from.q_home = newstr(pw->pw_dir);
     497:         define('z', CurEnv->e_from.q_home, CurEnv);
     498:
     499:         /* extract user and group id */
     500:         CurEnv->e_from.q_uid = pw->pw_uid;
     501:         CurEnv->e_from.q_gid = pw->pw_gid;
     502:
     503:         /* if the user has given fullname already, don't redefine */
     504:         if (FullName == NULL)
     505:             FullName = macvalue('x', CurEnv);
     506:         if (FullName != NULL && FullName[0] == '\0')
     507:             FullName = NULL;
     508:
     509:         /* extract full name from passwd file */
     510:         if (FullName == NULL && pw->pw_gecos != NULL &&
     511:             strcmp(pw->pw_name, CurEnv->e_from.q_user) == 0)
     512:         {
     513:             buildfname(pw->pw_gecos, CurEnv->e_from.q_user, buf);
     514:             if (buf[0] != '\0')
     515:                 FullName = newstr(buf);
     516:         }
     517:         if (FullName != NULL)
     518:             define('x', FullName, CurEnv);
     519:     }
     520:     else
     521:     {
     522: #ifndef V6
     523:         if (CurEnv->e_from.q_home == NULL)
     524:             CurEnv->e_from.q_home = getenv("HOME");
     525: #endif V6
     526:         CurEnv->e_from.q_uid = getuid();
     527:         CurEnv->e_from.q_gid = getgid();
     528:     }
     529:
     530:     if (CurEnv->e_from.q_uid != 0)
     531:     {
     532:         DefUid = CurEnv->e_from.q_uid;
     533:         DefGid = CurEnv->e_from.q_gid;
     534:     }
     535:
     536:     /*
     537: 	**  Rewrite the from person to dispose of possible implicit
     538: 	**	links in the net.
     539: 	*/
     540:
     541:     pvp = prescan(from, '\0', pvpbuf);
     542:     if (pvp == NULL)
     543:     {
     544:         syserr("cannot prescan from (%s)", from);
     545:         finis();
     546:     }
     547:     rewrite(pvp, 3);
     548:     rewrite(pvp, 1);
     549:     rewrite(pvp, 4);
     550:     cataddr(pvp, buf, sizeof buf);
     551:     define('f', newstr(buf), CurEnv);
     552:
     553:     /* save the domain spec if this mailer wants it */
     554:     if (CurEnv->e_from.q_mailer != NULL &&
     555:         bitnset(M_CANONICAL, CurEnv->e_from.q_mailer->m_flags))
     556:     {
     557:         extern char **copyplist();
     558:
     559:         while (*pvp != NULL && strcmp(*pvp, "@") != 0)
     560:             pvp++;
     561:         if (*pvp != NULL)
     562:             CurEnv->e_fromdomain = copyplist(pvp, TRUE);
     563:     }
     564: }
     565: /*
     566: **  TRUSTEDUSER -- tell us if this user is to be trusted.
     567: **
     568: **	Parameters:
     569: **		user -- the user to be checked.
     570: **
     571: **	Returns:
     572: **		TRUE if the user is in an approved list.
     573: **		FALSE otherwise.
     574: **
     575: **	Side Effects:
     576: **		none.
     577: */
     578:
     579: bool
     580: trusteduser(user)
     581:     char *user;
     582: {
     583:     register char **ulist;
     584:     extern char *TrustedUsers[];
     585:
     586:     for (ulist = TrustedUsers; *ulist != NULL; ulist++)
     587:         if (strcmp(*ulist, user) == 0)
     588:             return (TRUE);
     589:     return (FALSE);
     590: }

#### Defined functions

clearenvelope defined in line 179; used 3 times

- in line 46
- in /usr/src/usr.sbin/sendmail/src/queue.c line 596
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 671

closexscript defined in line 369; used 1 times

- in line 150

dropenvelope defined in line 75; used 6 times

- in /usr/src/usr.sbin/sendmail/src/main.c line 490, 640, 746
- in /usr/src/usr.sbin/sendmail/src/queue.c line 639
- in /usr/src/usr.sbin/sendmail/src/savemail.c line 428
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 356

initsys defined in line 225; used 3 times

- in /usr/src/usr.sbin/sendmail/src/main.c line 666
- in /usr/src/usr.sbin/sendmail/src/queue.c line 624
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 238

newenvelope defined in line 35; used 7 times

- in /usr/src/usr.sbin/sendmail/src/main.c line 113, 542, 647
- in /usr/src/usr.sbin/sendmail/src/savemail.c line 365, 391
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 116, 357

openxscript defined in line 338; used 3 times

- in line 241
- in /usr/src/usr.sbin/sendmail/src/main.c line 648
- in /usr/src/usr.sbin/sendmail/src/savemail.c line 397

setsender defined in line 409; used 4 times

- in /usr/src/usr.sbin/sendmail/src/headers.c line 364
- in /usr/src/usr.sbin/sendmail/src/main.c line 667
- in /usr/src/usr.sbin/sendmail/src/queue.c line 718
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 246

settime defined in line 297; used 2 times

- in line 267
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 125

trusteduser defined in line 579; used 3 times

- in line 448-450(2)
- in /usr/src/usr.sbin/sendmail/src/readcf.c line 659

#### Defined variables

SccsId defined in line 12; never used

Last modified: 1994-07-15 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2395 |