many fixes. primarily fix for seteuid problem in 8.2; also,
authorEric Allman <eric@ucbvax.Berkeley.EDU>
Wed, 14 Jul 1993 03:58:50 +0000 (19:58 -0800)
committerEric Allman <eric@ucbvax.Berkeley.EDU>
Wed, 14 Jul 1993 03:58:50 +0000 (19:58 -0800)
Solaris compatibility fixes; timed out messages problems; messages
silently discarded if checkcompat returned EX_TEMPFAIL

SCCS-vsn: usr.sbin/sendmail/src/READ_ME 8.3
SCCS-vsn: usr.sbin/sendmail/src/usersmtp.c 8.4
SCCS-vsn: usr.sbin/sendmail/src/recipient.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/main.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/envelope.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/conf.h 8.3
SCCS-vsn: usr.sbin/sendmail/src/version.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 8.3
SCCS-vsn: usr.sbin/sendmail/src/savemail.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/daemon.c 8.2
SCCS-vsn: usr.sbin/sendmail/src/srvrsmtp.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/clock.c 8.2
SCCS-vsn: usr.sbin/sendmail/src/util.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/readcf.c 8.2
SCCS-vsn: usr.sbin/sendmail/src/deliver.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/queue.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/conf.c 8.3
SCCS-vsn: usr.sbin/sendmail/src/alias.c 8.3

18 files changed:
usr/src/usr.sbin/sendmail/src/READ_ME
usr/src/usr.sbin/sendmail/src/alias.c
usr/src/usr.sbin/sendmail/src/clock.c
usr/src/usr.sbin/sendmail/src/conf.c
usr/src/usr.sbin/sendmail/src/conf.h
usr/src/usr.sbin/sendmail/src/daemon.c
usr/src/usr.sbin/sendmail/src/deliver.c
usr/src/usr.sbin/sendmail/src/envelope.c
usr/src/usr.sbin/sendmail/src/main.c
usr/src/usr.sbin/sendmail/src/queue.c
usr/src/usr.sbin/sendmail/src/readcf.c
usr/src/usr.sbin/sendmail/src/recipient.c
usr/src/usr.sbin/sendmail/src/savemail.c
usr/src/usr.sbin/sendmail/src/sendmail.h
usr/src/usr.sbin/sendmail/src/srvrsmtp.c
usr/src/usr.sbin/sendmail/src/usersmtp.c
usr/src/usr.sbin/sendmail/src/util.c
usr/src/usr.sbin/sendmail/src/version.c

index f80d571..4f7d1d5 100644 (file)
@@ -4,7 +4,7 @@
 #
 # %sccs.include.redist.sh%
 #
 #
 # %sccs.include.redist.sh%
 #
-#      @(#)READ_ME     8.2 (Berkeley) %G%
+#      @(#)READ_ME     8.3 (Berkeley) %G%
 #
 
 This directory contains the source files for sendmail.
 #
 
 This directory contains the source files for sendmail.
@@ -66,6 +66,16 @@ HASINITGROUPS        Define this if you have the initgroups(3) routine.
 HASSETVBUF     Define this if you have the setvbuf(3) library call.
                If you don't, setlinebuf will be used instead.  This
                defaults on if your compiler defines __STDC__.
 HASSETVBUF     Define this if you have the setvbuf(3) library call.
                If you don't, setlinebuf will be used instead.  This
                defaults on if your compiler defines __STDC__.
+HASSETEUID     Define this if you have seteuid(2) ***AND*** root can use
+               it to change to an arbitrary user.  This second condition
+               is not satisfied on AIX 3.x.  You may find that
+               your system has setreuid(2) or setresuid(2), in which
+               case you will also have to #define seteuid(uid) to be
+               the appropriate call.  The important thing is that you
+               have a call that will set the effective uid and NOT
+               set the real or saved uid.  Setting this improves the
+               security somewhat, since sendmail doesn't have to read
+               .forward and :include: files as root.
 LA_TYPE                The type of load average your kernel supports.  These
                can be LA_SUBR (4) if you have the getloadavg(3) routine,
                LA_FLOAT (3) if you read kmem and interpret the value
 LA_TYPE                The type of load average your kernel supports.  These
                can be LA_SUBR (4) if you have the getloadavg(3) routine,
                LA_FLOAT (3) if you read kmem and interpret the value
@@ -204,4 +214,4 @@ version.c   The version number and information about this
 
 Eric Allman
 
 
 Eric Allman
 
-(Version 8.2, last update %G% 06:52:16)
+(Version 8.3, last update %G% 12:58:13)
index b53f8d5..98952c6 100644 (file)
@@ -11,7 +11,7 @@
 # include <pwd.h>
 
 #ifndef lint
 # include <pwd.h>
 
 #ifndef lint
-static char sccsid[] = "@(#)alias.c    8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)alias.c    8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 
 #endif /* not lint */
 
 
