BSD 4_4_Lite1 release
[unix-history] / usr / src / usr.sbin / sendmail / src / envelope.c
index b404f2e..3a2314c 100644 (file)
@@ -3,15 +3,40 @@
  * Copyright (c) 1988, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
  * Copyright (c) 1988, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
- * %sccs.include.redist.c%
+ * 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 8.15 (Berkeley) %G%";
+static char sccsid[] = "@(#)envelope.c 8.34 (Berkeley) 4/14/94";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
-#include <sys/time.h>
 #include <pwd.h>
 
 /*
 #include <pwd.h>
 
 /*
@@ -84,7 +109,7 @@ dropenvelope(e)
        {
                printf("dropenvelope %x: id=", e);
                xputs(e->e_id);
        {
                printf("dropenvelope %x: id=", e);
                xputs(e->e_id);
-               printf(", flags=%o\n", e->e_flags);
+               printf(", flags=0x%x\n", e->e_flags);
                if (tTd(50, 10))
                {
                        printf("sendq=");
                if (tTd(50, 10))
                {
                        printf("sendq=");
@@ -97,10 +122,13 @@ dropenvelope(e)
                return;
 
 #ifdef LOG
                return;
 
 #ifdef LOG
+       if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
+               logsender(e, NULL);
        if (LogLevel > 84)
        if (LogLevel > 84)
-               syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d",
+               syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d",
                                  id, e->e_flags, getpid());
 #endif /* LOG */
                                  id, e->e_flags, getpid());
 #endif /* LOG */
+       e->e_flags &= ~EF_LOGSENDER;
 
        /* post statistics */
        poststats(StatFile);
 
        /* post statistics */
        poststats(StatFile);
@@ -182,12 +210,14 @@ dropenvelope(e)
        **  Send back return receipts as requested.
        */
 
        **  Send back return receipts as requested.
        */
 
-       if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags))
+       if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)
+           && !bitset(PRIV_NORECEIPTS, PrivacyFlags))
        {
                auto ADDRESS *rlist = NULL;
 
                (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e);
                (void) returntosender("Return receipt", rlist, FALSE, e);
        {
                auto ADDRESS *rlist = NULL;
 
                (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e);
                (void) returntosender("Return receipt", rlist, FALSE, e);
+               e->e_flags &= ~EF_SENDRECEIPT;
        }
 
        /*
        }
 
        /*
@@ -246,9 +276,6 @@ dropenvelope(e)
                (void) xfclose(e->e_dfp, "dropenvelope", e->e_df);
        e->e_dfp = NULL;
        e->e_id = e->e_df = NULL;
                (void) xfclose(e->e_dfp, "dropenvelope", e->e_df);
        e->e_dfp = NULL;
        e->e_id = e->e_df = NULL;
-#ifdef XDEBUG
-       checkfd012("dropenvelope");
-#endif
 }
 \f/*
 **  CLEARENVELOPE -- clear an envelope without unlocking
 }
 \f/*
 **  CLEARENVELOPE -- clear an envelope without unlocking
@@ -557,7 +584,8 @@ setsender(from, e, delimptr, internal)
        **      Username can return errno != 0 on non-errors.
        */
 
        **      Username can return errno != 0 on non-errors.
        */
 
-       if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP)
+       if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
+           OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
                realname = from;
        if (realname == NULL || realname[0] == '\0')
                realname = username();
                realname = from;
        if (realname == NULL || realname[0] == '\0')
                realname = username();
@@ -566,9 +594,14 @@ setsender(from, e, delimptr, internal)
                SuprErrs = TRUE;
 
        delimchar = internal ? '\0' : ' ';
                SuprErrs = TRUE;
 
        delimchar = internal ? '\0' : ' ';
+       e->e_from.q_flags = QBADADDR;
        if (from == NULL ||
            parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
        if (from == NULL ||
            parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
-                     delimchar, delimptr, e) == NULL)
+                     delimchar, delimptr, e) == NULL ||
+           bitset(QBADADDR, e->e_from.q_flags) ||
+           e->e_from.q_mailer == ProgMailer ||
+           e->e_from.q_mailer == FileMailer ||
+           e->e_from.q_mailer == InclMailer)
        {
                /* log garbage addresses for traceback */
 # ifdef LOG
        {
                /* log garbage addresses for traceback */
 # ifdef LOG
@@ -587,19 +620,31 @@ setsender(from, e, delimptr, internal)
                                p = ebuf;
                        }
                        syslog(LOG_NOTICE,
                                p = ebuf;
                        }
                        syslog(LOG_NOTICE,
-                               "from=%s unparseable, received from %s",
-                               from, p);
+                               "setsender: %s: invalid or unparseable, received from %s",
+                               shortenstring(from, 83), p);
                }
 # endif /* LOG */
                if (from != NULL)
                }
 # endif /* LOG */
                if (from != NULL)
