BSD 4_4 release
[unix-history] / usr / src / usr.sbin / sendmail / src / envelope.c
index a6098c9..3b6d2c1 100644 (file)
@@ -1,33 +1,44 @@
 /*
  * Copyright (c) 1983 Eric P. Allman
 /*
  * Copyright (c) 1983 Eric P. Allman
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1988, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the University nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)envelope.c 5.22 (Berkeley) 6/1/90";
+static char sccsid[] = "@(#)envelope.c 8.1 (Berkeley) 6/7/93";
 #endif /* not lint */
 
 #endif /* not lint */
 
-#include <sys/types.h>
+#include "sendmail.h"
 #include <sys/time.h>
 #include <sys/time.h>
-#include <sys/stat.h>
 #include <pwd.h>
 #include <pwd.h>
-#include <sys/file.h>
-#include "sendmail.h"
 
 /*
 **  NEWENVELOPE -- allocate a new envelope
 
 /*
 **  NEWENVELOPE -- allocate a new envelope
@@ -36,6 +47,7 @@ static char sccsid[] = "@(#)envelope.c        5.22 (Berkeley) 6/1/90";
 **
 **     Parameters:
 **             e -- the new envelope to fill in.
 **
 **     Parameters:
 **             e -- the new envelope to fill in.
+**             parent -- the envelope to be the parent of e.
 **
 **     Returns:
 **             e.
 **
 **     Returns:
 **             e.
@@ -45,15 +57,14 @@ static char sccsid[] = "@(#)envelope.c      5.22 (Berkeley) 6/1/90";
 */
 
 ENVELOPE *
 */
 
 ENVELOPE *
-newenvelope(e)
+newenvelope(e, parent)
        register ENVELOPE *e;
        register ENVELOPE *e;
-{
        register ENVELOPE *parent;
        register ENVELOPE *parent;
+{
        extern putheader(), putbody();
        extern ENVELOPE BlankEnvelope;
 
        extern putheader(), putbody();
        extern ENVELOPE BlankEnvelope;
 
-       parent = CurEnv;
-       if (e == CurEnv)
+       if (e == parent && e->e_parent != NULL)
                parent = e->e_parent;
        clearenvelope(e, TRUE);
        if (e == CurEnv)
                parent = e->e_parent;
        clearenvelope(e, TRUE);
        if (e == CurEnv)
@@ -62,7 +73,8 @@ newenvelope(e)
                bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from);
        e->e_parent = parent;
        e->e_ctime = curtime();
                bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from);
        e->e_parent = parent;
        e->e_ctime = curtime();
-       e->e_msgpriority = parent->e_msgsize;
+       if (parent != NULL)
+               e->e_msgpriority = parent->e_msgsize;
        e->e_puthdr = putheader;
        e->e_putbody = putbody;
        if (CurEnv->e_xfp != NULL)
        e->e_puthdr = putheader;
        e->e_putbody = putbody;
        if (CurEnv->e_xfp != NULL)
@@ -84,29 +96,31 @@ newenvelope(e)
 **             Unlocks this queue file.
 */
 
 **             Unlocks this queue file.
 */
 
+void
 dropenvelope(e)
        register ENVELOPE *e;
 {
        bool queueit = FALSE;
        register ADDRESS *q;
 dropenvelope(e)
        register ENVELOPE *e;
 {
        bool queueit = FALSE;
        register ADDRESS *q;
+       char *id = e->e_id;
 
        if (tTd(50, 1))
        {
 
        if (tTd(50, 1))
        {
-               printf("dropenvelope %x id=", e);
+               printf("dropenvelope %x: id=", e);
                xputs(e->e_id);
                xputs(e->e_id);
-               printf(" flags=%o\n", e->e_flags);
+               printf(", flags=%o\n", e->e_flags);
        }
        }
-#ifdef LOG
-       if (LogLevel > 10)
-               syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d",
-                                 e->e_id == NULL ? "(none)" : e->e_id,
-                                 e->e_flags, getpid());
-#endif LOG
 
        /* we must have an id to remove disk files */
 
        /* we must have an id to remove disk files */
-       if (e->e_id == NULL)
+       if (id == NULL)
                return;
 
                return;
 
+#ifdef LOG
+       if (LogLevel > 84)
+               syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d",
+                                 id, e->e_flags, getpid());
+#endif /* LOG */
+
        /*
        **  Extract state information from dregs of send list.
        */
        /*
        **  Extract state information from dregs of send list.
        */