@@ -670,7 +670,7 @@ forward(user, sendq, e)
 {
        char *pp;
        char *ep;
 {
        char *pp;
        char *ep;
-#ifdef _POSIX_SAVED_IDS
+#ifdef HASSETEUID
        register ADDRESS *ca;
        uid_t saveduid, uid;
 #endif
        register ADDRESS *ca;
        uid_t saveduid, uid;
 #endif
@@ -693,7 +693,7 @@ forward(user, sendq, e)
        if (ForwardPath == NULL)
                ForwardPath = newstr("\201z/.forward");
 
        if (ForwardPath == NULL)
                ForwardPath = newstr("\201z/.forward");
 
-#ifdef _POSIX_SAVED_IDS
+#ifdef HASSETEUID
        ca = getctladdr(user);
        if (ca != NULL)
                uid = ca->q_uid;
        ca = getctladdr(user);
        if (ca != NULL)
                uid = ca->q_uid;
@@ -715,19 +715,30 @@ forward(user, sendq, e)
                if (tTd(27, 3))
                        printf("forward: trying %s\n", buf);
 
                if (tTd(27, 3))
                        printf("forward: trying %s\n", buf);
 
-#ifdef _POSIX_SAVED_IDS
+               if (tTd(27, 9))
+                       printf("forward: old uid = %d/%d\n", getuid(), geteuid());
+
+#ifdef HASSETEUID
                saveduid = geteuid();
                if (saveduid == 0 && uid != 0)
                        (void) seteuid(uid);
 #endif                   
 
                saveduid = geteuid();
                if (saveduid == 0 && uid != 0)
                        (void) seteuid(uid);
 #endif                   
 
+               if (tTd(27, 9))
+                       printf("forward: new uid = %d/%d\n", getuid(), geteuid());
+
                err = include(buf, TRUE, user, sendq, e);
 
                err = include(buf, TRUE, user, sendq, e);
 
-#ifdef _POSIX_SAVED_IDS
+#ifdef HASSETEUID
                if (saveduid == 0 && uid != 0)
                if (saveduid == 0 && uid != 0)
-                       (void) seteuid(saveduid);
+                       if (seteuid(saveduid) < 0)
+                               syserr("seteuid(%d) failure (real=%d, eff=%d)",
+                                       saveduid, getuid(), geteuid());
 #endif
 
 #endif
 
+               if (tTd(27, 9))
+                       printf("forward: reset uid = %d/%d\n", getuid(), geteuid());
+
                if (err == 0)
                        break;
                if (transienterror(err))
                if (err == 0)
                        break;
                if (transienterror(err))
index d111e9a..d7d2f16 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)clock.c    8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)clock.c    8.2 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
@@ -140,6 +140,9 @@ tick()
        register time_t now;
        register EVENT *ev;
        int mypid = getpid();
        register time_t now;
        register EVENT *ev;
        int mypid = getpid();
+#ifdef SIG_UNBLOCK
+       sigset_t ss;
+#endif
 
        (void) signal(SIGALRM, SIG_IGN);
        (void) alarm(0);
 
        (void) signal(SIGALRM, SIG_IGN);
        (void) alarm(0);
@@ -164,10 +167,17 @@ tick()
 
                /* we must be careful in here because ev_func may not return */
                (void) signal(SIGALRM, tick);
 
                /* we must be careful in here because ev_func may not return */
                (void) signal(SIGALRM, tick);
+#ifdef SIG_UNBLOCK
+               /* unblock SIGALRM signal */
+               sigemptyset(&ss);
+               sigaddset(&ss, SIGALRM);
+               sigprocmask(SIG_UNBLOCK, &ss, NULL);
+#else
 #ifdef SIGVTALRM
                /* reset 4.2bsd signal mask to allow future alarms */
                (void) sigsetmask(sigblock(0) & ~sigmask(SIGALRM));
 #endif /* SIGVTALRM */
 #ifdef SIGVTALRM
                /* reset 4.2bsd signal mask to allow future alarms */
                (void) sigsetmask(sigblock(0) & ~sigmask(SIGALRM));
 #endif /* SIGVTALRM */
+#endif /* SIG_UNBLOCK */
 
                f = ev->ev_func;
                arg = ev->ev_arg;
 
                f = ev->ev_func;
                arg = ev->ev_arg;
index 0821b4e..d0c3cec 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)conf.c     8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)conf.c     8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 # include <sys/ioctl.h>
 #endif /* not lint */
 
 # include <sys/ioctl.h>
@@ -162,7 +162,7 @@ setdefaults(e)
        WkClassFact = 1800L;                    /* option z */
        WkTimeFact = 90000L;                    /* option Z */
        QueueFactor = WkRecipFact * 20;         /* option q */
        WkClassFact = 1800L;                    /* option z */
        WkTimeFact = 90000L;                    /* option Z */
        QueueFactor = WkRecipFact * 20;         /* option q */
-       FileMode = (getuid() != geteuid()) ? 0644 : 0600;
+       FileMode = (RealUid != geteuid()) ? 0644 : 0600;
                                                /* option F */
        DefUid = 1;                             /* option u */
        DefGid = 1;                             /* option g */
                                                /* option F */
        DefUid = 1;                             /* option u */
        DefGid = 1;                             /* option g */
