diff options
author | peter <peter@FreeBSD.org> | 1996-11-18 02:26:51 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-11-18 02:26:51 +0000 |
commit | 8e0d5faaa77159b266e4ab922edf43a79f52e0c0 (patch) | |
tree | dc9912f7544cf0388bda667e714af24cd2fc24f8 /usr.sbin/sendmail/src | |
parent | c25f71c7e501b060767f7d67d9448d649a801c95 (diff) | |
download | FreeBSD-src-8e0d5faaa77159b266e4ab922edf43a79f52e0c0.zip FreeBSD-src-8e0d5faaa77159b266e4ab922edf43a79f52e0c0.tar.gz |
Import sendmail-8.8.3 - this contains the official fix to replace the
previous workaround patch that I used.
Obtained from: Eric Allman <eric@sendmail.org>
Diffstat (limited to 'usr.sbin/sendmail/src')
-rw-r--r-- | usr.sbin/sendmail/src/READ_ME | 37 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/collect.c | 5 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/conf.c | 137 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/conf.h | 43 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/daemon.c | 48 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/deliver.c | 110 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/domain.c | 29 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/envelope.c | 24 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/main.c | 64 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/map.c | 36 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/mci.c | 53 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/mime.c | 183 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/queue.c | 131 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/readcf.c | 8 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/sendmail.h | 11 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/srvrsmtp.c | 21 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/usersmtp.c | 168 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/util.c | 60 | ||||
-rw-r--r-- | usr.sbin/sendmail/src/version.c | 4 |
19 files changed, 841 insertions, 331 deletions
diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME index 779f828..afeac1b 100644 --- a/usr.sbin/sendmail/src/READ_ME +++ b/usr.sbin/sendmail/src/READ_ME @@ -30,7 +30,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)READ_ME 8.125 (Berkeley) 10/18/96 +# @(#)READ_ME 8.130 (Berkeley) 11/10/96 # This directory contains the source files for sendmail. @@ -168,7 +168,7 @@ LDAPMAP Lightweight Directory Lookup Protocol support. You will this flag. >>> NOTE WELL for NEWDB support: it is CRITICAL that you remove ndbm.o ->>> from libdb.a and ndbm.h from the appropriate include directories if +>>> from libdb.a before you install it and DO NOT install ndbm.h if >>> you want to get ndbm support. If you don't delete these, there is >>> absolutely no point to including -DNDBM, since it will just get you >>> another (inferior) API to the same format database. These files @@ -355,11 +355,20 @@ LA_TYPE The type of load average your kernel supports. These the dg_sys_info system call. LA_HPUX (10) is an HP-UX specific version that uses the pstat_getdynamic system call. + LA_IRIX6 (11) is an IRIX 6.x specific version that adapts + to 32 or 64 bit kernels; it is otherwise very similar + to LA_INT. + LA_KSTAT (12) uses the (Solaris-specific) kstat(3k) + implementation. + LA_DEVSHORT (13) reads a short from a system file (default: + /dev/table/avenrun) and scales it in the same manner + as LA_SHORT. LA_INT, LA_SHORT, LA_FLOAT, and LA_READKSYM have several other parameters that they try to divine: the name of your kernel, the name of the variable in the kernel to examine, the number of bits of precision in a fixed point load average, - and so forth. + and so forth. LA_DEVSHORT uses _PATH_AVENRUN to find the + device to be read to find the load average. In desperation, use LA_ZERO. The actual code is in conf.c -- it can be tweaked if you are brave. FSHIFT For LA_INT, LA_SHORT, and LA_READKSYM, this is the number @@ -809,6 +818,26 @@ IRIX the developers' option in order to get the necessary include files. + If you compile with -lmalloc (the fast memory allocator), you may + get warning messages such as the following: + + ld32: WARNING 85: definition of _calloc in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _malloc in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _realloc in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _free in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _cfree in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + + These are unavoidable and innocuous -- just ignore them. + + According to Dave Sill <de5@ornl.gov>, there is a version of the + Berkeley db library patched to run on Irix 6.2 available from + http://reality.sgi.com/ariel/db-1.85-irix.tar.Z . + NeXT or NEXTSTEP NEXTSTEP 3.3 and earlier ship with the old DBM library. You will need to acquire the new Berkeley DB from ftp.cs.berkeley.edu. @@ -1348,4 +1377,4 @@ version.c The version number and information about this Eric Allman -(Version 8.125, last update 10/18/96 07:32:40) +(Version 8.130, last update 11/10/96 11:15:30) diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c index 233c247..48b5b89 100644 --- a/usr.sbin/sendmail/src/collect.c +++ b/usr.sbin/sendmail/src/collect.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)collect.c 8.58 (Berkeley) 9/18/96"; +static char sccsid[] = "@(#)collect.c 8.60 (Berkeley) 11/15/96"; #endif /* not lint */ # include <errno.h> @@ -488,7 +488,7 @@ readerr: ** Examples are who is the from person & the date. */ - eatheader(e, !requeueflag); + eatheader(e, TRUE); if (GrabTo && e->e_sendqueue == NULL) usrerr("No recipient addresses found in header"); @@ -557,6 +557,7 @@ readerr: /* check for message too large */ if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize) { + e->e_flags |= EF_NO_BODY_RETN; e->e_status = "5.2.3"; usrerr("552 Message exceeds maximum fixed size (%ld)", MaxMessageSize); diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c index 0799047..6f3fd95 100644 --- a/usr.sbin/sendmail/src/conf.c +++ b/usr.sbin/sendmail/src/conf.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)conf.c 8.312 (Berkeley) 10/17/96"; +static char sccsid[] = "@(#)conf.c 8.315 (Berkeley) 11/10/96"; #endif /* not lint */ # include "sendmail.h" @@ -1188,8 +1188,19 @@ init_md(argc, argv) /* keep gethostby*() from stripping the local domain name */ set_domain_trim_off(); #endif -#if SECUREWARE +#if SECUREWARE || defined(_SCO_unix_) set_auth_parameters(argc, argv); + +# ifdef _SCO_unix_ + /* + ** This is required for highest security levels (the kernel + ** won't let it call set*uid() or run setuid binaries without + ** it). It may be necessary on other SECUREWARE systems. + */ + + if (getluid() == -1) + setluid(0); +# endif #endif #ifdef VENDOR_DEFAULT @@ -1245,6 +1256,8 @@ init_vendor_macros(e) #define LA_DGUX 9 /* special DGUX implementation */ #define LA_HPUX 10 /* special HPUX implementation */ #define LA_IRIX6 11 /* special IRIX 6.2 implementation */ +#define LA_KSTAT 12 /* special Solaris kstat(3k) implementation */ +#define LA_DEVSHORT 13 /* read short from a device */ /* do guesses based on general OS type */ #ifndef LA_TYPE @@ -1780,8 +1793,100 @@ int getla(void) } #endif +#if LA_TYPE == LA_KSTAT + +#include <kstat.h> + +int +getla() +{ + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *ksn; + int la; + + kc = kstat_open(); + if (kc == NULL) + { + if (tTd(3, 1)) + printf("getla: kstat_open(): %s\n", + errstring(errno)); + return -1; + } + ksp = kstat_lookup(kc, "unix", 0, "system_misc"); /* NULL on error */ + if (ksp == NULL) + { + if (tTd(3, 1)) + printf("getla: kstat_lookup(): %s\n", + errstring(errno); + return -1; + } + if (kstat_read(kc, ksp, NULL) < 0) + { + if (tTd(3, 1)) + printf("getla: kstat_read(): %s\n", + errstring(errno); + return -1; + } + ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min"); + la = (ksn->value.ul + FSCALE/2) >> FSHIFT; + kstat_close(kc); + return la; +} + +#endif /* LA_TYPE == LA_KSTAT */ + +#if LA_TYPE == LA_DEVSHORT + +/* +** Read /dev/table/avenrun for the load average. This should contain +** three shorts for the 1, 5, and 15 minute loads. We only read the +** first, since that's all we care about. +** +** Intended for SCO OpenServer 5. +*/ + +# ifndef _PATH_AVENRUN +# define _PATH_AVENRUN "/dev/table/avenrun" +# endif + +int +getla() +{ + static int afd = -1; + short avenrun; + int loadav; + int r; + + errno = EBADF; + + if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1) + { + if (errno != EBADF) + return -1; + afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC); + if (afd < 0) + { + syslog(LOG_ERR, "can't open %s: %m", _PATH_AVENRUN); + return -1; + } + } + + r = read(afd, &avenrun, sizeof avenrun); + + if (tTd(3, 5)) + printf("getla: avenrun = %d\n", avenrun); + loadav = (int) (avenrun + FSCALE/2) >> FSHIFT; + if (tTd(3, 1)) + printf("getla: %d\n", loadav); + return loadav; +} + +#endif /* LA_TYPE == LA_DEVSHORT */ + #if LA_TYPE == LA_ZERO +int getla() { if (tTd(3, 1)) @@ -1941,8 +2046,10 @@ refuseconnections(port) syslog(LOG_INFO, "rejecting connections on port %d: load average: %d", port, CurrentLA); #endif + return TRUE; } - else if (!enoughdiskspace(MinBlocksFree + 1)) + + if (!enoughdiskspace(MinBlocksFree + 1)) { setproctitle("rejecting connections on port %d: min free: %d", port, MinBlocksFree); @@ -1951,20 +2058,26 @@ refuseconnections(port) syslog(LOG_INFO, "rejecting connections on port %d: min free: %d", port, MinBlocksFree); #endif + return TRUE; } - else if (MaxChildren > 0 && CurChildren >= MaxChildren) + + if (MaxChildren > 0 && CurChildren >= MaxChildren) { - setproctitle("rejecting connections on port %d: %d children, max %d", - port, CurChildren, MaxChildren); -#ifdef LOG - if (LogLevel >= 14) - syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d", + proc_list_probe(); + if (CurChildren >= MaxChildren) + { + setproctitle("rejecting connections on port %d: %d children, max %d", port, CurChildren, MaxChildren); +#ifdef LOG + if (LogLevel >= 14) + syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d", + port, CurChildren, MaxChildren); #endif + return TRUE; + } } - else - return FALSE; - return TRUE; + + return FALSE; } /* ** SETPROCTITLE -- set process title for ps diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h index 69558c2..cf7cbe5 100644 --- a/usr.sbin/sendmail/src/conf.h +++ b/usr.sbin/sendmail/src/conf.h @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)conf.h 8.267 (Berkeley) 10/17/96 + * @(#)conf.h 8.272 (Berkeley) 11/16/96 */ /* @@ -41,7 +41,9 @@ ** included in the next release. */ +#ifdef __GNUC__ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ +#endif # include <sys/param.h> # include <sys/types.h> @@ -216,7 +218,11 @@ extern void hard_syslog(int, char *, ...); #ifdef _AIX4 # define _AIX3 1 /* pull in AIX3 stuff */ -# define HASSETREUID 1 /* setreuid(2) works */ +# define USESETEUID 1 /* seteuid(2) works */ +# define TZ_TYPE TZ_NAME /* use tzname[] vector */ +# if _AIX4 >= 40200 +# define HASSETREUID 1 /* setreuid(2) works as of AIX 4.2 */ +# endif #endif @@ -409,6 +415,9 @@ typedef int pid_t; # define snprintf __snprintf /* but names it oddly in 2.5 */ # define vsnprintf __vsnprintf # endif +# ifndef LA_TYPE +# define LA_TYPE LA_KSTAT /* use kstat(3k) -- may work in < 2.5 */ +# endif # endif # ifndef HASGETUSERSHELL # define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */ @@ -588,6 +597,7 @@ extern long dgux_inet_addr(); # define WAITUNION 1 /* use "union wait" as wait argument type */ # define UID_T int /* compiler gripes on uid_t */ # define GID_T int /* ditto for gid_t */ +# define MODE_T int /* and mode_t */ # define sleep sleepX # define setpgid setpgrp # ifndef LA_TYPE @@ -791,31 +801,43 @@ extern int errno; ** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier. */ +/* SCO OpenServer 5 */ #if _SCO_DS >= 1 # include <paths.h> # define _SCO_unix_4_2 -# define HASSNPRINTF 1 /* has snprintf() call */ -# define HASFCHMOD 1 /* has fchmod() call */ -# define HASSETRLIMIT 1 /* has setrlimit() call */ +# define HASSNPRINTF 1 /* has snprintf(3) call */ +# define HASFCHMOD 1 /* has fchmod(2) call */ +# define HASSETRLIMIT 1 /* has setrlimit(2) call */ +# define USESETEUID 1 /* has seteuid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */ # define RLIMIT_NEEDS_SYS_TIME_H 1 +# ifndef LA_TYPE +# define LA_TYPE LA_DEVSHORT +# endif +# define _PATH_AVENRUN "/dev/table/avenrun" #endif - +/* SCO UNIX 3.2v4.2/Open Desktop 3.0 */ #ifdef _SCO_unix_4_2 # define _SCO_unix_ # define HASSETREUID 1 /* has setreuid(2) call */ #endif +/* SCO UNIX 3.2v4.0 Open Desktop 2.0 and earlier */ #ifdef _SCO_unix_ # include <sys/stream.h> /* needed for IP_SRCROUTE */ # define SYSTEM5 1 /* include all the System V defines */ # define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define NOFTRUNCATE 0 /* has (simulated) ftruncate call */ # define MAXPATHLEN PATHSIZE -# define LA_TYPE LA_SHORT # define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */ # define SFS_BAVAIL f_bfree /* alternate field name */ # define SPT_TYPE SPT_SCO /* write kernel u. area */ # define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */ +# define UID_T uid_t +# define GID_T gid_t +# define GIDSET_T gid_t # define _PATH_UNIX "/unix" # define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" # ifndef _PATH_SENDMAILPID @@ -828,9 +850,10 @@ extern int errno; # endif # ifndef _SCO_DS -# define NOFTRUNCATE 0 /* does not have ftruncate(3) call */ +# define ftruncate chsize /* use chsize(2) to emulate ftruncate */ # define NEEDFSYNC 1 /* needs the fsync(2) call stub */ # define NETUNIX 0 /* no unix domain socket support */ +# define LA_TYPE LA_SHORT # endif #endif @@ -1850,6 +1873,10 @@ extern int errno; # define SIZE_T size_t #endif +#ifndef MODE_T +# define MODE_T mode_t +#endif + #ifndef ARGV_T # define ARGV_T char ** #endif diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c index aead4ff..283d7e4 100644 --- a/usr.sbin/sendmail/src/daemon.c +++ b/usr.sbin/sendmail/src/daemon.c @@ -37,9 +37,9 @@ #ifndef lint #ifdef DAEMON -static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (with daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (with daemon mode)"; #else -static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (without daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (without daemon mode)"; #endif #endif /* not lint */ @@ -193,7 +193,7 @@ getrequests(e) for (;;) { - register int pid; + register pid_t pid; auto int lotherend; extern bool refuseconnections(); extern int getla(); @@ -244,6 +244,16 @@ getrequests(e) /* wait for a connection */ setproctitle("accepting connections on port %d", ntohs(DaemonAddr.sin.sin_port)); +#if 0 + /* + ** Andrew Sun <asun@ieps-sun.ml.com> claims that this will + ** fix the SVr4 problem. But it seems to have gone away, + ** so is it worth doing this? + */ + + if (SetNonBlocking(DaemonSocket, FALSE) < 0) + log an error here; +#endif do { errno = 0; @@ -734,9 +744,8 @@ makeconnection(host, port, mci, e) extern char MsgBuf[]; usrerr("553 Invalid numeric domain spec \"%s\"", host); - mci->mci_status = "5.1.2"; - mci->mci_rstatus = newstr(MsgBuf); - return (EX_NOHOST); + mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf); + return EX_NOHOST; } #if NETINET addr.sin.sin_family = AF_INET; /*XXX*/ @@ -773,11 +782,11 @@ gothostent: if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || (errno == ECONNREFUSED && UseNameServer)) { - mci->mci_status = "4.4.3"; - mci->mci_rstatus = NULL; - return (EX_TEMPFAIL); + mci_setstat(mci, EX_TEMPFAIL, "4.4.3", NULL); + return EX_TEMPFAIL; } #endif + mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); return (EX_NOHOST); } addr.sa.sa_family = hp->h_addrtype; @@ -839,6 +848,7 @@ gothostent: default: syserr("Can't connect to address family %d", addr.sa.sa_family); + mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); return (EX_NOHOST); } @@ -876,7 +886,11 @@ gothostent: { sav_errno = errno; syserr("makeconnection: cannot create socket"); - goto failure; +#ifdef XLA + xla_host_end(host); +#endif + mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); + return EX_TEMPFAIL; } #ifdef SO_SNDBUF @@ -964,18 +978,12 @@ gothostent: continue; } - /* failure, decide if temporary or not */ - failure: + /* couldn't open connection */ #ifdef XLA xla_host_end(host); #endif - if (transienterror(sav_errno)) - return EX_TEMPFAIL; - else - { - message("%s", errstring(sav_errno)); - return (EX_UNAVAILABLE); - } + mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); + return EX_TEMPFAIL; } /* connection ok, put it into canonical form */ @@ -984,9 +992,11 @@ gothostent: (mci->mci_in = fdopen(s, "r")) == NULL) { syserr("cannot open SMTP client channel, fd=%d", s); + mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); return EX_TEMPFAIL; } + mci_setstat(mci, EX_OK, NULL, NULL); return (EX_OK); } /* diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c index f446f53..c019d2b 100644 --- a/usr.sbin/sendmail/src/deliver.c +++ b/usr.sbin/sendmail/src/deliver.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)deliver.c 8.246 (Berkeley) 10/17/96"; +static char sccsid[] = "@(#)deliver.c 8.251 (Berkeley) 11/11/96"; #endif /* not lint */ #include "sendmail.h" @@ -78,7 +78,7 @@ sendall(e, mode) ENVELOPE *splitenv = NULL; bool oldverbose = Verbose; bool somedeliveries = FALSE; - int pid; + pid_t pid; extern void sendenvelope(); /* @@ -760,7 +760,7 @@ sendenvelope(e, mode) int dofork() { - register int pid = -1; + register pid_t pid = -1; DOFORK(fork); return (pid); @@ -813,11 +813,12 @@ deliver(e, firstto) ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */ int rcode; /* response code */ char *firstsig; /* signature of firstto */ - int pid = -1; + pid_t pid = -1; char *volatile curhost; register volatile u_short port = 0; time_t xstart; bool suidwarn; + bool anyok; /* at least one address was OK */ int mpvect[2]; int rpvect[2]; char *pv[MAXPV+1]; @@ -1314,7 +1315,7 @@ tryhost: if (mci_lock_host(mci) != EX_OK) { - mci->mci_exitstat = EX_TEMPFAIL; + mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); continue; } @@ -1840,6 +1841,7 @@ tryhost: extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *)); extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *)); extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *)); + extern int smtpgetstat __P((MAILER *, MCI *, ENVELOPE *)); /* ** Send the MAIL FROM: protocol @@ -1883,10 +1885,6 @@ tryhost: e->e_to = tobuf + 1; rcode = smtpdata(m, mci, e); } - - /* now close the connection */ - if (!bitset(MCIF_CACHED, mci->mci_flags)) - smtpquit(m, mci, e); } if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0') { @@ -1917,11 +1915,17 @@ tryhost: */ give_up: - if (tobuf[0] != '\0') - giveresponse(rcode, m, mci, ctladdr, xstart, e); - if (rcode == EX_OK) - markstats(e, tochain); - mci_store_persistent(mci); +#ifdef SMTP +# if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + { + tobuf[0] = '\0'; + anyok = FALSE; + } + else +# endif +#endif + anyok = rcode == EX_OK; for (to = tochain; to != NULL; to = to->q_tchain) { @@ -1929,11 +1933,37 @@ tryhost: if (bitset(QBADADDR|QQUEUEUP, to->q_flags)) continue; - /* mark bad addresses */ - if (rcode != EX_OK) +#ifdef SMTP +# if FFR_LMTP + /* if running LMTP, get the status for each address */ + if (bitnset(M_LMTP, m->m_flags)) { - markfailure(e, to, mci, rcode); - continue; + rcode = smtpgetstat(m, mci, e); + if (rcode == EX_OK) + { + strcat(tobuf, ","); + strcat(tobuf, to->q_paddr); + anyok = TRUE; + } + else + { + e->e_to = to->q_paddr; + markfailure(e, to, mci, rcode); + giveresponse(rcode, m, mci, ctladdr, xstart, e); + e->e_to = tobuf + 1; + continue; + } + } + else +# endif +#endif + { + /* mark bad addresses */ + if (rcode != EX_OK) + { + markfailure(e, to, mci, rcode); + continue; + } } /* successful delivery */ @@ -1958,6 +1988,38 @@ tryhost: } } +#ifdef SMTP +# if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + { + /* + ** Global information applies to the last recipient only; + ** clear it out to avoid bogus errors. + */ + + rcode = EX_OK; + e->e_statmsg = NULL; + + /* reset the mci state for the next transaction */ + if (mci->mci_state == MCIS_ACTIVE) + mci->mci_state = MCIS_OPEN; + } +# endif +#endif + + if (tobuf[0] != '\0') + giveresponse(rcode, m, mci, ctladdr, xstart, e); + if (anyok) + markstats(e, tochain); + mci_store_persistent(mci); + +#ifdef SMTP + /* now close the connection */ + if (clever && mci->mci_state != MCIS_CLOSED && + !bitset(MCIF_CACHED, mci->mci_flags)) + smtpquit(m, mci, e); +#endif + /* ** Restore state and return. */ @@ -2142,7 +2204,7 @@ endmailer(mci, e, pv) st = waitfor(mci->mci_pid); if (st == -1) { - syserr("endmailer %s: wait", pv[0]); + syserr("endmailer %s: wait", mci->mci_mailer->m_name); return (EX_SOFTWARE); } @@ -2951,7 +3013,7 @@ mailfile(filename, ctladdr, sfflags, e) register ENVELOPE *e; { register FILE *f; - register int pid = -1; + register pid_t pid = -1; int mode; bool suidwarn = geteuid() == 0; @@ -3146,9 +3208,9 @@ mailfile(filename, ctladdr, sfflags, e) /* reset ISUID & ISGID bits for paranoid systems */ #if HASFCHMOD - (void) fchmod(fileno(f), (int) stb.st_mode); + (void) fchmod(fileno(f), (MODE_T) stb.st_mode); #else - (void) chmod(filename, (int) stb.st_mode); + (void) chmod(filename, (MODE_T) stb.st_mode); #endif (void) xfclose(f, "mailfile", filename); (void) fflush(stdout); @@ -3259,10 +3321,10 @@ hostsignature(m, host, e) /* update the connection info for this host */ mci = mci_get(hp, m); - mci->mci_lastuse = curtime(); - mci->mci_exitstat = rcode; mci->mci_errno = errno; mci->mci_herrno = h_errno; + mci->mci_lastuse = curtime(); + mci_setstat(mci, rcode, NULL, NULL); /* use the original host name as signature */ nmx = 1; diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c index a494baf..9203651 100644 --- a/usr.sbin/sendmail/src/domain.c +++ b/usr.sbin/sendmail/src/domain.c @@ -36,9 +36,9 @@ #ifndef lint #if NAMED_BIND -static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (with name server)"; +static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)"; #else -static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name server)"; +static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)"; #endif #endif /* not lint */ @@ -48,10 +48,23 @@ static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name serve #include <resolv.h> #include <arpa/inet.h> +/* +** The standard udp packet size PACKETSZ (512) is not sufficient for some +** nameserver answers containing very many resource records. The resolver +** may switch to tcp and retry if it detects udp packet overflow. +** Also note that the resolver routines res_query and res_search return +** the size of the *un*truncated answer in case the supplied answer buffer +** it not big enough to accommodate the entire answer. +*/ + +#ifndef MAXPACKET +# define MAXPACKET 8192 /* max packet size used internally by BIND */ +#endif + typedef union { HEADER qb1; - u_char qb2[PACKETSZ]; + u_char qb2[MAXPACKET]; } querybuf; #ifndef MXHOSTBUFSIZE @@ -206,6 +219,10 @@ getmxrr(host, mxhosts, droplocalhost, rcode) return (-1); } + /* avoid problems after truncation in tcp packets */ + if (n > sizeof(answer)) + n = sizeof(answer); + /* find first satisfactory answer */ hp = (HEADER *)&answer; cp = (u_char *)&answer + HFIXEDSZ; @@ -515,7 +532,7 @@ dns_getcanonname(host, hbsize, trymx, statp) int qtype; int loopcnt; char *xp; - char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)]; + char nbuf[MAX(MAXPACKET, MAXDNAME*2+2)]; char *searchlist[MAXDNSRCH+2]; extern char *gethostalias(); @@ -648,6 +665,10 @@ cnameloop: else if (tTd(8, 7)) printf("\tYES\n"); + /* avoid problems after truncation in tcp packets */ + if (ret > sizeof(answer)) + ret = sizeof(answer); + /* ** Appear to have a match. Confirm it by searching for A or ** CNAME records. If we don't have a local domain diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c index 66b9773..80e5ce6 100644 --- a/usr.sbin/sendmail/src/envelope.c +++ b/usr.sbin/sendmail/src/envelope.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)envelope.c 8.93 (Berkeley) 9/26/96"; +static char sccsid[] = "@(#)envelope.c 8.96 (Berkeley) 11/11/96"; #endif /* not lint */ #include "sendmail.h" @@ -153,9 +153,24 @@ dropenvelope(e, fulldrop) e->e_flags &= ~EF_QUEUERUN; for (q = e->e_sendqueue; q != NULL; q = q->q_next) { - if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags) || - bitset(QQUEUEUP, q->q_flags)) + if (bitset(QQUEUEUP, q->q_flags) && + bitset(QDONTSEND, q->q_flags)) + { + /* I'm not sure how this happens..... */ + if (tTd(50, 2)) + { + printf("Bogus flags: "); + printaddr(q, FALSE); + } + q->q_flags &= ~QDONTSEND; + } + if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) queueit = TRUE; +#if XDEBUG + else if (bitset(QQUEUEUP, q->q_flags)) + syslog(LOG_DEBUG, "%s: q_flags = %x", + e->e_id, q->q_flags); +#endif /* see if a notification is needed */ if (bitset(QPINGONFAILURE, q->q_flags) && @@ -203,8 +218,7 @@ dropenvelope(e, fulldrop) 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) || - !bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) + if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) { q->q_flags |= QBADADDR; q->q_status = "4.4.7"; diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c index 8947d11..29b5ac1 100644 --- a/usr.sbin/sendmail/src/main.c +++ b/usr.sbin/sendmail/src/main.c @@ -39,7 +39,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.211 (Berkeley) 10/12/96"; +static char sccsid[] = "@(#)main.c 8.215 (Berkeley) 11/16/96"; #endif /* not lint */ #define _DEFINE @@ -387,12 +387,18 @@ main(argc, argv, envp) OpMode = MD_DELIVER; FullName = getextenv("NAME"); + /* + ** Initialize name server if it is going to be used. + */ + #if NAMED_BIND - if (tTd(8, 8)) - { + if (!bitset(RES_INIT, _res.options)) res_init(); + if (tTd(8, 8)) _res.options |= RES_DEBUG; - } +# ifdef RES_NOALIASES + _res.options |= RES_NOALIASES; +# endif #endif errno = 0; @@ -513,15 +519,7 @@ main(argc, argv, envp) { case MD_DAEMON: case MD_FGDAEMON: -# ifdef DAEMON - if (RealUid != 0) - { - usrerr("Permission denied"); - exit(EX_USAGE); - } - vendor_daemon_setup(CurEnv); - /* fall through ... */ -# else +# ifndef DAEMON usrerr("Daemon mode not implemented"); ExitStat = EX_USAGE; break; @@ -534,8 +532,6 @@ main(argc, argv, envp) # endif /* SMTP */ case MD_INITALIAS: - /* fall through ... */ - case MD_DELIVER: case MD_VERIFY: case MD_TEST: @@ -845,18 +841,6 @@ main(argc, argv, envp) } /* - ** Initialize name server if it is going to be used. - */ - -#if NAMED_BIND - if (UseNameServer && !bitset(RES_INIT, _res.options)) - res_init(); -# ifdef RES_NOALIASES - _res.options |= RES_NOALIASES; -# endif -#endif - - /* ** Do more command line checking -- these are things that ** have to modify the results of reading the config file. */ @@ -897,8 +881,8 @@ main(argc, argv, envp) /* check for sane configuration level */ if (ConfigLevel > MAXCONFIGLEVEL) { - syserr("Warning: .cf version level (%d) exceeds program functionality (%d)", - ConfigLevel, MAXCONFIGLEVEL); + syserr("Warning: .cf version level (%d) exceeds sendmail version %s functionality (%d)", + ConfigLevel, Version, MAXCONFIGLEVEL); } /* need MCI cache to have persistence */ @@ -931,6 +915,19 @@ main(argc, argv, envp) /* fall through ... */ case MD_DAEMON: + /* check for permissions */ + if (RealUid != 0) + { +#ifdef LOG + if (LogLevel > 1) + syslog(LOG_ALERT, "user %d attempted to run daemon", + RealUid); +#endif + usrerr("Permission denied"); + exit(EX_USAGE); + } + vendor_daemon_setup(CurEnv); + /* remove things that don't make sense in daemon mode */ FullName = NULL; GrabTo = FALSE; @@ -1964,6 +1961,15 @@ sighup() syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]); #endif releasesignal(SIGHUP); + if (setgid(RealGid) < 0 || setuid(RealUid) < 0) + { +#ifdef LOG + if (LogLevel > 0) + syslog(LOG_ALERT, "could not set[ug]id(%d, %d): %m", + RealUid, RealGid); +#endif + exit(EX_OSERR); + } execv(SaveArgv[0], (ARGV_T) SaveArgv); #ifdef LOG if (LogLevel > 0) diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c index 796e472..34e6fce 100644 --- a/usr.sbin/sendmail/src/map.c +++ b/usr.sbin/sendmail/src/map.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96"; +static char sccsid[] = "@(#)map.c 8.144 (Berkeley) 11/16/96"; #endif /* not lint */ #include "sendmail.h" @@ -107,7 +107,7 @@ static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96"; extern bool aliaswait __P((MAP *, char *, int)); extern bool extract_canonname __P((char *, char *, char[], int)); -#if defined(O_EXLOCK) && HASFLOCK +#if O_EXLOCK && HASFLOCK # define LOCK_ON_OPEN 1 /* we can open/create a locked file */ #else # define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */ @@ -690,6 +690,8 @@ extract_canonname(name, line, cbuf, cbuflen) p = get_column(line, i, '\0', nbuf, sizeof nbuf); if (p == NULL) break; + if (*p == '\0') + continue; if (cbuf[0] == '\0' || (strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL)) { @@ -1034,17 +1036,30 @@ ndbm_map_close(map) ** be pokey about it. That's hard to do. */ -extern bool db_map_open __P((MAP *, int, DBTYPE)); +extern bool db_map_open __P((MAP *, int, DBTYPE, const void *)); + +/* these should be K line arguments */ +#ifndef DB_CACHE_SIZE +# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */ +#endif +#ifndef DB_HASH_NELEM +# define DB_HASH_NELEM 4096 /* (starting) size of hash table */ +#endif bool bt_map_open(map, mode) MAP *map; int mode; { + BTREEINFO btinfo; + if (tTd(38, 2)) printf("bt_map_open(%s, %s, %d)\n", map->map_mname, map->map_file, mode); - return db_map_open(map, mode, DB_BTREE); + + bzero(&btinfo, sizeof btinfo); + btinfo.cachesize = DB_CACHE_SIZE; + return db_map_open(map, mode, DB_BTREE, &btinfo); } bool @@ -1052,17 +1067,24 @@ hash_map_open(map, mode) MAP *map; int mode; { + HASHINFO hinfo; + if (tTd(38, 2)) printf("hash_map_open(%s, %s, %d)\n", map->map_mname, map->map_file, mode); - return db_map_open(map, mode, DB_HASH); + + bzero(&hinfo, sizeof hinfo); + hinfo.nelem = DB_HASH_NELEM; + hinfo.cachesize = DB_CACHE_SIZE; + return db_map_open(map, mode, DB_HASH, &hinfo); } bool -db_map_open(map, mode, dbtype) +db_map_open(map, mode, dbtype, openinfo) MAP *map; int mode; DBTYPE dbtype; + const void *openinfo; { DB *db; int i; @@ -1113,7 +1135,7 @@ db_map_open(map, mode, dbtype) omode |= O_TRUNC; #endif - db = dbopen(buf, omode, DBMMODE, dbtype, NULL); + db = dbopen(buf, omode, DBMMODE, dbtype, openinfo); saveerrno = errno; #if !LOCK_ON_OPEN diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c index f901ea8..18e951a 100644 --- a/usr.sbin/sendmail/src/mci.c +++ b/usr.sbin/sendmail/src/mci.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)mci.c 8.44 (Berkeley) 10/9/96"; +static char sccsid[] = "@(#)mci.c 8.46 (Berkeley) 11/3/96"; #endif /* not lint */ #include "sendmail.h" @@ -362,6 +362,7 @@ mci_get(host, m) ** ** Parameters: ** mci -- the MCI structure to set. +** xstat -- the exit status code. ** dstat -- the DSN status code. ** rstat -- the SMTP status code. ** @@ -370,18 +371,19 @@ mci_get(host, m) */ void -mci_setstat(mci, dstat, rstat) +mci_setstat(mci, xstat, dstat, rstat) MCI *mci; + int xstat; char *dstat; char *rstat; { + mci->mci_exitstat = xstat; mci->mci_status = dstat; + if (mci->mci_rstatus != NULL) + free(mci->mci_rstatus); if (rstat != NULL) - { - if (mci->mci_rstatus != NULL) - free(mci->mci_rstatus); - mci->mci_rstatus = newstr(rstat); - } + rstat = newstr(rstat); + mci->mci_rstatus = rstat; } /* ** MCI_DUMP -- dump the contents of an MCI structure. @@ -1032,6 +1034,7 @@ mci_print_persistent(pathname, hostname) int status; int width = Verbose ? 78 : 25; bool locked; + char *p; MCI mcib; if (!initflag) @@ -1061,16 +1064,34 @@ mci_print_persistent(pathname, hostname) locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB); fclose(fp); - if (mcib.mci_rstatus == NULL) - printf("%c%-39s %12s %.*s\n", - locked ? '*' : ' ', hostname, - pintvl(curtime() - mcib.mci_lastuse, TRUE), - width, errstring(mcib.mci_errno)); + printf("%c%-39s %12s ", + locked ? '*' : ' ', hostname, + pintvl(curtime() - mcib.mci_lastuse, TRUE)); + if (mcib.mci_rstatus != NULL) + printf("%.*s\n", width, mcib.mci_rstatus); + else if (mcib.mci_exitstat == EX_TEMPFAIL && mcib.mci_errno != 0) + printf("Deferred: %.*s\n", width - 10, errstring(mcib.mci_errno)); + else if (mcib.mci_exitstat != 0) + { + int i = mcib.mci_exitstat - EX__BASE; + extern int N_SysEx; + extern char *SysExMsg[]; + + if (i < 0 || i > N_SysEx) + { + char buf[80]; + + snprintf(buf, sizeof buf, "Unknown mailer error %d", + mcib.mci_exitstat); + printf("%.*s\n", width, buf); + } + else + printf("%.*s\n", width, &(SysExMsg[i])[5]); + } + else if (mcib.mci_errno == 0) + printf("OK\n"); else - printf("%c%-39s %12s %.*s\n", - locked ? '*' : ' ', hostname, - pintvl(curtime() - mcib.mci_lastuse, TRUE), - width, mcib.mci_rstatus); + printf("OK: %.*s\n", width - 4, errstring(mcib.mci_errno)); return 0; } diff --git a/usr.sbin/sendmail/src/mime.c b/usr.sbin/sendmail/src/mime.c index 670a6cd..9ee726a 100644 --- a/usr.sbin/sendmail/src/mime.c +++ b/usr.sbin/sendmail/src/mime.c @@ -36,7 +36,7 @@ # include <string.h> #ifndef lint -static char sccsid[] = "@(#)mime.c 8.48 (Berkeley) 10/18/96"; +static char sccsid[] = "@(#)mime.c 8.49 (Berkeley) 10/30/96"; #endif /* not lint */ /* @@ -932,9 +932,23 @@ isboundary(line, boundaries) ** none. */ -extern void mime_from64 __P((u_char *, u_char *, int)); extern int mime_fromqp __P((u_char *, u_char **, int, int)); +static char index_64[128] = +{ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; + +#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) + + void mime7to8(mci, header, e) register MCI *mci; @@ -996,29 +1010,82 @@ mime7to8(mci, header, e) if (strcasecmp(cte, "base64") == 0) { + int nchar = 0; + int c1, c2, c3, c4; + fbufp = fbuf; - while (fgets(buf, sizeof buf, e->e_dfp) != NULL) + while ((c1 = fgetc(e->e_dfp)) != EOF) { - obufp = obuf; - mime_from64((u_char *) buf, obuf, MAXLINE); - while ((ch = *obufp++) != '\0') + if (isascii(c1) && isspace(c1)) + continue; + + do { - *fbufp++ = ch; - if (ch == '\n' || fbufp >= &fbuf[MAXLINE]) - { - *fbufp = '\0'; - putline((char *) fbuf, mci); - fbufp = fbuf; - } - } + c2 = fgetc(e->e_dfp); + } while (isascii(c2) && isspace(c2)); + if (c2 == EOF) + break; - /* force out partial last line */ - if (fbufp > fbuf) + do { + c3 = fgetc(e->e_dfp); + } while (isascii(c3) && isspace(c3)); + if (c3 == EOF) + break; + + do + { + c4 = fgetc(e->e_dfp); + } while (isascii(c4) && isspace(c4)); + if (c4 == EOF) + break; + + if (c1 == '=' || c2 == '=') + continue; + c1 = CHAR64(c1); + c2 = CHAR64(c2); + + *fbufp = (c1 << 2) | ((c2 & 0x30) >> 4); + if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE]) + { + if (*--fbufp != '\n' || *--fbufp != '\r') + fbufp++; + *fbufp = '\0'; + putline((char *) fbuf, mci); + fbufp = fbuf; + } + if (c3 == '=') + continue; + c3 = CHAR64(c3); + *fbufp = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); + if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE]) + { + if (*--fbufp != '\n' || *--fbufp != '\r') + fbufp++; + *fbufp = '\0'; + putline((char *) fbuf, mci); + fbufp = fbuf; + } + if (c4 == '=') + continue; + c4 = CHAR64(c4); + *fbufp = ((c3 & 0x03) << 6) | c4; + if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE]) + { + if (*--fbufp != '\n' || *--fbufp != '\r') + fbufp++; *fbufp = '\0'; putline((char *) fbuf, mci); + fbufp = fbuf; } } + + /* force out partial last line */ + if (fbufp > fbuf) + { + *fbufp = '\0'; + putline((char *) fbuf, mci); + } } else { @@ -1113,89 +1180,5 @@ mime_fromqp(infile, outfile, state, maxlen) return 1; } -static char index_64[128] = -{ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -}; - -#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) - -void -mime_from64(infile, outfile, maxlen) - u_char *infile; - u_char *outfile; - int maxlen; -{ - int nchar = 0; - int c1, c2, c3, c4; - - while ((c1 = *infile++) != '\0') - { - if (isascii(c1) && isspace(c1)) - continue; - - do - { - c2 = *infile++; - } while (isascii(c2) && isspace(c2)); - if (c2 == '\0') - break; - - do - { - c3 = *infile++; - } while (isascii(c3) && isspace(c3)); - if (c3 == '\0') - break; - - do - { - c4 = *infile++; - } while (isascii(c4) && isspace(c4)); - if (c4 == '\0') - break; - - if (c1 == '=' || c2 == '=') - { - continue; - } - c1 = CHAR64(c1); - c2 = CHAR64(c2); - - if (++nchar > maxlen) - break; - - *outfile++ = (c1 << 2) | ((c2 & 0x30) >> 4); - - if (c3 != '=') - { - c3 = CHAR64(c3); - - if (++nchar > maxlen) - break; - - *outfile++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); - if (c4 != '=') - { - c4 = CHAR64(c4); - - if (++nchar > maxlen) - break; - - *outfile++ = ((c3 & 0x03) << 6) | c4; - } - } - } - - *outfile = '\0'; - return; -} #endif /* MIME7TO8 */ diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c index 75263b7..299a016 100644 --- a/usr.sbin/sendmail/src/queue.c +++ b/usr.sbin/sendmail/src/queue.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef QUEUE -static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (with queueing)"; +static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (with queueing)"; #else -static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (without queueing)"; +static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (without queueing)"; #endif #endif /* not lint */ @@ -296,40 +296,45 @@ queueup(e, announce) printctladdr(NULL, NULL); for (q = e->e_sendqueue; q != NULL; q = q->q_next) { - if (bitset(QQUEUEUP, q->q_flags) || - !bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags)) + if (bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags)) { - printctladdr(q, tfp); - if (q->q_orcpt != NULL) - fprintf(tfp, "Q%s\n", - denlstring(q->q_orcpt, TRUE, FALSE)); - putc('R', tfp); - if (bitset(QPRIMARY, q->q_flags)) - putc('P', tfp); - if (bitset(QHASNOTIFY, q->q_flags)) - putc('N', tfp); - if (bitset(QPINGONSUCCESS, q->q_flags)) - putc('S', tfp); - if (bitset(QPINGONFAILURE, q->q_flags)) - putc('F', tfp); - if (bitset(QPINGONDELAY, q->q_flags)) - putc('D', tfp); - putc(':', tfp); - fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE)); - if (announce) - { - e->e_to = q->q_paddr; - message("queued"); - if (LogLevel > 8) - logdelivery(q->q_mailer, NULL, "queued", - NULL, (time_t) 0, e); - e->e_to = NULL; - } - if (tTd(40, 1)) - { - printf("queueing "); - printaddr(q, FALSE); - } +#if XDEBUG + if (bitset(QQUEUEUP, q->q_flags)) + syslog(LOG_DEBUG, "%s: q_flags = %x", + e->e_id, q->q_flags); +#endif + continue; + } + printctladdr(q, tfp); + if (q->q_orcpt != NULL) + fprintf(tfp, "Q%s\n", + denlstring(q->q_orcpt, TRUE, FALSE)); + putc('R', tfp); + if (bitset(QPRIMARY, q->q_flags)) + putc('P', tfp); + if (bitset(QHASNOTIFY, q->q_flags)) + putc('N', tfp); + if (bitset(QPINGONSUCCESS, q->q_flags)) + putc('S', tfp); + if (bitset(QPINGONFAILURE, q->q_flags)) + putc('F', tfp); + if (bitset(QPINGONDELAY, q->q_flags)) + putc('D', tfp); + putc(':', tfp); + fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE)); + if (announce) + { + e->e_to = q->q_paddr; + message("queued"); + if (LogLevel > 8) + logdelivery(q->q_mailer, NULL, "queued", + NULL, (time_t) 0, e); + e->e_to = NULL; + } + if (tTd(40, 1)) + { + printf("queueing "); + printaddr(q, FALSE); } } @@ -574,7 +579,7 @@ runqueue(forkflag) if (forkflag) { - int pid; + pid_t pid; extern void intsig(); #ifdef SIGCHLD extern void reapchild(); @@ -625,6 +630,15 @@ runqueue(forkflag) /* force it to run expensive jobs */ NoConnect = FALSE; + /* drop privileges */ + if (geteuid() == (uid_t) 0) + { + if (RunAsGid != (gid_t) 0) + (void) setgid(RunAsGid); + if (RunAsUid != (uid_t) 0) + (void) setuid(RunAsUid); + } + /* ** Create ourselves an envelope */ @@ -1387,6 +1401,7 @@ readqf(e) struct stat st; char *bp; int qfver = 0; + long hdrsize = 0; register char *p; char *orcpt = NULL; bool nomore = FALSE; @@ -1579,6 +1594,7 @@ readqf(e) case 'H': /* header */ (void) chompheader(&bp[1], FALSE, NULL, e); + hdrsize += strlen(&bp[1]); break; case 'M': /* message */ @@ -1611,6 +1627,26 @@ readqf(e) case 'N': /* number of delivery attempts */ e->e_ntries = atoi(&buf[1]); + + /* if this has been tried recently, let it be */ + if (e->e_ntries > 0 && + (curtime() - e->e_dtime) < MinQueueAge) + { + char *howlong = pintvl(curtime() - e->e_dtime, TRUE); + extern void unlockqueue(); + + if (Verbose || tTd(40, 8)) + printf("%s: too young (%s)\n", + e->e_id, howlong); +#ifdef LOG + if (LogLevel > 19) + syslog(LOG_DEBUG, "%s: too young (%s)", + e->e_id, howlong); +#endif + e->e_id = NULL; + unlockqueue(e); + return FALSE; + } break; case 'P': /* message priority */ @@ -1694,25 +1730,6 @@ readqf(e) return TRUE; } - /* if this has been tried recently, let it be */ - if (e->e_ntries > 0 && (curtime() - e->e_dtime) < MinQueueAge) - { - char *howlong = pintvl(curtime() - e->e_dtime, TRUE); - extern void unlockqueue(); - - if (Verbose || tTd(40, 8)) - printf("%s: too young (%s)\n", - e->e_id, howlong); -#ifdef LOG - if (LogLevel > 19) - syslog(LOG_DEBUG, "%s: too young (%s)", - e->e_id, howlong); -#endif - e->e_id = NULL; - unlockqueue(e); - return FALSE; - } - /* ** Arrange to read the data file. */ @@ -1728,7 +1745,7 @@ readqf(e) e->e_flags |= EF_HAS_DF; if (fstat(fileno(e->e_dfp), &st) >= 0) { - e->e_msgsize = st.st_size; + e->e_msgsize = st.st_size + hdrsize; e->e_dfdev = st.st_dev; e->e_dfino = st.st_ino; } @@ -1971,7 +1988,7 @@ queuename(e, type) register ENVELOPE *e; int type; { - static int pid = -1; + static pid_t pid = -1; static char c0; static char c1; static char c2; diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c index e3cb3a1..c95a6f3 100644 --- a/usr.sbin/sendmail/src/readcf.c +++ b/usr.sbin/sendmail/src/readcf.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)readcf.c 8.174 (Berkeley) 10/9/96"; +static char sccsid[] = "@(#)readcf.c 8.176 (Berkeley) 11/10/96"; #endif /* not lint */ # include "sendmail.h" @@ -715,7 +715,7 @@ fileclass(class, filename, fmt, safe, optional) { FILE *f; int sff; - int pid; + pid_t pid; register char *p; char buf[MAXLINE]; @@ -1024,6 +1024,10 @@ makemailer(line) m->m_uid = strtol(p, &q, 0); p = q; + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '\0') + p++; } while (isascii(*p) && isspace(*p)) p++; diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h index 62b0bb9..2dc30e4 100644 --- a/usr.sbin/sendmail/src/sendmail.h +++ b/usr.sbin/sendmail/src/sendmail.h @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)sendmail.h 8.206 (Berkeley) 10/17/96 + * @(#)sendmail.h 8.209 (Berkeley) 11/8/96 */ /* @@ -41,7 +41,7 @@ # ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailSccsId[] = "@(#)sendmail.h 8.206 10/17/96"; +static char SmailSccsId[] = "@(#)sendmail.h 8.209 11/8/96"; # endif # else /* _DEFINE */ # define EXTERN extern @@ -275,6 +275,7 @@ struct mailer # define M_HASPWENT 'w' /* check for /etc/passwd entry */ /* 'x' CF: include Full-Name: */ # define M_XDOT 'X' /* use hidden-dot algorithm */ +# define M_LMTP 'z' /* run Local Mail Transport Protocol */ # define M_NOMX '0' /* turn off MX lookups */ # define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */ # define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */ @@ -310,7 +311,7 @@ MCI long mci_maxsize; /* max size this server will accept */ FILE *mci_in; /* input side of connection */ FILE *mci_out; /* output side of connection */ - int mci_pid; /* process id of subordinate proc */ + pid_t mci_pid; /* process id of subordinate proc */ char *mci_phase; /* SMTP phase string */ struct mailer *mci_mailer; /* ptr to the mailer for this conn */ char *mci_host; /* host name */ @@ -1095,7 +1096,7 @@ EXTERN gid_t RealGid; /* real gid of caller */ EXTERN uid_t DefUid; /* default uid to run as */ EXTERN gid_t DefGid; /* default gid to run as */ EXTERN char *DefUser; /* default user to run as (from DefUid) */ -EXTERN int OldUmask; /* umask when sendmail starts up */ +EXTERN MODE_T OldUmask; /* umask when sendmail starts up */ EXTERN int Errors; /* set if errors (local to single pass) */ EXTERN int ExitStat; /* exit status code */ EXTERN int LineNumber; /* line number in current input */ @@ -1303,7 +1304,7 @@ extern void inittimeouts __P((char *)); extern void logdelivery __P((MAILER *, MCI *, const char *, ADDRESS *, time_t, ENVELOPE *)); extern void giveresponse __P((int, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *)); extern void buildfname __P((char *, char *, char *, int)); -extern void mci_setstat __P((MCI *, char *, char *)); +extern void mci_setstat __P((MCI *, int, char *, char *)); extern char *smtptodsn __P((int)); extern int rscheck __P((char *, char *, char *, ENVELOPE *e)); extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *)); diff --git a/usr.sbin/sendmail/src/srvrsmtp.c b/usr.sbin/sendmail/src/srvrsmtp.c index cda3ca8..062acde 100644 --- a/usr.sbin/sendmail/src/srvrsmtp.c +++ b/usr.sbin/sendmail/src/srvrsmtp.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (with SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (with SMTP)"; #else -static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (without SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (without SMTP)"; #endif #endif /* not lint */ @@ -1270,10 +1270,20 @@ runinchild(label, e) char *label; register ENVELOPE *e; { - int childpid; + pid_t childpid; + sigfunc_t chldsig; if (!OneXact) { + /* + ** Disable child process reaping, in case ETRN has preceeded + ** MAIL command. + */ + +#ifdef SIGCHLD + chldsig = setsignal(SIGCHLD, SIG_IGN); +#endif + childpid = dofork(); if (childpid < 0) { @@ -1300,6 +1310,11 @@ runinchild(label, e) finis(); } +#ifdef SIGCHLD + /* restore the child signal */ + (void) setsignal(SIGCHLD, chldsig); +#endif + return (1); } else diff --git a/usr.sbin/sendmail/src/usersmtp.c b/usr.sbin/sendmail/src/usersmtp.c index 1b684fb..1be0d84 100644 --- a/usr.sbin/sendmail/src/usersmtp.c +++ b/usr.sbin/sendmail/src/usersmtp.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (with SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (with SMTP)"; #else -static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (without SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (without SMTP)"; #endif #endif /* not lint */ @@ -143,8 +143,10 @@ smtpinit(m, mci, e) SmtpPhase = mci->mci_phase = "client greeting"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check); - if (r < 0 || REPLYTYPE(r) == 4) + if (r < 0) goto tempfail1; + if (REPLYTYPE(r) == 4) + goto tempfail2; if (REPLYTYPE(r) != 2) goto unavailable; @@ -153,11 +155,24 @@ smtpinit(m, mci, e) ** My mother taught me to always introduce myself. */ +#if FFR_LMTP + if (bitnset(M_ESMTP, m->m_flags) || bitnset(M_LMTP, m->m_flags)) +#else if (bitnset(M_ESMTP, m->m_flags)) +#endif mci->mci_flags |= MCIF_ESMTP; tryhelo: +#if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + { + smtpmessage("LHLO %s", m, mci, MyHostName); + SmtpPhase = mci->mci_phase = "client LHLO"; + } + else if (bitset(MCIF_ESMTP, mci->mci_flags)) +#else if (bitset(MCIF_ESMTP, mci->mci_flags)) +#endif { smtpmessage("EHLO %s", m, mci, MyHostName); SmtpPhase = mci->mci_phase = "client EHLO"; @@ -173,7 +188,12 @@ tryhelo: goto tempfail1; else if (REPLYTYPE(r) == 5) { +#if FFR_LMTP + if (bitset(MCIF_ESMTP, mci->mci_flags) && + !bitnset(M_LMTP, m->m_flags)) +#else if (bitset(MCIF_ESMTP, mci->mci_flags)) +#endif { /* try old SMTP instead */ mci->mci_flags &= ~MCIF_ESMTP; @@ -182,7 +202,7 @@ tryhelo: goto unavailable; } else if (REPLYTYPE(r) != 2) - goto tempfail1; + goto tempfail2; /* ** Check to see if we actually ended up talking to ourself. @@ -194,11 +214,14 @@ tryhelo: if (p != NULL) *p = '\0'; if (!bitnset(M_NOLOOPCHECK, m->m_flags) && +#if FFR_LMTP + !bitnset(M_LMTP, m->m_flags) && +#endif strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0) { syserr("553 %s config error: mail loops back to me (MX problem?)", mci->mci_host); - mci->mci_exitstat = EX_CONFIG; + mci_setstat(mci, EX_CONFIG, NULL, NULL); mci->mci_errno = 0; smtpquit(m, mci, e); return; @@ -215,7 +238,7 @@ tryhelo: smtpmessage("VERB", m, mci); r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); if (r < 0) - goto tempfail2; + goto tempfail1; } if (mci->mci_state != MCIS_CLOSED) @@ -227,17 +250,25 @@ tryhelo: /* got a 421 error code during startup */ tempfail1: + if (mci->mci_errno == 0) + mci->mci_errno = errno; + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); + if (mci->mci_state != MCIS_CLOSED) + smtpquit(m, mci, e); + return; + tempfail2: - mci->mci_exitstat = EX_TEMPFAIL; if (mci->mci_errno == 0) mci->mci_errno = errno; + /* XXX should use code from other end iff ENHANCEDSTATUSCODES */ + mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer); if (mci->mci_state != MCIS_CLOSED) smtpquit(m, mci, e); return; unavailable: - mci->mci_exitstat = EX_UNAVAILABLE; mci->mci_errno = errno; + mci_setstat(mci, EX_UNAVAILABLE, "5.5.0", SmtpReplyBuffer); smtpquit(m, mci, e); return; } @@ -387,7 +418,7 @@ smtpmailfrom(m, mci, e) extern char MsgBuf[]; usrerr("%s does not support 8BITMIME", mci->mci_host); - mci_setstat(mci, "5.6.3", MsgBuf); + mci_setstat(mci, EX_DATAERR, "5.6.3", MsgBuf); return EX_DATAERR; } @@ -447,17 +478,24 @@ smtpmailfrom(m, mci, e) SmtpPhase = mci->mci_phase = "client MAIL"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); r = reply(m, mci, e, TimeOuts.to_mail, NULL); - if (r < 0 || r == 421) + if (r < 0) { - /* communications failure/service shutting down */ - mci->mci_exitstat = EX_TEMPFAIL; + /* communications failure */ mci->mci_errno = errno; + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + else if (r == 421) + { + /* service shutting down */ + mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer); smtpquit(m, mci, e); return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 4) { - mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer); + mci_setstat(mci, EX_TEMPFAIL, smtptodsn(r), SmtpReplyBuffer); return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 2) @@ -467,25 +505,25 @@ smtpmailfrom(m, mci, e) else if (r == 501) { /* syntax error in arguments */ - mci_setstat(mci, "5.5.2", SmtpReplyBuffer); + mci_setstat(mci, EX_DATAERR, "5.5.2", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 553) { /* mailbox name not allowed */ - mci_setstat(mci, "5.1.3", SmtpReplyBuffer); + mci_setstat(mci, EX_DATAERR, "5.1.3", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 552) { /* exceeded storage allocation */ - mci_setstat(mci, "5.2.2", SmtpReplyBuffer); + mci_setstat(mci, EX_UNAVAILABLE, "5.2.2", SmtpReplyBuffer); return EX_UNAVAILABLE; } else if (REPLYTYPE(r) == 5) { /* unknown error */ - mci_setstat(mci, "5.0.0", SmtpReplyBuffer); + mci_setstat(mci, EX_UNAVAILABLE, "5.0.0", SmtpReplyBuffer); return EX_UNAVAILABLE; } @@ -499,7 +537,7 @@ smtpmailfrom(m, mci, e) #endif /* protocol error -- close up */ - mci_setstat(mci, "5.5.1", SmtpReplyBuffer); + mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer); smtpquit(m, mci, e); return EX_PROTOCOL; } @@ -536,7 +574,8 @@ smtprcpt(to, m, mci, e) { /* NOTIFY= parameter */ if (bitset(QHASNOTIFY, to->q_flags) && - bitset(QPRIMARY, to->q_flags)) + bitset(QPRIMARY, to->q_flags) && + !bitnset(M_LOCALMAILER, m->m_flags)) { bool firstone = TRUE; @@ -622,6 +661,7 @@ smtprcpt(to, m, mci, e) ** ** Parameters: ** m -- mailer being sent to. +** mci -- the mailer connection information. ** e -- the envelope for this message. ** ** Returns: @@ -642,6 +682,7 @@ smtpdata(m, mci, e) { register int r; register EVENT *ev; + int rstat; time_t timeout; /* @@ -690,8 +731,8 @@ smtpdata(m, mci, e) if (setjmp(CtxDataTimeout) != 0) { mci->mci_errno = errno; - mci->mci_exitstat = EX_TEMPFAIL; mci->mci_state = MCIS_ERROR; + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); syserr("451 timeout writing message to %s", mci->mci_host); smtpquit(m, mci, e); return EX_TEMPFAIL; @@ -720,8 +761,8 @@ smtpdata(m, mci, e) { /* error during processing -- don't send the dot */ mci->mci_errno = EIO; - mci->mci_exitstat = EX_IOERR; mci->mci_state = MCIS_ERROR; + mci_setstat(mci, EX_IOERR, "4.4.2", NULL); smtpquit(m, mci, e); return EX_IOERR; } @@ -734,8 +775,12 @@ smtpdata(m, mci, e) nmessage(">>> ."); /* check for the results of the transaction */ - SmtpPhase = mci->mci_phase = "client DATA 250"; + SmtpPhase = mci->mci_phase = "client DATA status"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); +#if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + return EX_OK; +#endif r = reply(m, mci, e, TimeOuts.to_datafinal, NULL); if (r < 0) { @@ -743,16 +788,22 @@ smtpdata(m, mci, e) return EX_TEMPFAIL; } mci->mci_state = MCIS_OPEN; - mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer); - e->e_statmsg = newstr(&SmtpReplyBuffer[4]); if (REPLYTYPE(r) == 4) - return EX_TEMPFAIL; + rstat = EX_TEMPFAIL; else if (REPLYCLASS(r) != 5) - /* fall through */ ; + rstat = EX_PROTOCOL; else if (REPLYTYPE(r) == 2) - return EX_OK; + rstat = EX_OK; else if (REPLYTYPE(r) == 5) - return EX_UNAVAILABLE; + rstat = EX_UNAVAILABLE; + else + rstat = EX_PROTOCOL; + mci_setstat(mci, rstat, smtptodsn(r), SmtpReplyBuffer); + if (e->e_statmsg != NULL) + free(e->e_statmsg); + e->e_statmsg = newstr(&SmtpReplyBuffer[4]); + if (rstat != EX_PROTOCOL) + return rstat; #ifdef LOG if (LogLevel > 1) { @@ -761,7 +812,7 @@ smtpdata(m, mci, e) shortenstring(SmtpReplyBuffer, 403)); } #endif - return EX_PROTOCOL; + return rstat; } @@ -771,10 +822,66 @@ datatimeout() longjmp(CtxDataTimeout, 1); } /* +** SMTPGETSTAT -- get status code from DATA in LMTP +** +** Parameters: +** m -- the mailer to which we are sending the message. +** mci -- the mailer connection structure. +** e -- the current envelope. +** +** Returns: +** The exit status corresponding to the reply code. +*/ + +#if FFR_LMTP + +int +smtpgetstat(m, mci, e) + MAILER *m; + MCI *mci; + ENVELOPE *e; +{ + int r; + int stat; + + /* check for the results of the transaction */ + r = reply(m, mci, e, TimeOuts.to_datafinal, NULL); + if (r < 0) + { + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + if (e->e_statmsg != NULL) + free(e->e_statmsg); + e->e_statmsg = newstr(&SmtpReplyBuffer[4]); + if (REPLYTYPE(r) == 4) + stat = EX_TEMPFAIL; + else if (REPLYCLASS(r) != 5) + stat = EX_PROTOCOL; + else if (REPLYTYPE(r) == 2) + stat = EX_OK; + else if (REPLYTYPE(r) == 5) + stat = EX_UNAVAILABLE; + mci_setstat(mci, stat, smtptodsn(r), SmtpReplyBuffer); +#ifdef LOG + if (LogLevel > 1 && stat == EX_PROTOCOL) + { + syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-3 protocol error: %s", + e->e_id, mci->mci_host, + shortenstring(SmtpReplyBuffer, 403)); + } +#endif + return stat; +} + +#endif +/* ** SMTPQUIT -- close the SMTP connection. ** ** Parameters: ** m -- a pointer to the mailer. +** mci -- the mailer connection information. +** e -- the current envelope. ** ** Returns: ** none. @@ -927,6 +1034,7 @@ reply(m, mci, e, timeout, pfunc) if (p == NULL) { bool oldholderrs; + extern char MsgBuf[]; /* if the remote end closed early, fake an error */ if (errno == 0) @@ -937,10 +1045,10 @@ reply(m, mci, e, timeout, pfunc) # endif /* ECONNRESET */ mci->mci_errno = errno; - mci->mci_exitstat = EX_TEMPFAIL; oldholderrs = HoldErrs; HoldErrs = TRUE; usrerr("451 reply: read error from %s", mci->mci_host); + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf); /* if debugging, pause so we can see state */ if (tTd(18, 100)) diff --git a/usr.sbin/sendmail/src/util.c b/usr.sbin/sendmail/src/util.c index 49d2a65..822aaf35 100644 --- a/usr.sbin/sendmail/src/util.c +++ b/usr.sbin/sendmail/src/util.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)util.c 8.105 (Berkeley) 10/12/96"; +static char sccsid[] = "@(#)util.c 8.109 (Berkeley) 11/16/96"; #endif /* not lint */ # include "sendmail.h" @@ -1012,6 +1012,15 @@ putxline(l, mci, pxflags) if (TrafficLogFile != NULL) (void) putc('.', TrafficLogFile); } + else if (l[0] == 'F' && slop == 0 && + bitset(PXLF_MAPFROM, pxflags) && + strncmp(l, "From ", 5) == 0 && + bitnset(M_ESCFROM, mci->mci_mailer->m_flags)) + { + (void) putc('>', mci->mci_out); + if (TrafficLogFile != NULL) + (void) putc('>', TrafficLogFile); + } if (TrafficLogFile != NULL) fprintf(TrafficLogFile, "%.*s\n", p - l, l); for ( ; l < p; ++l) @@ -2197,6 +2206,7 @@ proc_list_add(pid) pid_t pid; { int i; + extern void proc_list_probe __P((void)); for (i = 0; i < ProcListSize; i++) { @@ -2205,6 +2215,18 @@ proc_list_add(pid) } if (i >= ProcListSize) { + /* probe the existing vector to avoid growing infinitely */ + proc_list_probe(); + + /* now scan again */ + for (i = 0; i < ProcListSize; i++) + { + if (ProcListVec[i] == NO_PID) + break; + } + } + if (i >= ProcListSize) + { /* grow process list */ pid_t *npv; @@ -2244,8 +2266,42 @@ proc_list_drop(pid) if (ProcListVec[i] == pid) { ProcListVec[i] = NO_PID; - CurChildren--; break; } } + if (CurChildren > 0) + CurChildren--; +} +/* +** PROC_LIST_PROBE -- probe processes in the list to see if they still exist +** +** Parameters: +** none +** +** Returns: +** none +*/ + +void +proc_list_probe() +{ + int i; + + for (i = 0; i < ProcListSize; i++) + { + if (ProcListVec[i] == NO_PID) + continue; + if (kill(ProcListVec[i], 0) < 0) + { +#ifdef LOG + if (LogLevel > 3) + syslog(LOG_DEBUG, "proc_list_probe: lost pid %d", + ProcListVec[i]); +#endif + ProcListVec[i] = NO_PID; + CurChildren--; + } + } + if (CurChildren < 0) + CurChildren = 0; } diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c index 7544a9a..8a53f29 100644 --- a/usr.sbin/sendmail/src/version.c +++ b/usr.sbin/sendmail/src/version.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)version.c 8.8.2.1 (Berkeley) 10/18/96"; +static char sccsid[] = "@(#)version.c 8.8.3.2 (Berkeley) 11/16/96"; #endif /* not lint */ -char Version[] = "8.8.2"; +char Version[] = "8.8.3"; |