@@ -125,15 +139,16 @@ dropenvelope(e)
        {
                auto ADDRESS *rlist = NULL;
 
        {
                auto ADDRESS *rlist = NULL;
 
-               sendtolist(CurEnv->e_receiptto, (ADDRESS *) NULL, &rlist);
-               (void) returntosender("Return receipt", rlist, FALSE);
+               (void) sendtolist(e->e_receiptto, (ADDRESS *) NULL, &rlist, e);
+               (void) returntosender("Return receipt", rlist, FALSE, e);
        }
 
        /*
        **  Arrange to send error messages if there are fatal errors.
        */
 
        }
 
        /*
        **  Arrange to send error messages if there are fatal errors.
        */
 
-       if (bitset(EF_FATALERRS|EF_TIMEOUT, e->e_flags) && ErrorMode != EM_QUIET)
+       if (bitset(EF_FATALERRS|EF_TIMEOUT, e->e_flags) &&
+           e->e_errormode != EM_QUIET)
                savemail(e);
 
        /*
                savemail(e);
 
        /*
@@ -150,13 +165,10 @@ dropenvelope(e)
        else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
        {
 #ifdef QUEUE
        else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
        {
 #ifdef QUEUE
-               FILE *lockfp, *queueup();
-               lockfp = queueup(e, FALSE, FALSE);
-               if (lockfp != NULL)
-                       (void) fclose(lockfp);
-#else QUEUE
-               syserr("dropenvelope: queueup");
-#endif QUEUE
+               queueup(e, FALSE, FALSE);
+#else /* QUEUE */
+               syserr("554 dropenvelope: queueup");
+#endif /* QUEUE */
        }
 
        /* now unlock the job */
        }
 
        /* now unlock the job */
@@ -164,10 +176,15 @@ dropenvelope(e)
        unlockqueue(e);
 
        /* make sure that this envelope is marked unused */
        unlockqueue(e);
 
        /* make sure that this envelope is marked unused */
-       e->e_id = e->e_df = NULL;
        if (e->e_dfp != NULL)
        if (e->e_dfp != NULL)
-               (void) fclose(e->e_dfp);
+               (void) xfclose(e->e_dfp, "dropenvelope", e->e_df);
        e->e_dfp = NULL;
        e->e_dfp = NULL;
+       e->e_id = e->e_df = NULL;
+
+#ifdef LOG
+       if (LogLevel > 74)
+               syslog(LOG_INFO, "%s: done", id);
+#endif /* LOG */
 }
 \f/*
 **  CLEARENVELOPE -- clear an envelope without unlocking
 }
 \f/*
 **  CLEARENVELOPE -- clear an envelope without unlocking
@@ -189,6 +206,7 @@ dropenvelope(e)
 **             Marks the envelope as unallocated.
 */
 
 **             Marks the envelope as unallocated.
 */
 
+void
 clearenvelope(e, fullclear)
        register ENVELOPE *e;
        bool fullclear;
 clearenvelope(e, fullclear)
        register ENVELOPE *e;
        bool fullclear;