@@ -325,30 +325,6 @@ setupmaps()
 
 #undef MAPDEF
 \f/*
 
 #undef MAPDEF
 \f/*
-**  GETRUID -- get real user id (V7)
-*/
-
-getruid()
-{
-       if (OpMode == MD_DAEMON)
-               return (RealUid);
-       else
-               return (getuid());
-}
-
-
-/*
-**  GETRGID -- get real group id (V7).
-*/
-
-getrgid()
-{
-       if (OpMode == MD_DAEMON)
-               return (RealGid);
-       else
-               return (getgid());
-}
-\f/*
 **  USERNAME -- return the user id of the logged in user.
 **
 **     Parameters:
 **  USERNAME -- return the user id of the logged in user.
 **
 **     Parameters:
@@ -377,13 +353,13 @@ username()
                myname = getlogin();
                if (myname == NULL || myname[0] == '\0')
                {
                myname = getlogin();
                if (myname == NULL || myname[0] == '\0')
                {
-                       pw = getpwuid(getruid());
+                       pw = getpwuid(RealUid);
                        if (pw != NULL)
                                myname = newstr(pw->pw_name);
                }
                else
                {
                        if (pw != NULL)
                                myname = newstr(pw->pw_name);
                }
                else
                {
-                       uid_t uid = getuid();
+                       uid_t uid = RealUid;
 
                        myname = newstr(myname);
                        if ((pw = getpwnam(myname)) == NULL ||
 
                        myname = newstr(myname);
                        if ((pw = getpwnam(myname)) == NULL ||
@@ -997,19 +973,30 @@ unsetenv(name)
 **             none
 */
 
 **             none
 */
 
-#ifdef SYSTEM5
+#ifdef SOLARIS
+# include <sys/resource.h>
+#endif
 
 int
 
 int
-getdtablesize()
+getdtsize()
 {
 {
+#ifdef RLIMIT_NOFILE
+       struct rlimit rl;
+
+       if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
+               return rl.rlim_cur;
+#endif
+
 # ifdef _SC_OPEN_MAX
        return sysconf(_SC_OPEN_MAX);
 # else
 # ifdef _SC_OPEN_MAX
        return sysconf(_SC_OPEN_MAX);
 # else
+#  ifdef HASGETDTABLESIZE
+       return getdtablesize();
+#  else
        return NOFILE;
        return NOFILE;
+#  endif
 # endif
 }
 # endif
 }
-
-#endif
 \f/*
 **  UNAME -- get the UUCP name of this system.
 */
 \f/*
 **  UNAME -- get the UUCP name of this system.
 */
