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

##### Functions

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

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

#### Defined functions

clearenvelope defined in line 185; used 3 times

- in line 52
- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 609
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 680

closexscript defined in line 375; used 1 times

- in line 156

dropenvelope defined in line 81; used 6 times

- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 486, 636, 742
- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 652
- in /usr/src/usr.sbin/sendmail.MX/src/savemail.c line 434
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 366

initsys defined in line 231; used 3 times

- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 662
- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 637
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 248

newenvelope defined in line 41; used 7 times

- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 114, 538, 643
- in /usr/src/usr.sbin/sendmail.MX/src/savemail.c line 371, 397
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 124, 367

openxscript defined in line 344; used 3 times

- in line 247
- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 644
- in /usr/src/usr.sbin/sendmail.MX/src/savemail.c line 403

setsender defined in line 415; used 4 times

- in /usr/src/usr.sbin/sendmail.MX/src/headers.c line 370
- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 663
- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 731
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 256

settime defined in line 303; used 2 times

- in line 273
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 133

trusteduser defined in line 583; used 3 times

- in line 454-456(2)
- in /usr/src/usr.sbin/sendmail.MX/src/readcf.c line 665

#### Defined variables

sccsid defined in line 18; never used

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1733 |