summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src
diff options
context:
space:
mode:
authorgshapiro <gshapiro@FreeBSD.org>2006-03-22 16:40:03 +0000
committergshapiro <gshapiro@FreeBSD.org>2006-03-22 16:40:03 +0000
commitef9770707c0f88e94a0c4a409f8fb74cea250716 (patch)
treef3bd1c133ce6e698fd2ff3c0280c7103bfac7af3 /contrib/sendmail/src
parent3f99651e549f30e601bcde5ce7907ee58c365442 (diff)
downloadFreeBSD-src-ef9770707c0f88e94a0c4a409f8fb74cea250716.zip
FreeBSD-src-ef9770707c0f88e94a0c4a409f8fb74cea250716.tar.gz
Import sendmail 8.13.6
Security: FreeBSD-SA-06:13.sendmail
Diffstat (limited to 'contrib/sendmail/src')
-rw-r--r--contrib/sendmail/src/README10
-rw-r--r--contrib/sendmail/src/TRACEFLAGS4
-rw-r--r--contrib/sendmail/src/collect.c179
-rw-r--r--contrib/sendmail/src/conf.c140
-rw-r--r--contrib/sendmail/src/conf.h53
-rw-r--r--contrib/sendmail/src/daemon.c28
-rw-r--r--contrib/sendmail/src/deliver.c299
-rw-r--r--contrib/sendmail/src/envelope.c17
-rw-r--r--contrib/sendmail/src/headers.c69
-rw-r--r--contrib/sendmail/src/helpfile10
-rw-r--r--contrib/sendmail/src/main.c31
-rw-r--r--contrib/sendmail/src/map.c14
-rw-r--r--contrib/sendmail/src/mci.c13
-rw-r--r--contrib/sendmail/src/milter.c50
-rw-r--r--contrib/sendmail/src/mime.c124
-rw-r--r--contrib/sendmail/src/parseaddr.c16
-rw-r--r--contrib/sendmail/src/queue.c70
-rw-r--r--contrib/sendmail/src/ratectrl.c4
-rw-r--r--contrib/sendmail/src/readcf.c67
-rw-r--r--contrib/sendmail/src/savemail.c261
-rw-r--r--contrib/sendmail/src/sendmail.h52
-rw-r--r--contrib/sendmail/src/sfsasl.c236
-rw-r--r--contrib/sendmail/src/sfsasl.h6
-rw-r--r--contrib/sendmail/src/srvrsmtp.c251
-rw-r--r--contrib/sendmail/src/timers.c4
-rw-r--r--contrib/sendmail/src/tls.c29
-rw-r--r--contrib/sendmail/src/udb.c10
-rw-r--r--contrib/sendmail/src/usersmtp.c105
-rw-r--r--contrib/sendmail/src/util.c104
-rw-r--r--contrib/sendmail/src/version.c6
30 files changed, 1375 insertions, 887 deletions
diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README
index 0440657..b393613 100644
--- a/contrib/sendmail/src/README
+++ b/contrib/sendmail/src/README
@@ -9,7 +9,7 @@
# the sendmail distribution.
#
#
-# $Id: README,v 8.386 2005/03/04 23:24:08 ca Exp $
+# $Id: README,v 8.388 2005/07/26 05:45:39 ca Exp $
#
This directory contains the source files for sendmail(TM).
@@ -502,6 +502,12 @@ NEEDINTERRNO Set this if <errno.h> does not declare errno, i.e., if an
extern int errno;
USE_TTYPATH Set this to 1 to enable ErrorMode=write.
USESYSCTL Use sysctl(3) to determine the number of CPUs in a system.
+HASSNPRINTF Set this to 1 if your OS has a working snprintf(3), i.e.,
+ it properly obeys the size of the buffer and returns the
+ number of characters that would have been printed if the
+ size were unlimited.
+LDAP_REFERRALS Set this if you want to use the -R flag (do not auto chase
+ referrals) for LDAP maps (requires -DLDAPMAP).
+-----------------------+
@@ -1826,4 +1832,4 @@ util.c Some general purpose routines used by sendmail.
version.c The version number and information about this
version of sendmail.
-(Version $Revision: 8.386 $, last update $Date: 2005/03/04 23:24:08 $ )
+(Version $Revision: 8.388 $, last update $Date: 2005/07/26 05:45:39 $ )
diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS
index 3e0a14c..820cf20 100644
--- a/contrib/sendmail/src/TRACEFLAGS
+++ b/contrib/sendmail/src/TRACEFLAGS
@@ -1,4 +1,4 @@
-# $Id: TRACEFLAGS,v 8.43 2005/02/16 23:38:51 ca Exp $
+# $Id: TRACEFLAGS,v 8.44 2006/02/27 18:52:41 ca Exp $
0, 4 main.c main canonical name, UUCP node name, a.k.a.s
0, 15 main.c main print configuration
0, 44 util.c printav print address of each string
@@ -86,6 +86,8 @@
73 queue.c shared memory updates
80 content length
81 sun remote mode
+83 collect.c timeout
+84 deliver.c timeout
91 mci.c syslogging of MCI cache information
93,>99 * Prevent daemon connection fork for profiling/debugging
94,>99 srvrsmtp.c cause commands to fail (for protocol testing)
diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c
index 101bcd0..0bfe3f2 100644
--- a/contrib/sendmail/src/collect.c
+++ b/contrib/sendmail/src/collect.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,9 +13,8 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: collect.c,v 8.261 2005/02/16 23:38:51 ca Exp $")
+SM_RCSID("@(#)$Id: collect.c,v 8.272 2006/03/02 19:09:26 ca Exp $")
-static void collecttimeout __P((int));
static void eatfrom __P((char *volatile, ENVELOPE *));
static void collect_doheader __P((ENVELOPE *));
static SM_FILE_T *collect_dfopen __P((ENVELOPE *));
@@ -263,10 +262,6 @@ collect_dfopen(e)
** If data file cannot be created, the process is terminated.
*/
-static jmp_buf CtxCollectTimeout;
-static bool volatile CollectProgress;
-static SM_EVENT *volatile CollectTimeout = NULL;
-
/* values for input state machine */
#define IS_NORM 0 /* middle of line */
#define IS_BOL 1 /* beginning of line */
@@ -288,27 +283,31 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
register ENVELOPE *e;
bool rsetsize;
{
- register SM_FILE_T *volatile df;
- volatile bool ignrdot;
- volatile int dbto;
- register char *volatile bp;
- volatile int c;
- volatile bool inputerr;
+ register SM_FILE_T *df;
+ bool ignrdot;
+ int dbto;
+ register char *bp;
+ int c;
+ bool inputerr;
bool headeronly;
- char *volatile buf;
- volatile int buflen;
- volatile int istate;
- volatile int mstate;
- volatile int hdrslen;
- volatile int numhdrs;
- volatile int afd;
- unsigned char *volatile pbp;
+ char *buf;
+ int buflen;
+ int istate;
+ int mstate;
+ int hdrslen;
+ int numhdrs;
+ int afd;
+ unsigned char *pbp;
unsigned char peekbuf[8];
char bufbuf[MAXLINE];
df = NULL;
ignrdot = smtpmode ? false : IgnrDot;
- dbto = smtpmode ? (int) TimeOuts.to_datablock : 0;
+
+ /* timeout for I/O functions is in milliseconds */
+ dbto = smtpmode ? ((int) TimeOuts.to_datablock * 1000)
+ : SM_TIME_FOREVER;
+ sm_io_setinfo(fp, SM_IO_WHAT_TIMEOUT, &dbto);
c = SM_IO_EOF;
inputerr = false;
headeronly = hdrp != NULL;
@@ -320,7 +319,6 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
pbp = peekbuf;
istate = IS_BOL;
mstate = SaveFrom ? MS_HEADER : MS_UFROM;
- CollectProgress = false;
/*
** Tell ARPANET to go ahead.
@@ -329,6 +327,10 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
if (smtpmode)
message("354 Enter mail, end with \".\" on a line by itself");
+ /* simulate an I/O timeout when used as sink */
+ if (tTd(83, 101))
+ sleep(319);
+
if (tTd(30, 2))
sm_dprintf("collect\n");
@@ -341,32 +343,6 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
** the larger picture (e.g., header versus body).
*/
- if (dbto != 0)
- {
- /* handle possible input timeout */
- if (setjmp(CtxCollectTimeout) != 0)
- {
- if (LogLevel > 2)
- sm_syslog(LOG_NOTICE, e->e_id,
- "timeout waiting for input from %s during message collect",
- CURHOSTNAME);
- errno = 0;
- if (smtpmode)
- {
- /*
- ** Override e_message in usrerr() as this
- ** is the reason for failure that should
- ** be logged for undelivered recipients.
- */
-
- e->e_message = NULL;
- }
- usrerr("451 4.4.1 timeout waiting for input during message collect");
- goto readerr;
- }
- CollectTimeout = sm_setevent(dbto, collecttimeout, dbto);
- }
-
if (rsetsize)
e->e_msgsize = 0;
for (;;)
@@ -390,9 +366,26 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
sm_io_clearerr(fp);
continue;
}
+
+ /* timeout? */
+ if (c == SM_IO_EOF && errno == EAGAIN
+ && smtpmode)
+ {
+ /*
+ ** Override e_message in
+ ** usrerr() as this is the
+ ** reason for failure that
+ ** should be logged for
+ ** undelivered recipients.
+ */
+
+ e->e_message = NULL;
+ errno = 0;
+ inputerr = true;
+ goto readabort;
+ }
break;
}
- CollectProgress = true;
if (TrafficLogFile != NULL && !headeronly)
{
if (istate == IS_BOL)
@@ -446,7 +439,8 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
OpMode != MD_ARPAFTP))
{
- SM_ASSERT(pbp < peekbuf + sizeof(peekbuf));
+ SM_ASSERT(pbp < peekbuf +
+ sizeof(peekbuf));
*pbp++ = c;
c = '.';
}
@@ -458,7 +452,8 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
else
{
/* push back the ".\rx" */
- SM_ASSERT(pbp < peekbuf + sizeof(peekbuf));
+ SM_ASSERT(pbp < peekbuf +
+ sizeof(peekbuf));
*pbp++ = c;
if (OpMode != MD_SMTP &&
OpMode != MD_DAEMON &&
@@ -538,6 +533,18 @@ bufferchar:
buflen *= 2;
else
buflen += MEMCHUNKSIZE;
+ if (buflen <= 0)
+ {
+ sm_syslog(LOG_NOTICE, e->e_id,
+ "header overflow from %s during message collect",
+ CURHOSTNAME);
+ errno = 0;
+ e->e_flags |= EF_CLRQUEUE;
+ e->e_status = "5.6.0";
+ usrerrenh(e->e_status,
+ "552 Headers too large");
+ goto discard;
+ }
buf = xalloc(buflen);
memmove(buf, obuf, bp - obuf);
bp = &buf[bp - obuf];
@@ -581,6 +588,7 @@ bufferchar:
usrerrenh(e->e_status,
"552 Headers too large (%d max)",
MaxHeadersLength);
+ discard:
mstate = MS_DISCARD;
}
}
@@ -620,6 +628,24 @@ nextstate:
sm_io_clearerr(fp);
errno = 0;
c = sm_io_getc(fp, SM_TIME_DEFAULT);
+
+ /* timeout? */
+ if (c == SM_IO_EOF && errno == EAGAIN
+ && smtpmode)
+ {
+ /*
+ ** Override e_message in
+ ** usrerr() as this is the
+ ** reason for failure that
+ ** should be logged for
+ ** undelivered recipients.
+ */
+
+ e->e_message = NULL;
+ errno = 0;
+ inputerr = true;
+ goto readabort;
+ }
} while (c == SM_IO_EOF && errno == EINTR);
if (c != SM_IO_EOF)
(void) sm_io_ungetc(fp, SM_TIME_DEFAULT, c);
@@ -629,8 +655,12 @@ nextstate:
continue;
}
- /* trim off trailing CRLF or NL */
SM_ASSERT(bp > buf);
+
+ /* guaranteed by isheader(buf) */
+ SM_ASSERT(*(bp - 1) != '\n' || bp > buf + 1);
+
+ /* trim off trailing CRLF or NL */
if (*--bp != '\n' || *--bp != '\r')
bp++;
*bp = '\0';
@@ -696,10 +726,6 @@ readerr:
inputerr = true;
}
- /* reset global timer */
- if (CollectTimeout != NULL)
- sm_clrevent(CollectTimeout);
-
if (headeronly)
return;
@@ -786,6 +812,7 @@ readerr:
}
/* An EOF when running SMTP is an error */
+ readabort:
if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
{
char *host;
@@ -808,13 +835,14 @@ readerr:
problem, host,
shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
if (sm_io_eof(fp))
- usrerr("451 4.4.1 collect: %s on connection from %s, from=%s",
+ usrerr("421 4.4.1 collect: %s on connection from %s, from=%s",
problem, host,
shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
else
- syserr("451 4.4.1 collect: %s on connection from %s, from=%s",
+ syserr("421 4.4.1 collect: %s on connection from %s, from=%s",
problem, host,
shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
+ flush_errors(true);
/* don't return an error indication */
e->e_to = NULL;
@@ -907,39 +935,6 @@ readerr:
}
}
-static void
-collecttimeout(timeout)
- int timeout;
-{
- int save_errno = errno;
-
- /*
- ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
- ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
- ** DOING.
- */
-
- if (CollectProgress)
- {
- /* reset the timeout */
- CollectTimeout = sm_sigsafe_setevent(timeout, collecttimeout,
- timeout);
- CollectProgress = false;
- }
- else
- {
- /* event is done */
- CollectTimeout = NULL;
- }
-
- /* if no progress was made or problem resetting event, die now */
- if (CollectTimeout == NULL)
- {
- errno = ETIMEDOUT;
- longjmp(CtxCollectTimeout, 1);
- }
- errno = save_errno;
-}
/*
** DFERROR -- signal error on writing the data file.
**
diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c
index 4d7aa94..f8cd300 100644
--- a/contrib/sendmail/src/conf.c
+++ b/contrib/sendmail/src/conf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,13 +13,21 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: conf.c,v 8.1061 2005/03/07 17:18:44 ca Exp $")
+SM_RCSID("@(#)$Id: conf.c,v 8.1081 2006/02/24 02:21:53 ca Exp $")
#include <sendmail/pathnames.h>
#if NEWDB
# include "sm/bdb.h"
#endif /* NEWDB */
+#ifdef DEC
+# if NETINET6
+/* for the IPv6 device lookup */
+# define _SOCKADDR_LEN
+# include <macros.h>
+# endif /* NETINET6 */
+#endif /* DEC */
+
# include <sys/ioctl.h>
# include <sys/param.h>
@@ -344,6 +352,7 @@ setdefaults(e)
MaxMimeFieldLength = MaxMimeHeaderLength / 2;
MaxForwardEntries = 0;
FastSplit = 1;
+ MaxNOOPCommands = MAXNOOPCOMMANDS;
#if SASL
AuthMechanisms = newstr(AUTH_MECHANISMS);
AuthRealm = NULL;
@@ -2174,10 +2183,25 @@ shouldqueue(pri, ct)
time_t ct;
{
bool rval;
+#if _FFR_MEMSTAT
+ long memfree;
+#endif /* _FFR_MEMSTAT */
if (tTd(3, 30))
sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
CurrentLA, pri);
+
+#if _FFR_MEMSTAT
+ if (QueueLowMem > 0 &&
+ sm_memstat_get(MemoryResource, &memfree) >= 0 &&
+ memfree < QueueLowMem)
+ {
+ if (tTd(3, 30))
+ sm_dprintf("true (memfree=%ld < QueueLowMem)\n",
+ memfree, QueueLowMem);
+ return true;
+ }
+#endif /* _FFR_MEMSTAT */
if (CurrentLA < QueueLA)
{
if (tTd(3, 30))
@@ -2226,6 +2250,9 @@ refuseconnections(name, e, d, active)
static int conncnt[MAXDAEMONS];
static time_t firstrejtime[MAXDAEMONS];
static time_t nextlogtime[MAXDAEMONS];
+#if _FFR_MEMSTAT
+ long memfree;
+#endif /* _FFR_MEMSTAT */
#if XLA
if (!xla_smtp_ok())
@@ -2262,6 +2289,19 @@ refuseconnections(name, e, d, active)
conncnt[d] = 0;
}
+
+#if _FFR_MEMSTAT
+ if (RefuseLowMem > 0 &&
+ sm_memstat_get(MemoryResource, &memfree) >= 0 &&
+ memfree < RefuseLowMem)
+ {
+# define R_MSG_LM "rejecting connections on daemon %s: free memory: %ld"
+ sm_setproctitle(true, e, R_MSG_LM, name, memfree);
+ if (LogLevel > 8)
+ sm_syslog(LOG_NOTICE, NOQID, R_MSG_LM, name, memfree);
+ return true;
+ }
+#endif /* _FFR_MEMSTAT */
sm_getla();
if (RefuseLA > 0 && CurrentLA >= RefuseLA)
{
@@ -3731,7 +3771,7 @@ chownsafe(fd, safedir)
#if HASSETRLIMIT
# ifdef RLIMIT_NEEDS_SYS_TIME_H
-# include <sys/time.h>
+# include <sm/time.h>
# endif /* RLIMIT_NEEDS_SYS_TIME_H */
# include <sys/resource.h>
#endif /* HASSETRLIMIT */
@@ -3793,6 +3833,13 @@ setvendor(vendor)
return true;
}
#endif /* SUN_EXTENSIONS */
+#ifdef DEC
+ if (sm_strcasecmp(vendor, "Digital") == 0)
+ {
+ VendorCode = VENDOR_DEC;
+ return true;
+ }
+#endif /* DEC */
#if defined(VENDOR_NAME) && defined(VENDOR_CODE)
if (sm_strcasecmp(vendor, VENDOR_NAME) == 0)
@@ -3884,8 +3931,8 @@ vendor_pre_defaults(e)
** /etc/mail/sendmail.cf without this
*/
- setuserenv("ISP", NULL);
- setuserenv("SYSTYPE", NULL);
+ sm_setuserenv("ISP", NULL);
+ sm_setuserenv("SYSTYPE", NULL);
#endif /* apollo */
}
@@ -3899,7 +3946,7 @@ vendor_post_defaults(e)
/* Makes sure the SOCK environment variable remains */
if (p = getextenv("SOCK"))
- setuserenv("SOCK", p);
+ sm_setuserenv("SOCK", p);
#endif /* __QNX__ */
#if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
sun_post_defaults(e);
@@ -4675,7 +4722,7 @@ add_hostnames(sa)
struct rtentry;
struct mbuf;
# ifndef SUNOS403
-# include <sys/time.h>
+# include <sm/time.h>
# endif /* ! SUNOS403 */
# if (_AIX4 >= 40300) && !defined(_NET_IF_H)
# undef __P
@@ -4816,7 +4863,13 @@ load_if_names()
i += sizeof ifr->lifr_name + sa->sa.sa_len;
else
# endif /* BSD4_4_SOCKADDR */
+# ifdef DEC
+ /* fix for IPv6 size differences */
+ i += sizeof ifr->ifr_name +
+ max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
+# else /* DEC */
i += sizeof *ifr;
+# endif /* DEC */
if (tTd(0, 20))
sm_dprintf("%s\n", anynet_ntoa(sa));
@@ -5309,8 +5362,8 @@ sm_syslog(level, id, fmt, va_alist)
va_dcl
#endif /* __STDC__ */
{
- static char *buf = NULL;
- static size_t bufsize;
+ char *buf;
+ size_t bufsize;
char *begin, *end;
int save_errno;
int seq = 1;
@@ -5334,11 +5387,8 @@ sm_syslog(level, id, fmt, va_alist)
else
idlen = strlen(id) + SyslogPrefixLen;
- if (buf == NULL)
- {
- buf = buf0;
- bufsize = sizeof buf0;
- }
+ buf = buf0;
+ bufsize = sizeof buf0;
for (;;)
{
@@ -5380,8 +5430,8 @@ sm_syslog(level, id, fmt, va_alist)
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
"%s: %s\n", id, newstring);
#endif /* LOG */
- if (buf == buf0)
- buf = NULL;
+ if (buf != buf0)
+ sm_free(buf);
errno = save_errno;
return;
}
@@ -5445,8 +5495,8 @@ sm_syslog(level, id, fmt, va_alist)
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
"%s[%d]: %s\n", id, seq, begin);
#endif /* LOG */
- if (buf == buf0)
- buf = NULL;
+ if (buf != buf0)
+ sm_free(buf);
errno = save_errno;
}
/*
@@ -5656,6 +5706,9 @@ char *CompileOptions[] =
#if LDAPMAP
"LDAPMAP",
#endif /* LDAPMAP */
+#if LDAP_REFERRALS
+ "LDAP_REFERRALS",
+#endif /* LDAP_REFERRALS */
#if LOG
"LOG",
#endif /* LOG */
@@ -6046,6 +6099,10 @@ char *FFRCompileOptions[] =
/* What it says :-) */
"_FFR_DEPRECATE_MAILER_FLAG_I",
#endif /* _FFR_DEPRECATE_MAILER_FLAG_I */
+#if _FFR_DM_ONE
+ /* deliver first TA in background, then queue */
+ "_FFR_DM_ONE",
+#endif /* _FFR_DM_ONE */
#if _FFR_DIGUNIX_SAFECHOWN
/* Properly set SAFECHOWN (include/sm/conf.h) for Digital UNIX */
/* Problem noted by Anne Bennett of Concordia University */
@@ -6109,6 +6166,10 @@ char *FFRCompileOptions[] =
/* Generate a ORCPT DSN arg if not already provided */
"_FFR_GEN_ORCPT",
#endif /* _FFR_GEN_ORCPT */
+#if _FFR_LOG_GREET_PAUSE
+ /* log time for greet_pause delay; from Nik Clayton */
+ "_FFR_LOG_GREET_PAUSE",
+#endif /* _FFR_LOG_GREET_PAUSE */
#if _FFR_GROUPREADABLEAUTHINFOFILE
/* Allow group readable DefaultAuthInfo file. */
"_FFR_GROUPREADABLEAUTHINFOFILE",
@@ -6158,10 +6219,22 @@ char *FFRCompileOptions[] =
/* Randall S. Winchester of the University of Maryland */
"_FFR_MAX_FORWARD_ENTRIES",
#endif /* _FFR_MAX_FORWARD_ENTRIES */
+#if _FFR_MAXKEY
+ /* increase key size for LDAP lookups, see conf.h */
+ "_FFR_MAXKEY",
+#endif /* _FFR_MAXKEY */
+#if _FFR_MAXNOOPCOMMANDS
+ /* runtime option for "MaxNOOPCommands" */
+ "_FFR_MAXNOOPCOMMANDS",
+#endif /* _FFR_MAXNOOPCOMMANDS */
#if _FFR_MAX_SLEEP_TIME
/* Limit sleep(2) time in libsm/clock.c */
"_FFR_MAX_SLEEP_TIME",
#endif /* _FFR_MAX_SLEEP_TIME */
+#if _FFR_MEMSTAT
+ /* Check free memory */
+ "_FFR_MEMSTAT",
+#endif /* _FFR_MEMSTAT */
#if _FFR_MILTER_NAGLE
/* milter: turn off Nagle ("cork" on Linux) */
/* John Gardiner Myers of Proofpoint */
@@ -6176,6 +6249,10 @@ char *FFRCompileOptions[] =
/* Old mime7to8 code, the new is broken for at least one example. */
"_FFR_MIME7TO8_OLD",
#endif /* _FFR_MAX_SLEEP_TIME */
+#if _FFR_MSG_ACCEPT
+ /* allow to override "Message accepted for delivery" */
+ "_FFR_MSG_ACCEPT",
+#endif /* _FFR_MSG_ACCEPT */
#if _FFR_NODELAYDSN_ON_HOLD
/* Do not issue a DELAY DSN for mailers that use the hold flag. */
/* Steven Pitzl */
@@ -6191,9 +6268,9 @@ char *FFRCompileOptions[] =
#endif /* _FFR_LOG_NTRIES */
#if _FFR_PRIV_NOACTUALRECIPIENT
/*
- ** PrivacyOptions=noactualrecipient stops sendmail from putting
- ** X-Actual-Recipient lines in DSNs revealing the actual
- ** account that addresses map to. Patch from Dan Harkless.
+ ** PrivacyOptions=noactualrecipient stops sendmail from putting
+ ** X-Actual-Recipient lines in DSNs revealing the actual
+ ** account that addresses map to. Patch from Dan Harkless.
*/
"_FFR_PRIV_NOACTUALRECIPIENT",
@@ -6212,7 +6289,7 @@ char *FFRCompileOptions[] =
"_FFR_QUEUE_MACRO",
#endif /* _FFR_QUEUE_MACRO */
#if _FFR_QUEUE_RUN_PARANOIA
- /* Additional checks when doing queue runs. */
+ /* Additional checks when doing queue runs; interval of checks */
"_FFR_QUEUE_RUN_PARANOIA",
#endif /* _FFR_QUEUE_RUN_PARANOIA */
#if _FFR_QUEUE_SCHED_DBG
@@ -6244,6 +6321,25 @@ char *FFRCompileOptions[] =
/* Donated code (unused). */
"_FFR_SHM_STATUS",
#endif /* _FFR_SHM_STATUS */
+#if _FFR_LDAP_SINGLEDN
+ /*
+ ** The LDAP database map code in Sendmail 8.12.10, when
+ ** given the -1 switch, would match only a single DN,
+ ** but was able to return multiple attributes for that
+ ** DN. In Sendmail 8.13 this "bug" was corrected to
+ ** only return if exactly one attribute matched.
+ **
+ ** Unfortunately, our configuration uses the former
+ ** behaviour. Attached is a relatively simple patch
+ ** to 8.13.4 which adds a -2 switch (for lack of a
+ ** better option) which returns the single dn/multiple
+ ** attributes.
+ **
+ ** Jeffrey T. Eaton, Carnegie-Mellon University
+ */
+
+ "_FFR_LDAP_SINGLEDN",
+#endif /* _FFR_LDAP_SINGLEDN */
#if _FFR_SKIP_DOMAINS
/* process every N'th domain instead of every N'th message */
"_FFR_SKIP_DOMAINS",
diff --git a/contrib/sendmail/src/conf.h b/contrib/sendmail/src/conf.h
index 77577c4..5e85015 100644
--- a/contrib/sendmail/src/conf.h
+++ b/contrib/sendmail/src/conf.h
@@ -10,7 +10,7 @@
* the sendmail distribution.
*
*
- * $Id: conf.h,v 8.567 2004/07/23 20:45:01 gshapiro Exp $
+ * $Id: conf.h,v 8.570 2005/12/09 18:37:27 ca Exp $
*/
/*
@@ -59,31 +59,40 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
** If you do, be careful, none should be set anywhere near INT_MAX
**********************************************************************/
-#define MAXLINE 2048 /* max line length */
-#define MAXNAME 256 /* max length of a name */
+#define MAXLINE 2048 /* max line length */
+#define MAXNAME 256 /* max length of a name */
#ifndef MAXAUTHINFO
-# define MAXAUTHINFO 100 /* max length of authinfo token */
+# define MAXAUTHINFO 100 /* max length of authinfo token */
#endif /* ! MAXAUTHINFO */
-#define MAXPV 256 /* max # of parms to mailers */
-#define MAXATOM 1000 /* max atoms per address */
-#define MAXRWSETS 200 /* max # of sets of rewriting rules */
-#define MAXPRIORITIES 25 /* max values for Precedence: field */
-#define MAXMXHOSTS 100 /* max # of MX records for one host */
-#define SMTPLINELIM 990 /* maximum SMTP line length */
-#define MAXKEY 128 /* maximum size of a database key */
-#define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */
-#define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */
-#define MAXMAPSTACK 12 /* max # of stacked or sequenced maps */
+#define MAXPV 256 /* max # of parms to mailers */
+#define MAXATOM 1000 /* max atoms per address */
+#define MAXRWSETS 200 /* max # of sets of rewriting rules */
+#define MAXPRIORITIES 25 /* max values for Precedence: field */
+#define MAXMXHOSTS 100 /* max # of MX records for one host */
+#define SMTPLINELIM 990 /* max SMTP line length */
+#define MAXUDBKEY 128 /* max size of a database key (udb only) */
+#if _FFR_MAXKEY
+# define MAXKEY 1024 /* max size of a database key */
+#else /* _FFR_MAXKEY */
+# define MAXKEY (MAXNAME + 1) /* max size of a database key */
+#endif /* _FFR_MAXKEY */
+#define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */
+#define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */
+#define MAXMAPSTACK 12 /* max # of stacked or sequenced maps */
#if MILTER
-# define MAXFILTERS 25 /* max # of milter filters */
-# define MAXFILTERMACROS 50 /* max # of macros per milter cmd */
+# define MAXFILTERS 25 /* max # of milter filters */
+# define MAXFILTERMACROS 50 /* max # of macros per milter cmd */
#endif /* MILTER */
-#define MAXSMTPARGS 20 /* max # of ESMTP args for MAIL/RCPT */
-#define MAXTOCLASS 8 /* max # of message timeout classes */
-#define MAXRESTOTYPES 3 /* max # of resolver timeout types */
-#define MAXMIMEARGS 20 /* max args in Content-Type: */
-#define MAXMIMENESTING 20 /* max MIME multipart nesting */
-#define QUEUESEGSIZE 1000 /* increment for queue size */
+#define MAXSMTPARGS 20 /* max # of ESMTP args for MAIL/RCPT */
+#define MAXTOCLASS 8 /* max # of message timeout classes */
+#define MAXRESTOTYPES 3 /* max # of resolver timeout types */
+#define MAXMIMEARGS 20 /* max args in Content-Type: */
+#define MAXMIMENESTING 20 /* max MIME multipart nesting */
+#define QUEUESEGSIZE 1000 /* increment for queue size */
+
+#ifndef MAXNOOPCOMMANDS
+# define MAXNOOPCOMMANDS 20 /* max "noise" commands before slowdown */
+#endif /* ! MAXNOOPCOMMANDS */
/*
** MAXQFNAME == 2 (size of "qf", "df" prefix)
diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c
index 69a5f61..9bbde39 100644
--- a/contrib/sendmail/src/daemon.c
+++ b/contrib/sendmail/src/daemon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: daemon.c,v 8.658 2005/02/02 18:19:28 ca Exp $")
+SM_RCSID("@(#)$Id: daemon.c,v 8.665 2006/03/02 19:12:00 ca Exp $")
#if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__)
# define USE_SOCK_STREAM 1
@@ -34,7 +34,7 @@ SM_RCSID("@(#)$Id: daemon.c,v 8.658 2005/02/02 18:19:28 ca Exp $")
# include <openssl/rand.h>
#endif /* STARTTLS */
-#include <sys/time.h>
+#include <sm/time.h>
#if IP_SRCROUTE && NETINET
# include <netinet/in_systm.h>
@@ -90,9 +90,6 @@ typedef struct daemon DAEMON_T;
#define SAFE_NOTSET (-1) /* SuperSafe (per daemon) option not set */
/* see also sendmail.h: SuperSafe values */
-#define DM_NOTSET (-1) /* DeliveryMode (per daemon) option not set */
-/* see also sendmail.h: values for e_sendmode -- send modes */
-
static void connecttimeout __P((int));
static int opendaemonsocket __P((DAEMON_T *, bool));
static unsigned short setupdaemon __P((SOCKADDR *));
@@ -390,8 +387,8 @@ getrequests(e)
#endif /* _FFR_QUEUE_RUN_PARANOIA */
}
#if _FFR_QUEUE_RUN_PARANOIA
- else if (QueueIntvl > 0 &&
- lastrun + QueueIntvl + 60 < now)
+ else if (CheckQueueRunners > 0 && QueueIntvl > 0 &&
+ lastrun + QueueIntvl + CheckQueueRunners < now)
{
/*
@@ -764,7 +761,6 @@ getrequests(e)
set_delivery_mode(
Daemons[curdaemon].d_dm, e);
#endif /* _FFR_DM_PER_DAEMON */
-
sm_setproctitle(true, e, "startup with %s",
anynet_ntoa(&RealHostAddr));
@@ -1455,6 +1451,12 @@ setsockaddroptions(p, d)
if (d->d_addr.sa.sa_family == AF_UNSPEC)
d->d_addr.sa.sa_family = AF_INET;
#endif /* NETINET */
+#if _FFR_SS_PER_DAEMON
+ d->d_supersafe = SAFE_NOTSET;
+#endif /* _FFR_SS_PER_DAEMON */
+#if _FFR_DM_PER_DAEMON
+ d->d_dm = DM_NOTSET;
+#endif /* _FFR_DM_PER_DAEMON */
while (p != NULL)
{
@@ -1476,12 +1478,6 @@ setsockaddroptions(p, d)
continue;
if (isascii(*f) && islower(*f))
*f = toupper(*f);
-#if _FFR_SS_PER_DAEMON
- d->d_supersafe = SAFE_NOTSET;
-#endif /* _FFR_SS_PER_DAEMON */
-#if _FFR_DM_PER_DAEMON
- d->d_dm = DM_NOTSET;
-#endif /* _FFR_DM_PER_DAEMON */
switch (*f)
{
@@ -1496,7 +1492,7 @@ setsockaddroptions(p, d)
case SM_QUEUE:
case SM_DEFER:
case SM_DELIVER:
- case SM_FORK:
+ case SM_FORK:
d->d_dm = *v;
break;
default:
diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c
index a6b67c8..0458047 100644
--- a/contrib/sendmail/src/deliver.c
+++ b/contrib/sendmail/src/deliver.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -12,9 +12,9 @@
*/
#include <sendmail.h>
-#include <sys/time.h>
+#include <sm/time.h>
-SM_RCSID("@(#)$Id: deliver.c,v 8.986 2005/03/05 02:28:50 ca Exp $")
+SM_RCSID("@(#)$Id: deliver.c,v 8.1000 2006/03/02 01:37:39 ca Exp $")
#if HASSETUSERCONTEXT
# include <login_cap.h>
@@ -1201,13 +1201,13 @@ should_try_fbsh(e, tried_fallbacksmarthost, hostbuf, hbsz, status)
int status;
{
/*
- ** If the host was not found and a FallbackSmartHost is defined
- ** (and we have not yet tried it), then make one last try with
- ** it as the host.
+ ** If the host was not found or a temporary failure occurred
+ ** and a FallbackSmartHost is defined (and we have not yet
+ ** tried it), then make one last try with it as the host.
*/
- if (status == EX_NOHOST && FallbackSmartHost != NULL &&
- !*tried_fallbacksmarthost)
+ if ((status == EX_NOHOST || status == EX_TEMPFAIL) &&
+ FallbackSmartHost != NULL && !*tried_fallbacksmarthost)
{
*tried_fallbacksmarthost = true;
expand(FallbackSmartHost, hostbuf, hbsz, e);
@@ -2992,6 +2992,9 @@ reconnect: /* after switching to an encrypted connection */
case EX_SOFTWARE:
s = "SOFTWARE";
break;
+ case EX_UNAVAILABLE:
+ s = "NONE";
+ break;
/* everything else is a failure */
default:
@@ -3257,16 +3260,33 @@ do_transfer:
}
else if (!clever)
{
+ bool ok;
+
/*
** Format and send message.
*/
- putfromline(mci, e);
- (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
- (*e->e_putbody)(mci, e, NULL);
+ rcode = EX_OK;
+ errno = 0;
+ ok = putfromline(mci, e);
+ if (ok)
+ ok = (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
+ if (ok)
+ ok = (*e->e_putbody)(mci, e, NULL);
+
+ /*
+ ** Ignore an I/O error that was caused by EPIPE.
+ ** Some broken mailers don't read the entire body
+ ** but just exit() thus causing an I/O error.
+ */
+
+ if (!ok && (sm_io_error(mci->mci_out) && errno == EPIPE))
+ ok = true;
- /* get the exit status */
+ /* (always) get the exit status */
rcode = endmailer(mci, e, pv);
+ if (!ok)
+ rcode = EX_TEMPFAIL;
if (rcode == EX_TEMPFAIL && SmtpError[0] == '\0')
{
/*
@@ -4430,13 +4450,13 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
** e -- the envelope.
**
** Returns:
-** none
+** true iff line was written successfully
**
** Side Effects:
** outputs some text to fp.
*/
-void
+bool
putfromline(mci, e)
register MCI *mci;
ENVELOPE *e;
@@ -4446,7 +4466,7 @@ putfromline(mci, e)
char xbuf[MAXLINE];
if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
- return;
+ return true;
mci->mci_flags |= MCIF_INHEADER;
@@ -4487,8 +4507,9 @@ putfromline(mci, e)
}
}
expand(template, buf, sizeof buf, e);
- putxline(buf, strlen(buf), mci, PXLF_HEADER);
+ return putxline(buf, strlen(buf), mci, PXLF_HEADER);
}
+
/*
** PUTBODY -- put the body of a message.
**
@@ -4499,24 +4520,26 @@ putfromline(mci, e)
** not be permitted in the resulting message.
**
** Returns:
-** none.
+** true iff message was written successfully
**
** Side Effects:
** The message is written onto fp.
*/
/* values for output state variable */
-#define OS_HEAD 0 /* at beginning of line */
-#define OS_CR 1 /* read a carriage return */
-#define OS_INLINE 2 /* putting rest of line */
+#define OSTATE_HEAD 0 /* at beginning of line */
+#define OSTATE_CR 1 /* read a carriage return */
+#define OSTATE_INLINE 2 /* putting rest of line */
-void
+bool
putbody(mci, e, separator)
register MCI *mci;
register ENVELOPE *e;
char *separator;
{
bool dead = false;
+ bool ioerr = false;
+ int save_errno;
char buf[MAXLINE];
#if MIME8TO7
char *boundaries[MAXMIMENESTING + 1];
@@ -4546,10 +4569,12 @@ putbody(mci, e, separator)
{
if (bitset(MCIF_INHEADER, mci->mci_flags))
{
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
}
- putline("<<< No Message Collected >>>", mci);
+ if (!putline("<<< No Message Collected >>>", mci))
+ goto writeerr;
goto endofmessage;
}
@@ -4570,6 +4595,10 @@ putbody(mci, e, separator)
/* paranoia: the data file should always be in a rewound state */
(void) bfrewind(e->e_dfp);
+ /* simulate an I/O timeout when used as source */
+ if (tTd(84, 101))
+ sleep(319);
+
#if MIME8TO7
if (bitset(MCIF_CVT8TO7, mci->mci_flags))
{
@@ -4578,26 +4607,31 @@ putbody(mci, e, separator)
*/
/* make sure it looks like a MIME message */
- if (hvalue("MIME-Version", e->e_header) == NULL)
- putline("MIME-Version: 1.0", mci);
+ if (hvalue("MIME-Version", e->e_header) == NULL &&
+ !putline("MIME-Version: 1.0", mci))
+ goto writeerr;
if (hvalue("Content-Type", e->e_header) == NULL)
{
(void) sm_snprintf(buf, sizeof buf,
"Content-Type: text/plain; charset=%s",
defcharset(e));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* now do the hard work */
boundaries[0] = NULL;
mci->mci_flags |= MCIF_INHEADER;
- (void) mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER);
+ if (mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER) ==
+ SM_IO_EOF)
+ goto writeerr;
}
# if MIME7TO8
else if (bitset(MCIF_CVT7TO8, mci->mci_flags))
{
- (void) mime7to8(mci, e->e_header, e);
+ if (!mime7to8(mci, e->e_header, e))
+ goto writeerr;
}
# endif /* MIME7TO8 */
else if (MaxMimeHeaderLength > 0 || MaxMimeFieldLength > 0)
@@ -4619,8 +4653,9 @@ putbody(mci, e, separator)
if (bitset(EF_DONT_MIME, e->e_flags))
SuprErrs = true;
- (void) mime8to7(mci, e->e_header, e, boundaries,
- M87F_OUTER|M87F_NO8TO7);
+ if (mime8to7(mci, e->e_header, e, boundaries,
+ M87F_OUTER|M87F_NO8TO7) == SM_IO_EOF)
+ goto writeerr;
/* restore SuprErrs */
SuprErrs = oldsuprerrs;
@@ -4640,7 +4675,8 @@ putbody(mci, e, separator)
if (bitset(MCIF_INHEADER, mci->mci_flags))
{
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
}
@@ -4651,7 +4687,7 @@ putbody(mci, e, separator)
buflim = &buf[mci->mci_mailer->m_linelimit - 1];
/* copy temp file to output with mapping */
- ostate = OS_HEAD;
+ ostate = OSTATE_HEAD;
bp = buf;
pbp = peekbuf;
while (!sm_io_error(mci->mci_out) && !dead)
@@ -4665,7 +4701,7 @@ putbody(mci, e, separator)
c &= 0x7f;
switch (ostate)
{
- case OS_HEAD:
+ case OSTATE_HEAD:
if (c == '\0' &&
bitnset(M_NONULLS,
mci->mci_mailer->m_flags))
@@ -4731,11 +4767,6 @@ putbody(mci, e, separator)
dead = true;
continue;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
pos++;
}
for (xp = buf; xp < bp; xp++)
@@ -4748,11 +4779,6 @@ putbody(mci, e, separator)
dead = true;
break;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
}
if (dead)
continue;
@@ -4763,11 +4789,6 @@ putbody(mci, e, separator)
mci->mci_mailer->m_eol)
== SM_IO_EOF)
break;
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
pos = 0;
}
else
@@ -4785,14 +4806,14 @@ putbody(mci, e, separator)
/* determine next state */
if (c == '\n')
- ostate = OS_HEAD;
+ ostate = OSTATE_HEAD;
else if (c == '\r')
- ostate = OS_CR;
+ ostate = OSTATE_CR;
else
- ostate = OS_INLINE;
+ ostate = OSTATE_INLINE;
continue;
- case OS_CR:
+ case OSTATE_CR:
if (c == '\n')
{
/* got CRLF */
@@ -4801,11 +4822,6 @@ putbody(mci, e, separator)
mci->mci_mailer->m_eol)
== SM_IO_EOF)
continue;
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
if (TrafficLogFile != NULL)
{
@@ -4813,7 +4829,7 @@ putbody(mci, e, separator)
SM_TIME_DEFAULT,
mci->mci_mailer->m_eol);
}
- ostate = OS_HEAD;
+ ostate = OSTATE_HEAD;
continue;
}
@@ -4821,13 +4837,13 @@ putbody(mci, e, separator)
SM_ASSERT(pbp < peekbuf + sizeof(peekbuf));
*pbp++ = c;
c = '\r';
- ostate = OS_INLINE;
+ ostate = OSTATE_INLINE;
goto putch;
- case OS_INLINE:
+ case OSTATE_INLINE:
if (c == '\r')
{
- ostate = OS_CR;
+ ostate = OSTATE_CR;
continue;
}
if (c == '\0' &&
@@ -4867,11 +4883,6 @@ putch:
dead = true;
continue;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
pos++;
continue;
}
@@ -4887,11 +4898,6 @@ putch:
dead = true;
continue;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
if (TrafficLogFile != NULL)
{
@@ -4900,7 +4906,7 @@ putch:
"!%s",
mci->mci_mailer->m_eol);
}
- ostate = OS_HEAD;
+ ostate = OSTATE_HEAD;
SM_ASSERT(pbp < peekbuf +
sizeof(peekbuf));
*pbp++ = c;
@@ -4917,13 +4923,8 @@ putch:
mci->mci_mailer->m_eol)
== SM_IO_EOF)
continue;
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
pos = 0;
- ostate = OS_HEAD;
+ ostate = OSTATE_HEAD;
}
else
{
@@ -4939,13 +4940,8 @@ putch:
dead = true;
continue;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
pos++;
- ostate = OS_INLINE;
+ ostate = OSTATE_INLINE;
}
break;
}
@@ -4970,11 +4966,6 @@ putch:
dead = true;
break;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
}
pos += bp - buf;
}
@@ -4984,11 +4975,9 @@ putch:
(void) sm_io_fputs(TrafficLogFile,
SM_TIME_DEFAULT,
mci->mci_mailer->m_eol);
- (void) sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
- mci->mci_mailer->m_eol);
-
- /* record progress for DATA timeout */
- DataProgress = true;
+ if (sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
+ mci->mci_mailer->m_eol) == SM_IO_EOF)
+ goto writeerr;
}
}
@@ -4998,6 +4987,7 @@ putch:
qid_printqueue(e->e_dfqgrp, e->e_dfqdir),
DATAFL_LETTER, e->e_id);
ExitStat = EX_IOERR;
+ ioerr = true;
}
endofmessage:
@@ -5012,23 +5002,35 @@ endofmessage:
** offset to match.
*/
+ save_errno = errno;
if (e->e_dfp != NULL)
(void) bfrewind(e->e_dfp);
/* some mailers want extra blank line at end of message */
if (!dead && bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
buf[0] != '\0' && buf[0] != '\n')
- putline("", mci);
+ {
+ if (!putline("", mci))
+ goto writeerr;
+ }
- (void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT);
- if (sm_io_error(mci->mci_out) && errno != EPIPE)
+ if (!dead &&
+ (sm_io_flush(mci->mci_out, SM_TIME_DEFAULT) == SM_IO_EOF ||
+ (sm_io_error(mci->mci_out) && errno != EPIPE)))
{
+ save_errno = errno;
syserr("putbody: write error");
ExitStat = EX_IOERR;
+ ioerr = true;
}
- errno = 0;
+ errno = save_errno;
+ return !dead && !ioerr;
+
+ writeerr:
+ return false;
}
+
/*
** MAILFILE -- Send a message to a file.
**
@@ -5559,14 +5561,14 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
}
#endif /* MIME7TO8 */
- putfromline(&mcibuf, e);
- (*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
- (*e->e_putbody)(&mcibuf, e, NULL);
- putline("\n", &mcibuf);
- if (sm_io_flush(f, SM_TIME_DEFAULT) != 0 ||
+ if (!putfromline(&mcibuf, e) ||
+ !(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER) ||
+ !(*e->e_putbody)(&mcibuf, e, NULL) ||
+ !putline("\n", &mcibuf) ||
+ (sm_io_flush(f, SM_TIME_DEFAULT) != 0 ||
(SuperSafe != SAFE_NO &&
fsync(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL)) < 0) ||
- sm_io_error(f))
+ sm_io_error(f)))
{
setstat(EX_IOERR);
#if !NOFTRUNCATE
@@ -6079,12 +6081,16 @@ starttls(m, mci, e)
XS_STARTTLS);
/* check return code from server */
- if (smtpresult == 454)
+ if (REPLYTYPE(smtpresult) == 4)
return EX_TEMPFAIL;
if (smtpresult == 501)
return EX_USAGE;
if (smtpresult == -1)
return smtpresult;
+
+ /* not an expected reply but we have to deal with it */
+ if (REPLYTYPE(smtpresult) == 5)
+ return EX_UNAVAILABLE;
if (smtpresult != 220)
return EX_PROTOCOL;
@@ -6128,86 +6134,23 @@ starttls(m, mci, e)
ssl_retry:
if ((result = SSL_connect(clt_ssl)) <= 0)
{
- int i;
- bool timedout;
- time_t left;
- time_t now = curtime();
- struct timeval tv;
+ int i, ssl_err;
- /* what to do in this case? */
- i = SSL_get_error(clt_ssl, result);
+ ssl_err = SSL_get_error(clt_ssl, result);
+ i = tls_retry(clt_ssl, rfd, wfd, tlsstart,
+ TimeOuts.to_starttls, ssl_err, "client");
+ if (i > 0)
+ goto ssl_retry;
- /*
- ** For SSL_ERROR_WANT_{READ,WRITE}:
- ** There is not a complete SSL record available yet
- ** or there is only a partial SSL record removed from
- ** the network (socket) buffer into the SSL buffer.
- ** The SSL_connect will only succeed when a full
- ** SSL record is available (assuming a "real" error
- ** doesn't happen). To handle when a "real" error
- ** does happen the select is set for exceptions too.
- ** The connection may be re-negotiated during this time
- ** so both read and write "want errors" need to be handled.
- ** A select() exception loops back so that a proper SSL
- ** error message can be gotten.
- */
-
- left = TimeOuts.to_starttls - (now - tlsstart);
- timedout = left <= 0;
- if (!timedout)
- {
- tv.tv_sec = left;
- tv.tv_usec = 0;
- }
-
- if (!timedout && FD_SETSIZE > 0 &&
- (rfd >= FD_SETSIZE ||
- (i == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE)))
- {
- if (LogLevel > 5)
- {
- sm_syslog(LOG_ERR, e->e_id,
- "STARTTLS=client, error: fd %d/%d too large",
- rfd, wfd);
- if (LogLevel > 8)
- tlslogerr("client");
- }
- errno = EINVAL;
- goto tlsfail;
- }
- if (!timedout && i == SSL_ERROR_WANT_READ)
- {
- fd_set ssl_maskr, ssl_maskx;
-
- FD_ZERO(&ssl_maskr);
- FD_SET(rfd, &ssl_maskr);
- FD_ZERO(&ssl_maskx);
- FD_SET(rfd, &ssl_maskx);
- if (select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx, &tv)
- > 0)
- goto ssl_retry;
- }
- if (!timedout && i == SSL_ERROR_WANT_WRITE)
- {
- fd_set ssl_maskw, ssl_maskx;
-
- FD_ZERO(&ssl_maskw);
- FD_SET(wfd, &ssl_maskw);
- FD_ZERO(&ssl_maskx);
- FD_SET(rfd, &ssl_maskx);
- if (select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx, &tv)
- > 0)
- goto ssl_retry;
- }
if (LogLevel > 5)
{
- sm_syslog(LOG_ERR, e->e_id,
- "STARTTLS=client, error: connect failed=%d, SSL_error=%d, timedout=%d, errno=%d",
- result, i, (int) timedout, errno);
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=client, error: connect failed=%d, SSL_error=%d, errno=%d, retry=%d",
+ result, ssl_err, errno, i);
if (LogLevel > 8)
tlslogerr("client");
}
-tlsfail:
+
SSL_free(clt_ssl);
clt_ssl = NULL;
return EX_SOFTWARE;
diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c
index af6370b..164ed6f 100644
--- a/contrib/sendmail/src/envelope.c
+++ b/contrib/sendmail/src/envelope.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: envelope.c,v 8.294 2005/02/16 23:38:51 ca Exp $")
+SM_RCSID("@(#)$Id: envelope.c,v 8.295 2005/06/15 20:32:18 ca Exp $")
/*
** CLRSESSENVELOPE -- clear session oriented data in an envelope
@@ -75,6 +75,10 @@ newenvelope(e, parent, rpool)
register ENVELOPE *parent;
SM_RPOOL_T *rpool;
{
+#if _FFR_DM_PER_DAEMON
+ int sendmode;
+#endif /* _FFR_DM_PER_DAEMON */
+
/*
** This code used to read:
** if (e == parent && e->e_parent != NULL)
@@ -84,6 +88,13 @@ newenvelope(e, parent, rpool)
** This meant macvalue() could go into an infinite loop.
*/
+#if _FFR_DM_PER_DAEMON
+ if (parent != NULL)
+ sendmode = parent->e_sendmode;
+ else
+ sendmode = DM_NOTSET;
+#endif /* _FFR_DM_PER_DAEMON */
+
if (e == parent)
parent = e->e_parent;
clearenvelope(e, true, rpool);
@@ -119,6 +130,10 @@ newenvelope(e, parent, rpool)
e->e_putbody = putbody;
if (CurEnv->e_xfp != NULL)
(void) sm_io_flush(CurEnv->e_xfp, SM_TIME_DEFAULT);
+#if _FFR_DM_PER_DAEMON
+ if (sendmode != DM_NOTSET)
+ e->e_sendmode = sendmode;
+#endif /* _FFR_DM_PER_DAEMON */
return e;
}
diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c
index 892a2cf..96d6e55 100644
--- a/contrib/sendmail/src/headers.c
+++ b/contrib/sendmail/src/headers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2004, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,12 +13,12 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: headers.c,v 8.287 2004/12/03 18:29:51 ca Exp $")
+SM_RCSID("@(#)$Id: headers.c,v 8.290 2006/02/25 02:16:52 ca Exp $")
static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *));
static size_t fix_mime_header __P((HDR *, ENVELOPE *));
static int priencode __P((char *));
-static void put_vanilla_header __P((HDR *, char *, MCI *));
+static bool put_vanilla_header __P((HDR *, char *, MCI *));
/*
** SETUPHEADERS -- initialize headers in symbol table
@@ -993,7 +993,6 @@ logsender(e, msgid)
char *name;
register char *sbp;
register char *p;
- int l;
char hbuf[MAXNAME + 1];
char sbuf[MAXLINE + 1];
char mbuf[MAXNAME + 1];
@@ -1002,6 +1001,8 @@ logsender(e, msgid)
/* XXX do we still need this? sm_syslog() replaces control chars */
if (msgid != NULL)
{
+ size_t l;
+
l = strlen(msgid);
if (l > sizeof mbuf - 1)
l = sizeof mbuf - 1;
@@ -1541,13 +1542,13 @@ crackaddr(addr, e)
** flags -- MIME conversion flags.
**
** Returns:
-** none.
+** success
**
** Side Effects:
** none.
*/
-void
+bool
putheader(mci, hdr, e, flags)
register MCI *mci;
HDR *hdr;
@@ -1682,7 +1683,8 @@ putheader(mci, hdr, e, flags)
{
if (tTd(34, 11))
sm_dprintf("\n");
- put_vanilla_header(h, p, mci);
+ if (!put_vanilla_header(h, p, mci))
+ goto writeerr;
continue;
}
@@ -1741,7 +1743,8 @@ putheader(mci, hdr, e, flags)
/* no other recipient headers: truncate value */
(void) sm_strlcpyn(obuf, sizeof obuf, 2,
h->h_field, ":");
- putline(obuf, mci);
+ if (!putline(obuf, mci))
+ goto writeerr;
}
continue;
}
@@ -1760,7 +1763,8 @@ putheader(mci, hdr, e, flags)
}
else
{
- put_vanilla_header(h, p, mci);
+ if (!put_vanilla_header(h, p, mci))
+ goto writeerr;
}
}
@@ -1777,18 +1781,25 @@ putheader(mci, hdr, e, flags)
!bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags) &&
hvalue("MIME-Version", e->e_header) == NULL)
{
- putline("MIME-Version: 1.0", mci);
+ if (!putline("MIME-Version: 1.0", mci))
+ goto writeerr;
if (hvalue("Content-Type", e->e_header) == NULL)
{
(void) sm_snprintf(obuf, sizeof obuf,
"Content-Type: text/plain; charset=%s",
defcharset(e));
- putline(obuf, mci);
+ if (!putline(obuf, mci))
+ goto writeerr;
}
- if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL)
- putline("Content-Transfer-Encoding: 8bit", mci);
+ if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL
+ && !putline("Content-Transfer-Encoding: 8bit", mci))
+ goto writeerr;
}
#endif /* MIME8TO7 */
+ return true;
+
+ writeerr:
+ return false;
}
/*
** PUT_VANILLA_HEADER -- output a fairly ordinary header
@@ -1799,10 +1810,10 @@ putheader(mci, hdr, e, flags)
** mci -- the connection info for output
**
** Returns:
-** none.
+** success
*/
-static void
+static bool
put_vanilla_header(h, v, mci)
HDR *h;
char *v;
@@ -1833,7 +1844,8 @@ put_vanilla_header(h, v, mci)
l = SPACELEFT(obuf, obp) - 1;
(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v);
- putxline(obuf, strlen(obuf), mci, putflags);
+ if (!putxline(obuf, strlen(obuf), mci, putflags))
+ goto writeerr;
v += l + 1;
obp = obuf;
if (*v != ' ' && *v != '\t')
@@ -1843,7 +1855,10 @@ put_vanilla_header(h, v, mci)
/* XXX This is broken for SPACELEFT()==0 */
(void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s",
(int) (SPACELEFT(obuf, obp) - 1), v);
- putxline(obuf, strlen(obuf), mci, putflags);
+ return putxline(obuf, strlen(obuf), mci, putflags);
+
+ writeerr:
+ return false;
}
/*
** COMMAIZE -- output a header field, making a comma-translated list.
@@ -1856,13 +1871,13 @@ put_vanilla_header(h, v, mci)
** e -- the envelope containing the message.
**
** Returns:
-** none.
+** success
**
** Side Effects:
** outputs "p" to file "fp".
*/
-void
+bool
commaize(h, p, oldstyle, mci, e)
register HDR *h;
register char *p;
@@ -2001,13 +2016,6 @@ commaize(h, p, oldstyle, mci, e)
}
name = denlstring(name, false, true);
- /*
- ** record data progress so DNS timeouts
- ** don't cause DATA timeouts
- */
-
- DataProgress = true;
-
/* output the name with nice formatting */
opos += strlen(name);
if (!firstone)
@@ -2015,7 +2023,8 @@ commaize(h, p, oldstyle, mci, e)
if (opos > omax && !firstone)
{
(void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp));
- putxline(obuf, strlen(obuf), mci, putflags);
+ if (!putxline(obuf, strlen(obuf), mci, putflags))
+ goto writeerr;
obp = obuf;
(void) sm_strlcpy(obp, " ", sizeof obuf);
opos = strlen(obp);
@@ -2037,8 +2046,12 @@ commaize(h, p, oldstyle, mci, e)
*obp = '\0';
else
obuf[sizeof obuf - 1] = '\0';
- putxline(obuf, strlen(obuf), mci, putflags);
+ return putxline(obuf, strlen(obuf), mci, putflags);
+
+ writeerr:
+ return false;
}
+
/*
** COPYHEADER -- copy header list
**
diff --git a/contrib/sendmail/src/helpfile b/contrib/sendmail/src/helpfile
index af8bd15..5c502d3 100644
--- a/contrib/sendmail/src/helpfile
+++ b/contrib/sendmail/src/helpfile
@@ -1,6 +1,6 @@
#vers 2
cpyr
-cpyr Copyright (c) 1998-2000, 2002, 2004 Sendmail, Inc. and its suppliers.
+cpyr Copyright (c) 1998-2000, 2002, 2004, 2005 Sendmail, Inc. and its suppliers.
cpyr All rights reserved.
cpyr Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
cpyr Copyright (c) 1988, 1993
@@ -11,7 +11,7 @@ cpyr By using this file, you agree to the terms and conditions set
cpyr forth in the LICENSE file which can be found at the top level of
cpyr the sendmail distribution.
cpyr
-cpyr $$Id: helpfile,v 8.43 2004/10/29 18:05:39 ca Exp $$
+cpyr $$Id: helpfile,v 8.45 2005/09/13 00:05:23 ca Exp $$
cpyr
smtp This is sendmail version $v
smtp Topics:
@@ -48,10 +48,10 @@ ehlo STARTTLS Secure SMTP [RFC2487]
ehlo AUTH Authentication [RFC2554]
ehlo ENHANCEDSTATUSCODES Enhanced status codes [RFC2034]
ehlo DELIVERBY Deliver By [RFC2852]
-mail MAIL FROM: <sender> [ <parameters> ]
+mail MAIL From:<sender> [ <parameters> ]
mail Specifies the sender. Parameters are ESMTP extensions.
mail See "HELP DSN" for details.
-rcpt RCPT TO: <recipient> [ <parameters> ]
+rcpt RCPT To:<recipient> [ <parameters> ]
rcpt Specifies the recipient. Can be used any number of times.
rcpt Parameters are ESMTP extensions. See "HELP DSN" for details.
data DATA
@@ -91,7 +91,7 @@ saml implementation.
turn TURN
turn Reverses the direction of the connection. Not currently
turn implemented.
-etrn ETRN [ <hostname> | @<domain> | #<queuename> ]
+etrn ETRN [ <hostname> | @<domain> | \#<queuename> ]
etrn Run the queue for the specified <hostname>, or
etrn all hosts within a given <domain>, or a specially-named
etrn <queuename> (implementation-specific).
diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c
index f274ad8..45ea1ed 100644
--- a/contrib/sendmail/src/main.c
+++ b/contrib/sendmail/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -25,7 +25,7 @@ SM_UNUSED(static char copyright[]) =
The Regents of the University of California. All rights reserved.\n";
#endif /* ! lint */
-SM_RCSID("@(#)$Id: main.c,v 8.939 2004/06/17 16:39:21 ca Exp $")
+SM_RCSID("@(#)$Id: main.c,v 8.942 2005/12/26 04:39:13 ca Exp $")
#if NETINET || NETINET6
@@ -649,7 +649,7 @@ main(argc, argv, envp)
}
/* prime the child environment */
- setuserenv("AGENT", "sendmail");
+ sm_setuserenv("AGENT", "sendmail");
(void) sm_signal(SIGPIPE, SIG_IGN);
OldUmask = umask(022);
@@ -1318,9 +1318,9 @@ main(argc, argv, envp)
if (TimeZoneSpec == NULL)
unsetenv("TZ");
else if (TimeZoneSpec[0] != '\0')
- setuserenv("TZ", TimeZoneSpec);
+ sm_setuserenv("TZ", TimeZoneSpec);
else
- setuserenv("TZ", NULL);
+ sm_setuserenv("TZ", NULL);
tzset();
/* initialize mailbox database */
@@ -1462,6 +1462,16 @@ main(argc, argv, envp)
"Warning: HostStatusDirectory required for SingleThreadDelivery\n");
}
+#if _FFR_MEMSTAT
+ j = sm_memstat_open();
+ if (j < 0 && (RefuseLowMem > 0 || QueueLowMem > 0) && LogLevel > 4)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "cannot get memory statistics, settings ignored, error=%d"
+ , j);
+ }
+#endif /* _FFR_MEMSTAT */
+
/* check for permissions */
if (RealUid != 0 &&
RealUid != TrustedUid)
@@ -2949,6 +2959,9 @@ finis(drop, cleanup, exitstat)
/* reset uid for process accounting */
endpwent();
sm_mbdb_terminate();
+#if _FFR_MEMSTAT
+ (void) sm_memstat_close();
+#endif /* _FFR_MEMSTAT */
(void) setuid(RealUid);
#if SM_HEAP_CHECK
/* dump the heap, if we are checking for memory leaks */
@@ -3439,21 +3452,21 @@ getextenv(envar)
return NULL;
}
/*
-** SETUSERENV -- set an environment in the propagated environment
+** SM_SETUSERENV -- set an environment variable in the propagated environment
**
** Parameters:
** envar -- the name of the environment variable.
** value -- the value to which it should be set. If
** null, this is extracted from the incoming
** environment. If that is not set, the call
-** to setuserenv is ignored.
+** to sm_setuserenv is ignored.
**
** Returns:
** none.
*/
void
-setuserenv(envar, value)
+sm_setuserenv(envar, value)
const char *envar;
const char *value;
{
@@ -3488,7 +3501,7 @@ setuserenv(envar, value)
/* make sure it is in our environment as well */
if (putenv(p) < 0)
- syserr("setuserenv: putenv(%s) failed", p);
+ syserr("sm_setuserenv: putenv(%s) failed", p);
}
/*
** DUMPSTATE -- dump state
diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c
index 056d76e..ee3fbb7 100644
--- a/contrib/sendmail/src/map.c
+++ b/contrib/sendmail/src/map.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: map.c,v 8.669 2005/02/09 01:46:35 ca Exp $")
+SM_RCSID("@(#)$Id: map.c,v 8.671 2005/10/25 17:55:50 ca Exp $")
#if LDAPMAP
# include <sm/ldap.h>
@@ -3493,7 +3493,7 @@ ldapmap_lookup(map, name, av, statp)
char *result = NULL;
SM_RPOOL_T *rpool;
SM_LDAP_STRUCT *lmap = NULL;
- char keybuf[MAXNAME + 1];
+ char keybuf[MAXKEY];
if (tTd(38, 20))
sm_dprintf("ldapmap_lookup(%s, %s)\n", map->map_mname, name);
@@ -3551,6 +3551,10 @@ ldapmap_lookup(map, name, av, statp)
flags |= SM_LDAP_SINGLEMATCH;
if (bitset(MF_MATCHONLY, map->map_mflags))
flags |= SM_LDAP_MATCHONLY;
+# if _FFR_LDAP_SINGLEDN
+ if (bitset(MF_SINGLEDN, map->map_mflags))
+ flags |= SM_LDAP_SINGLEDN;
+# endif /* _FFR_LDAP_SINGLEDN */
/* Create an rpool for search related memory usage */
rpool = sm_rpool_new_x(NULL);
@@ -3911,6 +3915,12 @@ ldapmap_parseargs(map, args)
map->map_mflags |= MF_SINGLEMATCH;
break;
+# if _FFR_LDAP_SINGLEDN
+ case '2':
+ map->map_mflags |= MF_SINGLEDN;
+ break;
+# endif /* _FFR_LDAP_SINGLEDN */
+
/* args stolen from ldapsearch.c */
case 'R': /* don't auto chase referrals */
# ifdef LDAP_REFERRALS
diff --git a/contrib/sendmail/src/mci.c b/contrib/sendmail/src/mci.c
index 2ab0f4b..be4a455 100644
--- a/contrib/sendmail/src/mci.c
+++ b/contrib/sendmail/src/mci.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: mci.c,v 8.214 2005/02/04 22:01:45 ca Exp $")
+SM_RCSID("@(#)$Id: mci.c,v 8.216 2005/07/12 22:27:44 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
@@ -47,11 +47,9 @@ static int mci_read_persistent __P((SM_FILE_T *, MCI *));
** MciCacheTimeout is the time (in seconds) that a connection
** is permitted to survive without activity.
**
-** We actually try any cached connections by sending a NOOP
-** before we use them; if the NOOP fails we close down the
-** connection and reopen it. Note that this means that a
-** server SMTP that doesn't support NOOP will hose the
-** algorithm -- but that doesn't seem too likely.
+** We actually try any cached connections by sending a RSET
+** before we use them; if the RSET fails we close down the
+** connection and reopen it (see smtpprobe()).
**
** The persistent MCI code is donated by Mark Lovell and Paul
** Vixie. It is based on the long term host status code in KJS
@@ -1126,6 +1124,9 @@ mci_traverse_persistent(action, pathname)
char *newptr;
struct dirent *e;
char newpath[MAXPATHLEN];
+#if MAXPATHLEN <= MAXNAMLEN - 3
+ ERROR "MAXPATHLEN <= MAXNAMLEN - 3"
+#endif /* MAXPATHLEN <= MAXNAMLEN - 3 */
if ((d = opendir(pathname)) == NULL)
{
diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c
index 0fba8a1..19fd59d 100644
--- a/contrib/sendmail/src/milter.c
+++ b/contrib/sendmail/src/milter.c
@@ -10,14 +10,14 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: milter.c,v 8.229 2005/03/02 02:32:34 ca Exp $")
+SM_RCSID("@(#)$Id: milter.c,v 8.232 2005/08/05 21:49:04 ca Exp $")
#if MILTER
# include <libmilter/mfapi.h>
# include <libmilter/mfdef.h>
# include <errno.h>
-# include <sys/time.h>
+# include <sm/time.h>
# include <sys/uio.h>
# if NETINET || NETINET6
@@ -1962,11 +1962,20 @@ milter_send_command(m, command, data, sz, e, state)
#if SMFI_VERSION > 2
case SMFIC_UNKNOWN:
+ skipflag = SMFIP_NOUNKNOWN;
action = "unknown";
defresponse = "550 5.7.1 Command rejected";
break;
#endif /* SMFI_VERSION > 2 */
+#if SMFI_VERSION > 3
+ case SMFIC_DATA:
+ skipflag = SMFIP_NODATA;
+ action = "data";
+ defresponse = "550 5.7.1 Command rejected";
+ break;
+#endif /* SMFI_VERSION > 3 */
+
case SMFIC_BODYEOB:
case SMFIC_OPTNEG:
case SMFIC_MACRO:
@@ -2184,8 +2193,9 @@ milter_negotiate(m, e)
mi_int32 fvers;
mi_int32 fflags;
mi_int32 pflags;
- char *response;
+ mi_int32 curr_prot;
ssize_t rlen;
+ char *response;
char data[MILTER_OPTLEN];
/* sanity check */
@@ -2201,7 +2211,18 @@ milter_negotiate(m, e)
fvers = htonl(SMFI_VERSION);
fflags = htonl(SMFI_CURR_ACTS);
- pflags = htonl(SMFI_CURR_PROT);
+ curr_prot = SMFI_V2_PROT
+#if _FFR_MILTER_NOHDR_RESP
+ | SMFIP_NOHREPL
+#endif /* _FFR_MILTER_NOHDR_RESP */
+#if SMFI_VERSION >= 3
+ | SMFIP_NOUNKNOWN
+# if SMFI_VERSION >= 4
+ | SMFIP_NODATA
+# endif /* SMFI_VERSION >= 4 */
+#endif /* SMFI_VERSION >= 3 */
+ ;
+ pflags = htonl(curr_prot);
(void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES);
(void) memcpy(data + MILTER_LEN_BYTES,
(char *) &fflags, MILTER_LEN_BYTES);
@@ -2310,21 +2331,26 @@ milter_negotiate(m, e)
}
/* check for protocol feature mismatch */
- if ((m->mf_pflags & SMFI_CURR_PROT) != m->mf_pflags)
+ if ((m->mf_pflags & curr_prot) != m->mf_pflags)
{
if (tTd(64, 5))
sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n",
m->mf_name, m->mf_pflags,
- (unsigned long) SMFI_CURR_PROT);
+ (unsigned long) curr_prot);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
"Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx",
m->mf_name, m->mf_pflags,
- (unsigned long) SMFI_CURR_PROT);
+ (unsigned long) curr_prot);
milter_error(m, e);
return -1;
}
+ if (m->mf_fvers <= 2)
+ m->mf_pflags |= SMFIP_NOUNKNOWN;
+ if (m->mf_fvers <= 3)
+ m->mf_pflags |= SMFIP_NODATA;
+
if (tTd(64, 5))
sm_dprintf("milter_negotiate(%s): version %u, fflags 0x%x, pflags 0x%x\n",
m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
@@ -2689,10 +2715,10 @@ milter_addheader(response, rlen, e)
** Returns:
** none
**
-** Notes:
-** Unlike milter_addheader(), this does not attempt to determine
-** if the header already exists in the envelope, even a
-** deleted version. It just blindly inserts.
+** Notes:
+** Unlike milter_addheader(), this does not attempt to determine
+** if the header already exists in the envelope, even a
+** deleted version. It just blindly inserts.
*/
static void
@@ -2752,7 +2778,7 @@ milter_insheader(response, rlen, e)
sm_dprintf("Insert (%d) %s: %s\n", idx, response, val);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
- "Milter insert (%d): header: %s: %s",
+ "Milter insert (%d): header: %s: %s",
idx, field, val);
insheader(idx, newstr(field), val, H_USER, e);
}
diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c
index fd3e65a..541307d 100644
--- a/contrib/sendmail/src/mime.c
+++ b/contrib/sendmail/src/mime.c
@@ -14,7 +14,7 @@
#include <sendmail.h>
#include <string.h>
-SM_RCSID("@(#)$Id: mime.c,v 8.137 2004/09/02 21:37:26 ca Exp $")
+SM_RCSID("@(#)$Id: mime.c,v 8.139 2006/03/01 18:07:45 ca Exp $")
/*
** MIME support.
@@ -86,6 +86,7 @@ static bool MapNLtoCRLF;
** MBT_FINAL -- the final boundary
** MBT_INTERMED -- an intermediate boundary
** MBT_NOTSEP -- an end of file
+** SM_IO_EOF -- I/O error occurred
*/
struct args
@@ -298,7 +299,8 @@ mime8to7(mci, header, e, boundaries, flags)
mci->mci_flags |= MCIF_INMIME;
/* skip the early "comment" prologue */
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
bt = MBT_FINAL;
while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
@@ -307,8 +309,9 @@ mime8to7(mci, header, e, boundaries, flags)
bt = mimeboundary(buf, boundaries);
if (bt != MBT_NOTSEP)
break;
- putxline(buf, strlen(buf), mci,
- PXLF_MAPFROM|PXLF_STRIP8BIT);
+ if (!putxline(buf, strlen(buf), mci,
+ PXLF_MAPFROM|PXLF_STRIP8BIT))
+ goto writeerr;
if (tTd(43, 99))
sm_dprintf(" ...%s", buf);
}
@@ -319,19 +322,24 @@ mime8to7(mci, header, e, boundaries, flags)
auto HDR *hdr = NULL;
(void) sm_strlcpyn(buf, sizeof buf, 2, "--", bbuf);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
if (tTd(43, 35))
sm_dprintf(" ...%s\n", buf);
collect(e->e_dfp, false, &hdr, e, false);
if (tTd(43, 101))
putline("+++after collect", mci);
- putheader(mci, hdr, e, flags);
+ if (!putheader(mci, hdr, e, flags))
+ goto writeerr;
if (tTd(43, 101))
putline("+++after putheader", mci);
bt = mime8to7(mci, hdr, e, boundaries, flags);
+ if (bt == SM_IO_EOF)
+ goto writeerr;
}
(void) sm_strlcpyn(buf, sizeof buf, 3, "--", bbuf, "--");
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
if (tTd(43, 35))
sm_dprintf(" ...%s\n", buf);
boundaries[i] = NULL;
@@ -344,8 +352,9 @@ mime8to7(mci, header, e, boundaries, flags)
bt = mimeboundary(buf, boundaries);
if (bt != MBT_NOTSEP)
break;
- putxline(buf, strlen(buf), mci,
- PXLF_MAPFROM|PXLF_STRIP8BIT);
+ if (!putxline(buf, strlen(buf), mci,
+ PXLF_MAPFROM|PXLF_STRIP8BIT))
+ goto writeerr;
if (tTd(43, 99))
sm_dprintf(" ...%s", buf);
}
@@ -373,18 +382,21 @@ mime8to7(mci, header, e, boundaries, flags)
{
auto HDR *hdr = NULL;
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
mci->mci_flags |= MCIF_INMIME;
collect(e->e_dfp, false, &hdr, e, false);
if (tTd(43, 101))
putline("+++after collect", mci);
- putheader(mci, hdr, e, flags);
+ if (!putheader(mci, hdr, e, flags))
+ goto writeerr;
if (tTd(43, 101))
putline("+++after putheader", mci);
if (hvalue("MIME-Version", hdr) == NULL &&
- !bitset(M87F_NO8TO7, flags))
- putline("MIME-Version: 1.0", mci);
+ !bitset(M87F_NO8TO7, flags) &&
+ !putline("MIME-Version: 1.0", mci))
+ goto writeerr;
bt = mime8to7(mci, hdr, e, boundaries, flags);
mci->mci_flags &= ~MCIF_INMIME;
return bt;
@@ -480,11 +492,13 @@ mime8to7(mci, header, e, boundaries, flags)
(void) sm_snprintf(buf, sizeof buf,
"Content-Transfer-Encoding: %.200s", cte);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
if (tTd(43, 36))
sm_dprintf(" ...%s\n", buf);
}
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
!= NULL)
@@ -492,7 +506,8 @@ mime8to7(mci, header, e, boundaries, flags)
bt = mimeboundary(buf, boundaries);
if (bt != MBT_NOTSEP)
break;
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
if (sm_io_eof(e->e_dfp))
bt = MBT_FINAL;
@@ -505,12 +520,13 @@ mime8to7(mci, header, e, boundaries, flags)
if (tTd(43, 36))
sm_dprintf(" ...Content-Transfer-Encoding: base64\n");
- putline("Content-Transfer-Encoding: base64", mci);
+ if (!putline("Content-Transfer-Encoding: base64", mci))
+ goto writeerr;
(void) sm_snprintf(buf, sizeof buf,
"X-MIME-Autoconverted: from 8bit to base64 by %s id %s",
MyHostName, e->e_id);
- putline(buf, mci);
- putline("", mci);
+ if (!putline(buf, mci) || !putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
while ((c1 = mime_getchar_crlf(e->e_dfp, boundaries, &bt)) !=
SM_IO_EOF)
@@ -518,7 +534,8 @@ mime8to7(mci, header, e, boundaries, flags)
if (linelen > 71)
{
*bp = '\0';
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
linelen = 0;
bp = buf;
}
@@ -548,7 +565,8 @@ mime8to7(mci, header, e, boundaries, flags)
*bp++ = Base64Code[c2 & 0x3f];
}
*bp = '\0';
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
else
{
@@ -571,12 +589,14 @@ mime8to7(mci, header, e, boundaries, flags)
if (tTd(43, 36))
sm_dprintf(" ...Content-Transfer-Encoding: quoted-printable\n");
- putline("Content-Transfer-Encoding: quoted-printable", mci);
+ if (!putline("Content-Transfer-Encoding: quoted-printable",
+ mci))
+ goto writeerr;
(void) sm_snprintf(buf, sizeof buf,
"X-MIME-Autoconverted: from 8bit to quoted-printable by %s id %s",
MyHostName, e->e_id);
- putline(buf, mci);
- putline("", mci);
+ if (!putline(buf, mci) || !putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
fromstate = 0;
c2 = '\n';
@@ -598,7 +618,8 @@ mime8to7(mci, header, e, boundaries, flags)
*bp++ = Base16Code['.' & 0x0f];
}
*bp = '\0';
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
linelen = fromstate = 0;
bp = buf;
c2 = c1;
@@ -627,7 +648,8 @@ mime8to7(mci, header, e, boundaries, flags)
c2 = '\n';
*bp++ = '=';
*bp = '\0';
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
linelen = fromstate = 0;
bp = buf;
if (c2 == '.')
@@ -665,13 +687,17 @@ mime8to7(mci, header, e, boundaries, flags)
if (linelen > 0 || boundaries[0] != NULL)
{
*bp = '\0';
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
}
if (tTd(43, 3))
sm_dprintf("\t\t\tmime8to7=>%s (basic)\n", MimeBoundaryNames[bt]);
return bt;
+
+ writeerr:
+ return SM_IO_EOF;
}
/*
** MIME_GETCHAR -- get a character for MIME processing
@@ -958,7 +984,7 @@ static int mime_fromqp __P((unsigned char *, unsigned char **, int));
** e -- envelope.
**
** Returns:
-** none.
+** true iff body was written successfully
*/
static char index_64[128] =
@@ -975,7 +1001,7 @@ static char index_64[128] =
# define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
-void
+bool
mime7to8(mci, header, e)
register MCI *mci;
HDR *header;
@@ -1008,25 +1034,31 @@ mime7to8(mci, header, e)
{
(void) sm_snprintf(buf, sizeof buf,
"Content-Transfer-Encoding: %s", p);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
!= NULL)
- putline(buf, mci);
- return;
+ {
+ if (!putline(buf, mci))
+ goto writeerr;
+ }
+ return true;
}
cataddr(pvp, NULL, buf, sizeof buf, '\0');
cte = sm_rpool_strdup_x(e->e_rpool, buf);
mci->mci_flags |= MCIF_INHEADER;
- putline("Content-Transfer-Encoding: 8bit", mci);
+ if (!putline("Content-Transfer-Encoding: 8bit", mci))
+ goto writeerr;
(void) sm_snprintf(buf, sizeof buf,
"X-MIME-Autoconverted: from %.200s to 8bit by %s id %s",
cte, MyHostName, e->e_id);
- putline(buf, mci);
- putline("", mci);
+ if (!putline(buf, mci) || !putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
/*
@@ -1090,7 +1122,8 @@ mime7to8(mci, header, e)
if (*fbufp++ == '\n' || fbufp >= &fbuf[MAXLINE]) \
{ \
CHK_EOL; \
- putxline((char *) fbuf, fbufp - fbuf, mci, pxflags); \
+ if (!putxline((char *) fbuf, fbufp - fbuf, mci, pxflags)) \
+ goto writeerr; \
pxflags &= ~PXLF_NOADDEOL; \
fbufp = fbuf; \
} \
@@ -1127,8 +1160,11 @@ again:
continue;
if (fbufp - fbuf > 0)
- putxline((char *) fbuf, fbufp - fbuf - 1, mci,
- pxflags);
+ {
+ if (!putxline((char *) fbuf, fbufp - fbuf - 1,
+ mci, pxflags))
+ goto writeerr;
+ }
fbufp = fbuf;
if (off >= 0 && buf[off] != '\0')
{
@@ -1144,7 +1180,8 @@ again:
if (fbufp > fbuf)
{
*fbufp = '\0';
- putxline((char *) fbuf, fbufp - fbuf, mci, pxflags);
+ if (!putxline((char *) fbuf, fbufp - fbuf, mci, pxflags))
+ goto writeerr;
}
/*
@@ -1154,10 +1191,15 @@ again:
** but so is auto-converting MIME in the first place.
*/
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
if (tTd(43, 3))
sm_dprintf("\t\t\tmime7to8 => %s to 8bit done\n", cte);
+ return true;
+
+ writeerr:
+ return false;
}
/*
** The following is based on Borenstein's "codes.c" module, with simplifying
diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c
index 4852ab5..ee4f61f 100644
--- a/contrib/sendmail/src/parseaddr.c
+++ b/contrib/sendmail/src/parseaddr.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: parseaddr.c,v 8.381 2005/02/04 22:01:45 ca Exp $")
+SM_RCSID("@(#)$Id: parseaddr.c,v 8.383 2006/02/01 19:46:11 ca Exp $")
static void allocaddr __P((ADDRESS *, int, char *, ENVELOPE *));
static int callsubr __P((char**, int, ENVELOPE *));
@@ -1337,7 +1337,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
/* $&{x} replacement */
char *mval = macvalue(rp[1], e);
char **xpvp;
- int trsize = 0;
+ size_t trsize = 0;
static size_t pvpb1_size = 0;
static char **pvpb1 = NULL;
char pvpbuf[PSBUFSIZE];
@@ -1352,7 +1352,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
/* save the remainder of the input */
for (xpvp = pvp; *xpvp != NULL; xpvp++)
trsize += sizeof *xpvp;
- if ((size_t) trsize > pvpb1_size)
+ if (trsize > pvpb1_size)
{
if (pvpb1 != NULL)
sm_free(pvpb1);
@@ -1407,7 +1407,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
{
char **hbrvp;
char **xpvp;
- int trsize;
+ size_t trsize;
char *replac;
int endtoken;
STAB *map;
@@ -1415,7 +1415,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
char **key_rvp;
char **arg_rvp;
char **default_rvp;
- char cbuf[MAXNAME + 1];
+ char cbuf[MAXKEY];
char *pvpb1[MAXATOM + 1];
char *argvect[MAX_MAP_ARGS];
char pvpbuf[PSBUFSIZE];
@@ -1509,7 +1509,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
*++arg_rvp = NULL;
/* save the remainder of the input string */
- trsize = (int) (avp - rvp + 1) * sizeof *rvp;
+ trsize = (avp - rvp + 1) * sizeof *rvp;
memmove((char *) pvpb1, (char *) rvp, trsize);
/* look it up */
@@ -2949,7 +2949,7 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
char *logid;
{
char *volatile buf;
- int bufsize;
+ size_t bufsize;
int saveexitstat;
int volatile rstat = EX_OK;
char **pvp;
@@ -3163,7 +3163,7 @@ rscap(rwset, p1, p2, e, pvp, pvpbuf, size)
int size;
{
char *volatile buf;
- int bufsize;
+ size_t bufsize;
int volatile rstat = EX_OK;
int rsno;
bool saveQuickAbort = QuickAbort;
diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c
index 972e240..6cf7fc9 100644
--- a/contrib/sendmail/src/queue.c
+++ b/contrib/sendmail/src/queue.c
@@ -14,7 +14,7 @@
#include <sendmail.h>
#include <sm/sem.h>
-SM_RCSID("@(#)$Id: queue.c,v 8.944 2005/02/17 23:58:58 ca Exp $")
+SM_RCSID("@(#)$Id: queue.c,v 8.951 2006/03/02 19:13:38 ca Exp $")
#include <dirent.h>
@@ -2853,7 +2853,8 @@ gatherq(qgrp, qdir, doall, full, more)
if (cf != NULL)
(void) sm_io_close(cf, SM_TIME_DEFAULT);
- if ((!doall && shouldqueue(w->w_pri, w->w_ctime)) ||
+ if ((!doall && (shouldqueue(w->w_pri, w->w_ctime) ||
+ w->w_tooyoung)) ||
bitset(HAS_QUARANTINE, i) ||
bitset(NEED_QUARANTINE, i) ||
bitset(NEED_R|NEED_S, i))
@@ -2931,10 +2932,6 @@ sortq(max)
if (WorkList == NULL || wc <= 0)
return 0;
- /* Check if the per queue group item limit will be exceeded */
- if (wc > max && max > 0)
- wc = max;
-
/*
** The sort now takes place using all of the items in WorkList.
** The list gets trimmed to the most important items after the sort.
@@ -3046,6 +3043,10 @@ sortq(max)
}
/* else don't sort at all */
+ /* Check if the per queue group item limit will be exceeded */
+ if (wc > max && max > 0)
+ wc = max;
+
/*
** Convert the work list into canonical form.
** Should be turning it into a list of envelopes here perhaps.
@@ -3443,13 +3444,13 @@ init_shuffle_alphabet()
return;
/* fill the ShuffledAlphabet */
- for (i = 0; i < NCHAR; i++)
+ for (i = 0; i < NASCII; i++)
ShuffledAlphabet[i] = i;
/* mix it */
- for (i = 1; i < NCHAR; i++)
+ for (i = 1; i < NASCII; i++)
{
- register int j = get_random() % NCHAR;
+ register int j = get_random() % NASCII;
register int tmp;
tmp = ShuffledAlphabet[j];
@@ -3462,8 +3463,8 @@ init_shuffle_alphabet()
ShuffledAlphabet[i] = ShuffledAlphabet[i + 'a' - 'A'];
/* fill the upper part */
- for (i = 0; i < NCHAR; i++)
- ShuffledAlphabet[i + NCHAR] = ShuffledAlphabet[i];
+ for (i = 0; i < NASCII; i++)
+ ShuffledAlphabet[i + NASCII] = ShuffledAlphabet[i];
init = true;
}
@@ -6266,7 +6267,8 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
** If the directory does not exist, -1 is returned.
**
** Parameters:
-** path -- pathname of directory
+** name -- name of directory (must be persistent!)
+** path -- pathname of directory (name plus maybe "/df")
** add -- add to structure if not found.
**
** Returns:
@@ -6277,14 +6279,15 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
** FSF_NOT_FOUND: not in list
*/
-static short filesys_find __P((char *, bool));
+static short filesys_find __P((char *, char *, bool));
#define FSF_NOT_FOUND (-1)
#define FSF_STAT_FAIL (-2)
#define FSF_TOO_MANY (-3)
static short
-filesys_find(path, add)
+filesys_find(name, path, add)
+ char *name;
char *path;
bool add;
{
@@ -6310,7 +6313,7 @@ filesys_find(path, add)
return FSF_NOT_FOUND;
++NumFileSys;
- FILE_SYS_NAME(i) = path;
+ FILE_SYS_NAME(i) = name;
FILE_SYS_DEV(i) = st.st_dev;
FILE_SYS_AVAIL(i) = 0;
FILE_SYS_BLKSIZE(i) = 1024; /* avoid divide by zero */
@@ -6350,8 +6353,12 @@ filesys_setup(add)
for (j = 0; j < Queue[i]->qg_numqueues; ++j)
{
QPATHS *qp = &Queue[i]->qg_qpaths[j];
+ char qddf[MAXPATHLEN];
- fs = filesys_find(qp->qp_name, add);
+ (void) sm_strlcpyn(qddf, sizeof qddf, 2, qp->qp_name,
+ (bitset(QP_SUBDF, qp->qp_subdirs)
+ ? "/df" : ""));
+ fs = filesys_find(qp->qp_name, qddf, add);
if (fs >= 0)
qp->qp_fsysidx = fs;
else
@@ -6679,6 +6686,22 @@ write_key_file(keypath, key)
}
else
{
+ if (geteuid() == 0 && RunAsUid != 0)
+ {
+# if HASFCHOWN
+ int fd;
+
+ fd = keyf->f_file;
+ if (fd >= 0 && fchown(fd, RunAsUid, -1) < 0)
+ {
+ int err = errno;
+
+ sm_syslog(LOG_ALERT, NOQID,
+ "ownership change on %s to %d failed: %s",
+ keypath, RunAsUid, sm_errstring(err));
+ }
+# endif /* HASFCHOWN */
+ }
ok = sm_io_fprintf(keyf, SM_TIME_DEFAULT, "%ld\n", key) !=
SM_IO_EOF;
ok = (sm_io_close(keyf, SM_TIME_DEFAULT) != SM_IO_EOF) && ok;
@@ -6830,13 +6853,11 @@ init_shm(qn, owner, hash)
#endif /* _FFR_SELECT_SHM */
if (owner && RunAsUid != 0)
{
- i = sm_shmsetowner(ShmId, RunAsUid, RunAsGid,
- 0660);
+ i = sm_shmsetowner(ShmId, RunAsUid, RunAsGid, 0660);
if (i != 0)
sm_syslog(LOG_ERR, NOQID,
- "key=%ld, sm_shmsetowner=%d, RunAsUid=%d, RunAsGid=%d",
- (long) ShmKey, i,
- RunAsUid, RunAsGid);
+ "key=%ld, sm_shmsetowner=%d, RunAsUid=%d, RunAsGid=%d",
+ (long) ShmKey, i, RunAsUid, RunAsGid);
}
p = (int *) Pshm;
if (owner)
@@ -7722,8 +7743,11 @@ dup_df(old, new)
** are on the same file system.
*/
- ofs = Queue[old->e_qgrp]->qg_qpaths[old->e_qdir].qp_fsysidx;
- nfs = Queue[new->e_qgrp]->qg_qpaths[new->e_qdir].qp_fsysidx;
+ SM_REQUIRE(ISVALIDQGRP(old->e_dfqgrp) && ISVALIDQDIR(old->e_dfqdir));
+ SM_REQUIRE(ISVALIDQGRP(new->e_dfqgrp) && ISVALIDQDIR(new->e_dfqdir));
+
+ ofs = Queue[old->e_dfqgrp]->qg_qpaths[old->e_dfqdir].qp_fsysidx;
+ nfs = Queue[new->e_dfqgrp]->qg_qpaths[new->e_dfqdir].qp_fsysidx;
if (FILE_SYS_DEV(ofs) == FILE_SYS_DEV(nfs))
{
if (link(opath, npath) == 0)
diff --git a/contrib/sendmail/src/ratectrl.c b/contrib/sendmail/src/ratectrl.c
index d141125..3185eae 100644
--- a/contrib/sendmail/src/ratectrl.c
+++ b/contrib/sendmail/src/ratectrl.c
@@ -45,7 +45,7 @@
*/
#include <sendmail.h>
-SM_RCSID("@(#)$Id: ratectrl.c,v 8.9 2004/07/07 21:23:57 ca Exp $")
+SM_RCSID("@(#)$Id: ratectrl.c,v 8.10 2005/06/14 23:07:23 ca Exp $")
/*
** stuff included - given some warnings (inet_ntoa)
@@ -56,7 +56,7 @@ SM_RCSID("@(#)$Id: ratectrl.c,v 8.9 2004/07/07 21:23:57 ca Exp $")
# include <arpa/inet.h>
#endif /* NETINET || NETINET6 */
-#include <sys/time.h>
+#include <sm/time.h>
#ifndef HASH_ALG
# define HASH_ALG 2
diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c
index b362391..f4a3759 100644
--- a/contrib/sendmail/src/readcf.c
+++ b/contrib/sendmail/src/readcf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: readcf.c,v 8.642 2004/08/04 21:17:57 ca Exp $")
+SM_RCSID("@(#)$Id: readcf.c,v 8.651 2006/03/02 19:17:09 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
@@ -679,7 +679,7 @@ readcf(cfname, safe, e)
p = strchr(bp, '=');
if (p != NULL)
*p++ = '\0';
- setuserenv(&bp[1], p);
+ sm_setuserenv(&bp[1], p);
break;
case 'X': /* mail filter */
@@ -2191,6 +2191,26 @@ static struct optioninfo
# define O_HELONAME 0xd8
{ "HeloName", O_HELONAME, OI_NONE },
#endif /* _FFR_HELONAME */
+#if _FFR_MEMSTAT
+# define O_REFUSELOWMEM 0xd9
+ { "RefuseLowMem", O_REFUSELOWMEM, OI_NONE },
+# define O_QUEUELOWMEM 0xda
+ { "QueueLowMem", O_QUEUELOWMEM, OI_NONE },
+# define O_MEMRESOURCE 0xdb
+ { "MemoryResource", O_MEMRESOURCE, OI_NONE },
+#endif /* _FFR_MEMSTAT */
+#if _FFR_MAXNOOPCOMMANDS
+# define O_MAXNOOPCOMMANDS 0xdc
+ { "MaxNOOPCommands", O_MAXNOOPCOMMANDS, OI_NONE },
+#endif /* _FFR_MAXNOOPCOMMANDS */
+#if _FFR_MSG_ACCEPT
+# define O_MSG_ACCEPT 0xdd
+ { "MessageAccept", O_MSG_ACCEPT, OI_NONE },
+#endif /* _FFR_MSG_ACCEPT */
+#if _FFR_QUEUE_RUN_PARANOIA
+# define O_CHK_Q_RUNNERS 0xde
+ { "CheckQueueRunners", O_CHK_Q_RUNNERS, OI_NONE },
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
{ NULL, '\0', OI_NONE }
};
@@ -2231,10 +2251,10 @@ setoption(opt, val, safe, sticky, e)
#if _FFR_ALLOW_SASLINFO
extern unsigned int SubmitMode;
#endif /* _FFR_ALLOW_SASLINFO */
-#if STARTTLS
+#if STARTTLS || (_FFR_SELECT_SHM && SM_CONF_SHM)
char *newval;
char exbuf[MAXLINE];
-#endif /* STARTTLS */
+#endif /* STARTTLS || (_FFR_SELECT_SHM && SM_CONF_SHM) */
errno = 0;
if (opt == ' ')
@@ -2472,6 +2492,10 @@ setoption(opt, val, safe, sticky, e)
case SM_DEFER: /* queue only and defer map lookups */
case SM_DELIVER: /* do everything */
case SM_FORK: /* fork after verification */
+#if _FFR_DM_ONE
+ /* deliver first TA in background, then queue */
+ case SM_DM_ONE:
+#endif /* _FFR_DM_ONE */
set_delivery_mode(*val, e);
break;
@@ -3707,9 +3731,38 @@ setoption(opt, val, safe, sticky, e)
#if _FFR_HELONAME
case O_HELONAME:
- HeloName = newstr(val);
- break;
+ HeloName = newstr(val);
+ break;
#endif /* _FFR_HELONAME */
+#if _FFR_MEMSTAT
+ case O_REFUSELOWMEM:
+ RefuseLowMem = atoi(val);
+ break;
+ case O_QUEUELOWMEM:
+ QueueLowMem = atoi(val);
+ break;
+ case O_MEMRESOURCE:
+ MemoryResource = newstr(val);
+ break;
+#endif /* _FFR_MEMSTAT */
+
+#if _FFR_MAXNOOPCOMMANDS
+ case O_MAXNOOPCOMMANDS:
+ MaxNOOPCommands = atoi(val);
+ break;
+#endif /* _FFR_MAXNOOPCOMMANDS */
+
+#if _FFR_MSG_ACCEPT
+ case O_MSG_ACCEPT:
+ MessageAccept = newstr(val);
+ break;
+#endif /* _FFR_MSG_ACCEPT */
+
+#if _FFR_QUEUE_RUN_PARANOIA
+ case O_CHK_Q_RUNNERS:
+ CheckQueueRunners = atoi(val);
+ break;
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
default:
if (tTd(37, 1))
diff --git a/contrib/sendmail/src/savemail.c b/contrib/sendmail/src/savemail.c
index 857d81f..75231da 100644
--- a/contrib/sendmail/src/savemail.c
+++ b/contrib/sendmail/src/savemail.c
@@ -13,9 +13,9 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: savemail.c,v 8.304 2004/10/06 21:36:06 ca Exp $")
+SM_RCSID("@(#)$Id: savemail.c,v 8.306 2006/02/25 02:16:53 ca Exp $")
-static void errbody __P((MCI *, ENVELOPE *, char *));
+static bool errbody __P((MCI *, ENVELOPE *, char *));
static bool pruneroute __P((char *));
/*
@@ -432,12 +432,13 @@ savemail(e, sendbody)
p = macvalue('g', e);
macdefine(&e->e_macro, A_PERM, 'g', e->e_sender);
- putfromline(&mcibuf, e);
- (*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
- (*e->e_putbody)(&mcibuf, e, NULL);
- putline("\n", &mcibuf); /* XXX EOL from FileMailer? */
- (void) sm_io_flush(fp, SM_TIME_DEFAULT);
- if (sm_io_error(fp) ||
+ if (!putfromline(&mcibuf, e) ||
+ !(*e->e_puthdr)(&mcibuf, e->e_header, e,
+ M87F_OUTER) ||
+ !(*e->e_putbody)(&mcibuf, e, NULL) ||
+ !putline("\n", &mcibuf) ||
+ sm_io_flush(fp, SM_TIME_DEFAULT) == SM_IO_EOF ||
+ sm_io_error(fp) ||
sm_io_close(fp, SM_TIME_DEFAULT) < 0)
state = ESM_PANIC;
else
@@ -732,14 +733,14 @@ returntosender(msg, returnq, flags, e)
** separator -- any possible MIME separator (unused).
**
** Returns:
-** none
+** success
**
** Side Effects:
** Outputs the body of an error message.
*/
/* ARGSUSED2 */
-static void
+static bool
errbody(mci, e, separator)
register MCI *mci;
register ENVELOPE *e;
@@ -757,14 +758,16 @@ errbody(mci, e, separator)
if (bitset(MCIF_INHEADER, mci->mci_flags))
{
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
}
if (e->e_parent == NULL)
{
syserr("errbody: null parent");
- putline(" ----- Original message lost -----\n", mci);
- return;
+ if (!putline(" ----- Original message lost -----\n", mci))
+ goto writeerr;
+ return true;
}
/*
@@ -773,11 +776,12 @@ errbody(mci, e, separator)
if (e->e_msgboundary != NULL)
{
- putline("This is a MIME-encapsulated message", mci);
- putline("", mci);
(void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary);
- putline(buf, mci);
- putline("", mci);
+ if (!putline("This is a MIME-encapsulated message", mci) ||
+ !putline("", mci) ||
+ !putline(buf, mci) ||
+ !putline("", mci))
+ goto writeerr;
}
/*
@@ -799,31 +803,36 @@ errbody(mci, e, separator)
if (!pm_notify && q == NULL &&
!bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags))
{
- putline(" **********************************************",
- mci);
- putline(" ** THIS IS A WARNING MESSAGE ONLY **",
- mci);
- putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **",
- mci);
- putline(" **********************************************",
- mci);
- putline("", mci);
+ if (!putline(" **********************************************",
+ mci) ||
+ !putline(" ** THIS IS A WARNING MESSAGE ONLY **",
+ mci) ||
+ !putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **",
+ mci) ||
+ !putline(" **********************************************",
+ mci) ||
+ !putline("", mci))
+ goto writeerr;
}
(void) sm_snprintf(buf, sizeof buf,
"The original message was received at %s",
arpadate(ctime(&e->e_parent->e_ctime)));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
expand("from \201_", buf, sizeof buf, e->e_parent);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
/* include id in postmaster copies */
if (pm_notify && e->e_parent->e_id != NULL)
{
(void) sm_strlcpyn(buf, sizeof buf, 2, "with id ",
e->e_parent->e_id);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
/*
** Output error message header (if specified and available).
@@ -849,17 +858,19 @@ errbody(mci, e, separator)
{
translate_dollars(buf);
expand(buf, buf, sizeof buf, e);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
(void) sm_io_close(xfile, SM_TIME_DEFAULT);
- putline("\n", mci);
+ if (!putline("\n", mci))
+ goto writeerr;
}
}
else
{
expand(ErrMsgFile, buf, sizeof buf, e);
- putline(buf, mci);
- putline("", mci);
+ if (!putline(buf, mci) || !putline("", mci))
+ goto writeerr;
}
}
@@ -877,21 +888,24 @@ errbody(mci, e, separator)
if (printheader)
{
- putline(" ----- The following addresses had permanent fatal errors -----",
- mci);
+ if (!putline(" ----- The following addresses had permanent fatal errors -----",
+ mci))
+ goto writeerr;
printheader = false;
}
(void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR),
sizeof buf);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
if (q->q_rstatus != NULL)
{
(void) sm_snprintf(buf, sizeof buf,
" (reason: %s)",
shortenstring(exitstat(q->q_rstatus),
MAXSHORTSTR));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
if (q->q_alias != NULL)
{
@@ -899,11 +913,12 @@ errbody(mci, e, separator)
" (expanded from: %s)",
shortenstring(q->q_alias->q_paddr,
MAXSHORTSTR));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
}
- if (!printheader)
- putline("", mci);
+ if (!printheader && !putline("", mci))
+ goto writeerr;
/* transient non-fatal errors */
printheader = true;
@@ -917,25 +932,28 @@ errbody(mci, e, separator)
if (printheader)
{
- putline(" ----- The following addresses had transient non-fatal errors -----",
- mci);
+ if (!putline(" ----- The following addresses had transient non-fatal errors -----",
+ mci))
+ goto writeerr;
printheader = false;
}
(void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR),
sizeof buf);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
if (q->q_alias != NULL)
{
(void) sm_snprintf(buf, sizeof buf,
" (expanded from: %s)",
shortenstring(q->q_alias->q_paddr,
MAXSHORTSTR));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
}
- if (!printheader)
- putline("", mci);
+ if (!printheader && !putline("", mci))
+ goto writeerr;
/* successful delivery notifications */
printheader = true;
@@ -968,25 +986,28 @@ errbody(mci, e, separator)
if (printheader)
{
- putline(" ----- The following addresses had successful delivery notifications -----",
- mci);
+ if (!putline(" ----- The following addresses had successful delivery notifications -----",
+ mci))
+ goto writeerr;
printheader = false;
}
(void) sm_snprintf(buf, sizeof buf, "%s (%s)",
shortenstring(q->q_paddr, MAXSHORTSTR), p);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
if (q->q_alias != NULL)
{
(void) sm_snprintf(buf, sizeof buf,
" (expanded from: %s)",
shortenstring(q->q_alias->q_paddr,
MAXSHORTSTR));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
}
- if (!printheader)
- putline("", mci);
+ if (!printheader && !putline("", mci))
+ goto writeerr;
/*
** Output transcript of errors
@@ -995,8 +1016,9 @@ errbody(mci, e, separator)
(void) sm_io_flush(smioout, SM_TIME_DEFAULT);
if (e->e_parent->e_xfp == NULL)
{
- putline(" ----- Transcript of session is unavailable -----\n",
- mci);
+ if (!putline(" ----- Transcript of session is unavailable -----\n",
+ mci))
+ goto writeerr;
}
else
{
@@ -1007,11 +1029,12 @@ errbody(mci, e, separator)
while (sm_io_fgets(e->e_parent->e_xfp, SM_TIME_DEFAULT, buf,
sizeof buf) != NULL)
{
- if (printheader)
- putline(" ----- Transcript of session follows -----\n",
- mci);
+ if (printheader && !putline(" ----- Transcript of session follows -----\n",
+ mci))
+ goto writeerr;
printheader = false;
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
}
errno = 0;
@@ -1023,11 +1046,12 @@ errbody(mci, e, separator)
if (e->e_msgboundary != NULL)
{
- putline("", mci);
(void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary);
- putline(buf, mci);
- putline("Content-Type: message/delivery-status", mci);
- putline("", mci);
+ if (!putline("", mci) ||
+ !putline(buf, mci) ||
+ !putline("Content-Type: message/delivery-status", mci) ||
+ !putline("", mci))
+ goto writeerr;
/*
** Output per-message information.
@@ -1039,13 +1063,15 @@ errbody(mci, e, separator)
(void) sm_snprintf(buf, sizeof buf,
"Original-Envelope-Id: %.800s",
xuntextify(e->e_parent->e_envid));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* Reporting-MTA: is us (required) */
(void) sm_snprintf(buf, sizeof buf,
"Reporting-MTA: dns; %.800s", MyHostName);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
/* DSN-Gateway: not relevant since we are not translating */
@@ -1059,13 +1085,15 @@ errbody(mci, e, separator)
(void) sm_snprintf(buf, sizeof buf,
"Received-From-MTA: %s; %.800s",
p, RealHostName);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* Arrival-Date: -- when it arrived here */
(void) sm_strlcpyn(buf, sizeof buf, 2, "Arrival-Date: ",
arpadate(ctime(&e->e_parent->e_ctime)));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
/* Deliver-By-Date: -- when it should have been delivered */
if (IS_DLVR_BY(e->e_parent))
@@ -1076,7 +1104,8 @@ errbody(mci, e, separator)
(void) sm_strlcpyn(buf, sizeof buf, 2,
"Deliver-By-Date: ",
arpadate(ctime(&dbyd)));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/*
@@ -1119,7 +1148,8 @@ errbody(mci, e, separator)
else
continue;
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
/* Original-Recipient: -- passed from on high */
if (q->q_orcpt != NULL)
@@ -1127,7 +1157,8 @@ errbody(mci, e, separator)
(void) sm_snprintf(buf, sizeof buf,
"Original-Recipient: %.800s",
q->q_orcpt);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* Figure out actual recipient */
@@ -1176,7 +1207,8 @@ errbody(mci, e, separator)
(void) sm_snprintf(buf, sizeof buf,
"Final-Recipient: %s",
q->q_finalrcpt);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* X-Actual-Recipient: -- the real problem address */
@@ -1190,13 +1222,15 @@ errbody(mci, e, separator)
(void) sm_snprintf(buf, sizeof buf,
"X-Actual-Recipient: %s",
actual);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* Action: -- what happened? */
(void) sm_strlcpyn(buf, sizeof buf, 2, "Action: ",
action);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
/* Status: -- what _really_ happened? */
if (q->q_status != NULL)
@@ -1208,7 +1242,8 @@ errbody(mci, e, separator)
else
p = "2.0.0";
(void) sm_strlcpyn(buf, sizeof buf, 2, "Status: ", p);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
/* Remote-MTA: -- who was I talking to? */
if (q->q_statmta != NULL)
@@ -1222,7 +1257,8 @@ errbody(mci, e, separator)
p = &buf[strlen(buf) - 1];
if (*p == '.')
*p = '\0';
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* Diagnostic-Code: -- actual result from other end */
@@ -1234,7 +1270,8 @@ errbody(mci, e, separator)
(void) sm_snprintf(buf, sizeof buf,
"Diagnostic-Code: %s; %.800s",
p, q->q_rstatus);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
/* Last-Attempt-Date: -- fine granularity */
@@ -1243,7 +1280,8 @@ errbody(mci, e, separator)
(void) sm_strlcpyn(buf, sizeof buf, 2,
"Last-Attempt-Date: ",
arpadate(ctime(&q->q_statdate)));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
/* Will-Retry-Until: -- for delayed messages only */
if (QS_IS_QUEUEUP(q->q_state))
@@ -1255,7 +1293,8 @@ errbody(mci, e, separator)
(void) sm_strlcpyn(buf, sizeof buf, 2,
"Will-Retry-Until: ",
arpadate(ctime(&xdate)));
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
}
}
@@ -1265,7 +1304,8 @@ errbody(mci, e, separator)
** Output text of original message
*/
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
if (bitset(EF_HAS_DF, e->e_parent->e_flags))
{
sendbody = !bitset(EF_NO_BODY_RETN, e->e_parent->e_flags) &&
@@ -1273,21 +1313,27 @@ errbody(mci, e, separator)
if (e->e_msgboundary == NULL)
{
- if (sendbody)
- putline(" ----- Original message follows -----\n", mci);
- else
- putline(" ----- Message header follows -----\n", mci);
+ if (!putline(
+ sendbody
+ ? " ----- Original message follows -----\n"
+ : " ----- Message header follows -----\n",
+ mci))
+ {
+ goto writeerr;
+ }
}
else
{
(void) sm_strlcpyn(buf, sizeof buf, 2, "--",
e->e_msgboundary);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
(void) sm_strlcpyn(buf, sizeof buf, 2, "Content-Type: ",
sendbody ? "message/rfc822"
: "text/rfc822-headers");
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
p = hvalue("Content-Transfer-Encoding",
e->e_parent->e_header);
@@ -1301,43 +1347,62 @@ errbody(mci, e, separator)
(void) sm_snprintf(buf, sizeof buf,
"Content-Transfer-Encoding: %s",
p);
- putline(buf, mci);
+ if (!putline(buf, mci))
+ goto writeerr;
}
}
- putline("", mci);
+ if (!putline("", mci))
+ goto writeerr;
save_errno = errno;
- putheader(mci, e->e_parent->e_header, e->e_parent, M87F_OUTER);
+ if (!putheader(mci, e->e_parent->e_header, e->e_parent,
+ M87F_OUTER))
+ goto writeerr;
errno = save_errno;
if (sendbody)
- putbody(mci, e->e_parent, e->e_msgboundary);
+ {
+ if (!putbody(mci, e->e_parent, e->e_msgboundary))
+ goto writeerr;
+ }
else if (e->e_msgboundary == NULL)
{
- putline("", mci);
- putline(" ----- Message body suppressed -----", mci);
+ if (!putline("", mci) ||
+ !putline(" ----- Message body suppressed -----",
+ mci))
+ {
+ goto writeerr;
+ }
}
}
else if (e->e_msgboundary == NULL)
{
- putline(" ----- No message was collected -----\n", mci);
+ if (!putline(" ----- No message was collected -----\n", mci))
+ goto writeerr;
}
if (e->e_msgboundary != NULL)
{
- putline("", mci);
(void) sm_strlcpyn(buf, sizeof buf, 3, "--", e->e_msgboundary,
"--");
- putline(buf, mci);
+ if (!putline("", mci) || !putline(buf, mci))
+ goto writeerr;
}
- putline("", mci);
- (void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT);
+ if (!putline("", mci) ||
+ sm_io_flush(mci->mci_out, SM_TIME_DEFAULT) == SM_IO_EOF)
+ goto writeerr;
/*
** Cleanup and exit
*/
if (errno != 0)
+ {
+ writeerr:
syserr("errbody: I/O error");
+ return false;
+ }
+ return true;
}
+
/*
** SMTPTODSN -- convert SMTP to DSN status code
**
@@ -1402,9 +1467,9 @@ smtptodsn(smtpstat)
return "5.0.0";
}
- if ((smtpstat / 100) == 2)
+ if (REPLYTYPE(smtpstat) == 2)
return "2.0.0";
- if ((smtpstat / 100) == 4)
+ if (REPLYTYPE(smtpstat) == 4)
return "4.0.0";
return "5.0.0";
}
diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h
index ea48a75..302079e 100644
--- a/contrib/sendmail/src/sendmail.h
+++ b/contrib/sendmail/src/sendmail.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -52,7 +52,7 @@
#ifdef _DEFINE
# ifndef lint
-SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.993 2005/03/07 18:03:17 ca Exp $";
+SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1006 2006/02/27 17:49:09 ca Exp $";
# endif /* ! lint */
#endif /* _DEFINE */
@@ -809,13 +809,13 @@ extern struct hdrinfo HdrInfo[];
/* functions */
extern void addheader __P((char *, char *, int, ENVELOPE *));
extern unsigned long chompheader __P((char *, int, HDR **, ENVELOPE *));
-extern void commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
+extern bool commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
extern HDR *copyheader __P((HDR *, SM_RPOOL_T *));
extern void eatheader __P((ENVELOPE *, bool, bool));
extern char *hvalue __P((char *, HDR *));
extern void insheader __P((int, char *, char *, int, ENVELOPE *));
extern bool isheader __P((char *));
-extern void putfromline __P((MCI *, ENVELOPE *));
+extern bool putfromline __P((MCI *, ENVELOPE *));
extern void setupheaders __P((void));
/*
@@ -870,9 +870,9 @@ struct envelope
short e_sendmode; /* message send mode */
short e_errormode; /* error return mode */
short e_timeoutclass; /* message timeout class */
- void (*e_puthdr)__P((MCI *, HDR *, ENVELOPE *, int));
+ bool (*e_puthdr)__P((MCI *, HDR *, ENVELOPE *, int));
/* function to put header of message */
- void (*e_putbody)__P((MCI *, ENVELOPE *, char *));
+ bool (*e_putbody)__P((MCI *, ENVELOPE *, char *));
/* function to put body of message */
ENVELOPE *e_parent; /* the message this one encloses */
ENVELOPE *e_sibling; /* the next envelope of interest */
@@ -965,8 +965,8 @@ extern void dropenvelope __P((ENVELOPE *, bool, bool));
extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *, SM_RPOOL_T *));
extern void clrsessenvelope __P((ENVELOPE *));
extern void printenvflags __P((ENVELOPE *));
-extern void putbody __P((MCI *, ENVELOPE *, char *));
-extern void putheader __P((MCI *, HDR *, ENVELOPE *, int));
+extern bool putbody __P((MCI *, ENVELOPE *, char *));
+extern bool putheader __P((MCI *, HDR *, ENVELOPE *, int));
/*
** Message priority classes.
@@ -1213,7 +1213,7 @@ MAP
#define MF_REGEX_NOT 0x00040000 /* regular expression negation */
#define MF_DEFER 0x00080000 /* don't lookup map in defer mode */
#define MF_SINGLEMATCH 0x00100000 /* successful only if match one key */
-/* 0x00200000 available for use */
+#define MF_SINGLEDN 0x00200000 /* only one match, but multi values */
#define MF_FILECLASS 0x00400000 /* this is a file class map */
#define MF_OPENBOGUS 0x00800000 /* open failed, don't call map_close */
#define MF_CLOSING 0x01000000 /* map is being closed */
@@ -1542,9 +1542,13 @@ extern void stabapply __P((void (*)(STAB *, int), int));
/* values for e_sendmode -- send modes */
#define SM_DELIVER 'i' /* interactive delivery */
#define SM_FORK 'b' /* deliver in background */
+#if _FFR_DM_ONE
+#define SM_DM_ONE 'o' /* deliver first TA in background, then queue */
+#endif /* _FFR_DM_ONE */
#define SM_QUEUE 'q' /* queue, don't deliver */
#define SM_DEFER 'd' /* defer map lookups as well as queue */
#define SM_VERIFY 'v' /* verify only (used internally) */
+#define DM_NOTSET (-1) /* DeliveryMode (per daemon) option not set */
#define WILL_BE_QUEUED(m) ((m) == SM_QUEUE || (m) == SM_DEFER)
@@ -1650,7 +1654,7 @@ EXTERN unsigned long PrivacyFlags; /* privacy flags */
#define M87F_NO8TO7 0x0004 /* don't do 8->7 bit conversions */
/* functions */
-extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *));
+extern bool mime7to8 __P((MCI *, HDR *, ENVELOPE *));
extern int mime8to7 __P((MCI *, HDR *, ENVELOPE *, char **, int));
/*
@@ -1820,11 +1824,12 @@ struct termescape
#define TLS_I_SRV_CERT (TLS_I_CERT_EX | TLS_I_KEY_EX | \
TLS_I_KEY_UNR | TLS_I_KEY_OUNR | \
TLS_I_CERTP_EX | TLS_I_CERTF_EX | \
- TLS_I_USE_KEY | TLS_I_USE_CERT)
+ TLS_I_USE_KEY | TLS_I_USE_CERT | TLS_I_CACHE)
/* server requirements */
#define TLS_I_SRV (TLS_I_SRV_CERT | TLS_I_RSA_TMP | TLS_I_VRFY_PATH | \
- TLS_I_VRFY_LOC | TLS_I_TRY_DH | TLS_I_DH512)
+ TLS_I_VRFY_LOC | TLS_I_TRY_DH | TLS_I_DH512 | \
+ TLS_I_CACHE)
/* client requirements */
#define TLS_I_CLT (TLS_I_KEY_UNR | TLS_I_KEY_OUNR)
@@ -1841,7 +1846,7 @@ extern void setclttls __P((bool));
extern bool initsrvtls __P((bool));
extern int tls_get_info __P((SSL *, bool, char *, MACROS_T *, bool));
extern int endtls __P((SSL *, char *));
-extern void tlslogerr __P((char *));
+extern void tlslogerr __P((const char *));
EXTERN char *CACertPath; /* path to CA certificates (dir. with hashes) */
@@ -2141,11 +2146,13 @@ extern unsigned char tTdvect[100]; /* trace vector */
EXTERN bool AllowBogusHELO; /* allow syntax errors on HELO command */
EXTERN bool CheckAliases; /* parse addresses during newaliases */
+#if _FFR_QUEUE_RUN_PARANOIA
+EXTERN int CheckQueueRunners; /* check whether queue runners are OK */
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
EXTERN bool ColonOkInAddr; /* single colon legal in address */
#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
EXTERN bool ConfigFileRead; /* configuration file has been read */
#endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
-EXTERN bool volatile DataProgress; /* have we sent anything since last check */
EXTERN bool DisConnected; /* running with OutChannel redirect to transcript file */
EXTERN bool DontExpandCnames; /* do not $[...$] expand CNAMEs */
EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */
@@ -2212,9 +2219,14 @@ EXTERN int MaxHopCount; /* max # of hops until bounce */
EXTERN int MaxMacroRecursion; /* maximum depth of macro recursion */
EXTERN int MaxMimeFieldLength; /* maximum MIME field length */
EXTERN int MaxMimeHeaderLength; /* maximum MIME header length */
+EXTERN int MaxNOOPCommands; /* max "noise" commands before slowdown */
EXTERN int MaxRcptPerMsg; /* max recipients per SMTP message */
EXTERN int MaxRuleRecursion; /* maximum depth of ruleset recursion */
+#if _FFR_MSG_ACCEPT
+EXTERN char *MessageAccept;
+#endif /* _FFR_MSG_ACCEPT */
+
EXTERN int MimeMode; /* MIME processing mode */
EXTERN int NoRecipientAction;
@@ -2229,6 +2241,11 @@ EXTERN int NumFileSys; /* number of queue file systems */
EXTERN int QueueLA; /* load average starting forced queueing */
EXTERN int RefuseLA; /* load average refusing connections */
EXTERN time_t RejectLogInterval; /* time btwn log msgs while refusing */
+#if _FFR_MEMSTAT
+EXTERN long QueueLowMem; /* low memory starting forced queueing */
+EXTERN long RefuseLowMem; /* low memory refusing connections */
+EXTERN char *MemoryResource;/* memory resource to look up */
+#endif /* _FFR_MEMSTAT */
EXTERN int SuperSafe; /* be extra careful, even if expensive */
EXTERN int VendorCode; /* vendor-specific operation enhancements */
EXTERN int Verbose; /* set if blow-by-blow desired */
@@ -2371,6 +2388,7 @@ extern void smtpquit __P((MAILER *, MCI *, ENVELOPE *));
extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *, ADDRESS *, time_t));
extern void smtprset __P((MAILER *, MCI *, ENVELOPE *));
+#define REPLYTYPE(r) ((r) / 100) /* first digit of reply code */
#define ISSMTPCODE(c) (isascii(c[0]) && isdigit(c[0]) && \
isascii(c[1]) && isdigit(c[1]) && \
isascii(c[2]) && isdigit(c[2]))
@@ -2519,8 +2537,8 @@ extern void printopenfds __P((bool));
extern void printqueue __P((void));
extern void printrules __P((void));
extern pid_t prog_open __P((char **, int *, ENVELOPE *));
-extern void putline __P((char *, MCI *));
-extern void putxline __P((char *, size_t, MCI *, int));
+extern bool putline __P((char *, MCI *));
+extern bool putxline __P((char *, size_t, MCI *, int));
extern void queueup_macros __P((int, SM_FILE_T *, ENVELOPE *));
extern void readcf __P((char *, bool, ENVELOPE *));
extern SIGFUNC_DECL reapchild __P((int));
@@ -2540,7 +2558,7 @@ extern bool setvendor __P((char *));
extern void set_op_mode __P((int));
extern void setoption __P((int, char *, bool, bool, ENVELOPE *));
extern sigfunc_t setsignal __P((int, sigfunc_t));
-extern void setuserenv __P((const char *, const char *));
+extern void sm_setuserenv __P((const char *, const char *));
extern void settime __P((ENVELOPE *));
extern char *sfgets __P((char *, int, SM_FILE_T *, time_t, char *));
extern char *shortenstring __P((const char *, size_t));
diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c
index 38eb7af..89fb390 100644
--- a/contrib/sendmail/src/sfsasl.c
+++ b/contrib/sendmail/src/sfsasl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: sfsasl.c,v 8.101 2004/12/15 22:45:55 ca Exp $")
+SM_RCSID("@(#)$Id: sfsasl.c,v 8.113 2006/03/02 19:18:27 ca Exp $")
#include <stdlib.h>
#include <sendmail.h>
#include <errno.h>
@@ -223,6 +223,9 @@ sasl_read(fp, buf, size)
(unsigned int) len, &outbuf, &outlen);
if (result != SASL_OK)
{
+ if (LogLevel > 7)
+ sm_syslog(LOG_WARNING, NOQID,
+ "AUTH: sasl_decode error=%d", result);
outbuf = NULL;
offset = 0;
outlen = 0;
@@ -304,7 +307,7 @@ sasl_write(fp, buf, size)
*/
result = sasl_getprop(so->conn, SASL_MAXOUTBUF,
- (const void **) &maxencode);
+ (const void **) &maxencode);
if (result == SASL_OK && size > *maxencode && *maxencode > 0)
size = *maxencode;
@@ -312,7 +315,12 @@ sasl_write(fp, buf, size)
(unsigned int) size, &outbuf, &outlen);
if (result != SASL_OK)
+ {
+ if (LogLevel > 7)
+ sm_syslog(LOG_WARNING, NOQID,
+ "AUTH: sasl_encode error=%d", result);
return -1;
+ }
if (outbuf != NULL)
{
@@ -541,6 +549,125 @@ tls_close(fp)
# define MAX_TLS_IOS 4
/*
+** TLS_RETRY -- check whether a failed SSL operation can be retried
+**
+** Parameters:
+** ssl -- TLS structure
+** rfd -- read fd
+** wfd -- write fd
+** tlsstart -- start time of TLS operation
+** timeout -- timeout for TLS operation
+** err -- SSL error
+** where -- description of operation
+**
+** Results:
+** >0 on success
+** 0 on timeout
+** <0 on error
+*/
+
+int
+tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
+ SSL *ssl;
+ int rfd;
+ int wfd;
+ time_t tlsstart;
+ int timeout;
+ int err;
+ const char *where;
+{
+ int ret;
+ time_t left;
+ time_t now = curtime();
+ struct timeval tv;
+
+ ret = -1;
+
+ /*
+ ** For SSL_ERROR_WANT_{READ,WRITE}:
+ ** There is not a complete SSL record available yet
+ ** or there is only a partial SSL record removed from
+ ** the network (socket) buffer into the SSL buffer.
+ ** The SSL_connect will only succeed when a full
+ ** SSL record is available (assuming a "real" error
+ ** doesn't happen). To handle when a "real" error
+ ** does happen the select is set for exceptions too.
+ ** The connection may be re-negotiated during this time
+ ** so both read and write "want errors" need to be handled.
+ ** A select() exception loops back so that a proper SSL
+ ** error message can be gotten.
+ */
+
+ left = timeout - (now - tlsstart);
+ if (left <= 0)
+ return 0; /* timeout */
+ tv.tv_sec = left;
+ tv.tv_usec = 0;
+
+ if (LogLevel > 14)
+ {
+ sm_syslog(LOG_INFO, NOQID,
+ "STARTTLS=%s, info: fds=%d/%d, err=%d",
+ where, rfd, wfd, err);
+ }
+
+ if (FD_SETSIZE > 0 &&
+ ((err == SSL_ERROR_WANT_READ && rfd >= FD_SETSIZE) ||
+ (err == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE)))
+ {
+ if (LogLevel > 5)
+ {
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=%s, error: fd %d/%d too large",
+ where, rfd, wfd);
+ if (LogLevel > 8)
+ tlslogerr(where);
+ }
+ errno = EINVAL;
+ }
+ else if (err == SSL_ERROR_WANT_READ)
+ {
+ fd_set ssl_maskr, ssl_maskx;
+
+ FD_ZERO(&ssl_maskr);
+ FD_SET(rfd, &ssl_maskr);
+ FD_ZERO(&ssl_maskx);
+ FD_SET(rfd, &ssl_maskx);
+ do
+ {
+ ret = select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx,
+ &tv);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0 && errno > 0)
+ ret = -errno;
+ }
+ else if (err == SSL_ERROR_WANT_WRITE)
+ {
+ fd_set ssl_maskw, ssl_maskx;
+
+ FD_ZERO(&ssl_maskw);
+ FD_SET(wfd, &ssl_maskw);
+ FD_ZERO(&ssl_maskx);
+ FD_SET(rfd, &ssl_maskx);
+ do
+ {
+ ret = select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx,
+ &tv);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0 && errno > 0)
+ ret = -errno;
+ }
+ return ret;
+}
+
+/* errno to force refill() etc to stop (see IS_IO_ERROR()) */
+#ifdef ETIMEDOUT
+# define SM_ERR_TIMEOUT ETIMEDOUT
+#else /* ETIMEDOUT */
+# define SM_ERR_TIMEOUT EIO
+#endif /* ETIMEDOUT */
+
+/*
** TLS_READ -- read secured information for the caller
**
** Parameters:
@@ -561,38 +688,42 @@ tls_read(fp, buf, size)
char *buf;
size_t size;
{
- int r;
- static int again = MAX_TLS_IOS;
+ int r, rfd, wfd, try, ssl_err;
struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
+ time_t tlsstart;
char *err;
+ try = 99;
+ err = NULL;
+ tlsstart = curtime();
+
+ retry:
r = SSL_read(so->con, (char *) buf, size);
if (r > 0)
- {
- again = MAX_TLS_IOS;
return r;
- }
err = NULL;
- switch (SSL_get_error(so->con, r))
+ switch (ssl_err = SSL_get_error(so->con, r))
{
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
- again = MAX_TLS_IOS;
break;
case SSL_ERROR_WANT_WRITE:
- if (--again <= 0)
- err = "read W BLOCK";
- else
- errno = EAGAIN;
- break;
+ err = "read W BLOCK";
+ /* FALLTHROUGH */
case SSL_ERROR_WANT_READ:
- if (--again <= 0)
+ if (err == NULL)
err = "read R BLOCK";
- else
- errno = EAGAIN;
+ rfd = SSL_get_rfd(so->con);
+ wfd = SSL_get_wfd(so->con);
+ try = tls_retry(so->con, rfd, wfd, tlsstart,
+ TimeOuts.to_datablock, ssl_err, "read");
+ if (try > 0)
+ goto retry;
+ errno = SM_ERR_TIMEOUT;
break;
+
case SSL_ERROR_WANT_X509_LOOKUP:
err = "write X BLOCK";
break;
@@ -625,15 +756,22 @@ tls_read(fp, buf, size)
int save_errno;
save_errno = (errno == 0) ? EIO : errno;
- again = MAX_TLS_IOS;
- if (LogLevel > 9)
+ if (try == 0 && save_errno == SM_ERR_TIMEOUT)
+ {
+ if (LogLevel > 7)
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS: read error=timeout");
+ }
+ else if (LogLevel > 8)
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS: read error=%s (%d), errno=%d, get_error=%s",
+ "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
err, r, errno,
- ERR_error_string(ERR_get_error(), NULL));
+ ERR_error_string(ERR_get_error(), NULL), try,
+ ssl_err);
else if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS: read error=%s (%d)", err, r);
+ "STARTTLS: read error=%s (%d), retry=%d, ssl_err=%d",
+ err, r, errno, try, ssl_err);
errno = save_errno;
}
return r;
@@ -660,36 +798,39 @@ tls_write(fp, buf, size)
const char *buf;
size_t size;
{
- int r;
- static int again = MAX_TLS_IOS;
+ int r, rfd, wfd, try, ssl_err;
struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
+ time_t tlsstart;
char *err;
+ try = 99;
+ err = NULL;
+ tlsstart = curtime();
+
+ retry:
r = SSL_write(so->con, (char *) buf, size);
if (r > 0)
- {
- again = MAX_TLS_IOS;
return r;
- }
err = NULL;
- switch (SSL_get_error(so->con, r))
+ switch (ssl_err = SSL_get_error(so->con, r))
{
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
- again = MAX_TLS_IOS;
break;
case SSL_ERROR_WANT_WRITE:
- if (--again <= 0)
- err = "write W BLOCK";
- else
- errno = EAGAIN;
- break;
+ err = "read W BLOCK";
+ /* FALLTHROUGH */
case SSL_ERROR_WANT_READ:
- if (--again <= 0)
- err = "write R BLOCK";
- else
- errno = EAGAIN;
+ if (err == NULL)
+ err = "read R BLOCK";
+ rfd = SSL_get_rfd(so->con);
+ wfd = SSL_get_wfd(so->con);
+ try = tls_retry(so->con, rfd, wfd, tlsstart,
+ DATA_PROGRESS_TIMEOUT, ssl_err, "write");
+ if (try > 0)
+ goto retry;
+ errno = SM_ERR_TIMEOUT;
break;
case SSL_ERROR_WANT_X509_LOOKUP:
err = "write X BLOCK";
@@ -722,15 +863,22 @@ tls_write(fp, buf, size)
int save_errno;
save_errno = (errno == 0) ? EIO : errno;
- again = MAX_TLS_IOS;
- if (LogLevel > 9)
+ if (try == 0 && save_errno == SM_ERR_TIMEOUT)
+ {
+ if (LogLevel > 7)
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS: write error=timeout");
+ }
+ else if (LogLevel > 8)
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS: write error=%s (%d), errno=%d, get_error=%s",
+ "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
err, r, errno,
- ERR_error_string(ERR_get_error(), NULL));
+ ERR_error_string(ERR_get_error(), NULL), try,
+ ssl_err);
else if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS: write error=%s (%d)", err, r);
+ "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
+ err, r, errno, try, ssl_err);
errno = save_errno;
}
return r;
diff --git a/contrib/sendmail/src/sfsasl.h b/contrib/sendmail/src/sfsasl.h
index c75418a..1cc1892 100644
--- a/contrib/sendmail/src/sfsasl.h
+++ b/contrib/sendmail/src/sfsasl.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 1999, 2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999, 2000, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
- * $Id: sfsasl.h,v 8.17 2000/09/19 21:30:49 ca Exp $"
+ * $Id: sfsasl.h,v 8.19 2006/02/27 19:53:37 ca Exp $"
*/
#ifndef SFSASL_H
@@ -17,6 +17,8 @@ extern int sfdcsasl __P((SM_FILE_T **, SM_FILE_T **, sasl_conn_t *));
#endif /* SASL */
# if STARTTLS
+extern int tls_retry __P((SSL *, int, int, time_t, int, int,
+ const char *));
extern int sfdctls __P((SM_FILE_T **, SM_FILE_T **, SSL *));
# endif /* STARTTLS */
diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c
index bfa2872..e5cfdcf 100644
--- a/contrib/sendmail/src/srvrsmtp.c
+++ b/contrib/sendmail/src/srvrsmtp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -17,9 +17,9 @@
# include <libmilter/mfdef.h>
#endif /* MILTER */
-SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.906 2005/03/16 00:36:09 ca Exp $")
+SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.922 2006/02/28 00:42:13 ca Exp $")
-#include <sys/time.h>
+#include <sm/time.h>
#include <sm/fdset.h>
#if SASL || STARTTLS
@@ -36,6 +36,9 @@ static SSL_CTX *srv_ctx = NULL; /* TLS server context */
static SSL *srv_ssl = NULL; /* per connection context */
static bool tls_ok_srv = false;
+#if _FFR_DM_ONE
+static bool NotFirstDelivery = false;
+#endif /* _FFR_DM_ONE */
extern void tls_set_verify __P((SSL_CTX *, SSL *, bool));
# define TLS_VERIFY_CLIENT() tls_set_verify(srv_ctx, srv_ssl, \
@@ -221,9 +224,6 @@ static char *CurSmtpClient; /* who's at the other end of channel */
#ifndef MAXBADCOMMANDS
# define MAXBADCOMMANDS 25 /* maximum number of bad commands */
#endif /* ! MAXBADCOMMANDS */
-#ifndef MAXNOOPCOMMANDS
-# define MAXNOOPCOMMANDS 20 /* max "noise" commands before slowdown */
-#endif /* ! MAXNOOPCOMMANDS */
#ifndef MAXHELOCOMMANDS
# define MAXHELOCOMMANDS 3 /* max HELO/EHLO commands before slowdown */
#endif /* ! MAXHELOCOMMANDS */
@@ -292,6 +292,24 @@ static bool smtp_data __P((SMTP_T *, ENVELOPE *));
\
switch (state) \
{ \
+ case SMFIR_SHUTDOWN: \
+ if (MilterLogLevel > 3) \
+ { \
+ sm_syslog(LOG_INFO, e->e_id, \
+ "Milter: %s=%s, reject=421, errormode=4", \
+ str, addr); \
+ LogUsrErrs = false; \
+ } \
+ { \
+ bool tsave = QuickAbort; \
+ \
+ QuickAbort = false; \
+ usrerr("421 4.3.0 closing connection"); \
+ QuickAbort = tsave; \
+ e->e_sendqueue = NULL; \
+ goto doquit; \
+ } \
+ break; \
case SMFIR_REPLYCODE: \
if (MilterLogLevel > 3) \
{ \
@@ -300,7 +318,8 @@ static bool smtp_data __P((SMTP_T *, ENVELOPE *));
str, addr, response); \
LogUsrErrs = false; \
} \
- if (strncmp(response, "421 ", 4) == 0) \
+ if (strncmp(response, "421 ", 4) == 0 \
+ || strncmp(response, "421-", 4) == 0) \
{ \
bool tsave = QuickAbort; \
\
@@ -504,7 +523,6 @@ smtp(nullserver, d_flags, e)
#endif /* SASL */
int r;
#if STARTTLS
- int fdfl;
int rfd, wfd;
volatile bool tls_active = false;
volatile bool smtps = bitnset(D_SMTPS, d_flags);
@@ -810,6 +828,19 @@ smtp(nullserver, d_flags, e)
tempfail = true;
smtp.sm_milterize = false;
break;
+
+ case SMFIR_SHUTDOWN:
+ if (MilterLogLevel > 3)
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: initialization failed, closing connection");
+ tempfail = true;
+ smtp.sm_milterize = false;
+ message("421 4.7.0 %s closing connection",
+ MyHostName);
+
+ /* arrange to ignore send list */
+ e->e_sendqueue = NULL;
+ goto doquit;
}
}
@@ -896,6 +927,9 @@ smtp(nullserver, d_flags, e)
int fd;
fd_set readfds;
struct timeval timeout;
+#if _FFR_LOG_GREET_PAUSE
+ struct timeval bp, ep, tp; /* {begin,end,total}pause */
+#endif /* _FFR_LOG_GREET_PAUSE */
/* pause for a moment */
timeout.tv_sec = msecs / 1000;
@@ -912,16 +946,32 @@ smtp(nullserver, d_flags, e)
fd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
FD_ZERO(&readfds);
SM_FD_SET(fd, &readfds);
+#if _FFR_LOG_GREET_PAUSE
+ gettimeofday(&bp, NULL);
+#endif /* _FFR_LOG_GREET_PAUSE */
if (select(fd + 1, FDSET_CAST &readfds,
NULL, NULL, &timeout) > 0 &&
FD_ISSET(fd, &readfds))
{
+#if _FFR_LOG_GREET_PAUSE
+ gettimeofday(&ep, NULL);
+ timersub(&ep, &bp, &tp);
+#endif /* _FFR_LOG_GREET_PAUSE */
greetcode = "554";
nullserver = "Command rejected";
sm_syslog(LOG_INFO, e->e_id,
+#if _FFR_LOG_GREET_PAUSE
+ "rejecting commands from %s [%s] after %d seconds due to pre-greeting traffic",
+#else /* _FFR_LOG_GREET_PAUSE */
"rejecting commands from %s [%s] due to pre-greeting traffic",
+#endif /* _FFR_LOG_GREET_PAUSE */
peerhostname,
- anynet_ntoa(&RealHostAddr));
+ anynet_ntoa(&RealHostAddr)
+#if _FFR_LOG_GREET_PAUSE
+ , (int) tp.tv_sec +
+ (tp.tv_usec >= 500000 ? 1 : 0)
+#endif /* _FFR_LOG_GREET_PAUSE */
+ );
}
}
}
@@ -1693,97 +1743,26 @@ smtp(nullserver, d_flags, e)
# define SSL_ACC(s) SSL_accept(s)
tlsstart = curtime();
- fdfl = fcntl(rfd, F_GETFL);
- if (fdfl != -1)
- fcntl(rfd, F_SETFL, fdfl|O_NONBLOCK);
ssl_retry:
if ((r = SSL_ACC(srv_ssl)) <= 0)
{
- int i;
- bool timedout;
- time_t left;
- time_t now = curtime();
- struct timeval tv;
+ int i, ssl_err;
- /* what to do in this case? */
- i = SSL_get_error(srv_ssl, r);
+ ssl_err = SSL_get_error(srv_ssl, r);
+ i = tls_retry(srv_ssl, rfd, wfd, tlsstart,
+ TimeOuts.to_starttls, ssl_err,
+ "server");
+ if (i > 0)
+ goto ssl_retry;
- /*
- ** For SSL_ERROR_WANT_{READ,WRITE}:
- ** There is no SSL record available yet
- ** or there is only a partial SSL record
- ** removed from the network (socket) buffer
- ** into the SSL buffer. The SSL_accept will
- ** only succeed when a full SSL record is
- ** available (assuming a "real" error
- ** doesn't happen). To handle when a "real"
- ** error does happen the select is set for
- ** exceptions too.
- ** The connection may be re-negotiated
- ** during this time so both read and write
- ** "want errors" need to be handled.
- ** A select() exception loops back so that
- ** a proper SSL error message can be gotten.
- */
-
- left = TimeOuts.to_starttls - (now - tlsstart);
- timedout = left <= 0;
- if (!timedout)
- {
- tv.tv_sec = left;
- tv.tv_usec = 0;
- }
-
- if (!timedout && FD_SETSIZE > 0 &&
- (rfd >= FD_SETSIZE ||
- (i == SSL_ERROR_WANT_WRITE &&
- wfd >= FD_SETSIZE)))
- {
- if (LogLevel > 5)
- {
- sm_syslog(LOG_ERR, NOQID,
- "STARTTLS=server, error: fd %d/%d too large",
- rfd, wfd);
- if (LogLevel > 8)
- tlslogerr("server");
- }
- goto tlsfail;
- }
-
- /* XXX what about SSL_pending() ? */
- if (!timedout && i == SSL_ERROR_WANT_READ)
- {
- fd_set ssl_maskr, ssl_maskx;
-
- FD_ZERO(&ssl_maskr);
- FD_SET(rfd, &ssl_maskr);
- FD_ZERO(&ssl_maskx);
- FD_SET(rfd, &ssl_maskx);
- if (select(rfd + 1, &ssl_maskr, NULL,
- &ssl_maskx, &tv) > 0)
- goto ssl_retry;
- }
- if (!timedout && i == SSL_ERROR_WANT_WRITE)
- {
- fd_set ssl_maskw, ssl_maskx;
-
- FD_ZERO(&ssl_maskw);
- FD_SET(wfd, &ssl_maskw);
- FD_ZERO(&ssl_maskx);
- FD_SET(rfd, &ssl_maskx);
- if (select(wfd + 1, NULL, &ssl_maskw,
- &ssl_maskx, &tv) > 0)
- goto ssl_retry;
- }
if (LogLevel > 5)
{
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=server, error: accept failed=%d, SSL_error=%d, timedout=%d, errno=%d",
- r, i, (int) timedout, errno);
+ "STARTTLS=server, error: accept failed=%d, SSL_error=%d, errno=%d, retry=%d",
+ r, ssl_err, errno, i);
if (LogLevel > 8)
tlslogerr("server");
}
-tlsfail:
tls_ok_srv = false;
SSL_free(srv_ssl);
srv_ssl = NULL;
@@ -1798,9 +1777,6 @@ tlsfail:
goto doquit;
}
- if (fdfl != -1)
- fcntl(rfd, F_SETFL, fdfl);
-
/* ignore return code for now, it's in {verify} */
(void) tls_get_info(srv_ssl, true,
CurSmtpClient,
@@ -1998,10 +1974,8 @@ tlsfail:
q = "accepting invalid domain name";
}
- if (gothello)
- {
+ if (gothello || smtp.sm_gotmail)
CLEAR_STATE(cmdbuf);
- }
#if MILTER
if (smtp.sm_milterlist && smtp.sm_milterize &&
@@ -2039,6 +2013,19 @@ tlsfail:
tempfail = true;
smtp.sm_milterize = false;
break;
+
+ case SMFIR_SHUTDOWN:
+ if (MilterLogLevel > 3)
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: Milter: helo=%s, reject=421 4.7.0 %s closing connection",
+ p, MyHostName);
+ tempfail = true;
+ smtp.sm_milterize = false;
+ message("421 4.7.0 %s closing connection",
+ MyHostName);
+ /* arrange to ignore send list */
+ e->e_sendqueue = NULL;
+ goto doquit;
}
if (response != NULL)
sm_free(response);
@@ -2475,7 +2462,11 @@ tlsfail:
goto rcpt_done;
}
- if (e->e_sendmode != SM_DELIVER)
+ if (e->e_sendmode != SM_DELIVER
+#if _FFR_DM_ONE
+ && (NotFirstDelivery || SM_DM_ONE != e->e_sendmode)
+#endif /* _FFR_DM_ONE */
+ )
e->e_flags |= EF_VRFYONLY;
#if MILTER
@@ -2900,7 +2891,7 @@ tlsfail:
case CMDNOOP: /* noop -- do nothing */
DELAY_CONN("NOOP");
- STOP_IF_ATTACK(checksmtpattack(&n_noop, MAXNOOPCOMMANDS,
+ STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands,
true, "NOOP", e));
message("250 2.0.0 OK");
break;
@@ -2974,6 +2965,9 @@ doquit:
finis(true, true, ExitStat);
/* NOTREACHED */
+ /* just to avoid bogus warning from some compilers */
+ exit(EX_OSERR);
+
case CMDVERB: /* set verbose mode */
DELAY_CONN("VERB");
if (!bitset(SRV_OFFER_EXPN, features) ||
@@ -2983,7 +2977,7 @@ doquit:
message("502 5.7.0 Verbose unavailable");
break;
}
- STOP_IF_ATTACK(checksmtpattack(&n_noop, MAXNOOPCOMMANDS,
+ STOP_IF_ATTACK(checksmtpattack(&n_noop, MaxNOOPCommands,
true, "VERB", e));
Verbose = 1;
set_delivery_mode(SM_DELIVER, e);
@@ -3044,7 +3038,8 @@ doquit:
MILTER_REPLY("unknown");
if (state == SMFIR_REPLYCODE ||
state == SMFIR_REJECT ||
- state == SMFIR_TEMPFAIL)
+ state == SMFIR_TEMPFAIL ||
+ state == SMFIR_SHUTDOWN)
{
/* MILTER_REPLY already gave an error */
break;
@@ -3111,6 +3106,7 @@ smtp_data(smtp, e)
char *id;
char *oldid;
char buf[32];
+ bool rv = true;
SmtpPhase = "server DATA";
if (!smtp->sm_gotmail)
@@ -3149,7 +3145,8 @@ smtp_data(smtp, e)
LogUsrErrs = false;
}
usrerr(response);
- if (strncmp(response, "421 ", 4) == 0)
+ if (strncmp(response, "421 ", 4) == 0
+ || strncmp(response, "421-", 4) == 0)
{
e->e_sendqueue = NULL;
return false;
@@ -3183,6 +3180,18 @@ smtp_data(smtp, e)
}
usrerr(MSG_TEMPFAIL);
return true;
+
+ case SMFIR_SHUTDOWN:
+ if (MilterLogLevel > 3)
+ {
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: cmd=data, reject=421 4.7.0 %s closing connection",
+ MyHostName);
+ LogUsrErrs = false;
+ }
+ usrerr("421 4.7.0 %s closing connection", MyHostName);
+ e->e_sendqueue = NULL;
+ return false;
}
LogUsrErrs = savelogusrerrs;
if (response != NULL)
@@ -3273,6 +3282,16 @@ smtp_data(smtp, e)
milteraccept = false;
usrerr(MSG_TEMPFAIL);
break;
+
+ case SMFIR_SHUTDOWN:
+ if (MilterLogLevel > 3)
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: data, reject=421 4.7.0 %s closing connection",
+ MyHostName);
+ milteraccept = false;
+ usrerr("421 4.7.0 %s closing connection", MyHostName);
+ rv = false;
+ break;
}
if (response != NULL)
sm_free(response);
@@ -3451,8 +3470,26 @@ smtp_data(smtp, e)
}
else
{
+ int mode;
+
/* send to all recipients */
- sendall(ee, SM_DEFAULT);
+ mode = SM_DEFAULT;
+#if _FFR_DM_ONE
+ if (SM_DM_ONE == e->e_sendmode)
+ {
+ if (NotFirstDelivery)
+ {
+ mode = SM_QUEUE;
+ e->e_sendmode = SM_QUEUE;
+ }
+ else
+ {
+ mode = SM_FORK;
+ NotFirstDelivery = true;
+ }
+ }
+#endif /* _FFR_DM_ONE */
+ sendall(ee, mode);
}
ee->e_to = NULL;
}
@@ -3462,6 +3499,16 @@ smtp_data(smtp, e)
CurEnv->e_id = id;
/* issue success message */
+#if _FFR_MSG_ACCEPT
+ if (MessageAccept != NULL && *MessageAccept != '\0')
+ {
+ char msg[MAXLINE];
+
+ expand(MessageAccept, msg, sizeof msg, e);
+ message("250 2.0.0 %s", msg);
+ }
+ else
+#endif /* _FFR_MSG_ACCEPT */
message("250 2.0.0 %s Message accepted for delivery", id);
CurEnv->e_id = oldid;
@@ -3566,7 +3613,7 @@ smtp_data(smtp, e)
macdefine(&e->e_macro, A_PERM,
macid("{quarantine}"), e->e_quarmsg);
}
- return true;
+ return rv;
}
/*
** LOGUNDELRCPTS -- log undelivered (or all) recipients.
diff --git a/contrib/sendmail/src/timers.c b/contrib/sendmail/src/timers.c
index 43dd73a..fdace01 100644
--- a/contrib/sendmail/src/timers.c
+++ b/contrib/sendmail/src/timers.c
@@ -11,11 +11,11 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: timers.c,v 8.24 2001/09/11 04:05:17 gshapiro Exp $")
+SM_RCSID("@(#)$Id: timers.c,v 8.25 2005/06/14 23:07:23 ca Exp $")
#if _FFR_TIMERS
# include <sys/types.h>
-# include <sys/time.h>
+# include <sm/time.h>
# include "sendmail.h"
# include <sys/resource.h> /* Must be after sendmail.h for NCR MP-RAS */
diff --git a/contrib/sendmail/src/tls.c b/contrib/sendmail/src/tls.c
index 3b915cb..dc4a1d9 100644
--- a/contrib/sendmail/src/tls.c
+++ b/contrib/sendmail/src/tls.c
@@ -10,7 +10,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: tls.c,v 8.97 2005/03/08 22:20:52 ca Exp $")
+SM_RCSID("@(#)$Id: tls.c,v 8.102 2006/03/02 19:18:27 ca Exp $")
#if STARTTLS
# include <openssl/err.h>
@@ -497,6 +497,15 @@ tls_safe_f(var, sff, srv)
** succeeded?
*/
+/*
+** The session_id_context identifies the service that created a session.
+** This information is used to distinguish between multiple TLS-based
+** servers running on the same server. We use the name of the mail system.
+** Note: the session cache is not persistent.
+*/
+
+static char server_session_id_context[] = "sendmail8";
+
bool
inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
SSL_CTX **ctx;
@@ -972,8 +981,20 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
/* XXX do we need this cache here? */
if (bitset(TLS_I_CACHE, req))
- SSL_CTX_sess_set_cache_size(*ctx, 128);
- /* timeout? SSL_CTX_set_timeout(*ctx, TimeOut...); */
+ {
+ SSL_CTX_sess_set_cache_size(*ctx, 1);
+ SSL_CTX_set_timeout(*ctx, 1);
+ SSL_CTX_set_session_id_context(*ctx,
+ (void *) &server_session_id_context,
+ sizeof(server_session_id_context));
+ (void) SSL_CTX_set_session_cache_mode(*ctx,
+ SSL_SESS_CACHE_SERVER);
+ }
+ else
+ {
+ (void) SSL_CTX_set_session_cache_mode(*ctx,
+ SSL_SESS_CACHE_OFF);
+ }
/* load certificate locations and default CA paths */
if (bitset(TLS_S_CERTP_EX, status) && bitset(TLS_S_CERTF_EX, status))
@@ -1557,7 +1578,7 @@ tls_verify_cb(ctx, unused)
void
tlslogerr(who)
- char *who;
+ const char *who;
{
unsigned long l;
int line, flags;
diff --git a/contrib/sendmail/src/udb.c b/contrib/sendmail/src/udb.c
index aaf8569..8331230 100644
--- a/contrib/sendmail/src/udb.c
+++ b/contrib/sendmail/src/udb.c
@@ -14,9 +14,9 @@
#include <sendmail.h>
#if USERDB
-SM_RCSID("@(#)$Id: udb.c,v 8.160 2003/04/03 16:32:46 ca Exp $ (with USERDB)")
+SM_RCSID("@(#)$Id: udb.c,v 8.161 2005/08/31 21:34:20 ca Exp $ (with USERDB)")
#else /* USERDB */
-SM_RCSID("@(#)$Id: udb.c,v 8.160 2003/04/03 16:32:46 ca Exp $ (without USERDB)")
+SM_RCSID("@(#)$Id: udb.c,v 8.161 2005/08/31 21:34:20 ca Exp $ (without USERDB)")
#endif /* USERDB */
#if USERDB
@@ -137,7 +137,7 @@ udbexpand(a, sendq, aliaslevel, e)
int keylen;
int naddrs;
char *user;
- char keybuf[MAXKEY];
+ char keybuf[MAXUDBKEY];
memset(&key, '\0', sizeof key);
memset(&info, '\0', sizeof info);
@@ -597,7 +597,7 @@ udbmatch(user, field, rpool)
int i;
int keylen;
DBT key, info;
- char keybuf[MAXKEY];
+ char keybuf[MAXUDBKEY];
if (tTd(28, 1))
sm_dprintf("udbmatch(%s, %s)\n", user, field);
@@ -1232,7 +1232,7 @@ hes_udb_get(key, info)
{
char *name, *type;
char **hp;
- char kbuf[MAXKEY + 1];
+ char kbuf[MAXUDBKEY + 1];
if (sm_strlcpy(kbuf, key->data, sizeof kbuf) >= sizeof kbuf)
return 0;
diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c
index bd3de97..0c5195e 100644
--- a/contrib/sendmail/src/usersmtp.c
+++ b/contrib/sendmail/src/usersmtp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,12 +13,11 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: usersmtp.c,v 8.463 2005/03/16 00:36:09 ca Exp $")
+SM_RCSID("@(#)$Id: usersmtp.c,v 8.467 2006/03/19 06:07:56 ca Exp $")
#include <sysexits.h>
-static void datatimeout __P((int));
static void esmtp_check __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
static void helo_options __P((char *, bool, MAILER *, MCI *, ENVELOPE *));
static int smtprcptstat __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
@@ -34,7 +33,6 @@ extern void sm_sasl_free __P((void *));
** This protocol is described in RFC821.
*/
-#define REPLYTYPE(r) ((r) / 100) /* first digit of reply code */
#define REPLYCLASS(r) (((r) / 10) % 10) /* second digit of reply code */
#define SMTPCLOSING 421 /* "Service Shutting Down" */
@@ -2491,9 +2489,6 @@ smtprcptstat(to, m, mci, e)
** exit status corresponding to DATA command.
*/
-static jmp_buf CtxDataTimeout;
-static SM_EVENT *volatile DataTimeout = NULL;
-
int
smtpdata(m, mci, e, ctladdr, xstart)
MAILER *m;
@@ -2505,7 +2500,7 @@ smtpdata(m, mci, e, ctladdr, xstart)
register int r;
int rstat;
int xstat;
- time_t timeout;
+ int timeout;
char *enhsc;
/*
@@ -2629,43 +2624,22 @@ smtpdata(m, mci, e, ctladdr, xstart)
** factor. The main thing is that it should not be infinite.
*/
- if (setjmp(CtxDataTimeout) != 0)
- {
- mci->mci_errno = errno;
- mci->mci_state = MCIS_ERROR;
- mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
-
- /*
- ** If putbody() couldn't finish due to a timeout,
- ** rewind it here in the timeout handler. See
- ** comments at the end of putbody() for reasoning.
- */
-
- if (e->e_dfp != NULL)
- (void) bfrewind(e->e_dfp);
-
- errno = mci->mci_errno;
- syserr("451 4.4.1 timeout writing message to %s", CurHostName);
- smtpquit(m, mci, e);
- return EX_TEMPFAIL;
- }
-
if (tTd(18, 101))
{
/* simulate a DATA timeout */
- timeout = 1;
+ timeout = 10;
}
else
- timeout = DATA_PROGRESS_TIMEOUT;
-
- DataTimeout = sm_setevent(timeout, datatimeout, 0);
+ timeout = DATA_PROGRESS_TIMEOUT * 1000;
+ sm_io_setinfo(mci->mci_out, SM_IO_WHAT_TIMEOUT, &timeout);
/*
** Output the actual message.
*/
- (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
+ if (!(*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER))
+ goto writeerr;
if (tTd(18, 101))
{
@@ -2673,14 +2647,13 @@ smtpdata(m, mci, e, ctladdr, xstart)
(void) sleep(2);
}
- (*e->e_putbody)(mci, e, NULL);
+ if (!(*e->e_putbody)(mci, e, NULL))
+ goto writeerr;
/*
** Cleanup after sending message.
*/
- if (DataTimeout != NULL)
- sm_clrevent(DataTimeout);
#if PIPELINING
}
@@ -2720,7 +2693,9 @@ smtpdata(m, mci, e, ctladdr, xstart)
}
/* terminate the message */
- (void) sm_io_fprintf(mci->mci_out, SM_TIME_DEFAULT, ".%s", m->m_eol);
+ if (sm_io_fprintf(mci->mci_out, SM_TIME_DEFAULT, ".%s", m->m_eol) ==
+ SM_IO_EOF)
+ goto writeerr;
if (TrafficLogFile != NULL)
(void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT,
"%05d >>> .\n", (int) CurrentPid);
@@ -2771,51 +2746,27 @@ smtpdata(m, mci, e, ctladdr, xstart)
shortenstring(SmtpReplyBuffer, 403));
}
return rstat;
-}
-static void
-datatimeout(ignore)
- int ignore;
-{
- int save_errno = errno;
+ writeerr:
+ mci->mci_errno = errno;
+ mci->mci_state = MCIS_ERROR;
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
/*
- ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
- ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
- ** DOING.
+ ** If putbody() couldn't finish due to a timeout,
+ ** rewind it here in the timeout handler. See
+ ** comments at the end of putbody() for reasoning.
*/
- if (DataProgress)
- {
- time_t timeout;
-
- /* check back again later */
- if (tTd(18, 101))
- {
- /* simulate a DATA timeout */
- timeout = 1;
- }
- else
- timeout = DATA_PROGRESS_TIMEOUT;
-
- /* reset the timeout */
- DataTimeout = sm_sigsafe_setevent(timeout, datatimeout, 0);
- DataProgress = false;
- }
- else
- {
- /* event is done */
- DataTimeout = NULL;
- }
+ if (e->e_dfp != NULL)
+ (void) bfrewind(e->e_dfp);
- /* if no progress was made or problem resetting event, die now */
- if (DataTimeout == NULL)
- {
- errno = ETIMEDOUT;
- longjmp(CtxDataTimeout, 1);
- }
- errno = save_errno;
+ errno = mci->mci_errno;
+ syserr("451 4.4.1 timeout writing message to %s", CurHostName);
+ smtpquit(m, mci, e);
+ return EX_TEMPFAIL;
}
+
/*
** SMTPGETSTAT -- get status code from DATA in LMTP
**
@@ -3021,6 +2972,8 @@ smtprset(m, mci, e)
if (mci->mci_state != MCIS_SSD && mci->mci_state != MCIS_CLOSED)
mci->mci_state = MCIS_OPEN;
+ else if (mci->mci_exitstat == EX_OK)
+ mci_setstat(mci, EX_TEMPFAIL, "4.5.0", NULL);
}
/*
** SMTPPROBE -- check the connection state
diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c
index e7a3ff0..ea36b6e 100644
--- a/contrib/sendmail/src/util.c
+++ b/contrib/sendmail/src/util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: util.c,v 8.383 2004/08/02 18:50:59 ca Exp $")
+SM_RCSID("@(#)$Id: util.c,v 8.392 2006/03/09 19:49:35 ca Exp $")
#include <sysexits.h>
#include <sm/xtrap.h>
@@ -456,6 +456,8 @@ xalloc(sz)
{
register char *p;
+ SM_REQUIRE(sz >= 0);
+
/* some systems can't handle size zero mallocs */
if (sz <= 0)
sz = 1;
@@ -970,18 +972,18 @@ fixcrlf(line, stripnl)
** mci -- the mailer connection information.
**
** Returns:
-** none
+** true iff line was written successfully
**
** Side Effects:
** output of l to mci->mci_out.
*/
-void
+bool
putline(l, mci)
register char *l;
register MCI *mci;
{
- putxline(l, strlen(l), mci, PXLF_MAPFROM);
+ return putxline(l, strlen(l), mci, PXLF_MAPFROM);
}
/*
** PUTXLINE -- putline with flags bits.
@@ -1000,13 +1002,13 @@ putline(l, mci)
** PXLF_NOADDEOL -- don't add an EOL if one wasn't present.
**
** Returns:
-** none
+** true iff line was written successfully
**
** Side Effects:
** output of l to mci->mci_out.
*/
-void
+bool
putxline(l, len, mci, pxflags)
register char *l;
size_t len;
@@ -1058,11 +1060,6 @@ putxline(l, len, mci, pxflags)
if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
'.') == SM_IO_EOF)
dead = true;
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
if (TrafficLogFile != NULL)
(void) sm_io_putc(TrafficLogFile,
SM_TIME_DEFAULT, '.');
@@ -1075,11 +1072,6 @@ putxline(l, len, mci, pxflags)
if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
'>') == SM_IO_EOF)
dead = true;
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
if (TrafficLogFile != NULL)
(void) sm_io_putc(TrafficLogFile,
SM_TIME_DEFAULT,
@@ -1091,16 +1083,11 @@ putxline(l, len, mci, pxflags)
while (l < q)
{
if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
- (unsigned char) *l++) == SM_IO_EOF)
+ (unsigned char) *l++) == SM_IO_EOF)
{
dead = true;
break;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
}
if (dead)
break;
@@ -1116,11 +1103,6 @@ putxline(l, len, mci, pxflags)
dead = true;
break;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
if (TrafficLogFile != NULL)
{
for (l = l_base; l < q; l++)
@@ -1144,11 +1126,9 @@ putxline(l, len, mci, pxflags)
{
if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, '.') ==
SM_IO_EOF)
- break;
- else
{
- /* record progress for DATA timeout */
- DataProgress = true;
+ dead = true;
+ break;
}
if (TrafficLogFile != NULL)
(void) sm_io_putc(TrafficLogFile,
@@ -1161,11 +1141,9 @@ putxline(l, len, mci, pxflags)
{
if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, '>') ==
SM_IO_EOF)
- break;
- else
{
- /* record progress for DATA timeout */
- DataProgress = true;
+ dead = true;
+ break;
}
if (TrafficLogFile != NULL)
(void) sm_io_putc(TrafficLogFile,
@@ -1183,11 +1161,6 @@ putxline(l, len, mci, pxflags)
dead = true;
break;
}
- else
- {
- /* record progress for DATA timeout */
- DataProgress = true;
- }
}
if (dead)
break;
@@ -1198,11 +1171,9 @@ putxline(l, len, mci, pxflags)
if ((!bitset(PXLF_NOADDEOL, pxflags) || !noeol) &&
sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
mci->mci_mailer->m_eol) == SM_IO_EOF)
- break;
- else
{
- /* record progress for DATA timeout */
- DataProgress = true;
+ dead = true;
+ break;
}
if (l < end && *l == '\n')
{
@@ -1211,11 +1182,9 @@ putxline(l, len, mci, pxflags)
{
if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
' ') == SM_IO_EOF)
- break;
- else
{
- /* record progress for DATA timeout */
- DataProgress = true;
+ dead = true;
+ break;
}
if (TrafficLogFile != NULL)
@@ -1224,10 +1193,10 @@ putxline(l, len, mci, pxflags)
}
}
- /* record progress for DATA timeout */
- DataProgress = true;
} while (l < end);
+ return !dead;
}
+
/*
** XUNLINK -- unlink a file, doing logging as appropriate.
**
@@ -2096,6 +2065,9 @@ prog_open(argv, pfd, e)
/* run as default user */
endpwent();
sm_mbdb_terminate();
+#if _FFR_MEMSTAT
+ (void) sm_memstat_close();
+#endif /* _FFR_MEMSTAT */
if (setgid(DefGid) < 0 && geteuid() == 0)
{
syserr("prog_open: setgid(%ld) failed", (long) DefGid);
@@ -2433,6 +2405,7 @@ str2prt(s)
*h++ = 'r';
break;
default:
+ SM_ASSERT(l >= 2);
(void) sm_snprintf(h, l, "%03o",
(unsigned int)((unsigned char) c));
@@ -2669,11 +2642,11 @@ proc_list_drop(pid, st, other)
type = ProcListVec[i].proc_type;
if (other != NULL)
*other = ProcListVec[i].proc_other;
+ if (CurChildren > 0)
+ CurChildren--;
break;
}
}
- if (CurChildren > 0)
- CurChildren--;
if (type == PROC_CONTROL && WIFEXITED(st))
@@ -2732,14 +2705,20 @@ proc_list_clear()
void
proc_list_probe()
{
- int i;
+ int i, children;
+ int chldwasblocked;
+ pid_t pid;
+
+ children = 0;
+ chldwasblocked = sm_blocksignal(SIGCHLD);
/* start from 1 since 0 is the daemon itself */
for (i = 1; i < ProcListSize; i++)
{
- if (ProcListVec[i].proc_pid == NO_PID)
+ pid = ProcListVec[i].proc_pid;
+ if (pid == NO_PID || pid == CurrentPid)
continue;
- if (kill(ProcListVec[i].proc_pid, 0) < 0)
+ if (kill(pid, 0) < 0)
{
if (LogLevel > 3)
sm_syslog(LOG_DEBUG, CurEnv->e_id,
@@ -2749,9 +2728,21 @@ proc_list_probe()
SM_FREE_CLR(ProcListVec[i].proc_task);
CurChildren--;
}
+ else
+ {
+ ++children;
+ }
}
if (CurChildren < 0)
CurChildren = 0;
+ if (chldwasblocked == 0)
+ (void) sm_releasesignal(SIGCHLD);
+ if (LogLevel > 10 && children != CurChildren)
+ {
+ sm_syslog(LOG_ERR, NOQID,
+ "proc_list_probe: found %d children, expected %d",
+ children, CurChildren);
+ }
}
/*
@@ -2859,7 +2850,6 @@ count_open_connections(hostaddr)
{
if (ProcListVec[i].proc_pid == NO_PID)
continue;
-
if (hostaddr->sa.sa_family !=
ProcListVec[i].proc_hostaddr.sa.sa_family)
continue;
diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c
index 9fcf31c..7ca90a8 100644
--- a/contrib/sendmail/src/version.c
+++ b/contrib/sendmail/src/version.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,6 +13,6 @@
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: version.c,v 8.145 2005/03/25 18:44:44 ca Exp $")
+SM_RCSID("@(#)$Id: version.c,v 8.160 2006/03/08 19:21:21 ca Exp $")
-char Version[] = "8.13.4";
+char Version[] = "8.13.6";
OpenPOWER on IntegriCloud