index 6d34c69..ad5102c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)conf.h      8.2 (Berkeley) %G%
+ *     @(#)conf.h      8.3 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
 **     change these.
 */
 
 **     change these.
 */
 
+/* general "standard C" defines */
 #ifdef __STDC__
 # define HASSETVBUF    1       /* yes, we have setvbuf in libc */
 #endif
 
 #ifdef __STDC__
 # define HASSETVBUF    1       /* yes, we have setvbuf in libc */
 #endif
 
+/* general POSIX defines */
+#ifdef _POSIX_VERSION
+# define HASSETSID     1       /* has setsid(2) call */
+#endif
+
+/*
+**  Per-Operating System defines
+*/
+
 /* HP-UX -- tested for 8.07 */
 # ifdef __hpux
 /* HP-UX -- tested for 8.07 */
 # ifdef __hpux
-# define SYSTEM5       1
+# define SYSTEM5       1       /* include all the System V defines */
 # define UNSETENV      1       /* need unsetenv(3) support */
 # define UNSETENV      1       /* need unsetenv(3) support */
-# define seteuid       setuid
-# define HASSETVBUF            /* we have setvbuf in libc (but not __STDC__) */
+# define HASSETEUID    1       /* we have seteuid call */
+# define seteuid(uid)  setresuid(-1, uid, -1)  
+# ifndef __STDC__
+#  define HASSETVBUF   1       /* we have setvbuf in libc (but not __STDC__) */
+# endif
 # endif
 
 /* IBM AIX 3.x -- actually tested for 3.2.3 */
 # endif
 
 /* IBM AIX 3.x -- actually tested for 3.2.3 */
 # define setpgrp       BSDsetpgrp
 # endif
 
 # define setpgrp       BSDsetpgrp
 # endif
 
-/* general System V defines */
-# ifdef SYSTEM5
-# define LOCKF         1       /* use System V lockf instead of flock */
-# define SYS5TZ                1       /* use System V style timezones */
-# define HASUNAME      1       /* use System V uname system call */
-# endif
-
+/* various systems from Sun Microsystems */
 #if defined(sun) && !defined(BSD)
 #if defined(sun) && !defined(BSD)
+
 # define UNSETENV      1       /* need unsetenv(3) support */
 
 # ifdef SOLARIS
 # define UNSETENV      1       /* need unsetenv(3) support */
 
 # ifdef SOLARIS
+                       /* Solaris 2.x */
 #  define LOCKF                1       /* use System V lockf instead of flock */
 #  define LOCKF                1       /* use System V lockf instead of flock */
-#  define UNSETENV     1       /* need unsetenv(3) support */
 #  define HASUSTAT     1       /* has the ustat(2) syscall */
 #  define HASUSTAT     1       /* has the ustat(2) syscall */
+#  define bcopy(s, d, l)       (memmove((d), (s), (l)))
+#  define bzero(d, l)          (memset((d), '\0', (l)))
+#  define bcmp(s, d, l)                (memcmp((s), (d), (l)))
+#  include <sys/time.h>
+
 # else
 # else
+                       /* SunOS 4.1.x */
 #  define HASSTATFS    1       /* has the statfs(2) syscall */
 #  define HASSTATFS    1       /* has the statfs(2) syscall */
+#  define HASSETEUID   1       /* we have seteuid call */
 #  include <vfork.h>
 #  include <vfork.h>
-# endif
 
 
+# endif
 #endif
 
 #endif
 
+/* Digital Ultrix 4.2A or 4.3 */
 #ifdef ultrix
 # define HASSTATFS     1       /* has the statfs(2) syscall */
 #ifdef ultrix
 # define HASSTATFS     1       /* has the statfs(2) syscall */
+# define HASSETEUID    1       /* we have seteuid call */
 #endif
 
 #endif
 
-#ifdef _POSIX_VERSION
-# define HASSETSID     1       /* has setsid(2) call */
+/* OSF/1 (tested on Alpha) */
+#ifdef __osf__
+# define HASSETEUID    1       /* we have seteuid call */
+# define seteuid(uid)  setreuid(-1, uid)
 #endif
 
 #endif
 
+/* NeXTstep */
 #ifdef __NeXT__
 # define sleep         sleepX
 # define UNSETENV      1       /* need unsetenv(3) support */
 #endif
 
 #ifdef __NeXT__
 # define sleep         sleepX
 # define UNSETENV      1       /* need unsetenv(3) support */
 #endif
 
+/* various flavors of BSD */
+#ifdef BSD
+# define HASGETDTABLESIZE 1    /* we have getdtablesize(2) call */
+#endif
+
+/* 4.4BSD */
 #ifdef BSD4_4
 # include <sys/cdefs.h>
 #ifdef BSD4_4
 # include <sys/cdefs.h>
-# ifndef _POSIX_SAVED_IDS
-#  define _POSIX_SAVED_IDS     /* safe because we actually use seteuid */
-# endif
+# define HASSETEUID    1       /* we have seteuid(2) call */
 #endif
 
 #endif
 
+/*
+**  End of Per-Operating System defines
+*/
+
+/* general System V defines */
+# ifdef SYSTEM5
+# define LOCKF         1       /* use System V lockf instead of flock */
+# define SYS5TZ                1       /* use System V style timezones */
+# define HASUNAME      1       /* use System V uname system call */
+# define NEEDGETDTABLESIZE 1   /* needs a replacement getdtablesize */
+# endif
+
 /*
 **  Due to a "feature" in some operating systems such as Ultrix 4.3 and
 **  HPUX 8.0, if you receive a "No route to host" message (ICMP message
 /*
 **  Due to a "feature" in some operating systems such as Ultrix 4.3 and
 **  HPUX 8.0, if you receive a "No route to host" message (ICMP message
index 30c4f5f..df4fdda 100644 (file)
@@ -13,9 +13,9 @@
 
 #ifndef lint
 #ifdef DAEMON
 
 #ifndef lint
 #ifdef DAEMON
-static char sccsid[] = "@(#)daemon.c   8.1 (Berkeley) %G% (with daemon mode)";
+static char sccsid[] = "@(#)daemon.c   8.2 (Berkeley) %G% (with daemon mode)";
 #else
 #else
-static char sccsid[] = "@(#)daemon.c   8.1 (Berkeley) %G% (without daemon mode)";
+static char sccsid[] = "@(#)daemon.c   8.2 (Berkeley) %G% (without daemon mode)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
@@ -108,7 +108,11 @@ getrequests()
                        syserr("554 service \"smtp\" unknown");
                        goto severe;
                }
                        syserr("554 service \"smtp\" unknown");
                        goto severe;
                }
+#ifdef _SCO_unix_
+               DaemonAddr.sin.sin_port = htons(sp->s_port);
+#else
                DaemonAddr.sin.sin_port = sp->s_port;
                DaemonAddr.sin.sin_port = sp->s_port;
+#endif
        }
 
        /*
        }
 
        /*
@@ -316,7 +320,11 @@ gothostent:
                        syserr("554 makeconnection: service \"smtp\" unknown");
                        return (EX_OSERR);
                }
                        syserr("554 makeconnection: service \"smtp\" unknown");
                        return (EX_OSERR);
                }
+#ifdef _SCO_unix_
+               port = htons(sp->s_port);
+#else
                port = sp->s_port;
                port = sp->s_port;
+#endif
        }
 
        switch (addr.sa.sa_family)
        }
 
        switch (addr.sa.sa_family)
@@ -571,7 +579,13 @@ getauthinfo(fd)
        /* create foreign address */
        sp = getservbyname("auth", "tcp");
        if (sp != NULL)
        /* create foreign address */
        sp = getservbyname("auth", "tcp");
        if (sp != NULL)
+       {
+#ifdef _SCO_unix_
+               fa.sin.sin_port = htons(sp->s_port);
+#else
                fa.sin.sin_port = sp->s_port;
                fa.sin.sin_port = sp->s_port;
+#endif
+       }
        else
                fa.sin.sin_port = htons(113);
 
        else
                fa.sin.sin_port = htons(113);
 
index c182e2d..6b76d8c 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)deliver.c  8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)deliver.c  8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
@@ -474,6 +474,9 @@ sendenvelope(e, mode)
                    bitset(QDONTSEND, q->q_flags))
                        continue;
 
                    bitset(QDONTSEND, q->q_flags))
                        continue;
 