@@ -201,13 +219,16 @@ clearenvelope(e, fullclear)
        {
                /* clear out any file information */
                if (e->e_xfp != NULL)
        {
                /* clear out any file information */
                if (e->e_xfp != NULL)
-                       (void) fclose(e->e_xfp);
+                       (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id);
                if (e->e_dfp != NULL)
                if (e->e_dfp != NULL)
-                       (void) fclose(e->e_dfp);
+                       (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df);
+               e->e_xfp = e->e_dfp = NULL;
        }
 
        /* now clear out the data */
        STRUCTCOPY(BlankEnvelope, *e);
        }
 
        /* now clear out the data */
        STRUCTCOPY(BlankEnvelope, *e);
+       if (Verbose)
+               e->e_sendmode = SM_DELIVER;
        bh = BlankEnvelope.e_header;
        nhp = &e->e_header;
        while (bh != NULL)
        bh = BlankEnvelope.e_header;
        nhp = &e->e_header;
        while (bh != NULL)
@@ -235,16 +256,18 @@ clearenvelope(e, fullclear)
 **             forms is set.
 */
 
 **             forms is set.
 */
 
-initsys()
+void
+initsys(e)
+       register ENVELOPE *e;
 {
        static char cbuf[5];                    /* holds hop count */
        static char pbuf[10];                   /* holds pid */
 #ifdef TTYNAME
 {
        static char cbuf[5];                    /* holds hop count */
        static char pbuf[10];                   /* holds pid */
 #ifdef TTYNAME
-       static char ybuf[10];                   /* holds tty id */
+       static char ybuf[60];                   /* holds tty id */
        register char *p;
        register char *p;
-#endif TTYNAME
+#endif /* TTYNAME */
        extern char *ttyname();
        extern char *ttyname();
-       extern char *macvalue();
+       extern void settime();
        extern char Version[];
 
        /*
        extern char Version[];
 
        /*
@@ -252,8 +275,8 @@ initsys()
        **      I.e., an id, a transcript, and a creation time.
        */
 
        **      I.e., an id, a transcript, and a creation time.
        */
 
-       openxscript(CurEnv);
-       CurEnv->e_ctime = curtime();
+       openxscript(e);
+       e->e_ctime = curtime();
 
        /*
        **  Set OutChannel to something useful if stdout isn't it.
 
        /*
        **  Set OutChannel to something useful if stdout isn't it.
@@ -262,8 +285,9 @@ initsys()
        **      tucked away in the transcript).
        */
 
        **      tucked away in the transcript).
        */
 
-       if (OpMode == MD_DAEMON && QueueRun)
-               OutChannel = CurEnv->e_xfp;
+       if (OpMode == MD_DAEMON && !bitset(EF_QUEUERUN, e->e_flags) &&
+           e->e_xfp != NULL)
+               OutChannel = e->e_xfp;
 
        /*
        **  Set up some basic system macros.
 
        /*
        **  Set up some basic system macros.
@@ -271,29 +295,29 @@ initsys()
 
        /* process id */
        (void) sprintf(pbuf, "%d", getpid());
 
        /* process id */
        (void) sprintf(pbuf, "%d", getpid());
-       define('p', pbuf, CurEnv);
+       define('p', pbuf, e);
 
        /* hop count */
 
        /* hop count */
-       (void) sprintf(cbuf, "%d", CurEnv->e_hopcount);
-       define('c', cbuf, CurEnv);
+       (void) sprintf(cbuf, "%d", e->e_hopcount);
+       define('c', cbuf, e);
 
        /* time as integer, unix time, arpa time */
 
        /* time as integer, unix time, arpa time */
-       settime();
+       settime(e);
 
 #ifdef TTYNAME
        /* tty name */
 
 #ifdef TTYNAME
        /* tty name */
-       if (macvalue('y', CurEnv) == NULL)
+       if (macvalue('y', e) == NULL)
        {
                p = ttyname(2);
                if (p != NULL)
                {
        {
                p = ttyname(2);
                if (p != NULL)
                {
-                       if (rindex(p, '/') != NULL)
-                               p = rindex(p, '/') + 1;
+                       if (strrchr(p, '/') != NULL)
+                               p = strrchr(p, '/') + 1;
                        (void) strcpy(ybuf, p);
                        (void) strcpy(ybuf, p);
-                       define('y', ybuf, CurEnv);
+                       define('y', ybuf, e);
                }
        }
                }
        }
-#endif TTYNAME
+#endif /* TTYNAME */
 }
 \f/*
 **  SETTIME -- set the current time.
 }
 \f/*
 **  SETTIME -- set the current time.
@@ -308,7 +332,9 @@ initsys()
 **             Sets the various time macros -- $a, $b, $d, $t.
 */
 
 **             Sets the various time macros -- $a, $b, $d, $t.
 */
 