+               {
+                       if (!bitset(QBADADDR, e->e_from.q_flags))
+                       {
+                               /* it was a bogus mailer in the from addr */
+                               usrerr("553 Invalid sender address");
+                       }
                        SuprErrs = TRUE;
                        SuprErrs = TRUE;
+               }
                if (from == realname ||
                    parseaddr(from = newstr(realname), &e->e_from,
                              RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
                {
                if (from == realname ||
                    parseaddr(from = newstr(realname), &e->e_from,
                              RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
                {
+                       char nbuf[100];
+
                        SuprErrs = TRUE;
                        SuprErrs = TRUE;
-                       if (parseaddr("postmaster", &e->e_from, RF_COPYALL,
-                                     ' ', NULL, e) == NULL)
+                       expand("\201n", nbuf, &nbuf[sizeof nbuf], e);
+                       if (parseaddr(from = newstr(nbuf), &e->e_from,
+                                     RF_COPYALL, ' ', NULL, e) == NULL &&
+                           parseaddr(from = "postmaster", &e->e_from,
+                                     RF_COPYALL, ' ', NULL, e) == NULL)
                                syserr("553 setsender: can't even parse postmaster!");
                }
        }
                                syserr("553 setsender: can't even parse postmaster!");
                }
        }
@@ -638,7 +683,7 @@ setsender(from, e, delimptr, internal)
                                **  We have an alternate address for the sender
                                */
 
                                **  We have an alternate address for the sender
                                */
 
-                               pvp = prescan(p, '\0', pvpbuf, NULL);
+                               pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL);
                        }
 # endif /* USERDB */
                }
                        }
 # endif /* USERDB */
                }
@@ -649,14 +694,17 @@ setsender(from, e, delimptr, internal)
                        **  Process passwd file entry.
                        */
 
                        **  Process passwd file entry.
                        */
 
-
                        /* extract home directory */
                        /* extract home directory */
-                       e->e_from.q_home = newstr(pw->pw_dir);
+                       if (strcmp(pw->pw_dir, "/") == 0)
+                               e->e_from.q_home = newstr("");
+                       else
+                               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;
                        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;
+                       e->e_from.q_flags |= QGOODUID;
 
                        /* extract full name from passwd file */
                        if (FullName == NULL && pw->pw_gecos != NULL &&
 
                        /* extract full name from passwd file */
                        if (FullName == NULL && pw->pw_gecos != NULL &&
@@ -671,12 +719,18 @@ setsender(from, e, delimptr, internal)
                if (FullName != NULL && !internal)
                        define('x', FullName, e);
        }
                if (FullName != NULL && !internal)
                        define('x', FullName, e);
        }
-       else if (!internal)
+       else if (!internal && OpMode != MD_DAEMON)
        {
                if (e->e_from.q_home == NULL)
        {
                if (e->e_from.q_home == NULL)
+               {
                        e->e_from.q_home = getenv("HOME");
                        e->e_from.q_home = getenv("HOME");
+                       if (e->e_from.q_home != NULL &&
+                           strcmp(e->e_from.q_home, "/") == 0)
+                               e->e_from.q_home++;
+               }
                e->e_from.q_uid = RealUid;
                e->e_from.q_gid = RealGid;
                e->e_from.q_uid = RealUid;
                e->e_from.q_gid = RealGid;
+               e->e_from.q_flags |= QGOODUID;
        }
 
        /*
        }
 
        /*
@@ -685,7 +739,7 @@ setsender(from, e, delimptr, internal)
        */
 
        if (pvp == NULL)
        */
 
        if (pvp == NULL)
-               pvp = prescan(from, '\0', pvpbuf, NULL);
+               pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL);
        if (pvp == NULL)
        {
                /* don't need to give error -- prescan did that already */
        if (pvp == NULL)
        {
                /* don't need to give error -- prescan did that already */
@@ -695,9 +749,9 @@ setsender(from, e, delimptr, internal)
 # endif
                finis();
        }
 # endif
                finis();
        }
-       (void) rewrite(pvp, 3, e);
-       (void) rewrite(pvp, 1, e);
-       (void) rewrite(pvp, 4, e);
+       (void) rewrite(pvp, 3, 0, e);
+       (void) rewrite(pvp, 1, 0, e);
+       (void) rewrite(pvp, 4, 0, e);
        bp = buf + 1;
        cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
        if (*bp == '@')
        bp = buf + 1;
        cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
        if (*bp == '@')
@@ -710,7 +764,7 @@ setsender(from, e, delimptr, internal)
        define('f', e->e_sender, e);
 
        /* save the domain spec if this mailer wants it */
        define('f', e->e_sender, e);
 
        /* save the domain spec if this mailer wants it */
-       if (!internal && e->e_from.q_mailer != NULL &&
+       if (e->e_from.q_mailer != NULL &&
            bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
        {
                extern char **copyplist();
            bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
        {
                extern char **copyplist();