+               if (tTd(13, 3))
+                       printf("FATAL ERRORS\n");
+
                e->e_flags |= EF_FATALERRS;
 
                if (q->q_owner == NULL && strcmp(e->e_from.q_paddr, "<>") != 0)
                e->e_flags |= EF_FATALERRS;
 
                if (q->q_owner == NULL && strcmp(e->e_from.q_paddr, "<>") != 0)
@@ -790,6 +793,7 @@ deliver(e, firstto)
                rcode = checkcompat(to, e);
                if (rcode != EX_OK)
                {
                rcode = checkcompat(to, e);
                if (rcode != EX_OK)
                {
+                       markfailure(e, to, rcode);
                        giveresponse(rcode, m, NULL, e);
                        continue;
                }
                        giveresponse(rcode, m, NULL, e);
                        continue;
                }
index 32716bb..45279ff 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)envelope.c 8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)envelope.c 8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
@@ -132,7 +132,14 @@ dropenvelope(e)
                        message(buf);
                }
                e->e_flags |= EF_TIMEOUT|EF_CLRQUEUE;
                        message(buf);
                }
                e->e_flags |= EF_TIMEOUT|EF_CLRQUEUE;
-               fprintf(e->e_xfp, "421 Message timed out\n");
+               fprintf(e->e_xfp, "Message could not be delivered for %s\n",
+                       pintvl(TimeOuts.to_q_return, FALSE));
+               fprintf(e->e_xfp, "Message will be deleted from queue\n");
+               for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+               {
+                       if (bitset(QQUEUEUP, q->q_flags))
+                               q->q_flags |= QBADADDR;
+               }
        }
        else if (TimeOuts.to_q_warning > 0 &&
            curtime() > e->e_ctime + TimeOuts.to_q_warning)
        }
        else if (TimeOuts.to_q_warning > 0 &&
            curtime() > e->e_ctime + TimeOuts.to_q_warning)
@@ -155,6 +162,11 @@ dropenvelope(e)
                        pintvl(TimeOuts.to_q_warning, FALSE));
                fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
                        pintvl(TimeOuts.to_q_return, FALSE));
                        pintvl(TimeOuts.to_q_warning, FALSE));
                fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
                        pintvl(TimeOuts.to_q_return, FALSE));
+               for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+               {
+                       if (bitset(QQUEUEUP, q->q_flags))
+                               q->q_flags |= QREPORT;
+               }
        }
 
        /*
        }
 
        /*
@@ -625,8 +637,8 @@ setsender(from, e, delimptr, internal)
        {
                if (e->e_from.q_home == NULL)
                        e->e_from.q_home = getenv("HOME");
        {
                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();
+               e->e_from.q_uid = RealUid;
+               e->e_from.q_gid = RealGid;
        }
 
        /*
        }
 
        /*
index 1df525b..338cade 100644 (file)
@@ -13,7 +13,7 @@ static char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 #define        _DEFINE
 #endif /* not lint */
 
 #define        _DEFINE
@@ -153,7 +153,7 @@ main(argc, argv, envp)
 #endif
 
        /* in 4.4BSD, the table can be huge; impose a reasonable limit */
 #endif
 
        /* in 4.4BSD, the table can be huge; impose a reasonable limit */
-       DtableSize = getdtablesize();
+       DtableSize = getdtsize();
        if (DtableSize > 256)
                DtableSize = 256;
 
        if (DtableSize > 256)
                DtableSize = 256;
 
@@ -209,6 +209,9 @@ main(argc, argv, envp)
        else
                (void) sprintf(RealUserName, "Unknown UID %d", RealUid);
 
        else
                (void) sprintf(RealUserName, "Unknown UID %d", RealUid);
 
+       /* our real uid will have to be root -- we will trash this later */
+       setuid((uid_t) 0);
+
        /* Handle any non-getoptable constructions. */
        obsolete(argv);
 
        /* Handle any non-getoptable constructions. */
        obsolete(argv);
 
@@ -236,8 +239,8 @@ main(argc, argv, envp)
 
                  case 'C':
                        ConfFile = optarg;
 
                  case 'C':
                        ConfFile = optarg;
-                       (void) setgid(getrgid());
-                       (void) setuid(getruid());
+                       (void) setgid(RealGid);
+                       (void) setuid(RealUid);
                        safecf = FALSE;
                        nothaw = TRUE;
                        break;
                        safecf = FALSE;
                        nothaw = TRUE;
                        break;