-settime()
+void
+settime(e)
+       register ENVELOPE *e;
 {
        register char *p;
        auto time_t now;
 {
        register char *p;
        auto time_t now;
@@ -317,21 +343,21 @@ settime()
        register struct tm *tm;
        extern char *arpadate();
        extern struct tm *gmtime();
        register struct tm *tm;
        extern char *arpadate();
        extern struct tm *gmtime();
-       extern char *macvalue();
 
        now = curtime();
        tm = gmtime(&now);
 
        now = curtime();
        tm = gmtime(&now);
-       (void) sprintf(tbuf, "%02d%02d%02d%02d%02d", tm->tm_year, tm->tm_mon+1,
-                       tm->tm_mday, tm->tm_hour, tm->tm_min);
-       define('t', tbuf, CurEnv);
+       (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
+                       tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
+       define('t', tbuf, e);
        (void) strcpy(dbuf, ctime(&now));
        (void) strcpy(dbuf, ctime(&now));
-       *index(dbuf, '\n') = '\0';
-       if (macvalue('d', CurEnv) == NULL)
-               define('d', dbuf, CurEnv);
+       p = strchr(dbuf, '\n');
+       if (p != NULL)
+               *p = '\0';
+       define('d', dbuf, e);
        p = newstr(arpadate(dbuf));
        p = newstr(arpadate(dbuf));
-       if (macvalue('a', CurEnv) == NULL)
-               define('a', p, CurEnv);
-       define('b', p, CurEnv);
+       if (macvalue('a', e) == NULL)
+               define('a', p, e);
+       define('b', p, e);
 }
 \f/*
 **  OPENXSCRIPT -- Open transcript file
 }
 \f/*
 **  OPENXSCRIPT -- Open transcript file
@@ -349,20 +375,21 @@ settime()
 **             Creates the transcript file.
 */
 
 **             Creates the transcript file.
 */
 
+#ifndef O_APPEND
+#define O_APPEND       0
+#endif
+
+void
 openxscript(e)
        register ENVELOPE *e;
 {
        register char *p;
        int fd;
 
 openxscript(e)
        register ENVELOPE *e;
 {
        register char *p;
        int fd;
 
-# ifdef LOG
-       if (LogLevel > 19)
-               syslog(LOG_DEBUG, "%s: openx%s", e->e_id, e->e_xfp == NULL ? "" : " (no)");
-# endif LOG
        if (e->e_xfp != NULL)
                return;
        p = queuename(e, 'x');
        if (e->e_xfp != NULL)
                return;
        p = queuename(e, 'x');
-       fd = open(p, O_WRONLY|O_CREAT, 0644);
+       fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644);
        if (fd < 0)
                syserr("Can't create %s", p);
        else
        if (fd < 0)
                syserr("Can't create %s", p);
        else
@@ -381,12 +408,13 @@ openxscript(e)
 **             none.
 */
 
 **             none.
 */
 
+void
 closexscript(e)
        register ENVELOPE *e;
 {
        if (e->e_xfp == NULL)
                return;
 closexscript(e)
        register ENVELOPE *e;
 {
        if (e->e_xfp == NULL)
                return;
-       (void) fclose(e->e_xfp);
+       (void) xfclose(e->e_xfp, "closexscript", e->e_id);
        e->e_xfp = NULL;
 }
 \f/*
        e->e_xfp = NULL;
 }
 \f/*
@@ -413,6 +441,11 @@ closexscript(e)
 **     Parameters:
 **             from -- the person we would like to believe this message
 **                     is from, as specified on the command line.
 **     Parameters:
 **             from -- the person we would like to believe this message
 **                     is from, as specified on the command line.
+**             e -- the envelope in which we would like the sender set.
+**             delimptr -- if non-NULL, set to the location of the
+**                     trailing delimiter.
+**             internal -- set if this address is coming from an internal
+**                     source such as an owner alias.
 **
 **     Returns:
 **             none.
 **
 **     Returns:
 **             none.
@@ -421,18 +454,20 @@ closexscript(e)
 **             sets sendmail's notion of who the from person is.
 */
 
 **             sets sendmail's notion of who the from person is.
 */
 
-setsender(from)
+void
+setsender(from, e, delimptr, internal)
        char *from;
        char *from;
+       register ENVELOPE *e;
+       char **delimptr;
+       bool internal;
 {
        register char **pvp;
        char *realname = NULL;
        register struct passwd *pw;
 {
        register char **pvp;
        char *realname = NULL;
        register struct passwd *pw;
+       char delimchar;
        char buf[MAXNAME];
        char pvpbuf[PSBUFSIZE];
        extern struct passwd *getpwnam();
        char buf[MAXNAME];
        char pvpbuf[PSBUFSIZE];
        extern struct passwd *getpwnam();
-       extern char *macvalue();
-       extern char **prescan();
-       extern bool safefile();
        extern char *FullName;
 
        if (tTd(45, 1))
        extern char *FullName;
 
        if (tTd(45, 1))
@@ -443,102 +478,123 @@ setsender(from)
        **      Username can return errno != 0 on non-errors.
        */
 
        **      Username can return errno != 0 on non-errors.
        */
 
-       if (QueueRun || OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
+       if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP)
                realname = from;
        if (realname == NULL || realname[0] == '\0')
                realname = from;
        if (realname == NULL || realname[0] == '\0')
-       {
-               extern char *username();
-
                realname = username();
                realname = username();
-       }
 
 
-       /*
-       **  Determine if this real person is allowed to alias themselves.
-       */
+       if (ConfigLevel < 2)
+               SuprErrs = TRUE;
 
 
-       if (from != NULL)
-       {
-               extern bool trusteduser();
-
-               if (!trusteduser(realname) && getuid() != geteuid() &&
-                   index(from, '!') == NULL && getuid() != 0)
-               {
-                       /* network sends -r regardless (why why why?) */
-                       /* syserr("%s, you cannot use the -f flag", realname); */
-                       from = NULL;
-               }
-       }
-
-       SuprErrs = TRUE;
-       if (from == NULL || parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL)
+       delimchar = internal ? '\0' : ' ';
+       if (from == NULL ||
+           parseaddr(from, &e->e_from, 1, delimchar, delimptr, e) == NULL)
        {
                /* log garbage addresses for traceback */
        {
                /* log garbage addresses for traceback */
-               if (from != NULL)
-               {
 # ifdef LOG
 # ifdef LOG
-                       if (LogLevel >= 1)
-                           if (realname == from && RealHostName != NULL)
-                               syslog(LOG_NOTICE,
-                                   "from=%s unparseable, received from %s",
-                                   from, RealHostName);
-                           else
-                               syslog(LOG_NOTICE,
-                                   "Unparseable username %s wants from=%s",
-                                   realname, from);
-# endif LOG
+               if (from != NULL && LogLevel > 2)
+               {
+                       char *p;
+                       char ebuf[MAXNAME * 2 + 2];
+
+                       p = macvalue('_', e);
+                       if (p == NULL)
+                       {
+                               char *host = RealHostName;
+                               if (host == NULL)
+                                       host = MyHostName;
+                               (void) sprintf(ebuf, "%s@%s", realname, host);
+                               p = ebuf;
+                       }
+                       syslog(LOG_NOTICE,
+                               "from=%s unparseable, received from %s",
+                               from, p);
                }
                }
-               from = newstr(realname);
-               if (parseaddr(from, &CurEnv->e_from, 1, '\0') == NULL &&
-                   parseaddr("postmaster", &CurEnv->e_from, 1, '\0') == NULL)
+# endif /* LOG */
+               if (from != NULL)
+                       SuprErrs = TRUE;
+               if (from == realname ||
+                   parseaddr(from = newstr(realname), &e->e_from, 1, ' ', NULL, e) == NULL)
                {
                {
-                       syserr("setsender: can't even parse postmaster!");
+                       SuprErrs = TRUE;
+                       if (parseaddr("postmaster", &e->e_from, 1, ' ', NULL, e) == NULL)
+                               syserr("553 setsender: can't even parse postmaster!");
                }
        }
        else
                FromFlag = TRUE;
                }
        }
        else
                FromFlag = TRUE;
-       CurEnv->e_from.q_flags |= QDONTSEND;
-       loweraddr(&CurEnv->e_from);
+       e->e_from.q_flags |= QDONTSEND;
+       if (tTd(45, 5))
+       {
+               printf("setsender: QDONTSEND ");
+               printaddr(&e->e_from, FALSE);
+       }
        SuprErrs = FALSE;
 
        SuprErrs = FALSE;
 
-       if (CurEnv->e_from.q_mailer == LocalMailer &&
-           (pw = getpwnam(CurEnv->e_from.q_user)) != NULL)
+       pvp = NULL;
+       if (e->e_from.q_mailer == LocalMailer)
        {
        {
-               /*
-               **  Process passwd file entry.
-               */
-
-
-               /* extract home directory */
-               CurEnv->e_from.q_home = newstr(pw->pw_dir);
-               define('z', CurEnv->e_from.q_home, CurEnv);
-
-               /* extract user and group id */
-               CurEnv->e_from.q_uid = pw->pw_uid;
-               CurEnv->e_from.q_gid = pw->pw_gid;
+# ifdef USERDB
+               register char *p;
+               extern char *udbsender();
+# endif
 
 
-               /* if the user has given fullname already, don't redefine */
-               if (FullName == NULL)
-                       FullName = macvalue('x', CurEnv);
-               if (FullName != NULL && FullName[0] == '\0')
-                       FullName = NULL;
+               if (!internal)
+               {
+                       /* if the user has given fullname already, don't redefine */
+                       if (FullName == NULL)
+                               FullName = macvalue('x', e);
+                       if (FullName != NULL && FullName[0] == '\0')
+                               FullName = NULL;
+
+# ifdef USERDB
+                       p = udbsender(from);
+
+                       if (p != NULL)
+                       {
+                               /*
+                               **  We have an alternate address for the sender
+                               */
+
+                               pvp = prescan(p, '\0', pvpbuf, NULL);
+                       }
+# endif /* USERDB */
+               }
 
 
-               /* extract full name from passwd file */
-               if (FullName == NULL && pw->pw_gecos != NULL &&
-                   strcmp(pw->pw_name, CurEnv->e_from.q_user) == 0)
+               if ((pw = getpwnam(e->e_from.q_user)) != NULL)
                {
                {
-                       buildfname(pw->pw_gecos, CurEnv->e_from.q_user, buf);
-                       if (buf[0] != '\0')
-                               FullName = newstr(buf);
+                       /*
+                       **  Process passwd file entry.
+                       */
+
+
+                       /* extract home directory */
+                       e->e_from.q_home = newstr(pw->pw_dir);
+                       define('z', e->e_from.q_home, e);
+
+                       /* extract user and group id */
+                       e->e_from.q_uid = pw->pw_uid;
+                       e->e_from.q_gid = pw->pw_gid;
+
+                       /* extract full name from passwd file */
+                       if (FullName == NULL && pw->pw_gecos != NULL &&
+                           strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
+                           !internal)
+                       {
+                               buildfname(pw->pw_gecos, e->e_from.q_user, buf);
+                               if (buf[0] != '\0')
+                                       FullName = newstr(buf);
+                       }
                }
                }
-               if (FullName != NULL)
-                       define('x', FullName, CurEnv);
+               if (FullName != NULL && !internal)
+                       define('x', FullName, e);
        }
        }
-       else
+       else if (!internal)
        {
        {
-               if (CurEnv->e_from.q_home == NULL)
-                       CurEnv->e_from.q_home = getenv("HOME");
-               CurEnv->e_from.q_uid = getuid();
-               CurEnv->e_from.q_gid = getgid();
+               if (e->e_from.q_home == NULL)
+                       e->e_from.q_home = getenv("HOME");
+               e->e_from.q_uid = getuid();
+               e->e_from.q_gid = getgid();
        }
 
        /*
        }
 
        /*
@@ -546,57 +602,33 @@ setsender(from)
        **      links in the net.
        */
 
        **      links in the net.
        */
 
-       pvp = prescan(from, '\0', pvpbuf);
+       if (pvp == NULL)
+               pvp = prescan(from, '\0', pvpbuf, NULL);
        if (pvp == NULL)
        {
        if (pvp == NULL)
        {
+               /* don't need to give error -- prescan did that already */
 # ifdef LOG
 # ifdef LOG
-               if (LogLevel >= 1)
+               if (LogLevel > 2)
                        syslog(LOG_NOTICE, "cannot prescan from (%s)", from);
 # endif
                        syslog(LOG_NOTICE, "cannot prescan from (%s)", from);
 # endif
-               usrerr("cannot prescan from (%s)", from);
                finis();
        }
                finis();
        }
-       rewrite(pvp, 3);
-       rewrite(pvp, 1);
-       rewrite(pvp, 4);
-       cataddr(pvp, buf, sizeof buf);
-       define('f', newstr(buf), CurEnv);
+       (void) rewrite(pvp, 3, e);
+       (void) rewrite(pvp, 1, e);
+       (void) rewrite(pvp, 4, e);
+       cataddr(pvp, NULL, buf, sizeof buf, '\0');
+       e->e_sender = newstr(buf);
+       define('f', e->e_sender, e);
 
        /* save the domain spec if this mailer wants it */
 
        /* save the domain spec if this mailer wants it */
-       if (CurEnv->e_from.q_mailer != NULL &&
-           bitnset(M_CANONICAL, CurEnv->e_from.q_mailer->m_flags))
+       if (!internal && e->e_from.q_mailer != NULL &&
+           bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
        {
                extern char **copyplist();
 
                while (*pvp != NULL && strcmp(*pvp, "@") != 0)
                        pvp++;
                if (*pvp != NULL)
        {
                extern char **copyplist();
 
                while (*pvp != NULL && strcmp(*pvp, "@") != 0)
                        pvp++;
                if (*pvp != NULL)
-                       CurEnv->e_fromdomain = copyplist(pvp, TRUE);
+                       e->e_fromdomain = copyplist(pvp, TRUE);
        }
 }
        }
 }
-\f/*
-**  TRUSTEDUSER -- tell us if this user is to be trusted.
-**
-**     Parameters:
-**             user -- the user to be checked.
-**
-**     Returns:
-**             TRUE if the user is in an approved list.
-**             FALSE otherwise.
-**
-**     Side Effects:
-**             none.
-*/
-
-bool
-trusteduser(user)
-       char *user;
-{
-       register char **ulist;
-       extern char *TrustedUsers[];
-
-       for (ulist = TrustedUsers; *ulist != NULL; ulist++)
-               if (strcmp(*ulist, user) == 0)
-                       return (TRUE);
-       return (FALSE);
-}