@@ -390,7 +393,7 @@ main(argc, argv, envp)
                        {
                          case MD_DAEMON:
 # ifdef DAEMON
                        {
                          case MD_DAEMON:
 # ifdef DAEMON
-                               if (getuid() != 0) {
+                               if (RealUid != 0) {
                                        usrerr("Permission denied");
                                        exit (EX_USAGE);
                                }
                                        usrerr("Permission denied");
                                        exit (EX_USAGE);
                                }
@@ -436,7 +439,7 @@ main(argc, argv, envp)
                        break;
 
                  case 'C':     /* select configuration file (already done) */
                        break;
 
                  case 'C':     /* select configuration file (already done) */
-                       if (getuid() != 0)
+                       if (RealUid != 0)
                                auth_warning(CurEnv,
                                        "Processed by %s with -C %s",
                                        RealUserName, optarg);
                                auth_warning(CurEnv,
                                        "Processed by %s with -C %s",
                                        RealUserName, optarg);
@@ -529,7 +532,7 @@ main(argc, argv, envp)
                        break;
 
                  case 'X':     /* traffic log file */
                        break;
 
                  case 'X':     /* traffic log file */
-                       setuid(getuid());
+                       setuid(RealUid);
                        TrafficLogFile = fopen(optarg, "a");
                        if (TrafficLogFile == NULL)
                        {
                        TrafficLogFile = fopen(optarg, "a");
                        if (TrafficLogFile == NULL)
                        {
@@ -609,14 +612,14 @@ main(argc, argv, envp)
 
 
 # ifdef QUEUE
 
 
 # ifdef QUEUE
-       if (queuemode && getuid() != 0)
+       if (queuemode && RealUid != 0)
        {
                struct stat stbuf;
 
                /* check to see if we own the queue directory */
                if (stat(QueueDir, &stbuf) < 0)
                        syserr("main: cannot stat %s", QueueDir);
        {
                struct stat stbuf;
 
                /* check to see if we own the queue directory */
                if (stat(QueueDir, &stbuf) < 0)
                        syserr("main: cannot stat %s", QueueDir);
-               if (stbuf.st_uid != getuid())
+               if (stbuf.st_uid != RealUid)
                {
                        /* nope, really a botch */
                        usrerr("Permission denied");
                {
                        /* nope, really a botch */
                        usrerr("Permission denied");
@@ -630,8 +633,8 @@ main(argc, argv, envp)
 # ifdef FROZENCONFIG
          case MD_FREEZE:
                /* this is critical to avoid forgeries of the frozen config */
 # ifdef FROZENCONFIG
          case MD_FREEZE:
                /* this is critical to avoid forgeries of the frozen config */
-               (void) setgid(getgid());
-               (void) setuid(getuid());
+               (void) setgid(RealGid);
+               (void) setuid(RealUid);
 
                /* freeze the configuration */
                freeze(FreezeFile);
 
                /* freeze the configuration */
                freeze(FreezeFile);
@@ -709,7 +712,10 @@ main(argc, argv, envp)
 
        /* if we've had errors so far, exit now */
        if (ExitStat != EX_OK && OpMode != MD_TEST)
 
        /* if we've had errors so far, exit now */
        if (ExitStat != EX_OK && OpMode != MD_TEST)
+       {
+               setuid(RealUid);
                exit(ExitStat);
                exit(ExitStat);
+       }
 
        /*
        **  Do operation-mode-dependent initialization.
 
        /*
        **  Do operation-mode-dependent initialization.
@@ -722,6 +728,7 @@ main(argc, argv, envp)
 #ifdef QUEUE
                dropenvelope(CurEnv);
                printqueue();
 #ifdef QUEUE
                dropenvelope(CurEnv);
                printqueue();
+               setuid(RealUid);
                exit(EX_OK);
 #else /* QUEUE */
                usrerr("No queue to print");
                exit(EX_OK);
 #else /* QUEUE */
                usrerr("No queue to print");
@@ -731,6 +738,7 @@ main(argc, argv, envp)
          case MD_INITALIAS:
                /* initialize alias database */
                initmaps(TRUE, CurEnv);
          case MD_INITALIAS:
                /* initialize alias database */
                initmaps(TRUE, CurEnv);
+               setuid(RealUid);
                exit(EX_OK);
 
          case MD_DAEMON:
                exit(EX_OK);
 
          case MD_DAEMON:
@@ -1061,6 +1069,10 @@ finis()
 # endif /* LOG */
        if (ExitStat == EX_TEMPFAIL)
                ExitStat = EX_OK;
 # endif /* LOG */
        if (ExitStat == EX_TEMPFAIL)
                ExitStat = EX_OK;
+
+       /* reset uid for process accounting */
+       setuid(RealUid);
+
        exit(ExitStat);
 }
 \f/*
        exit(ExitStat);
 }
 \f/*
@@ -1087,6 +1099,10 @@ intsig()
 #ifdef XLA
        xla_all_end();
 #endif
 #ifdef XLA
        xla_all_end();
 #endif
+
+       /* reset uid for process accounting */
+       setuid(RealUid);
+
        exit(EX_OK);
 }
 \f/*
        exit(EX_OK);
 }
 \f/*
index 3c8ae20..1a285cb 100644 (file)
@@ -10,9 +10,9 @@
 
 #ifndef lint
 #ifdef QUEUE
 
 #ifndef lint
 #ifdef QUEUE
-static char sccsid[] = "@(#)queue.c    8.2 (Berkeley) %G% (with queueing)";
+static char sccsid[] = "@(#)queue.c    8.3 (Berkeley) %G% (with queueing)";
 #else
 #else
-static char sccsid[] = "@(#)queue.c    8.2 (Berkeley) %G% (without queueing)";
+static char sccsid[] = "@(#)queue.c    8.3 (Berkeley) %G% (without queueing)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
@@ -1099,7 +1099,7 @@ printqueue()
        **  Check for permission to print the queue
        */
 
        **  Check for permission to print the queue
        */
 
-       if (bitset(PRIV_RESTRMAILQ, PrivacyFlags) && getuid() != 0)
+       if (bitset(PRIV_RESTRMAILQ, PrivacyFlags) && RealUid != 0)
        {
                struct stat st;
 # ifdef NGROUPS
        {
                struct stat st;
 # ifdef NGROUPS
@@ -1121,7 +1121,7 @@ printqueue()
                }
                if (n < 0)
 # else
                }
                if (n < 0)
 # else
-               if (getgid() != st.st_gid)
+               if (RealGid != st.st_gid)
 # endif
                {
                        usrerr("510 You are not permitted to see the queue");
 # endif
                {
                        usrerr("510 You are not permitted to see the queue");
index 004a348..d4c559b 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)readcf.c   8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)readcf.c   8.2 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
index e1fcfae..8c64238 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)recipient.c        8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)recipient.c        8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
@@ -352,7 +352,7 @@ recipient(a, sendq, e)
                        usrerr("550 Cannot mail directly to files");
                }
                else if ((stat(buf, &stb) >= 0) ? (!writable(&stb)) :
                        usrerr("550 Cannot mail directly to files");
                }
                else if ((stat(buf, &stb) >= 0) ? (!writable(&stb)) :
-                   (*p = '\0', safefile(buf, getruid(), TRUE, S_IWRITE|S_IEXEC) != 0))
+                   (*p = '\0', safefile(buf, RealUid, TRUE, S_IWRITE|S_IEXEC) != 0))
                {
                        a->q_flags |= QBADADDR;
                        giveresponse(EX_CANTCREAT, m, NULL, e);
                {
                        a->q_flags |= QBADADDR;
                        giveresponse(EX_CANTCREAT, m, NULL, e);
@@ -589,8 +589,8 @@ writable(s)
 
        if (bitset(0111, s->st_mode))
                return (FALSE);
 
        if (bitset(0111, s->st_mode))
                return (FALSE);
-       euid = getruid();
-       egid = getrgid();
+       euid = RealUid;
+       egid = RealGid;
        if (geteuid() == 0)
        {
                if (bitset(S_ISUID, s->st_mode))
        if (geteuid() == 0)
        {
                if (bitset(S_ISUID, s->st_mode))
index 777348a..894ee29 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)savemail.c 8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)savemail.c 8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 # include <pwd.h>
 #endif /* not lint */
 
 # include <pwd.h>
@@ -586,18 +586,23 @@ errbody(fp, m, e)
        printheader = TRUE;
        for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
        {
        printheader = TRUE;
        for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
        {
-               if (bitset(QBADADDR, q->q_flags))
+               if (bitset(QBADADDR|QREPORT, q->q_flags))
                {
                        if (printheader)
                        {
                {
                        if (printheader)
                        {
-                               putline("   ----- The following addresses failed -----",
+                               putline("   ----- The following addresses had delivery problems -----",
                                        fp, m);
                                printheader = FALSE;
                        }
                        if (q->q_alias != NULL)
                                        fp, m);
                                printheader = FALSE;
                        }
                        if (q->q_alias != NULL)
-                               putline(q->q_alias->q_paddr, fp, m);
+                               strcpy(buf, q->q_alias->q_paddr);
+                       else
+                               strcpy(buf, q->q_paddr);
+                       if (bitset(QBADADDR, q->q_flags))
+                               strcat(buf, "  (hard error -- address deleted)");
                        else
                        else
-                               putline(q->q_paddr, fp, m);
+                               strcat(buf, "  (temporary failure -- will retry)");
+                       putline(buf, fp, m);
                }
        }
        if (!printheader)
                }
        }
        if (!printheader)
index 278fadb..ca9f3ce 100644 (file)
@@ -5,7 +5,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sendmail.h  8.2 (Berkeley) %G%
+ *     @(#)sendmail.h  8.3 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -15,7 +15,7 @@
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
-static char SmailSccsId[] =    "@(#)sendmail.h 8.2             %G%";
+static char SmailSccsId[] =    "@(#)sendmail.h 8.3             %G%";
 # endif
 # else /*  _DEFINE */
 # define EXTERN extern
 # endif
 # else /*  _DEFINE */
 # define EXTERN extern
@@ -133,6 +133,7 @@ typedef struct address ADDRESS;
 # define QNOTREMOTE    000100  /* not an address for remote forwarding */
 # define QSELFREF      000200  /* this address references itself */
 # define QVERIFIED     000400  /* verified, but not expanded */
 # define QNOTREMOTE    000100  /* not an address for remote forwarding */
 # define QSELFREF      000200  /* this address references itself */
 # define QVERIFIED     000400  /* verified, but not expanded */
+# define QREPORT       001000  /* report this address in return message */
 # define QPSEUDO       000040  /* only on the list for verification */
 \f/*
 **  Mailer definition structure.
 # define QPSEUDO       000040  /* only on the list for verification */
 \f/*
 **  Mailer definition structure.
index fd88e06..76937ab 100644 (file)
@@ -10,9 +10,9 @@
 
 #ifndef lint
 #ifdef SMTP
 
 #ifndef lint
 #ifdef SMTP
-static char sccsid[] = "@(#)srvrsmtp.c 8.2 (Berkeley) %G% (with SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.3 (Berkeley) %G% (with SMTP)";
 #else
 #else
-static char sccsid[] = "@(#)srvrsmtp.c 8.2 (Berkeley) %G% (without SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.3 (Berkeley) %G% (without SMTP)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
@@ -279,6 +279,7 @@ smtp(e)
                                {
                                        QuickAbort = FALSE;
                                        SuprErrs = TRUE;
                                {
                                        QuickAbort = FALSE;
                                        SuprErrs = TRUE;
+                                       e->e_flags &= ~EF_FATALERRS;
                                        finis();
                                }
                                break;
                                        finis();
                                }
                                break;
@@ -444,15 +445,26 @@ smtp(e)
                        }
 
                        /* check to see if we need to re-expand aliases */
                        }
 
                        /* check to see if we need to re-expand aliases */
+                       /* also reset QBADADDR on already-diagnosted addrs */
+                       doublequeue = FALSE;
                        for (a = e->e_sendqueue; a != NULL; a = a->q_next)
                        {
                                if (bitset(QVERIFIED, a->q_flags))
                        for (a = e->e_sendqueue; a != NULL; a = a->q_next)
                        {
                                if (bitset(QVERIFIED, a->q_flags))
-                                       break;
+                               {
+                                       /* need to re-expand aliases */
+                                       doublequeue = TRUE;
+                               }
+                               if (bitset(QBADADDR, a->q_flags))
+                               {
+                                       /* make this "go away" */
+                                       a->q_flags |= QDONTSEND;
+                                       a->q_flags &= ~QBADADDR;
+                               }
                        }
 
                        /* collect the text of the message */
                        SmtpPhase = "collect";
                        }
 
                        /* collect the text of the message */
                        SmtpPhase = "collect";
-                       collect(TRUE, a != NULL, e);
+                       collect(TRUE, doublequeue, e);
                        e->e_flags &= ~EF_FATALERRS;
                        if (Errors != 0)
                                goto abortmessage;
                        e->e_flags &= ~EF_FATALERRS;
                        if (Errors != 0)
                                goto abortmessage;
@@ -476,7 +488,7 @@ smtp(e)
                        */
 
                        SmtpPhase = "delivery";
                        */
 
                        SmtpPhase = "delivery";
-                       if (nrcpts != 1 && a == NULL)
+                       if (nrcpts != 1 && !doublequeue)
                        {
                                HoldErrs = TRUE;
                                e->e_errormode = EM_MAIL;
                        {
                                HoldErrs = TRUE;
                                e->e_errormode = EM_MAIL;
@@ -510,7 +522,7 @@ smtp(e)
                                e->e_errormode = EM_MAIL;
 
                                /* if we just queued, poke it */
                                e->e_errormode = EM_MAIL;
 
                                /* if we just queued, poke it */
-                               if (a != NULL && e->e_sendmode != SM_QUEUE)
+                               if (doublequeue && e->e_sendmode != SM_QUEUE)
                                {
                                        unlockqueue(e);
                                        dowork(id, TRUE, TRUE, e);
                                {
                                        unlockqueue(e);
                                        dowork(id, TRUE, TRUE, e);
index 3b86537..912ddda 100644 (file)
@@ -10,9 +10,9 @@
 
 #ifndef lint
 #ifdef SMTP
 
 #ifndef lint
 #ifdef SMTP
-static char sccsid[] = "@(#)usersmtp.c 8.3 (Berkeley) %G% (with SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.4 (Berkeley) %G% (with SMTP)";
 #else
 #else
-static char sccsid[] = "@(#)usersmtp.c 8.3 (Berkeley) %G% (without SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.4 (Berkeley) %G% (without SMTP)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
@@ -434,7 +434,6 @@ smtpdata(m, mci, e)
        register int r;
        register EVENT *ev;
        time_t timeout;
        register int r;
        register EVENT *ev;
        time_t timeout;
-       time_t mintimeout;
        static int datatimeout();
 
        /*
        static int datatimeout();
 
        /*
@@ -489,10 +488,10 @@ smtpdata(m, mci, e)
                return EX_TEMPFAIL;
        }
 
                return EX_TEMPFAIL;
        }
 
-       timeout = e->e_msgsize / 64;
-       mintimeout = e->e_nrcpts * 90 + 60;
-       if (timeout < mintimeout)
-               timeout = mintimeout;
+       timeout = e->e_msgsize / 16;
+       if (timeout < (time_t) 60)
+               timeout = (time_t) 60;
+       timeout += e->e_nrcpts * 90;
        ev = setevent(timeout, datatimeout, 0);
 
        /* now output the actual message */
        ev = setevent(timeout, datatimeout, 0);
 
        /* now output the actual message */
index 0afa640..028bbbf 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)util.c     8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)util.c     8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
@@ -550,7 +550,10 @@ dfopen(filename, omode, cmode)
                (void) lockfile(fd, filename, locktype);
                errno = 0;
        }
                (void) lockfile(fd, filename, locktype);
                errno = 0;
        }
-       return fdopen(fd, om->farg);
+       if (fd < 0)
+               return NULL;
+       else
+               return fdopen(fd, om->farg);
 }
 \f/*
 **  PUTLINE -- put a line like fputs obeying SMTP conventions
 }
 \f/*
 **  PUTLINE -- put a line like fputs obeying SMTP conventions
index 69bfc6d..0098730 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)version.c  8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)version.c  8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 #endif /* not lint */
 
-char   Version[] = "8.2";
+char   Version[] = "8.3";