summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src
diff options
context:
space:
mode:
authorgshapiro <gshapiro@FreeBSD.org>2002-04-10 03:05:00 +0000
committergshapiro <gshapiro@FreeBSD.org>2002-04-10 03:05:00 +0000
commit9e3bd35cd79720a6547b183a6a6fb97ab1ae7b84 (patch)
tree348e6162af337e0b74db963f6e4dcc567e2f99e9 /contrib/sendmail/src
parent1a7e50d796833cbb4346a251bc88555ea2c58e94 (diff)
downloadFreeBSD-src-9e3bd35cd79720a6547b183a6a6fb97ab1ae7b84.zip
FreeBSD-src-9e3bd35cd79720a6547b183a6a6fb97ab1ae7b84.tar.gz
Import sendmail 8.12.3
Diffstat (limited to 'contrib/sendmail/src')
-rw-r--r--contrib/sendmail/src/README37
-rw-r--r--contrib/sendmail/src/SECURITY16
-rw-r--r--contrib/sendmail/src/TUNING17
-rw-r--r--contrib/sendmail/src/bf.c14
-rw-r--r--contrib/sendmail/src/collect.c29
-rw-r--r--contrib/sendmail/src/conf.c75
-rw-r--r--contrib/sendmail/src/conf.h4
-rw-r--r--contrib/sendmail/src/control.c4
-rw-r--r--contrib/sendmail/src/daemon.c37
-rw-r--r--contrib/sendmail/src/deliver.c57
-rw-r--r--contrib/sendmail/src/domain.c15
-rw-r--r--contrib/sendmail/src/envelope.c13
-rw-r--r--contrib/sendmail/src/helpfile6
-rw-r--r--contrib/sendmail/src/main.c43
-rw-r--r--contrib/sendmail/src/map.c293
-rw-r--r--contrib/sendmail/src/mci.c11
-rw-r--r--contrib/sendmail/src/milter.c64
-rw-r--r--contrib/sendmail/src/mime.c110
-rw-r--r--contrib/sendmail/src/parseaddr.c122
-rw-r--r--contrib/sendmail/src/queue.c436
-rw-r--r--contrib/sendmail/src/readcf.c96
-rw-r--r--contrib/sendmail/src/sasl.c7
-rw-r--r--contrib/sendmail/src/sendmail.h41
-rw-r--r--contrib/sendmail/src/sfsasl.c17
-rw-r--r--contrib/sendmail/src/srvrsmtp.c38
-rw-r--r--contrib/sendmail/src/stats.c13
-rw-r--r--contrib/sendmail/src/tls.c25
-rw-r--r--contrib/sendmail/src/usersmtp.c80
-rw-r--r--contrib/sendmail/src/util.c15
-rw-r--r--contrib/sendmail/src/version.c4
30 files changed, 1241 insertions, 498 deletions
diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README
index 3f984d9..f985795 100644
--- a/contrib/sendmail/src/README
+++ b/contrib/sendmail/src/README
@@ -9,7 +9,7 @@
# the sendmail distribution.
#
#
-# $Id: README,v 8.345 2002/01/09 18:04:30 ca Exp $
+# $Id: README,v 8.353 2002/04/04 21:39:33 gshapiro Exp $
#
This directory contains the source files for sendmail(TM).
@@ -73,7 +73,8 @@ file.
You can recompile from scratch using the -c flag with the Build
command. This removes the existing compilation directory for the
-current platform and builds a new one.
+current platform and builds a new one. The -c flag must also
+be used if any site.*.m4 file in devtools/Site/ is changed.
Porting to a new Unix-based system should be a matter of creating
an appropriate configuration file in the devtools/OS/ directory.
@@ -158,8 +159,8 @@ and the filename includes the string "/yp/", sendmail adds the special
tokens "YP_LAST_MODIFIED" and "YP_MASTER_NAME", both of which are
required if the NDBM file is to be used as an NIS map.
-All of these flags are normally defined in the DBMDEF line in the
-Makefile.
+All of these flags are normally defined in a confMAPDEF setting in your
+site.config.m4.
If you define NEWDB or HESIOD you get the User Database (USERDB)
automatically. Generally you do want to have NEWDB for it to do
@@ -465,10 +466,8 @@ NEEDSGETIPNODE Set this if your system supports IPv6 but doesn't include
for Linux's glibc.
PIPELINING Support SMTP PIPELINING (set by default).
USING_NETSCAPE_LDAP
- Set this if LDAPMAP is set and your LDAP libraries are from
- (or are derived from) Netscape's implementation, which
- requires that the return value of ldap_first_attribute()
- and ldap_next_attribute() be ldap_memfree()'d.
+ Deprecated in favor of SM_CONF_LDAP_MEMFREE. See
+ libsm/README.
NEEDLINK Set this if your system doesn't have a link() call. It
will create a copy of the file instead of a hardlink.
USE_ENVIRON Set this to 1 to access process environment variables from
@@ -586,7 +585,7 @@ SASL Enables SMTP AUTH (RFC 2554). This requires the Cyrus SASL
compared with the actual version found and if there is a
mismatch, compilation will fail.
EGD Define this if your system has EGD installed, see
- http://www.lothar.com/tech/crypto/ . It should be used to
+ http://egd.sourceforge.net/ . It should be used to
seed the PRNG for STARTTLS if HASURANDOMDEV is not defined.
STARTTLS Enables SMTP STARTTLS (RFC 2487). This requires OpenSSL
(http://www.OpenSSL.org/); use OpenSSL 0.9.5a or later
@@ -878,10 +877,10 @@ Solaris 2.x (SunOS 5.x)
make sure /opt/SUNWspro/bin/cc is used instead of /usr/ucb/cc
(or it might complain about tm_zone).
- The Solaris "syslog" function is apparently limited to something
- about 90 characters because of a kernel limitation. If you have
- source code, you can probably up this number. You can get patches
- that fix this problem: the patch ids are:
+ The Solaris 2.x (x <= 3) "syslog" function is apparently limited
+ to something about 90 characters because of a kernel limitation.
+ If you have source code, you can probably up this number. You
+ can get patches that fix this problem: the patch ids are:
Solaris 2.1 100834
Solaris 2.2 100999
@@ -974,9 +973,10 @@ Solaris 8 and later (SunOS 5.8 and later)
Solaris 9 and later (SunOS 5.9 and later)
Solaris 9 and later have a revised LDAP library, libldap.so.5,
which is derived from a Netscape implementation, thus requiring
- that USING_NETSCAPE_LDAP be defined in conjunction with LDAPMAP:
+ that SM_CONF_LDAP_MEMFREE be defined in conjunction with LDAPMAP:
- APPENDDEF(`confMAPDEF', `-DLDAPMAP -DUSING_NETSCAPE_LDAP')
+ APPENDDEF(`confMAPDEF', `-DLDAPMAP')
+ APPENDDEF(`confENVDEF', `-DSM_CONF_LDAP_MEMFREE')
APPENDDEF(`confLIBS', `-lldap')
Solaris
@@ -1472,7 +1472,10 @@ UNICOS 8.0.3.4
problems. You may want to turn this off if you have problems
running sendmail. Reported by Jerry G. DeLapp <jgd@acl.lanl.gov>.
-Mac OS X (10.0.X)
+Darwin/Mac OS X (10.X.X)
+ The linker errors produced regarding getopt() and it's associated
+ variables can safely be ignored.
+
From Mike Zimmerman <zimmy@torrentnet.com>:
From scratch here is what Darwin users need to do to the standard
@@ -1735,4 +1738,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.345 $, last update $Date: 2002/01/09 18:04:30 $ )
+(Version $Revision: 8.353 $, last update $Date: 2002/04/04 21:39:33 $ )
diff --git a/contrib/sendmail/src/SECURITY b/contrib/sendmail/src/SECURITY
index 7e55024..e42c024 100644
--- a/contrib/sendmail/src/SECURITY
+++ b/contrib/sendmail/src/SECURITY
@@ -1,11 +1,11 @@
-# Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
+# Copyright (c) 2000-2002 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: SECURITY,v 1.47 2001/09/23 02:29:05 ca Exp $
+# $Id: SECURITY,v 1.50 2002/03/29 19:45:48 ca Exp $
#
This file gives some hints how to configure and run sendmail for
@@ -61,6 +61,9 @@ drwx------ root wheel ... /var/spool/mqueue
-r--r--r-- root wheel ... /etc/mail/sendmail.cf
-r--r--r-- root wheel ... /etc/mail/submit.cf
+[Notice: On some OS "wheel" is not used but "bin" or "root" instead,
+however, this is not important here.]
+
That is, the owner of sendmail is root, the group is smmsp, and
the binary is set-group-ID. The client mail queue is owned by
smmsp with group smmsp and is group writable. The client mail
@@ -186,7 +189,14 @@ sm-mta.
Set-User-Id
-----------
-If you really have to install sendmail set-user-ID root, you can use
+If you really have to install sendmail set-user-ID root, first build
+the sendmail package normally using
+
+ sh ./Build
+
+Then you can use
sh ./Build install-set-user-id
+to install the package in the old (pre-8.12) way. Make sure that
+no submit.cf file is installed.
diff --git a/contrib/sendmail/src/TUNING b/contrib/sendmail/src/TUNING
index e055269..52da793 100644
--- a/contrib/sendmail/src/TUNING
+++ b/contrib/sendmail/src/TUNING
@@ -1,11 +1,11 @@
-# Copyright (c) 2001 Sendmail, Inc. and its suppliers.
+# Copyright (c) 2001-2002 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: TUNING,v 1.16 2001/08/19 21:03:38 gshapiro Exp $
+# $Id: TUNING,v 1.18 2002/03/03 03:38:21 ca Exp $
#
********************************************
@@ -141,13 +141,12 @@ should be added to the .mc file.
Before 8.12 sendmail delivers an e-mail sequentially to all its
recipients. For mailing lists or large aliases the overall delivery
-time can be substantial, especially if some of the recipients are located
-at hosts that are slow to accept e-mail. Some mailing list software
-therefore "split" up e-mails into smaller pieces with fewer recipients.
-sendmail 8.12 can do this itself, either across queue groups or
-within a queue directory. For the former the option SplitAcrossQueueGroups
-option must be set, the latter is controlled by the 'r=' field of
-a queue group declaration.
+time can be substantial, especially if some of the recipients are
+located at hosts that are slow to accept e-mail. Some mailing list
+software therefore "split" up e-mails into smaller pieces with
+fewer recipients. sendmail 8.12 can do this itself, either across
+queue groups or within a queue directory. The latter is controlled
+by the 'r=' field of a queue group declaration.
Let's assume a simple example: a mailing lists where most of
the recipients are at three domains: the local one (local.domain)
diff --git a/contrib/sendmail/src/bf.c b/contrib/sendmail/src/bf.c
index 031b1f7..7b076a9 100644
--- a/contrib/sendmail/src/bf.c
+++ b/contrib/sendmail/src/bf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -18,7 +18,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: bf.c,v 8.48 2001/11/04 17:10:49 ca Exp $")
+SM_RCSID("@(#)$Id: bf.c,v 8.51 2002/03/04 21:51:25 gshapiro Exp $")
#include <sys/types.h>
#include <sys/stat.h>
@@ -61,7 +61,6 @@ struct bf
MODE_T bf_filemode; /* Mode of buffered file, if ever committed */
off_t bf_offset; /* Currect file offset */
int bf_size; /* Total current size of file */
- int bf_refcount; /* Reference count */
};
#ifdef BF_STANDALONE
@@ -84,10 +83,8 @@ struct bf_info
**
** Parameters:
** fp -- file pointer being filled-in for file being open'd
-** filename -- name of the file being open'd
+** info -- information about file being opened
** flags -- ignored
-** fmode -- file mode (stored for use later)
-** sflags -- "safeopen" flags (stored for use later)
** rpool -- ignored (currently)
**
** Returns:
@@ -156,7 +153,6 @@ sm_bfopen(fp, info, flags, rpool)
/* Nearly home free, just set all the parameters now */
bfp->bf_committed = false;
bfp->bf_ondisk = false;
- bfp->bf_refcount = 1;
bfp->bf_flags = sflags;
bfp->bf_bufsize = bsize;
bfp->bf_buffilled = 0;
@@ -173,7 +169,7 @@ sm_bfopen(fp, info, flags, rpool)
(void) sm_strlcpy(bfp->bf_filename, filename, l);
bfp->bf_filemode = fmode;
bfp->bf_offset = 0;
- bfp->bf_size = bsize;
+ bfp->bf_size = 0;
bfp->bf_disk_fd = -1;
fp->f_cookie = bfp;
@@ -262,6 +258,8 @@ sm_bfgetinfo(fp, what, valp)
{
case SM_IO_WHAT_FD:
return bfp->bf_disk_fd;
+ case SM_IO_WHAT_SIZE:
+ return bfp->bf_size;
default:
return -1;
}
diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c
index 95a14ae..177a1ba 100644
--- a/contrib/sendmail/src/collect.c
+++ b/contrib/sendmail/src/collect.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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: collect.c,v 8.237 2001/12/10 19:56:03 ca Exp $")
+SM_RCSID("@(#)$Id: collect.c,v 8.241 2002/03/15 01:32:47 gshapiro Exp $")
static void collecttimeout __P((time_t));
static void dferror __P((SM_FILE_T *volatile, char *, ENVELOPE *));
@@ -104,10 +104,6 @@ collect_doheader(e)
if (GrabTo && e->e_sendqueue == NULL)
usrerr("No recipient addresses found in header");
- /* collect statistics */
- if (OpMode != MD_VERIFY)
- markstats(e, (ADDRESS *) NULL, STATS_NORMAL);
-
/*
** If we have a Return-Receipt-To:, turn it into a DSN.
*/
@@ -431,10 +427,12 @@ collect(fp, smtpmode, hdrp, e)
istate = IS_DOTCR;
continue;
}
- else if (c != '.' ||
- (OpMode != MD_SMTP &&
+ else if (ignrdot ||
+ (c != '.' &&
+ OpMode != MD_SMTP &&
OpMode != MD_DAEMON &&
OpMode != MD_ARPAFTP))
+
{
*pbp++ = c;
c = '.';
@@ -448,8 +446,15 @@ collect(fp, smtpmode, hdrp, e)
{
/* push back the ".\rx" */
*pbp++ = c;
- *pbp++ = '\r';
- c = '.';
+ if (OpMode != MD_SMTP &&
+ OpMode != MD_DAEMON &&
+ OpMode != MD_ARPAFTP)
+ {
+ *pbp++ = '\r';
+ c = '.';
+ }
+ else
+ c = '\r';
}
break;
@@ -851,6 +856,10 @@ readerr:
}
else
e->e_dfp = df;
+
+ /* collect statistics */
+ if (OpMode != MD_VERIFY)
+ markstats(e, (ADDRESS *) NULL, STATS_NORMAL);
}
static void
diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c
index 41644e0..33b464f 100644
--- a/contrib/sendmail/src/conf.c
+++ b/contrib/sendmail/src/conf.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: conf.c,v 8.939 2002/01/09 17:26:28 gshapiro Exp $")
+SM_RCSID("@(#)$Id: conf.c,v 8.961 2002/04/04 21:32:14 gshapiro Exp $")
#include <sendmail/pathnames.h>
@@ -524,9 +524,15 @@ setupmaps()
#if NAMED_BIND
# if DNSMAP
+# if _FFR_DNSMAP_ALIASABLE
+ MAPDEF("dns", NULL, MCF_ALIASOK,
+ dns_map_parseargs, dns_map_open, null_map_close,
+ dns_map_lookup, null_map_store);
+# else /* _FFR_DNSMAP_ALIASABLE */
MAPDEF("dns", NULL, 0,
dns_map_parseargs, dns_map_open, null_map_close,
dns_map_lookup, null_map_store);
+# endif /* _FFR_DNSMAP_ALIASABLE */
# endif /* DNSMAP */
#endif /* NAMED_BIND */
@@ -3012,6 +3018,7 @@ static char *DefaultUserShells[] =
"/bin/pam",
"/usr/bin/keysh", /* key shell (extended Korn shell) */
"/bin/posix/sh",
+ "/sbin/sh"
# endif /* V4FS */
# endif /* __hpux */
# if defined(_AIX3) || defined(_AIX4)
@@ -3482,13 +3489,12 @@ lockfile(fd, filename, ext, type)
if (!bitset(LOCK_NB, type) ||
(save_errno != EACCES && save_errno != EAGAIN))
{
- int omode = -1;
-# ifdef F_GETFL
- (void) fcntl(fd, F_GETFL, &omode);
+ int omode = fcntl(fd, F_GETFL, 0);
+ uid_t euid = geteuid();
+
errno = save_errno;
-# endif /* F_GETFL */
syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
- filename, ext, fd, type, omode, geteuid());
+ filename, ext, fd, type, omode, euid);
dumpfd(fd, true, true);
}
# else /* !HASFLOCK */
@@ -3513,13 +3519,12 @@ lockfile(fd, filename, ext, type)
if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
{
- int omode = -1;
-# ifdef F_GETFL
- (void) fcntl(fd, F_GETFL, &omode);
+ int omode = fcntl(fd, F_GETFL, 0);
+ uid_t euid = geteuid();
+
errno = save_errno;
-# endif /* F_GETFL */
syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
- filename, ext, fd, type, omode, geteuid());
+ filename, ext, fd, type, omode, euid);
dumpfd(fd, true, true);
}
# endif /* !HASFLOCK */
@@ -5416,7 +5421,7 @@ link(source, target)
left -= writelen;
p += writelen;
}
- if (writeln < 0)
+ if (writelen < 0)
break;
}
@@ -5575,6 +5580,9 @@ char *CompileOptions[] =
#if USERDB
"USERDB",
#endif /* USERDB */
+#if USE_LDAP_INIT
+ "USE_LDAP_INIT",
+#endif /* USE_LDAP_INIT */
#if XDEBUG
"XDEBUG",
#endif /* XDEBUG */
@@ -5804,6 +5812,9 @@ char *FFRCompileOptions[] =
#if _FFR_ALLOW_SASLINFO
"_FFR_ALLOW_SASLINFO",
#endif /* _FFR_ALLOW_SASLINFO */
+#if _FFR_ALLOW_S0_ERROR_4XX
+ "_FFR_ALLOW_S0_ERROR_4XX",
+#endif /* _FFR_ALLOW_S0_ERROR_4XX */
#if _FFR_BESTMX_BETTER_TRUNCATION
"_FFR_BESTMX_BETTER_TRUNCATION",
#endif /* _FFR_BESTMX_BETTER_TRUNCATION */
@@ -5814,6 +5825,9 @@ char *FFRCompileOptions[] =
#if _FFR_CATCH_BROKEN_MTAS
"_FFR_CATCH_BROKEN_MTAS",
#endif /* _FFR_CATCH_BROKEN_MTAS */
+#if _FFR_CATCH_LONG_STRINGS
+ "_FFR_CATCH_LONG_STRINGS",
+#endif /* _FFR_CATCH_LONG_STRINGS */
#if _FFR_CHECK_EOM
"_FFR_CHECK_EOM",
#endif /* _FFR_CHECK_EOM */
@@ -5826,6 +5840,14 @@ char *FFRCompileOptions[] =
#if _FFR_DEPRECATE_MAILER_FLAG_I
"_FFR_DEPRECATE_MAILER_FLAG_I",
#endif /* _FFR_DEPRECATE_MAILER_FLAG_I */
+#if _FFR_DIGUNIX_SAFECHOWN
+/* Problem noted by Anne Bennett of Concordia University */
+ "_FFR_DIGUNIX_SAFECHOWN",
+#endif /* _FFR_DIGUNIX_SAFECHOWN */
+#if _FFR_DNSMAP_ALIASABLE
+/* Don Lewis of TDK */
+ "_FFR_DNSMAP_ALIASABLE",
+#endif /* _FFR_DNSMAP_ALIASABLE */
#if _FFR_DNSMAP_BASE
"_FFR_DNSMAP_BASE",
#endif /* _FFR_DNSMAP_BASE */
@@ -5838,6 +5860,10 @@ char *FFRCompileOptions[] =
#if _FFR_DONTLOCKFILESFORREAD_OPTION
"_FFR_DONTLOCKFILESFORREAD_OPTION",
#endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
+# if _FFR_DONT_STOP_LOOKING
+/* Noted by Neil Rickert of Northern Illinois University */
+ "_FFR_DONT_STOP_LOOKING",
+# endif /* _FFR_DONT_STOP_LOOKING */
#if _FFR_DOTTED_USERNAMES
"_FFR_DOTTED_USERNAMES",
#endif /* _FFR_DOTTED_USERNAMES */
@@ -5856,6 +5882,10 @@ char *FFRCompileOptions[] =
#if _FFR_GROUPREADABLEAUTHINFOFILE
"_FFR_GROUPREADABLEAUTHINFOFILE",
#endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
+#if _FFR_HANDLE_ISO8859_GECOS
+/* Peter Eriksson of Linkopings universitet */
+ "_FFR_HANDLE_ISO8859_GECOS",
+#endif /* _FFR_HANDLE_ISO8859_GECOS */
#if _FFR_HDR_TYPE
"_FFR_HDR_TYPE",
#endif /* _FFR_HDR_TYPE */
@@ -5866,8 +5896,15 @@ char *FFRCompileOptions[] =
"_FFR_IGNORE_EXT_ON_HELO",
#endif /* _FFR_IGNORE_EXT_ON_HELO */
#if _FFR_LDAP_RECURSION
+/* Andrew Baucom */
"_FFR_LDAP_RECURSION",
#endif /* _FFR_LDAP_RECURSION */
+#if _FFR_LDAP_SETVERSION
+ "_FFR_LDAP_SETVERSION",
+#endif /* _FFR_LDAP_SETVERSION */
+#if _FFR_LDAP_URI
+ "_FFR_LDAP_URI",
+#endif /* _FFR_LDAP_URI */
#if _FFR_MAX_FORWARD_ENTRIES
/* Randall S. Winchester of the University of Maryland */
"_FFR_MAX_FORWARD_ENTRIES",
@@ -5890,9 +5927,16 @@ char *FFRCompileOptions[] =
#if _FFR_QUEUEDELAY
"_FFR_QUEUEDELAY",
#endif /* _FFR_QUEUEDELAY */
+#if _FFR_QUEUE_GROUP_SORTORDER
+/* XXX: Still need to actually use qgrp->qg_sortorder */
+ "_FFR_QUEUE_GROUP_SORTORDER",
+#endif /* _FFR_QUEUE_GROUP_SORTORDER */
#if _FFR_QUEUE_MACRO
"_FFR_QUEUE_MACRO",
#endif /* _FFR_QUEUE_MACRO */
+#if _FFR_QUEUE_RUN_PARANOIA
+ "_FFR_QUEUE_RUN_PARANOIA",
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
#if _FFR_QUEUE_SCHED_DBG
"_FFR_QUEUE_SCHED_DBG",
#endif /* _FFR_QUEUE_SCHED_DBG */
@@ -5905,6 +5949,9 @@ char *FFRCompileOptions[] =
#if _FFR_RHS
"_FFR_RHS",
#endif /* _FFR_RHS */
+#if _FFR_SELECT_SHM
+ "_FFR_SELECT_SHM",
+#endif /* _FFR_SELECT_SHM */
#if _FFR_SHM_STATUS
"_FFR_SHM_STATUS",
#endif /* _FFR_SHM_STATUS */
@@ -5923,6 +5970,10 @@ char *FFRCompileOptions[] =
#if _FFR_TRUSTED_QF
"_FFR_TRUSTED_QF",
#endif /* _FFR_TRUSTED_QF */
+#if _FFR_USE_SETLOGIN
+/* Peter Philipp */
+ "_FFR_USE_SETLOGIN",
+#endif /* _FFR_USE_SETLOGIN */
NULL
};
diff --git a/contrib/sendmail/src/conf.h b/contrib/sendmail/src/conf.h
index 86a4b24..a3a30d1 100644
--- a/contrib/sendmail/src/conf.h
+++ b/contrib/sendmail/src/conf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -10,7 +10,7 @@
* the sendmail distribution.
*
*
- * $Id: conf.h,v 8.557 2001/10/05 03:49:41 ca Exp $
+ * $Id: conf.h,v 8.560 2002/03/15 06:01:54 geir Exp $
*/
/*
diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c
index c319192..88ff72f 100644
--- a/contrib/sendmail/src/control.c
+++ b/contrib/sendmail/src/control.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -10,7 +10,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: control.c,v 8.116 2001/12/13 21:51:38 gshapiro Exp $")
+SM_RCSID("@(#)$Id: control.c,v 8.118 2002/03/19 00:23:27 gshapiro Exp $")
/* values for cmd_code */
#define CMDERROR 0 /* bad command */
diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c
index c3e8dcc..8409066 100644
--- a/contrib/sendmail/src/daemon.c
+++ b/contrib/sendmail/src/daemon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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.603 2001/12/31 19:46:38 gshapiro Exp $")
+SM_RCSID("@(#)$Id: daemon.c,v 8.611 2002/03/18 23:08:50 gshapiro Exp $")
#if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__)
# define USE_SOCK_STREAM 1
@@ -154,6 +154,9 @@ getrequests(e)
char status[MAXLINE];
SOCKADDR sa;
SOCKADDR_LEN_T len = sizeof sa;
+#if _FFR_QUEUE_RUN_PARANOIA
+ time_t lastrun;
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
# if NETUNIX
extern int ControlSocket;
# endif /* NETUNIX */
@@ -388,7 +391,28 @@ getrequests(e)
curdaemon = -1;
if (doqueuerun())
+ {
(void) runqueue(true, false, false, false);
+#if _FFR_QUEUE_RUN_PARANOIA
+ lastrun = now;
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
+ }
+#if _FFR_QUEUE_RUN_PARANOIA
+ else if (QueueIntvl > 0 &&
+ lastrun + QueueIntvl + 60 < now)
+ {
+
+ /*
+ ** set lastrun unconditionally to avoid
+ ** calling checkqueuerunner() all the time.
+ ** That's also why we currently ignore the
+ ** result of the function call.
+ */
+
+ (void) checkqueuerunner();
+ lastrun = now;
+ }
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
if (t <= 0)
{
@@ -759,6 +783,7 @@ getrequests(e)
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{client_resolve}"), "OK");
sm_setproctitle(true, e, "startup with %s", p);
+ markstats(e, NULL, STATS_CONNECT);
if ((inchannel = sm_io_open(SmFtStdiofd,
SM_TIME_DEFAULT,
@@ -2504,6 +2529,9 @@ gothostent:
else
save_errno = errno;
+ /* couldn't connect.... figure out why */
+ (void) close(s);
+
/* if running demand-dialed connection, try again */
if (DialDelay > 0 && firstconnect &&
bitnset(M_DIALDELAY, mci->mci_mailer->m_flags))
@@ -2516,9 +2544,6 @@ gothostent:
continue;
}
- /* couldn't connect.... figure out why */
- (void) close(s);
-
if (LogLevel > 13)
sm_syslog(LOG_INFO, e->e_id,
"makeconnection (%s [%s]) failed: %s",
@@ -2980,6 +3005,8 @@ restart_daemon()
#ifdef SIGUSR1
SM_NOOP_SIGNAL(SIGUSR1, ousr1);
#endif /* SIGUSR1 */
+
+ /* Turn back on signals */
sm_allsignals(false);
(void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron);
diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c
index 402eac4..38931ec 100644
--- a/contrib/sendmail/src/deliver.c
+++ b/contrib/sendmail/src/deliver.c
@@ -14,12 +14,16 @@
#include <sendmail.h>
#include <sys/time.h>
-SM_RCSID("@(#)$Id: deliver.c,v 8.928 2002/01/10 03:23:29 gshapiro Exp $")
+SM_RCSID("@(#)$Id: deliver.c,v 8.935 2002/03/23 18:30:40 gshapiro Exp $")
#if HASSETUSERCONTEXT
# include <login_cap.h>
#endif /* HASSETUSERCONTEXT */
+#if NETINET || NETINET6
+# include <arpa/inet.h>
+#endif /* NETINET || NETINET6 */
+
#if STARTTLS || SASL
# include "sfsasl.h"
#endif /* STARTTLS || SASL */
@@ -2112,6 +2116,7 @@ tryhost:
if (i == EX_OK)
{
goodmxfound = true;
+ markstats(e, firstto, STATS_CONNECT);
mci->mci_state = MCIS_OPENING;
mci_cache(mci);
if (TrafficLogFile != NULL)
@@ -2501,6 +2506,22 @@ tryhost:
new_ruid = m->m_uid;
else
new_ruid = DefUid;
+
+# if _FFR_USE_SETLOGIN
+ /* run disconnected from terminal and set login name */
+ if (setsid() >= 0 &&
+ ctladdr != NULL && ctladdr->q_uid != 0 &&
+ new_euid == ctladdr->q_uid)
+ {
+ struct passwd *pwd;
+
+ pwd = sm_getpwuid(ctladdr->q_uid);
+ if (pwd != NULL && suidwarn)
+ (void) setlogin(pwd->pw_name);
+ endpwent();
+ }
+# endif /* _FFR_USE_SETLOGIN */
+
if (new_euid != NO_UID)
{
if (RunAsUid != 0 && new_euid != RunAsUid)
@@ -2631,8 +2652,10 @@ tryhost:
j | FD_CLOEXEC);
}
+# if !_FFR_USE_SETLOGIN
/* run disconnected from terminal */
(void) setsid();
+# endif /* !_FFR_USE_SETLOGIN */
/* try to execute the mailer */
(void) execve(m->m_mailer, (ARGV_T) pv,
@@ -3931,6 +3954,13 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
statmsg = buf;
usestat = true;
}
+ else if (bitnset(M_LMTP, m->m_flags) && e->e_statmsg != NULL)
+ {
+ (void) sm_snprintf(buf, sizeof buf, "%s (%s)", statmsg,
+ shortenstring(e->e_statmsg, 403));
+ statmsg = buf;
+ usestat = true;
+ }
}
/*
@@ -4998,11 +5028,17 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
}
(void) sm_strlcpy(targetfile, SafeFileEnv, sizeof targetfile);
realfile = targetfile + len;
- if (targetfile[len - 1] != '/')
- (void) sm_strlcat(targetfile, "/", sizeof targetfile);
if (*filename == '/')
filename++;
- (void) sm_strlcat(targetfile, filename, sizeof targetfile);
+ if (*filename != '\0')
+ {
+ /* paranoia: trailing / should be removed in readcf */
+ if (targetfile[len - 1] != '/')
+ (void) sm_strlcat(targetfile,
+ "/", sizeof targetfile);
+ (void) sm_strlcat(targetfile, filename,
+ sizeof targetfile);
+ }
}
else if (mailer->m_rootdir != NULL)
{
@@ -5045,6 +5081,14 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
** the complications of calling subroutines, etc.
*/
+
+ /*
+ ** Dispose of SIGCHLD signal catchers that may be laying
+ ** around so that the waitfor() below will get it.
+ */
+
+ (void) sm_signal(SIGCHLD, SIG_DFL);
+
DOFORK(fork);
if (pid < 0)
@@ -5234,6 +5278,9 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
if (realfile != targetfile)
{
+ char save;
+
+ save = *realfile;
*realfile = '\0';
if (tTd(11, 20))
sm_dprintf("mailfile: chroot %s\n", targetfile);
@@ -5243,7 +5290,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
targetfile);
RETURN(EX_CANTCREAT);
}
- *realfile = '/';
+ *realfile = save;
}
if (tTd(11, 40))
diff --git a/contrib/sendmail/src/domain.c b/contrib/sendmail/src/domain.c
index f34df4c..20b7fb4 100644
--- a/contrib/sendmail/src/domain.c
+++ b/contrib/sendmail/src/domain.c
@@ -14,9 +14,9 @@
#include <sendmail.h>
#if NAMED_BIND
-SM_RCSID("@(#)$Id: domain.c,v 8.177 2001/12/12 01:16:15 ca Exp $ (with name server)")
+SM_RCSID("@(#)$Id: domain.c,v 8.180 2002/03/05 05:47:12 gshapiro Exp $ (with name server)")
#else /* NAMED_BIND */
-SM_RCSID("@(#)$Id: domain.c,v 8.177 2001/12/12 01:16:15 ca Exp $ (without name server)")
+SM_RCSID("@(#)$Id: domain.c,v 8.180 2002/03/05 05:47:12 gshapiro Exp $ (without name server)")
#endif /* NAMED_BIND */
#if NAMED_BIND
@@ -931,6 +931,14 @@ cnameloop:
*/
SM_SET_H_ERRNO(TRY_AGAIN);
+# if _FFR_DONT_STOP_LOOKING
+ if (**dp == '\0')
+ {
+ if (*statp == EX_OK)
+ *statp = EX_TEMPFAIL;
+ goto nexttype;
+ }
+# endif /* _FFR_DONT_STOP_LOOKING */
*statp = EX_TEMPFAIL;
if (WorkAroundBrokenAAAA)
@@ -952,6 +960,9 @@ cnameloop:
return false;
}
+# if _FFR_DONT_STOP_LOOKING
+nexttype:
+# endif /* _FFR_DONT_STOP_LOOKING */
if (h_errno != HOST_NOT_FOUND)
{
/* might have another type of interest */
diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c
index 16449f1..ec86b87 100644
--- a/contrib/sendmail/src/envelope.c
+++ b/contrib/sendmail/src/envelope.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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: envelope.c,v 8.279 2001/12/10 19:56:04 ca Exp $")
+SM_RCSID("@(#)$Id: envelope.c,v 8.281 2002/02/06 19:54:54 ca Exp $")
/*
** NEWENVELOPE -- fill in a new envelope
@@ -1030,8 +1030,13 @@ setsender(from, e, delimptr, delimchar, internal)
/* if the user already given fullname don't redefine */
if (FullName == NULL)
FullName = macvalue('x', e);
- if (FullName != NULL && FullName[0] == '\0')
- FullName = NULL;
+ if (FullName != NULL)
+ {
+ if (FullName[0] == '\0')
+ FullName = NULL;
+ else
+ FullName = newstr(FullName);
+ }
}
if (e->e_from.q_user[0] != '\0' &&
diff --git a/contrib/sendmail/src/helpfile b/contrib/sendmail/src/helpfile
index 02e6138..931a06e 100644
--- a/contrib/sendmail/src/helpfile
+++ b/contrib/sendmail/src/helpfile
@@ -1,6 +1,6 @@
#vers 2
cpyr
-cpyr Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+cpyr Copyright (c) 1998-2000, 2002 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.38 2000/10/15 17:18:44 ca Exp $$
+cpyr $$Id: helpfile,v 8.40 2002/03/19 00:23:28 gshapiro Exp $$
cpyr
smtp This is sendmail version $v
smtp Topics:
@@ -133,4 +133,4 @@ control help This message.
control restart Restart sendmail.
control shutdown Shutdown sendmail.
control status Show sendmail status.
-control memdump Dump allocated memory list.
+control memdump Dump allocated memory list (for debugging only).
diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c
index 3d3f3cf..a77c245 100644
--- a/contrib/sendmail/src/main.c
+++ b/contrib/sendmail/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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.868 2001/12/29 04:54:38 ca Exp $")
+SM_RCSID("@(#)$Id: main.c,v 8.876 2002/02/27 23:49:52 ca Exp $")
#if NETINET || NETINET6
@@ -326,11 +326,16 @@ main(argc, argv, envp)
#ifdef SIGUSR1
/* Only allow root (or non-set-*-ID binaries) to use SIGUSR1 */
- if (extraprivs)
+ if (!extraprivs)
{
/* arrange to dump state on user-1 signal */
(void) sm_signal(SIGUSR1, sigusr1);
}
+ else
+ {
+ /* ignore user-1 signal */
+ (void) sm_signal(SIGUSR1, SIG_IGN);
+ }
#endif /* SIGUSR1 */
/* initialize for setproctitle */
@@ -389,7 +394,8 @@ main(argc, argv, envp)
switch (j)
{
case 'b': /* operations mode */
- switch (j = *optarg)
+ j = (optarg == NULL) ? ' ' : *optarg;
+ switch (j)
{
case MD_DAEMON:
case MD_FGDAEMON:
@@ -544,13 +550,6 @@ main(argc, argv, envp)
j = 0;
for (av = argv; *av != NULL; )
j += strlen(*av++) + 1;
- if (j < 0 || j > SM_ARG_MAX)
- {
- syserr("!Arguments too long");
-
- /* NOTREACHED */
- return EX_USAGE;
- }
SaveArgv = (char **) xalloc(sizeof (char *) * (argc + 1));
CommandLineArgs = xalloc(j);
p = CommandLineArgs;
@@ -2179,7 +2178,10 @@ main(argc, argv, envp)
** increment the work counter.
*/
- runqueueevent(qgrp);
+ for (i = 0; i < NumQueue && Queue[i] != NULL;
+ i++)
+ Queue[i]->qg_nextrun = (time_t) -1;
+ Queue[qgrp]->qg_nextrun = 0;
(void) run_work_group(Queue[qgrp]->qg_wgrp,
false, Verbose,
queuepersistent, false);
@@ -3537,6 +3539,7 @@ drop_privileges(to_real_uid)
RunAsUserName = RealUserName;
RunAsUid = RealUid;
RunAsGid = RealGid;
+ EffGid = RunAsGid;
}
/* make sure no one can grab open descriptors for secret files */
@@ -3620,20 +3623,19 @@ drop_privileges(to_real_uid)
/* fiddle with uid */
if (to_real_uid || RunAsUid != 0)
{
- uid_t euid = geteuid();
+ uid_t euid;
/*
** Try to setuid(RunAsUid).
** euid must be RunAsUid,
- ** ruid must be RunAsUid unless it's the MSP and the euid
- ** wasn't 0 and we didn't have to drop privileges to the
- ** real uid.
+ ** ruid must be RunAsUid unless (e|r)uid wasn't 0
+ ** and we didn't have to drop privileges to the real uid.
*/
if (setuid(RunAsUid) < 0 ||
- (getuid() != RunAsUid &&
- (!UseMSP || euid == 0 || to_real_uid )) ||
- geteuid() != RunAsUid)
+ geteuid() != RunAsUid ||
+ (getuid() != RunAsUid &&
+ (to_real_uid || geteuid() == 0 || getuid() == 0)))
{
#if HASSETREUID
/*
@@ -3642,7 +3644,7 @@ drop_privileges(to_real_uid)
** setuid() to drop the saved-uid as well.
*/
- if (euid == RunAsUid)
+ if (geteuid() == RunAsUid)
{
if (setreuid(RunAsUid, -1) < 0)
{
@@ -3665,6 +3667,7 @@ drop_privileges(to_real_uid)
rval = EX_OSERR;
}
}
+ euid = geteuid();
if (RunAsUid != 0 && setuid(0) == 0)
{
/*
diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c
index 7205da0..f9be086 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.618 2002/01/11 22:06:52 gshapiro Exp $")
+SM_RCSID("@(#)$Id: map.c,v 8.641 2002/03/26 22:56:36 gshapiro Exp $")
#if LDAPMAP
# include <sm/ldap.h>
@@ -2591,7 +2591,7 @@ nis_map_open(map, mode)
if (yperr != 0)
{
if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 4.3.5 NIS map %s specified, but NIS not running",
+ syserr("451 4.3.5 NIS map %s specified, but NIS not running",
map->map_file);
return false;
}
@@ -2625,7 +2625,7 @@ nis_map_open(map, mode)
if (!bitset(MF_OPTIONAL, map->map_mflags))
{
- syserr("421 4.0.0 Cannot bind to map %s in domain %s: %s",
+ syserr("451 4.3.5 Cannot bind to map %s in domain %s: %s",
map->map_file, map->map_domain, yperr_string(yperr));
}
@@ -2879,7 +2879,7 @@ nisplus_map_open(map, mode)
default: /* all other nisplus errors */
# if 0
if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 4.0.0 Cannot find table %s.%s: %s",
+ syserr("451 4.3.5 Cannot find table %s.%s: %s",
map->map_file, map->map_domain,
nis_sperrno(res->status));
# endif /* 0 */
@@ -2895,7 +2895,7 @@ nisplus_map_open(map, mode)
sm_dprintf("nisplus_map_open: %s is not a table\n", qbuf);
# if 0
if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 4.0.0 %s.%s: %s is not a table",
+ syserr("451 4.3.5 %s.%s: %s is not a table",
map->map_file, map->map_domain,
nis_sperrno(res->status));
# endif /* 0 */
@@ -3132,7 +3132,7 @@ nisplus_getcanonname(name, hbsize, statp)
}
if (tTd(38, 20))
- sm_dprintf("\nnisplus_getcanoname(%s), qbuf=%s\n",
+ sm_dprintf("\nnisplus_getcanonname(%s), qbuf=%s\n",
name, qbuf);
result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH,
@@ -3152,12 +3152,12 @@ nisplus_getcanonname(name, hbsize, statp)
/* ignore second entry */
if (tTd(38, 20))
- sm_dprintf("nisplus_getcanoname(%s), got %d entries, all but first ignored\n",
+ sm_dprintf("nisplus_getcanonname(%s), got %d entries, all but first ignored\n",
name, count);
}
if (tTd(38, 20))
- sm_dprintf("nisplus_getcanoname(%s), found in directory \"%s\"\n",
+ sm_dprintf("nisplus_getcanonname(%s), found in directory \"%s\"\n",
name, (NIS_RES_OBJECT(result))->zo_domain);
@@ -3325,7 +3325,7 @@ ldapmap_open(map, mode)
if (LogLevel > 1)
sm_syslog(LOG_NOTICE, CurEnv->e_id,
"timeout conning to LDAP server %.100s",
- lmap->ldap_host == NULL ? "localhost" : lmap->ldap_host);
+ lmap->ldap_target == NULL ? "localhost" : lmap->ldap_target);
}
if (!bitset(MF_OPTIONAL, map->map_mflags))
@@ -3337,18 +3337,18 @@ ldapmap_open(map, mode)
# else /* USE_LDAP_INIT */
"ldap_open",
# endif /* USE_LDAP_INIT */
- lmap->ldap_host == NULL ? "localhost"
- : lmap->ldap_host,
+ lmap->ldap_target == NULL ? "localhost"
+ : lmap->ldap_target,
map->map_mname);
else
- syserr("421 4.0.0 %s failed to %s in map %s",
+ syserr("451 4.3.5 %s failed to %s in map %s",
# if USE_LDAP_INIT
"ldap_init/ldap_bind",
# else /* USE_LDAP_INIT */
"ldap_open",
# endif /* USE_LDAP_INIT */
- lmap->ldap_host == NULL ? "localhost"
- : lmap->ldap_host,
+ lmap->ldap_target == NULL ? "localhost"
+ : lmap->ldap_target,
map->map_mname);
}
return false;
@@ -3445,12 +3445,17 @@ ldapmap_lookup(map, name, av, statp)
char **av;
int *statp;
{
- int i;
+# if _FFR_LDAP_RECURSION
+ int plen = 0;
+ int psize = 0;
+# else /* _FFR_LDAP_RECURSION */
int entries = 0;
- int msgid;
+ int i;
int ret;
- int save_errno;
int vsize;
+# endif /* _FFR_LDAP_RECURSION */
+ int msgid;
+ int save_errno;
char *vp, *p;
char *result = NULL;
SM_LDAP_STRUCT *lmap = NULL;
@@ -3485,15 +3490,15 @@ ldapmap_lookup(map, name, av, statp)
syserr("Error in ldap_search using %s in map %s",
keybuf, map->map_mname);
else
- syserr("421 4.0.0 Error in ldap_search using %s in map %s",
+ syserr("451 4.3.5 Error in ldap_search using %s in map %s",
keybuf, map->map_mname);
}
*statp = EX_TEMPFAIL;
switch (save_errno - E_LDAPBASE)
{
-#ifdef LDAP_SERVER_DOWN
+# ifdef LDAP_SERVER_DOWN
case LDAP_SERVER_DOWN:
-#endif /* LDAP_SERVER_DOWN */
+# endif /* LDAP_SERVER_DOWN */
case LDAP_TIMEOUT:
case LDAP_UNAVAILABLE:
/* server disappeared, try reopen on next search */
@@ -3523,7 +3528,7 @@ ldapmap_lookup(map, name, av, statp)
p = NULL;
*statp = sm_ldap_results(lmap, msgid, flags, map->map_coldelim,
- rpool, &p, NULL);
+ rpool, &p, &plen, &psize, NULL);
save_errno = errno;
/* Copy result so rpool can be freed */
@@ -3547,15 +3552,14 @@ ldapmap_lookup(map, name, av, statp)
syserr("Error getting LDAP results in map %s",
map->map_mname);
else
- syserr("421 4.0.0 Error getting LDAP results in map %s",
+ syserr("451 4.3.5 Error getting LDAP results in map %s",
map->map_mname);
}
errno = save_errno;
return NULL;
}
- goto finishlookup;
}
-# endif /* _FFR_LDAP_RECURSION */
+# else /* _FFR_LDAP_RECURSION */
/* Get results */
while ((ret = ldap_result(lmap->ldap_ld, msgid, 0,
@@ -3608,7 +3612,7 @@ ldapmap_lookup(map, name, av, statp)
bitset(MF_MATCHONLY, map->map_mflags))
continue;
-# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
+# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
/*
** Reset value to prevent lingering
** LDAP_DECODING_ERROR due to
@@ -3616,7 +3620,7 @@ ldapmap_lookup(map, name, av, statp)
*/
lmap->ldap_ld->ld_errno = LDAP_SUCCESS;
-# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
+# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
for (attr = ldap_first_attribute(lmap->ldap_ld, entry,
&ber);
@@ -3636,9 +3640,7 @@ ldapmap_lookup(map, name, av, statp)
save_errno = sm_ldap_geterrno(lmap->ldap_ld);
if (save_errno == LDAP_SUCCESS)
{
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
continue;
}
@@ -3653,13 +3655,11 @@ ldapmap_lookup(map, name, av, statp)
syserr("Error getting LDAP values in map %s",
map->map_mname);
else
- syserr("421 4.0.0 Error getting LDAP values in map %s",
+ syserr("451 4.3.5 Error getting LDAP values in map %s",
map->map_mname);
}
*statp = EX_TEMPFAIL;
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
if (lmap->ldap_res != NULL)
{
ldap_msgfree(lmap->ldap_res);
@@ -3676,7 +3676,7 @@ ldapmap_lookup(map, name, av, statp)
*statp = EX_OK;
-# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
+# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
/*
** Reset value to prevent lingering
** LDAP_DECODING_ERROR due to
@@ -3684,7 +3684,7 @@ ldapmap_lookup(map, name, av, statp)
*/
lmap->ldap_ld->ld_errno = LDAP_SUCCESS;
-# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
+# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
/*
** If matching only,
@@ -3696,9 +3696,7 @@ ldapmap_lookup(map, name, av, statp)
if (lmap->ldap_attrsonly == LDAPMAP_FALSE)
ldap_value_free(vals);
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
continue;
}
@@ -3712,18 +3710,14 @@ ldapmap_lookup(map, name, av, statp)
if (lmap->ldap_attrsonly == LDAPMAP_TRUE)
{
vp = newstr(attr);
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
break;
}
if (vals[0] == NULL)
{
ldap_value_free(vals);
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
continue;
}
@@ -3740,9 +3734,7 @@ ldapmap_lookup(map, name, av, statp)
else
sm_strlcpy(vp, vals[0], vsize);
ldap_value_free(vals);
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
break;
}
@@ -3763,9 +3755,7 @@ ldapmap_lookup(map, name, av, statp)
sm_free(vp); /* XXX */
vp = tmp;
}
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
continue;
}
@@ -3803,9 +3793,7 @@ ldapmap_lookup(map, name, av, statp)
}
ldap_value_free(vals);
-# if USING_NETSCAPE_LDAP
ldap_memfree(attr);
-# endif /* USING_NETSCAPE_LDAP */
if (vp == NULL)
{
vp = vp_tmp;
@@ -3843,7 +3831,7 @@ ldapmap_lookup(map, name, av, statp)
syserr("Error getting LDAP attributes in map %s",
map->map_mname);
else
- syserr("421 4.0.0 Error getting LDAP attributes in map %s",
+ syserr("451 4.3.5 Error getting LDAP attributes in map %s",
map->map_mname);
}
*statp = EX_TEMPFAIL;
@@ -3876,7 +3864,7 @@ ldapmap_lookup(map, name, av, statp)
syserr("Error getting LDAP entries in map %s",
map->map_mname);
else
- syserr("421 4.0.0 Error getting LDAP entries in map %s",
+ syserr("451 4.3.5 Error getting LDAP entries in map %s",
map->map_mname);
}
*statp = EX_TEMPFAIL;
@@ -3911,7 +3899,7 @@ ldapmap_lookup(map, name, av, statp)
syserr("Error getting LDAP results in map %s",
map->map_mname);
else
- syserr("421 4.0.0 Error getting LDAP results in map %s",
+ syserr("451 4.3.5 Error getting LDAP results in map %s",
map->map_mname);
}
*statp = EX_TEMPFAIL;
@@ -3920,9 +3908,9 @@ ldapmap_lookup(map, name, av, statp)
switch (save_errno - E_LDAPBASE)
{
-#ifdef LDAP_SERVER_DOWN
+# ifdef LDAP_SERVER_DOWN
case LDAP_SERVER_DOWN:
-#endif /* LDAP_SERVER_DOWN */
+# endif /* LDAP_SERVER_DOWN */
case LDAP_TIMEOUT:
case LDAP_UNAVAILABLE:
/* server disappeared, try reopen on next search */
@@ -3932,9 +3920,6 @@ ldapmap_lookup(map, name, av, statp)
errno = save_errno;
return NULL;
}
-
-# if _FFR_LDAP_RECURSION
-finishlookup:
# endif /* _FFR_LDAP_RECURSION */
/* Did we match anything? */
@@ -3980,15 +3965,25 @@ static STAB *
ldapmap_findconn(lmap)
SM_LDAP_STRUCT *lmap;
{
+ char *format;
char *nbuf;
STAB *SM_NONVOLATILE s = NULL;
- nbuf = sm_stringf_x("%s%c%d%c%s%c%s%d",
- (lmap->ldap_host == NULL ? "localhost"
- : lmap->ldap_host),
+# if _FFR_LDAP_SETVERSION
+ format = "%s%c%d%c%d%c%s%c%s%d";
+# else /* _FFR_LDAP_SETVERSION */
+ format = "%s%c%d%c%s%c%s%d";
+# endif /* _FFR_LDAP_SETVERSION */
+ nbuf = sm_stringf_x(format,
+ (lmap->ldap_target == NULL ? "localhost"
+ : lmap->ldap_target),
CONDELSE,
lmap->ldap_port,
CONDELSE,
+# if _FFR_LDAP_SETVERSION
+ lmap->ldap_version,
+ CONDELSE,
+# endif /* _FFR_LDAP_SETVERSION */
(lmap->ldap_binddn == NULL ? ""
: lmap->ldap_binddn),
CONDELSE,
@@ -4039,6 +4034,9 @@ ldapmap_parseargs(map, args)
char *args;
{
bool secretread = true;
+# if _FFR_LDAP_URI
+ bool ldaphost = false;
+# endif /* _FFR_LDAP_URI */
int i;
register char *p = args;
SM_LDAP_STRUCT *lmap;
@@ -4320,7 +4318,16 @@ ldapmap_parseargs(map, args)
case 'h': /* ldap host */
while (isascii(*++p) && isspace(*p))
continue;
- lmap->ldap_host = p;
+# if _FFR_LDAP_URI
+ if (lmap->ldap_uri)
+ {
+ syserr("Can not specify both an LDAP host and an LDAP URI in map %s",
+ map->map_mname);
+ return false;
+ }
+ ldaphost = true;
+# endif /* _FFR_LDAP_URI */
+ lmap->ldap_target = p;
break;
case 'b': /* search base */
@@ -4402,6 +4409,54 @@ ldapmap_parseargs(map, args)
secretread = false;
break;
+# if _FFR_LDAP_URI
+ case 'H': /* Use LDAP URI */
+# if !USE_LDAP_INIT
+ syserr("Must compile with -DUSE_LDAP_INIT to use LDAP URIs (-H) in map %s",
+ map->map_mname);
+ return false;
+# else /* !USE_LDAP_INIT */
+ if (ldaphost)
+ {
+ syserr("Can not specify both an LDAP host and an LDAP URI in map %s",
+ map->map_mname);
+ return false;
+ }
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ lmap->ldap_target = p;
+ lmap->ldap_uri = true;
+ break;
+# endif /* !USE_LDAP_INIT */
+# endif /* _FFR_LDAP_URI */
+
+# if _FFR_LDAP_SETVERSION
+ case 'w':
+ /* -w should be for passwd, -P should be for version */
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ lmap->ldap_version = atoi(p);
+# ifdef LDAP_VERSION_MAX
+ if (lmap->ldap_version > LDAP_VERSION_MAX)
+ {
+ syserr("LDAP version %d exceeds max of %d in map %s",
+ lmap->ldap_version, LDAP_VERSION_MAX,
+ map->map_mname);
+ return false;
+ }
+# endif /* LDAP_VERSION_MAX */
+# ifdef LDAP_VERSION_MIN
+ if (lmap->ldap_version < LDAP_VERSION_MIN)
+ {
+ syserr("LDAP version %d is lower than min of %d in map %s",
+ lmap->ldap_version, LDAP_VERSION_MIN,
+ map->map_mname);
+ return false;
+ }
+# endif /* LDAP_VERSION_MIN */
+ break;
+# endif /* _FFR_LDAP_SETVERSION */
+
default:
syserr("Illegal option %c map %s", *p, map->map_mname);
break;
@@ -4435,12 +4490,12 @@ ldapmap_parseargs(map, args)
** and dump it into map->map_dbptr1
*/
- if (lmap->ldap_host != NULL &&
+ if (lmap->ldap_target != NULL &&
(LDAPDefaults == NULL ||
LDAPDefaults == lmap ||
- LDAPDefaults->ldap_host != lmap->ldap_host))
- lmap->ldap_host = newstr(ldapmap_dequote(lmap->ldap_host));
- map->map_domain = lmap->ldap_host;
+ LDAPDefaults->ldap_target != lmap->ldap_target))
+ lmap->ldap_target = newstr(ldapmap_dequote(lmap->ldap_target));
+ map->map_domain = lmap->ldap_target;
if (lmap->ldap_binddn != NULL &&
(LDAPDefaults == NULL ||
@@ -4564,15 +4619,23 @@ ldapmap_parseargs(map, args)
if (lmap->ldap_attr[0] != NULL)
{
-#if _FFR_LDAP_RECURSION
+# if _FFR_LDAP_RECURSION
bool recurse = false;
- int final = 0;
-#endif /* _FFR_LDAP_RECURSION */
+ bool normalseen = false;
+# endif /* _FFR_LDAP_RECURSION */
i = 0;
p = ldapmap_dequote(lmap->ldap_attr[0]);
lmap->ldap_attr[0] = NULL;
+# if _FFR_LDAP_RECURSION
+ /* Prime the attr list with the objectClass attribute */
+ lmap->ldap_attr[i] = "objectClass";
+ lmap->ldap_attr_type[i] = SM_LDAP_ATTR_OBJCLASS;
+ lmap->ldap_attr_needobjclass[i] = NULL;
+ i++;
+# endif /* _FFR_LDAP_RECURSION */
+
while (p != NULL)
{
char *v;
@@ -4594,48 +4657,85 @@ ldapmap_parseargs(map, args)
}
if (*v != '\0')
{
-#if _FFR_LDAP_RECURSION
+# if _FFR_LDAP_RECURSION
+ int j;
+ int use;
char *type;
+ char *needobjclass;
type = strchr(v, ':');
if (type != NULL)
+ {
*type++ = '\0';
-#endif /* _FFR_LDAP_RECURSION */
+ needobjclass = strchr(type, ':');
+ if (needobjclass != NULL)
+ *needobjclass++ = '\0';
+ }
+ else
+ {
+ needobjclass = NULL;
+ }
- lmap->ldap_attr[i] = newstr(v);
+ use = i;
-#if _FFR_LDAP_RECURSION
- if (type != NULL)
+ /* allow override on "objectClass" type */
+ if (sm_strcasecmp(v, "objectClass") == 0 &&
+ lmap->ldap_attr_type[0] == SM_LDAP_ATTR_OBJCLASS)
+ {
+ use = 0;
+ }
+ else
{
- if (sm_strcasecmp(type, "normal") == 0)
+ /*
+ ** Don't add something to attribute
+ ** list twice.
+ */
+
+ for (j = 1; j < i; j++)
{
- lmap->ldap_attr_type[i] = LDAPMAP_ATTR_NORMAL;
+ if (sm_strcasecmp(v, lmap->ldap_attr[j]) == 0)
+ {
+ syserr("Duplicate attribute (%s) in %s",
+ v, map->map_mname);
+ return false;
+ }
}
- else if (sm_strcasecmp(type, "dn") == 0)
+
+ lmap->ldap_attr[use] = newstr(v);
+ if (needobjclass != NULL &&
+ *needobjclass != '\0' &&
+ *needobjclass != '*')
+ {
+ lmap->ldap_attr_needobjclass[use] = newstr(needobjclass);
+ }
+ else
+ {
+ lmap->ldap_attr_needobjclass[use] = NULL;
+ }
+
+ }
+
+ if (type != NULL && *type != '\0')
+ {
+ if (sm_strcasecmp(type, "dn") == 0)
{
recurse = true;
- lmap->ldap_attr_type[i] = LDAPMAP_ATTR_DN;
+ lmap->ldap_attr_type[use] = SM_LDAP_ATTR_DN;
}
else if (sm_strcasecmp(type, "filter") == 0)
{
recurse = true;
- lmap->ldap_attr_type[i] = LDAPMAP_ATTR_FILTER;
+ lmap->ldap_attr_type[use] = SM_LDAP_ATTR_FILTER;
}
else if (sm_strcasecmp(type, "url") == 0)
{
recurse = true;
- lmap->ldap_attr_type[i] = LDAPMAP_ATTR_URL;
+ lmap->ldap_attr_type[use] = SM_LDAP_ATTR_URL;
}
- else if (sm_strcasecmp(type, "final") == 0)
+ else if (sm_strcasecmp(type, "normal") == 0)
{
- lmap->ldap_attr_type[i] = LDAPMAP_ATTR_FINAL;
- if (final >= LDAPMAP_MAX_ATTR)
- {
- syserr("Too many FINAL attributes in %s (max %d)",
- map->map_mname, LDAPMAP_MAX_ATTR);
- return false;
- }
- lmap->ldap_attr_final[final++] = lmap->ldap_attr[i];
+ lmap->ldap_attr_type[use] = SM_LDAP_ATTR_NORMAL;
+ normalseen = true;
}
else
{
@@ -4645,17 +4745,21 @@ ldapmap_parseargs(map, args)
}
}
else
- lmap->ldap_attr_type[i] = LDAPMAP_ATTR_NORMAL;
-#endif /* _FFR_LDAP_RECURSION */
+ {
+ lmap->ldap_attr_type[use] = SM_LDAP_ATTR_NORMAL;
+ normalseen = true;
+ }
+# else /* _FFR_LDAP_RECURSION */
+ lmap->ldap_attr[i] = newstr(v);
+# endif /* _FFR_LDAP_RECURSION */
i++;
}
}
lmap->ldap_attr[i] = NULL;
-#if _FFR_LDAP_RECURSION
- lmap->ldap_attr_final[final] = NULL;
- if (recurse && lmap->ldap_attr_final[0] == NULL)
+# if _FFR_LDAP_RECURSION
+ if (recurse && !normalseen)
{
- syserr("LDAP recursion requested in %s but no FINAL attribute given",
+ syserr("LDAP recursion requested in %s but no returnable attribute given",
map->map_mname);
return false;
}
@@ -4665,7 +4769,7 @@ ldapmap_parseargs(map, args)
map->map_mname);
return false;
}
-#endif /* _FFR_LDAP_RECURSION */
+# endif /* _FFR_LDAP_RECURSION */
}
map->map_db1 = (ARBPTR_T) lmap;
return true;
@@ -4722,6 +4826,7 @@ ldapmap_set_defaults(spec)
if (LDAPDefaults->ldap_filter != NULL)
{
syserr("readcf: option LDAPDefaultSpec: Do not set the LDAP search filter");
+
/* don't free, it isn't malloc'ed in parseargs */
LDAPDefaults->ldap_filter = NULL;
}
@@ -4917,7 +5022,7 @@ ph_map_close(map)
pmap = (PH_MAP_STRUCT *)map->map_db1;
if (tTd(38, 9))
- sm_dprintf("ph_map_close(%s): pmap->ph_fastclose=%d",
+ sm_dprintf("ph_map_close(%s): pmap->ph_fastclose=%d\n",
map->map_mname, pmap->ph_fastclose);
@@ -5311,7 +5416,7 @@ hes_map_open(map, mode)
return true;
if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 4.0.0 cannot initialize Hesiod map (%s)",
+ syserr("451 4.3.5 cannot initialize Hesiod map (%s)",
sm_errstring(errno));
return false;
# else /* HESIOD_INIT */
@@ -5325,7 +5430,7 @@ hes_map_open(map, mode)
}
if (!bitset(MF_OPTIONAL, map->map_mflags))
- syserr("421 4.0.0 cannot initialize Hesiod map (%d)", hes_error());
+ syserr("451 4.3.5 cannot initialize Hesiod map (%d)", hes_error());
return false;
# endif /* HESIOD_INIT */
diff --git a/contrib/sendmail/src/mci.c b/contrib/sendmail/src/mci.c
index ce9422c..a819bbb 100644
--- a/contrib/sendmail/src/mci.c
+++ b/contrib/sendmail/src/mci.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: mci.c,v 8.202 2001/11/05 22:12:17 ca Exp $")
+SM_RCSID("@(#)$Id: mci.c,v 8.204 2002/02/22 18:24:57 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
@@ -157,7 +157,7 @@ mci_scan(savemci)
bestmci = &MciCache[i];
continue;
}
- if ((mci->mci_lastuse + MciCacheTimeout < now ||
+ if ((mci->mci_lastuse + MciCacheTimeout <= now ||
(mci->mci_mailer != NULL &&
mci->mci_mailer->m_maxdeliveries > 0 &&
mci->mci_deliveries + 1 >= mci->mci_mailer->m_maxdeliveries))&&
@@ -388,7 +388,7 @@ mci_get(host, m)
time_t now = curtime();
/* if this info is stale, ignore it */
- if (now > mci->mci_lastuse + MciInfoTimeout)
+ if (mci->mci_lastuse + MciInfoTimeout <= now)
{
mci->mci_lastuse = now;
mci->mci_errno = 0;
@@ -510,7 +510,6 @@ static struct mcifbits MciFlags[] =
{ MCIF_SIZE, "SIZE" },
{ MCIF_8BITMIME, "8BITMIME" },
{ MCIF_7BIT, "7BIT" },
- { MCIF_MULTSTAT, "MULTSTAT" },
{ MCIF_INHEADER, "INHEADER" },
{ MCIF_CVT8TO7, "CVT8TO7" },
{ MCIF_DSN, "DSN" },
@@ -1311,7 +1310,7 @@ mci_purge_persistent(pathname, hostname)
pathname, sm_errstring(errno));
return ret;
}
- if (curtime() - statbuf.st_mtime < MciInfoTimeout)
+ if (curtime() - statbuf.st_mtime <= MciInfoTimeout)
return 1;
if (hostname != NULL)
{
diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c
index 844a3ba..af196dc 100644
--- a/contrib/sendmail/src/milter.c
+++ b/contrib/sendmail/src/milter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -10,7 +10,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: milter.c,v 8.185 2001/11/21 02:21:15 gshapiro Exp $")
+SM_RCSID("@(#)$Id: milter.c,v 8.194 2002/03/05 00:23:47 gshapiro Exp $")
#if MILTER
# include <libmilter/mfapi.h>
@@ -139,14 +139,17 @@ static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
return NULL; \
} \
\
- FD_ZERO(&fds); \
- SM_FD_SET(m->mf_sock, &fds); \
- tv.tv_sec = (secs); \
- tv.tv_usec = 0; \
- ret = select(m->mf_sock + 1, \
- (write) ? NULL : &fds, \
- (write) ? &fds : NULL, \
- NULL, &tv); \
+ do \
+ { \
+ FD_ZERO(&fds); \
+ SM_FD_SET(m->mf_sock, &fds); \
+ tv.tv_sec = (secs); \
+ tv.tv_usec = 0; \
+ ret = select(m->mf_sock + 1, \
+ (write) ? NULL : &fds, \
+ (write) ? &fds : NULL, \
+ NULL, &tv); \
+ } while (ret < 0 && errno == EINTR); \
\
switch (ret) \
{ \
@@ -566,6 +569,7 @@ milter_open(m, parseonly, e)
}
/* protocol:filename or protocol:port@host */
+ memset(&addr, '\0', sizeof addr);
p = m->mf_conn;
colon = strchr(p, ':');
if (colon != NULL)
@@ -1881,7 +1885,7 @@ milter_send_command(m, command, data, sz, e, state)
m->mf_timeout[SMFTO_WRITE], e);
if (m->mf_state == SMFS_ERROR)
{
- MILTER_CHECK_ERROR(/* EMPTY */;);
+ MILTER_CHECK_ERROR(return NULL);
return NULL;
}
@@ -1890,7 +1894,7 @@ milter_send_command(m, command, data, sz, e, state)
m->mf_timeout[SMFTO_READ], e);
if (m->mf_state == SMFS_ERROR)
{
- MILTER_CHECK_ERROR(/* EMPTY */;);
+ MILTER_CHECK_ERROR(return NULL);
return NULL;
}
@@ -2166,11 +2170,11 @@ milter_negotiate(m, e)
m->mf_fvers > SMFI_VERSION)
{
if (tTd(64, 5))
- sm_dprintf("milter_negotiate(%s): version %lu != MTA milter version %d\n",
+ sm_dprintf("milter_negotiate(%s): version %d != MTA milter version %d\n",
m->mf_name, m->mf_fvers, SMFI_VERSION);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "Milter (%s): negotiate: version %ld != MTA milter version %d",
+ "Milter (%s): negotiate: version %d != MTA milter version %d",
m->mf_name, m->mf_fvers, SMFI_VERSION);
milter_error(m, e);
return -1;
@@ -2180,12 +2184,12 @@ milter_negotiate(m, e)
if ((m->mf_fflags & SMFI_CURR_ACTS) != m->mf_fflags)
{
if (tTd(64, 5))
- sm_dprintf("milter_negotiate(%s): filter abilities 0x%lx != MTA milter abilities 0x%lx\n",
+ sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n",
m->mf_name, m->mf_fflags,
- (unsigned long) SMFI_CURR_ACTS);
+ SMFI_CURR_ACTS);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "Milter (%s): negotiate: filter abilities 0x%lx != MTA milter abilities 0x%lx",
+ "Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx",
m->mf_name, m->mf_fflags,
(unsigned long) SMFI_CURR_ACTS);
milter_error(m, e);
@@ -2196,12 +2200,12 @@ milter_negotiate(m, e)
if ((m->mf_pflags & SMFI_CURR_PROT) != m->mf_pflags)
{
if (tTd(64, 5))
- sm_dprintf("milter_negotiate(%s): protocol abilities 0x%lx != MTA milter abilities 0x%lx\n",
+ 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);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "Milter (%s): negotiate: protocol abilities 0x%lx != MTA milter abilities 0x%lx",
+ "Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx",
m->mf_name, m->mf_pflags,
(unsigned long) SMFI_CURR_PROT);
milter_error(m, e);
@@ -2209,7 +2213,7 @@ milter_negotiate(m, e)
}
if (tTd(64, 5))
- sm_dprintf("milter_negotiate(%s): version %lu, fflags 0x%lx, pflags 0x%lx\n",
+ 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);
return 0;
}
@@ -2864,7 +2868,7 @@ milter_replbody(response, rlen, newfilter, e)
/* If a new filter, reset previous character and truncate data file */
if (newfilter)
{
- off_t prevsize = 0;
+ off_t prevsize;
char dfname[MAXPATHLEN];
(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER),
@@ -2874,15 +2878,9 @@ milter_replbody(response, rlen, newfilter, e)
prevchar = '\0';
/* Get the current data file information */
- if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL)
- {
- int afd;
- struct stat st;
-
- afd = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL);
- if (afd > 0 && fstat(afd, &st) == 0)
- prevsize = st.st_size;
- }
+ prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL);
+ if (prevsize < 0)
+ prevsize = 0;
/* truncate current data file */
if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE))
@@ -3117,7 +3115,7 @@ milter_connect(hostname, addr, e, state)
# if NETINET
case AF_INET:
family = SMFIA_INET;
- port = htons(addr.sin.sin_port);
+ port = addr.sin.sin_port;
sockinfo = (char *) inet_ntoa(addr.sin.sin_addr);
break;
# endif /* NETINET */
@@ -3128,7 +3126,7 @@ milter_connect(hostname, addr, e, state)
family = SMFIA_INET;
else
family = SMFIA_INET6;
- port = htons(addr.sin6.sin6_port);
+ port = addr.sin6.sin6_port;
sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
sizeof buf6);
if (sockinfo == NULL)
@@ -3559,7 +3557,7 @@ milter_data(e, state)
"milter_data(%s): EOM ACK/NAK timeout",
m->mf_name);
milter_error(m, e);
- MILTER_CHECK_ERROR(continue);
+ MILTER_CHECK_ERROR(break);
break;
}
diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c
index f5980bb..32c0b47 100644
--- a/contrib/sendmail/src/mime.c
+++ b/contrib/sendmail/src/mime.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1994, 1996-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1994
@@ -14,7 +14,7 @@
#include <sendmail.h>
#include <string.h>
-SM_RCSID("@(#)$Id: mime.c,v 8.125 2001/09/11 04:05:15 gshapiro Exp $")
+SM_RCSID("@(#)$Id: mime.c,v 8.129 2002/03/13 07:28:05 gshapiro Exp $")
/*
** MIME support.
@@ -924,7 +924,7 @@ isboundary(line, boundaries)
#endif /* MIME8TO7 */
#if MIME7TO8
-static int mime_fromqp __P((unsigned char *, unsigned char **, int, int));
+static int mime_fromqp __P((unsigned char *, unsigned char **, int));
/*
** MIME7TO8 -- output 7 bit encoded MIME body in 8 bit format
@@ -936,7 +936,7 @@ static int mime_fromqp __P((unsigned char *, unsigned char **, int, int));
** will be able to deal with encoded MIME bodies if it can parse MIME
** multipart messages.
**
-** Note also that we wont be called unless it is a text/plain MIME
+** Note also that we won't be called unless it is a text/plain MIME
** message, encoded base64 or QP and mailer flag '9' has been defined
** on mailer.
**
@@ -971,6 +971,7 @@ mime7to8(mci, header, e)
HDR *header;
register ENVELOPE *e;
{
+ int pxflags;
register char *p;
char *cte;
char **pvp;
@@ -1024,6 +1025,7 @@ mime7to8(mci, header, e)
** it is not base64.
*/
+ pxflags = PXLF_MAPFROM;
if (sm_strcasecmp(cte, "base64") == 0)
{
int c1, c2, c3, c4;
@@ -1066,9 +1068,13 @@ mime7to8(mci, header, e)
{
if (*--fbufp != '\n' ||
(fbufp > fbuf && *--fbufp != '\r'))
+ {
+ pxflags |= PXLF_NOADDEOL;
fbufp++;
+ }
putxline((char *) fbuf, fbufp - fbuf,
- mci, PXLF_MAPFROM);
+ mci, pxflags);
+ pxflags &= ~PXLF_NOADDEOL;
fbufp = fbuf;
}
if (c3 == '=')
@@ -1079,9 +1085,13 @@ mime7to8(mci, header, e)
{
if (*--fbufp != '\n' ||
(fbufp > fbuf && *--fbufp != '\r'))
+ {
+ pxflags |= PXLF_NOADDEOL;
fbufp++;
+ }
putxline((char *) fbuf, fbufp - fbuf,
- mci, PXLF_MAPFROM);
+ mci, pxflags);
+ pxflags &= ~PXLF_NOADDEOL;
fbufp = fbuf;
}
if (c4 == '=')
@@ -1092,28 +1102,44 @@ mime7to8(mci, header, e)
{
if (*--fbufp != '\n' ||
(fbufp > fbuf && *--fbufp != '\r'))
+ {
+ pxflags |= PXLF_NOADDEOL;
fbufp++;
+ }
putxline((char *) fbuf, fbufp - fbuf,
- mci, PXLF_MAPFROM);
+ mci, pxflags);
+ pxflags &= ~PXLF_NOADDEOL;
fbufp = fbuf;
}
}
}
else
{
+ int off;
+
/* quoted-printable */
+ pxflags |= PXLF_NOADDEOL;
fbufp = fbuf;
- while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
- != NULL)
+ while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf,
+ sizeof buf) != NULL)
{
- if (mime_fromqp((unsigned char *) buf, &fbufp, 0,
- &fbuf[MAXLINE] - fbufp) == 0)
+ off = mime_fromqp((unsigned char *) buf, &fbufp,
+ &fbuf[MAXLINE] - fbufp);
+again:
+ if (off < -1)
continue;
if (fbufp - fbuf > 0)
putxline((char *) fbuf, fbufp - fbuf - 1, mci,
- PXLF_MAPFROM);
+ pxflags);
fbufp = fbuf;
+ if (off >= 0 && buf[off] != '\0')
+ {
+ off = mime_fromqp((unsigned char *) (buf + off),
+ &fbufp,
+ &fbuf[MAXLINE] - fbufp);
+ goto again;
+ }
}
}
@@ -1121,8 +1147,18 @@ mime7to8(mci, header, e)
if (fbufp > fbuf)
{
*fbufp = '\0';
- putxline((char *) fbuf, fbufp - fbuf, mci, PXLF_MAPFROM);
+ putxline((char *) fbuf, fbufp - fbuf, mci, pxflags);
}
+
+ /*
+ ** The decoded text may end without an EOL. Since this function
+ ** is only called for text/plain MIME messages, it is safe to
+ ** add an extra one at the end just in case. This is a hack,
+ ** but so is auto-converting MIME in the first place.
+ */
+
+ putline("", mci);
+
if (tTd(43, 3))
sm_dprintf("\t\t\tmime7to8 => %s to 8bit done\n", cte);
}
@@ -1149,31 +1185,47 @@ static char index_hex[128] =
# define HEXCHAR(c) (((c) < 0 || (c) > 127) ? -1 : index_hex[(c)])
+/*
+** MIME_FROMQP -- decode quoted printable string
+**
+** Parameters:
+** infile -- input (encoded) string
+** outfile -- output string
+** maxlen -- size of output buffer
+**
+** Returns:
+** -2 if decoding failure
+** -1 if infile completely decoded into outfile
+** >= 0 is the position in infile decoding
+** reached before maxlen was reached
+*/
+
static int
-mime_fromqp(infile, outfile, state, maxlen)
+mime_fromqp(infile, outfile, maxlen)
unsigned char *infile;
unsigned char **outfile;
- int state; /* Decoding body (0) or header (1) */
int maxlen; /* Max # of chars allowed in outfile */
{
int c1, c2;
int nchar = 0;
+ unsigned char *b;
- if (maxlen < 0)
+ /* decrement by one for trailing '\0', at least one other char */
+ if (--maxlen < 1)
return 0;
- while ((c1 = *infile++) != '\0')
+ b = infile;
+ while ((c1 = *infile++) != '\0' && nchar < maxlen)
{
if (c1 == '=')
{
- if ((c1 = *infile++) == 0)
+ if ((c1 = *infile++) == '\0')
break;
if (c1 == '\n' || (c1 = HEXCHAR(c1)) == -1)
{
- /* ignore it */
- if (state == 0)
- return 0;
+ /* ignore it and the rest of the buffer */
+ return -2;
}
else
{
@@ -1186,27 +1238,23 @@ mime_fromqp(infile, outfile, state, maxlen)
}
} while ((c2 = HEXCHAR(c2)) == -1);
- if (c2 == -1 || ++nchar > maxlen)
+ if (c2 == -1)
break;
-
+ nchar++;
*(*outfile)++ = c1 << 4 | c2;
}
}
else
{
- if (state == 1 && c1 == '_')
- c1 = ' ';
-
- if (++nchar > maxlen)
- break;
-
+ nchar++;
*(*outfile)++ = c1;
-
if (c1 == '\n')
break;
}
}
*(*outfile)++ = '\0';
- return 1;
+ if (nchar >= maxlen)
+ return (infile - b - 1);
+ return -1;
}
#endif /* MIME7TO8 */
diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c
index c456506..aa0e31d 100644
--- a/contrib/sendmail/src/parseaddr.c
+++ b/contrib/sendmail/src/parseaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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,16 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: parseaddr.c,v 8.349 2001/12/12 02:50:22 gshapiro Exp $")
+SM_RCSID("@(#)$Id: parseaddr.c,v 8.359 2002/03/29 16:20:47 ca Exp $")
static void allocaddr __P((ADDRESS *, int, char *, ENVELOPE *));
static int callsubr __P((char**, int, ENVELOPE *));
static char *map_lookup __P((STAB *, char *, char **, int *, ENVELOPE *));
static ADDRESS *buildaddr __P((char **, ADDRESS *, int, ENVELOPE *));
-static bool hasctrlchar __P((register char *, bool));
+static bool hasctrlchar __P((register char *, bool, bool));
+
+/* replacement for illegal characters in addresses */
+#define BAD_CHAR_REPLACEMENT '?'
/*
** PARSEADDR -- Parse an address
@@ -138,11 +141,18 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
a = buildaddr(pvp, a, flags, e);
- if (hasctrlchar(a->q_user, isrcpt))
+ if (hasctrlchar(a->q_user, isrcpt, true))
{
if (tTd(20, 1))
sm_dprintf("parseaddr-->bad q_user\n");
- return NULL;
+
+ /*
+ ** Just mark the address as bad so DSNs work.
+ ** hasctrlchar() has to make sure that the address
+ ** has been sanitized, e.g., shortened.
+ */
+
+ a->q_state = QS_BADADDR;
}
/*
@@ -152,7 +162,11 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
allocaddr(a, flags, addr, e);
if (QS_IS_BADADDR(a->q_state))
+ {
+ /* weed out bad characters in the printable address too */
+ (void) hasctrlchar(a->q_paddr, isrcpt, false);
return a;
+ }
/*
** Select a queue directory for recipient addresses.
@@ -242,6 +256,7 @@ invalidaddr(addr, delimptr, isrcpt)
{
bool result = false;
char savedelim = '\0';
+ char *b = addr;
int len = 0;
if (delimptr != NULL)
@@ -257,12 +272,16 @@ invalidaddr(addr, delimptr, isrcpt)
{
setstat(EX_USAGE);
result = true;
- break;
+ *addr = BAD_CHAR_REPLACEMENT;
}
if (++len > MAXNAME - 1)
{
- usrerr("553 5.1.0 Address too long (%d bytes max)",
- MAXNAME - 1);
+ char saved = *addr;
+
+ *addr = '\0';
+ usrerr("553 5.1.0 Address \"%s\" too long (%d bytes max)",
+ b, MAXNAME - 1);
+ *addr = saved;
result = true;
goto delim;
}
@@ -270,9 +289,11 @@ invalidaddr(addr, delimptr, isrcpt)
if (result)
{
if (isrcpt)
- usrerr("501 5.1.3 Syntax error in mailbox address");
+ usrerr("501 5.1.3 8-bit character in mailbox address \"%s\"",
+ b);
else
- usrerr("501 5.1.7 Syntax error in mailbox address");
+ usrerr("501 5.1.7 8-bit character in mailbox address \"%s\"",
+ b);
}
delim:
if (delimptr != NULL && savedelim != '\0')
@@ -290,6 +311,8 @@ delim:
** addr -- the address to check.
** isrcpt -- true if the address is for a recipient; false
** indicates a from.
+** complain -- true if an error should issued if the address
+** is invalid and should be "repaired".
**
** Returns:
** true -- if the address has any "wierd" characters or
@@ -298,22 +321,35 @@ delim:
*/
static bool
-hasctrlchar(addr, isrcpt)
+hasctrlchar(addr, isrcpt, complain)
register char *addr;
- bool isrcpt;
+ bool isrcpt, complain;
{
- bool result = false;
- int len = 0;
bool quoted = false;
+ int len = 0;
+ char *result = NULL;
+ char *b = addr;
if (addr == NULL)
return false;
for (; *addr != '\0'; addr++)
{
+ if (++len > MAXNAME - 1)
+ {
+ if (complain)
+ {
+ (void) shorten_rfc822_string(b, MAXNAME - 1);
+ usrerr("553 5.1.0 Address \"%s\" too long (%d bytes max)",
+ b, MAXNAME - 1);
+ return true;
+ }
+ result = "too long";
+ }
if (!quoted && (*addr < 32 || *addr == 127))
{
- result = true; /* a non-printable */
- break;
+ result = "non-printable character";
+ *addr = BAD_CHAR_REPLACEMENT;
+ continue;
}
if (*addr == '"')
quoted = !quoted;
@@ -322,33 +358,31 @@ hasctrlchar(addr, isrcpt)
/* XXX Generic problem: no '\0' in strings. */
if (*++addr == '\0')
{
- result = true;
+ result = "trailing \\ character";
+ *--addr = BAD_CHAR_REPLACEMENT;
break;
}
}
if ((*addr & 0340) == 0200)
{
setstat(EX_USAGE);
- result = true;
- break;
- }
- if (++len > MAXNAME - 1)
- {
- usrerr("553 5.1.0 Address too long (%d bytes max)",
- MAXNAME - 1);
- return true;
+ result = "8-bit character";
+ *addr = BAD_CHAR_REPLACEMENT;
+ continue;
}
}
if (quoted)
- result = true; /* unbalanced quote */
- if (result)
+ result = "unbalanced quote"; /* unbalanced quote */
+ if (result != NULL && complain)
{
if (isrcpt)
- usrerr("501 5.1.3 Syntax error in mailbox address");
+ usrerr("501 5.1.3 Syntax error in mailbox address \"%s\" (%s)",
+ b, result);
else
- usrerr("501 5.1.7 Syntax error in mailbox address");
+ usrerr("501 5.1.7 Syntax error in mailbox address \"%s\" (%s)",
+ b, result);
}
- return result;
+ return result != NULL;
}
/*
** ALLOCADDR -- do local allocations of address on demand.
@@ -1820,6 +1854,7 @@ buildaddr(tv, a, flags, e)
int flags;
register ENVELOPE *e;
{
+ bool tempfail = false;
struct mailer **mp;
register struct mailer *m;
register char *p;
@@ -1847,7 +1882,23 @@ buildaddr(tv, a, flags, e)
{
syserr("554 5.3.5 buildaddr: no mailer in parsed address");
badaddr:
- if (ExitStat == EX_TEMPFAIL)
+#if _FFR_ALLOW_S0_ERROR_4XX
+ /*
+ ** ExitStat may have been set by an earlier map open
+ ** failure (to a permanent error (EX_OSERR) in syserr())
+ ** so we also need to check if this particular $#error
+ ** return wanted a 4XX failure.
+ **
+ ** XXX the real fix is probably to set ExitStat correctly,
+ ** i.e., to EX_TEMPFAIL if the map open is just a temporary
+ ** error.
+ **
+ ** tempfail is tested here even if _FFR_ALLOW_S0_ERROR_4XX
+ ** is not set; that's ok because it is initialized to false.
+ */
+#endif /* _FFR_ALLOW_S0_ERROR_4XX */
+
+ if (ExitStat == EX_TEMPFAIL || tempfail)
a->q_state = QS_QUEUEUP;
else
{
@@ -1936,6 +1987,10 @@ badaddr:
else
usrerr(fmt, ubuf + off);
/* XXX ubuf[off - 1] = ' '; */
+#if _FFR_ALLOW_S0_ERROR_4XX
+ if (ubuf[0] == '4')
+ tempfail = true;
+#endif /* _FFR_ALLOW_S0_ERROR_4XX */
}
else
{
@@ -2093,6 +2148,11 @@ cataddr(pvp, evp, buf, sz, spacesub)
if (pvp++ == evp)
break;
}
+#if _FFR_CATCH_LONG_STRINGS
+ /* Don't silently truncate long strings */
+ if (*pvp != NULL)
+ syserr("cataddr: string too long");
+#endif /* _FFR_CATCH_LONG_STRINGS */
*p = '\0';
}
/*
diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c
index 6a2da9c..cb40c98 100644
--- a/contrib/sendmail/src/queue.c
+++ b/contrib/sendmail/src/queue.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: queue.c,v 8.834 2002/01/08 23:04:58 ca Exp $")
+SM_RCSID("@(#)$Id: queue.c,v 8.857 2002/04/02 16:43:25 ca Exp $")
#include <dirent.h>
@@ -71,13 +71,11 @@ static WORK *WorkQ; /* queue of things to be done */
static int NumWorkGroups; /* number of work groups */
/*
-** use of DoQueueRun:
-** NumQueue: indicates that a queue run is needed, look at individual bits
-** 0 - NumQueue-1: indicates that a queue run for this queue group
-** is needed.
+** DoQueueRun indicates that a queue run is needed.
+** Notice: DoQueueRun is modified in a signal handler!
*/
-static BITMAP256 volatile DoQueueRun; /* non-interrupt time queue run needed */
+static bool volatile DoQueueRun; /* non-interrupt time queue run needed */
/*
** Work group definition structure.
@@ -124,7 +122,7 @@ static void printctladdr __P((ADDRESS *, SM_FILE_T *));
static bool readqf __P((ENVELOPE *, bool));
static void restart_work_group __P((int));
static void runner_work __P((ENVELOPE *, int, bool, int, int));
-static void schedule_queue_runs __P((bool, int));
+static void schedule_queue_runs __P((bool, int, bool));
static char *strrev __P((char *));
static ADDRESS *setctluser __P((char *, int, ENVELOPE *));
#if _FFR_RHS
@@ -1217,6 +1215,7 @@ restart_work_group(wgrp)
** Parameters:
** runall -- schedule even if individual bit is not set.
** wgrp -- the work group id to schedule.
+** didit -- the queue run was performed for this work group.
**
** Returns:
** nothing
@@ -1227,22 +1226,35 @@ restart_work_group(wgrp)
else
static void
-schedule_queue_runs(runall, wgrp)
+schedule_queue_runs(runall, wgrp, didit)
bool runall;
int wgrp;
+ bool didit;
{
int qgrp, cgrp, endgrp;
+#if _FFR_QUEUE_SCHED_DBG
+ time_t lastsched;
+ bool sched;
+#endif /* _FFR_QUEUE_SCHED_DBG */
+ time_t now;
+ time_t minqintvl;
/*
** This is a bit ugly since we have to duplicate the
** code that "walks" through a work queue group.
*/
+ now = curtime();
+ minqintvl = 0;
cgrp = endgrp = WorkGrp[wgrp].wg_curqgrp;
do
{
time_t qintvl;
+#if _FFR_QUEUE_SCHED_DBG
+ lastsched = 0;
+ sched = false;
+#endif /* _FFR_QUEUE_SCHED_DBG */
qgrp = WorkGrp[wgrp].wg_qgs[cgrp]->qg_index;
if (Queue[qgrp]->qg_queueintvl > 0)
qintvl = Queue[qgrp]->qg_queueintvl;
@@ -1250,21 +1262,97 @@ schedule_queue_runs(runall, wgrp)
qintvl = QueueIntvl;
else
qintvl = (time_t) 0;
- if ((runall || bitnset(qgrp, DoQueueRun)) && qintvl > 0)
- (void) sm_setevent(qintvl, runqueueevent, qgrp);
+#if _FFR_QUEUE_SCHED_DBG
+ lastsched = Queue[qgrp]->qg_nextrun;
+#endif /* _FFR_QUEUE_SCHED_DBG */
+ if ((runall || Queue[qgrp]->qg_nextrun <= now) && qintvl > 0)
+ {
+#if _FFR_QUEUE_SCHED_DBG
+ sched = true;
+#endif /* _FFR_QUEUE_SCHED_DBG */
+ if (minqintvl == 0 || qintvl < minqintvl)
+ minqintvl = qintvl;
+
+ /*
+ ** Only set a new time if a queue run was performed
+ ** for this queue group. If the queue was not run,
+ ** we could starve it by setting a new time on each
+ ** call.
+ */
+
+ if (didit)
+ Queue[qgrp]->qg_nextrun += qintvl;
+ }
#if _FFR_QUEUE_SCHED_DBG
if (tTd(69, 10))
sm_syslog(LOG_INFO, NOQID,
- "sqr: wgrp=%d, cgrp=%d, qgrp=%d, intvl=%ld, QI=%ld, runall=%d, bit=%d, sched=%d",
+ "sqr: wgrp=%d, cgrp=%d, qgrp=%d, intvl=%ld, QI=%ld, runall=%d, lastrun=%ld, nextrun=%ld, sched=%d",
wgrp, cgrp, qgrp, Queue[qgrp]->qg_queueintvl,
- QueueIntvl, runall, bitnset(qgrp, DoQueueRun),
- (runall || bitnset(qgrp, DoQueueRun)) &&
- qintvl > 0);
+ QueueIntvl, runall, lastsched,
+ Queue[qgrp]->qg_nextrun, sched);
#endif /* _FFR_QUEUE_SCHED_DBG */
- clrbitn(qgrp, DoQueueRun);
INCR_MOD(cgrp, WorkGrp[wgrp].wg_numqgrp);
} while (endgrp != cgrp);
+ if (minqintvl > 0)
+ (void) sm_setevent(minqintvl, runqueueevent, 0);
}
+
+#if _FFR_QUEUE_RUN_PARANOIA
+/*
+** CHECKQUEUERUNNER -- check whether a queue group hasn't been run.
+**
+** Use this if events may get lost and hence queue runners may not
+** be started and mail will pile up in a queue.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** true if a queue run is necessary.
+**
+** Side Effects:
+** may schedule a queue run.
+*/
+
+bool
+checkqueuerunner()
+{
+ int qgrp;
+ time_t now, minqintvl;
+
+ now = curtime();
+ minqintvl = 0;
+ for (qgrp = 0; qgrp < NumQueue && Queue[qgrp] != NULL; qgrp++)
+ {
+ time_t qintvl;
+
+ if (Queue[qgrp]->qg_queueintvl > 0)
+ qintvl = Queue[qgrp]->qg_queueintvl;
+ else if (QueueIntvl > 0)
+ qintvl = QueueIntvl;
+ else
+ qintvl = (time_t) 0;
+ if (Queue[qgrp]->qg_nextrun <= now - qintvl)
+ {
+ if (minqintvl == 0 || qintvl < minqintvl)
+ minqintvl = qintvl;
+ if (LogLevel > 1)
+ sm_syslog(LOG_WARNING, NOQID,
+ "checkqueuerunner: queue %d should have been run at %s, queue interval %ld",
+ qgrp,
+ arpadate(ctime(&Queue[qgrp]->qg_nextrun)),
+ qintvl);
+ }
+ }
+ if (minqintvl > 0)
+ {
+ (void) sm_setevent(minqintvl, runqueueevent, 0);
+ return true;
+ }
+ return false;
+}
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
+
/*
** RUNQUEUE -- run the jobs in the queue.
**
@@ -1286,7 +1374,6 @@ schedule_queue_runs(runall, wgrp)
** Side Effects:
** runs things in the mail queue using run_work_group().
** maybe schedules next queue run.
-**
*/
static ENVELOPE QueueEnvelope; /* the queue run envelope */
@@ -1322,7 +1409,7 @@ runqueue(forkflag, verbose, persistent, runall)
#endif /* SM_HEAP_CHECK */
/* queue run has been started, don't do any more this time */
- clrbitn(NumQueue, DoQueueRun);
+ DoQueueRun = false;
/* more than one queue or more than one directory per queue */
if (!forkflag && !verbose &&
@@ -1392,7 +1479,7 @@ runqueue(forkflag, verbose, persistent, runall)
/* Success means the runner count needs to be updated. */
CurRunners += WorkGrp[curnum].wg_maxact;
if (!persistent)
- schedule_queue_runs(runall, curnum);
+ schedule_queue_runs(runall, curnum, true);
INCR_MOD(curnum, NumWorkGroups);
}
@@ -1403,7 +1490,7 @@ runqueue(forkflag, verbose, persistent, runall)
for (h = curnum; i < NumWorkGroups; i++)
{
- schedule_queue_runs(runall, h);
+ schedule_queue_runs(runall, h, false);
INCR_MOD(h, NumWorkGroups);
}
}
@@ -1638,7 +1725,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall)
int njobs, qdir;
int sequenceno = 1;
int qgrp, endgrp, h, i;
- time_t current_la_time;
+ time_t current_la_time, now;
bool full, more;
SM_RPOOL_T *rpool;
extern void rmexpstab __P((void));
@@ -1809,6 +1896,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall)
** runall is set or the bit for this group is set.
*/
+ now = curtime();
for (;;)
{
/*
@@ -1819,7 +1907,9 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall)
qgrp = WorkGrp[wgrp].wg_qgs[WorkGrp[wgrp].wg_curqgrp]->qg_index;
WorkGrp[wgrp].wg_curqgrp++; /* advance */
WorkGrp[wgrp].wg_curqgrp %= WorkGrp[wgrp].wg_numqgrp; /* wrap */
- if (runall || bitnset(qgrp, DoQueueRun))
+ if (runall ||
+ (Queue[qgrp]->qg_nextrun <= now &&
+ Queue[qgrp]->qg_nextrun != (time_t) -1))
break;
if (endgrp == WorkGrp[wgrp].wg_curqgrp)
{
@@ -2039,8 +2129,6 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall)
/* No more queues in work group to process. Now check persistent. */
if (persistent)
{
- time_t now;
-
sequenceno = 1;
sm_setproctitle(true, CurEnv, "running queue: %s",
qid_printqueue(qgrp, qdir));
@@ -2134,25 +2222,19 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall)
bool
doqueuerun()
{
- return bitnset(NumQueue, DoQueueRun);
+ return DoQueueRun;
}
/*
-** RUNQUEUEEVENT -- stub for use in sm_setevent
-**
-** Sets the bit to indicate that on the next run this queue should be
-** processed. The work group that the queue group is a member of has its
-** count of queue's to process updated.
+** RUNQUEUEEVENT -- Sets a flag to indicate that a queue run should be done.
**
** Parameters:
-** qgrp -- the index of the queue group.
+** none.
**
** Returns:
** none.
**
** Side Effects:
-** The work group that the queue group is a member of has its
-** count of queues to process updated.
** The invocation of this function via an alarm may interrupt
** a set of actions. Thus errno may be set in that context.
** We need to restore errno at the end of this function to ensure
@@ -2168,10 +2250,8 @@ doqueuerun()
*/
void
-runqueueevent(qgrp)
- int qgrp;
+runqueueevent()
{
- int i;
int save_errno = errno;
/*
@@ -2179,23 +2259,12 @@ runqueueevent(qgrp)
** tested in doqueuerun()
*/
- setbitn(NumQueue, DoQueueRun);
-
- /* if it is a specific group: set that bit */
- if (qgrp != NOQGRP)
- {
- setbitn(qgrp, DoQueueRun);
- goto ret;
- }
-
- /* for all others: set the bit if it doesn't have a queue interval */
- for (i = 0; i < NumQueue; i++)
- {
- if (Queue[i]->qg_queueintvl <= 0)
- setbitn(i, DoQueueRun);
- }
+ DoQueueRun = true;
+#if _FFR_QUEUE_SCHED_DBG
+ if (tTd(69, 10))
+ sm_syslog(LOG_INFO, NOQID, "rqe: done");
+#endif /* _FFR_QUEUE_SCHED_DBG */
- ret:
errno = save_errno;
if (errno == EINTR)
errno = ETIMEDOUT;
@@ -2374,7 +2443,7 @@ gatherq(qgrp, qdir, doall, full, more)
check = QueueLimitId;
while (check != NULL)
{
- if (strcontainedin(true, check->queue_match,
+ if (strcontainedin(false, check->queue_match,
d->d_name) != check->queue_negate)
break;
else
@@ -3689,6 +3758,7 @@ readqf(e, openonly)
bool nomore = false;
bool bogus = false;
MODE_T qsafe;
+ char *err;
char qf[MAXPATHLEN];
char buf[MAXLINE];
@@ -3934,13 +4004,8 @@ readqf(e, openonly)
hackattack:
syserr("SECURITY ALERT: extra or bogus data in queue file: %s",
bp);
- (void) sm_io_close(qfp, SM_TIME_DEFAULT);
-
- /* the file is already on disk */
- e->e_flags |= EF_INQUEUE;
- loseqfile(e, "bogus queue line");
- RELEASE_QUEUE;
- return false;
+ err = "bogus queue line";
+ goto fail;
}
switch (bp[0])
{
@@ -3992,9 +4057,8 @@ readqf(e, openonly)
}
}
}
- loseqfile(e, "bogus queue file directory");
- RELEASE_QUEUE;
- return false;
+ err = "bogus queue file directory";
+ goto fail;
done:
break;
}
@@ -4008,10 +4072,8 @@ readqf(e, openonly)
{
/* we are being spoofed! */
syserr("SECURITY ALERT: bogus qf line %s", bp);
- (void) sm_io_close(qfp, SM_TIME_DEFAULT);
- loseqfile(e, "bogus queue line");
- RELEASE_QUEUE;
- return false;
+ err = "bogus queue line";
+ goto fail;
}
for (p = &bp[1]; *p != '\0'; p++)
{
@@ -4063,8 +4125,15 @@ readqf(e, openonly)
#endif /* _FFR_QUARANTINE */
case 'H': /* header */
+
+ /*
+ ** count size before chompheader() destroys the line.
+ ** this isn't accurate due to macro expansion, but
+ ** better than before. "+3" to skip H?? at least.
+ */
+
+ hdrsize += strlen(bp + 3);
(void) chompheader(&bp[1], CHHDR_QUEUE, NULL, e);
- hdrsize += strlen(&bp[1]);
break;
case 'I': /* data file's inode number */
@@ -4184,6 +4253,9 @@ readqf(e, openonly)
true);
if (q != NULL)
{
+ /* make sure we keep the current qgrp */
+ if (ISVALIDQGRP(e->e_qgrp))
+ q->q_qgrp = e->e_qgrp;
q->q_alias = ctladdr;
if (qfver >= 1)
q->q_flags &= ~Q_PINGFLAGS;
@@ -4215,10 +4287,8 @@ readqf(e, openonly)
break;
syserr("Version number in queue file (%d) greater than max (%d)",
qfver, QF_VERSION);
- (void) sm_io_close(qfp, SM_TIME_DEFAULT);
- loseqfile(e, "unsupported queue file version");
- RELEASE_QUEUE;
- return false;
+ err = "unsupported queue file version";
+ goto fail;
/* NOTREACHED */
break;
@@ -4260,10 +4330,8 @@ readqf(e, openonly)
default:
syserr("readqf: %s: line %d: bad line \"%s\"",
qf, LineNumber, shortenstring(bp, MAXSHORTSTR));
- (void) sm_io_close(qfp, SM_TIME_DEFAULT);
- loseqfile(e, "unrecognized line");
- RELEASE_QUEUE;
- return false;
+ err = "unrecognized line";
+ goto fail;
}
if (bp != buf)
@@ -4328,6 +4396,24 @@ readqf(e, openonly)
RELEASE_QUEUE;
return true;
+
+ fail:
+ /*
+ ** There was some error reading the qf file (reason is in err var.)
+ ** Cleanup:
+ ** close file; clear e_lockfp since it is the same as qfp,
+ ** hence it is invalid (as file) after qfp is closed;
+ ** the qf file is on disk, so set the flag to avoid calling
+ ** queueup() with bogus data.
+ */
+
+ if (qfp != NULL)
+ (void) sm_io_close(qfp, SM_TIME_DEFAULT);
+ e->e_lockfp = NULL;
+ e->e_flags |= EF_INQUEUE;
+ loseqfile(e, err);
+ RELEASE_QUEUE;
+ return false;
}
/*
** PRTSTR -- print a string, "unprintable" characters are shown as \oct
@@ -4987,7 +5073,8 @@ queuename(e, type)
}
}
- if (e->e_qdir == NOQDIR)
+ /* xf files always have a valid qd and qg picked above */
+ if (e->e_qdir == NOQDIR && type != XSCRPT_LETTER)
(void) sm_strlcpyn(buf, sizeof buf, 2, pref, e->e_id);
else
{
@@ -6289,6 +6376,98 @@ upd_qs(e, delete, avail)
FILE_SYS_AVAIL(fidx) -= s;
}
+
+#if _FFR_SELECT_SHM
+
+static bool write_key_file __P((char *, long));
+static long read_key_file __P((char *, long));
+
+/*
+** WRITE_KEY_FILE -- record some key into a file.
+**
+** Parameters:
+** keypath -- file name.
+** key -- key to write.
+**
+** Returns:
+** true iff file could be written.
+**
+** Side Effects:
+** writes file.
+*/
+
+static bool
+write_key_file(keypath, key)
+ char *keypath;
+ long key;
+{
+ bool ok;
+ long sff;
+ SM_FILE_T *keyf;
+
+ ok = false;
+ if (keypath == NULL || *keypath == '\0')
+ return ok;
+ sff = SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT;
+ if (TrustedUid != 0 && RealUid == TrustedUid)
+ sff |= SFF_OPENASROOT;
+ keyf = safefopen(keypath, O_WRONLY|O_TRUNC, 0644, sff);
+ if (keyf == NULL)
+ {
+ sm_syslog(LOG_ERR, NOQID, "unable to write %s: %s",
+ keypath, sm_errstring(errno));
+ }
+ else
+ {
+ ok = sm_io_fprintf(keyf, SM_TIME_DEFAULT, "%ld\n", key) !=
+ SM_IO_EOF;
+ ok = ok && (sm_io_close(keyf, SM_TIME_DEFAULT) != SM_IO_EOF);
+ }
+ return ok;
+}
+
+/*
+** READ_KEY_FILE -- read a key from a file.
+**
+** Parameters:
+** keypath -- file name.
+** key -- default key.
+**
+** Returns:
+** key.
+*/
+
+static long
+read_key_file(keypath, key)
+ char *keypath;
+ long key;
+{
+ int r;
+ long sff, n;
+ SM_FILE_T *keyf;
+
+ if (keypath == NULL || *keypath == '\0')
+ return key;
+ sff = SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY;
+ if (TrustedUid != 0 && RealUid == TrustedUid)
+ sff |= SFF_OPENASROOT;
+ keyf = safefopen(keypath, O_RDONLY, 0644, sff);
+ if (keyf == NULL)
+ {
+ sm_syslog(LOG_ERR, NOQID, "unable to read %s: %s",
+ keypath, sm_errstring(errno));
+ }
+ else
+ {
+ r = sm_io_fscanf(keyf, SM_TIME_DEFAULT, "%ld", &n);
+ if (r == 1)
+ key = n;
+ (void) sm_io_close(keyf, SM_TIME_DEFAULT);
+ }
+ return key;
+}
+#endif /* _FFR_SELECT_SHM */
+
/*
** INIT_SHM -- initialize shared memory structure
**
@@ -6316,9 +6495,17 @@ init_shm(qn, owner, hash)
unsigned int hash;
{
int i;
+#if _FFR_SELECT_SHM
+ bool keyselect;
+#endif /* _FFR_SELECT_SHM */
PtrFileSys = &FileSys[0];
PNumFileSys = &Numfilesys;
+#if _FFR_SELECT_SHM
+/* if this "key" is specified: select one yourself */
+# define SEL_SHM_KEY ((key_t) -1)
+# define FIRST_SHM_KEY 25
+#endif /* _FFR_SELECT_SHM */
/* This allows us to disable shared memory at runtime. */
if (ShmKey != 0)
@@ -6329,6 +6516,21 @@ init_shm(qn, owner, hash)
count = 0;
shms = SM_T_SIZE + qn * sizeof(QUEUE_SHM_T);
+#if _FFR_SELECT_SHM
+ keyselect = ShmKey == SEL_SHM_KEY;
+ if (keyselect)
+ {
+ if (owner)
+ ShmKey = FIRST_SHM_KEY;
+ else
+ {
+ ShmKey = read_key_file(ShmKeyFile, ShmKey);
+ keyselect = false;
+ if (ShmKey == SEL_SHM_KEY)
+ goto error;
+ }
+ }
+#endif /* _FFR_SELECT_SHM */
for (;;)
{
/* XXX: maybe allow read access for group? */
@@ -6338,13 +6540,34 @@ init_shm(qn, owner, hash)
if (Pshm != NULL || save_errno != EEXIST)
break;
if (++count >= 3)
+ {
+#if _FFR_SELECT_SHM
+ if (keyselect)
+ {
+ ++ShmKey;
+
+ /* back where we started? */
+ if (ShmKey == SEL_SHM_KEY)
+ break;
+ continue;
+ }
+#endif /* _FFR_SELECT_SHM */
break;
+ }
+#if _FFR_SELECT_SHM
+ /* only sleep if we are at the first key */
+ if (!keyselect || ShmKey == SEL_SHM_KEY)
+#endif /* _FFR_SELECT_SHM */
sleep(count);
}
if (Pshm != NULL)
{
int *p;
+#if _FFR_SELECT_SHM
+ if (keyselect)
+ (void) write_key_file(ShmKeyFile, (long) ShmKey);
+#endif /* _FFR_SELECT_SHM */
p = (int *) Pshm;
if (owner)
{
@@ -6425,6 +6648,7 @@ setup_queues(owner)
{
int i, qn, len;
unsigned int hashval;
+ time_t now;
char basedir[MAXPATHLEN];
struct stat st;
@@ -6494,8 +6718,11 @@ setup_queues(owner)
hashval = hash_q(basedir, hashval);
#endif /* SM_CONF_SHM */
- /* initialize map for queue runs */
- clrbitmap(DoQueueRun);
+ /* initialize for queue runs */
+ DoQueueRun = false;
+ now = curtime();
+ for (i = 0; i < NumQueue && Queue[i] != NULL; i++)
+ Queue[i]->qg_nextrun = now;
if (UseMSP && OpMode != MD_TEST)
@@ -6645,9 +6872,9 @@ set_def_queueval(qg, all)
return;
if (all)
qg->qg_qdir = QueueDir;
-#if 0
+#if _FFR_QUEUE_GROUP_SORTORDER
qg->qg_sortorder = QueueSortOrder;
-#endif /* 0 */
+#endif /* _FFR_QUEUE_GROUP_SORTORDER */
qg->qg_maxqrun = all ? MaxRunnersPerQueue : -1;
qg->qg_nice = NiceQueueRun;
}
@@ -6788,7 +7015,7 @@ makequeue(line, qdef)
qg->qg_maxrcpt = atoi(p);
break;
-#if 0
+#if _FFR_QUEUE_GROUP_SORTORDER
case 'S': /* queue sorting order */
switch (*p)
{
@@ -6814,14 +7041,26 @@ makequeue(line, qdef)
case 'm': /* Modification time */
case 'M':
- qgrp->qg_sortorder = QSO_BYMODTIME;
+ qg->qg_sortorder = QSO_BYMODTIME;
+ break;
+
+ case 'r': /* Random */
+ case 'R':
+ qg->qg_sortorder = QSO_RANDOM;
+ break;
+
+# if _FFR_RHS
+ case 's': /* Shuffled host name */
+ case 'S':
+ qg->qg_sortorder = QSO_BYSHUFFLE;
break;
+# endif /* _FFR_RHS */
default:
syserr("Invalid queue sort order \"%s\"", p);
}
break;
-#endif /* 0 */
+#endif /* _FFR_QUEUE_GROUP_SORTORDER */
default:
syserr("Q%s: unknown queue equate %c=",
@@ -7117,12 +7356,16 @@ makeworkgroups()
dir = 1;
}
- WorkGrp[j].wg_qgs = (QUEUEGRP **)sm_realloc(WorkGrp[j].wg_qgs,
- sizeof(QUEUEGRP *) *
- (WorkGrp[j].wg_numqgrp + 1));
+ if (WorkGrp[j].wg_qgs == NULL)
+ WorkGrp[j].wg_qgs = (QUEUEGRP **)sm_malloc(sizeof(QUEUEGRP *) *
+ (WorkGrp[j].wg_numqgrp + 1));
+ else
+ WorkGrp[j].wg_qgs = (QUEUEGRP **)sm_realloc(WorkGrp[j].wg_qgs,
+ sizeof(QUEUEGRP *) *
+ (WorkGrp[j].wg_numqgrp + 1));
if (WorkGrp[j].wg_qgs == NULL)
{
- syserr("@cannot allocate memory for work queues, need %d bytes",
+ syserr("!cannot allocate memory for work queues, need %d bytes",
(int) (sizeof(QUEUEGRP *) *
(WorkGrp[j].wg_numqgrp + 1)));
}
@@ -7203,7 +7446,15 @@ dup_df(old, new)
char opath[MAXPATHLEN];
char npath[MAXPATHLEN];
- SM_REQUIRE(bitset(EF_HAS_DF, old->e_flags));
+ if (!bitset(EF_HAS_DF, old->e_flags))
+ {
+ /*
+ ** this can happen if: SuperSafe != True
+ ** and a bounce mail is sent that is split.
+ */
+
+ queueup(old, false, true);
+ }
SM_REQUIRE(ISVALIDQGRP(old->e_qgrp) && ISVALIDQDIR(old->e_qdir));
SM_REQUIRE(ISVALIDQGRP(new->e_qgrp) && ISVALIDQDIR(new->e_qdir));
@@ -7305,6 +7556,11 @@ split_env(e, sendqueue, qgrp, qdir)
ee->e_lockfp = NULL;
if (e->e_xfp != NULL)
ee->e_xfp = sm_io_dup(e->e_xfp);
+
+ /* failed to dup e->e_xfp, start a new transcript */
+ if (ee->e_xfp == NULL)
+ openxscript(ee);
+
ee->e_qgrp = ee->e_dfqgrp = qgrp;
ee->e_qdir = ee->e_dfqdir = qdir;
ee->e_errormode = EM_MAIL;
@@ -7317,7 +7573,7 @@ split_env(e, sendqueue, qgrp, qdir)
/*
** XXX Not sure if this copying is necessary.
- ** sendall() does this copying, but I don't know if that is
+ ** sendall() does this copying, but I (dm) don't know if that is
** because of the storage management discipline we were using
** before rpools were introduced, or if it is because these lists
** can be modified later.
@@ -7444,6 +7700,8 @@ split_across_queue_groups(e)
if (q->q_mailer != NULL &&
ISVALIDQGRP(q->q_mailer->m_qgrp))
q->q_qgrp = q->q_mailer->m_qgrp;
+ else if (ISVALIDQGRP(e->e_qgrp))
+ q->q_qgrp = e->e_qgrp;
else
q->q_qgrp = 0;
}
diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c
index 1f6a662..afb366a 100644
--- a/contrib/sendmail/src/readcf.c
+++ b/contrib/sendmail/src/readcf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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.594 2001/12/14 00:43:17 gshapiro Exp $")
+SM_RCSID("@(#)$Id: readcf.c,v 8.604 2002/04/02 16:43:25 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
@@ -24,7 +24,7 @@ SM_RCSID("@(#)$Id: readcf.c,v 8.594 2001/12/14 00:43:17 gshapiro Exp $")
#define HOUR * 3600
#define HOURS HOUR
-static void fileclass __P((int, char *, char *, bool, bool));
+static void fileclass __P((int, char *, char *, bool, bool, bool));
static char **makeargv __P((char *));
static void settimeout __P((char *, char *, bool));
static void toomany __P((int, int));
@@ -96,6 +96,7 @@ readcf(cfname, safe, e)
char *file;
bool optional;
bool ok;
+ bool ismap;
int mid;
register char *p;
long sff = SFF_OPENASROOT;
@@ -458,7 +459,22 @@ readcf(cfname, safe, e)
else
optional = false;
- if (*p == '@')
+ /* check if [key]@map:spec */
+ ismap = false;
+ if (!SM_IS_DIR_DELIM(*p) &&
+ *p != '|' &&
+ (q = strchr(p, '@')) != NULL)
+ {
+ q++;
+
+ /* look for @LDAP or @map: in string */
+ if (strcmp(q, "LDAP") == 0 ||
+ (*q != ':' &&
+ strchr(q, ':') != NULL))
+ ismap = true;
+ }
+
+ if (ismap)
{
/* use entire spec */
file = p;
@@ -473,7 +489,7 @@ readcf(cfname, safe, e)
}
}
- if (*file == '|' || *file == '@')
+ if (*file == '|' || ismap)
p = "%s";
else
{
@@ -487,7 +503,7 @@ readcf(cfname, safe, e)
continue;
}
}
- fileclass(mid, file, p, safe, optional);
+ fileclass(mid, file, p, ismap, safe, optional);
break;
#if XLA
@@ -754,6 +770,7 @@ toomany(id, maxcnt)
** class -- class to define.
** filename -- name of file to read.
** fmt -- scanf string to use for match.
+** ismap -- if set, this is a map lookup.
** safe -- if set, this is a safe read.
** optional -- if set, it is not an error for the file to
** not exist.
@@ -798,10 +815,11 @@ parse_class_words(class, line)
}
static void
-fileclass(class, filename, fmt, safe, optional)
+fileclass(class, filename, fmt, ismap, safe, optional)
int class;
char *filename;
char *fmt;
+ bool ismap;
bool safe;
bool optional;
{
@@ -819,8 +837,7 @@ fileclass(class, filename, fmt, safe, optional)
syserr("fileclass: missing file name");
return;
}
- else if (!SM_IS_DIR_DELIM(*filename) && *filename != '|' &&
- (p = strchr(filename, '@')) != NULL)
+ else if (ismap)
{
int status = 0;
char *key;
@@ -833,6 +850,15 @@ fileclass(class, filename, fmt, safe, optional)
key = filename;
+ /* skip past key */
+ if ((p = strchr(filename, '@')) == NULL)
+ {
+ /* should not happen */
+ syserr("fileclass: bogus map specification");
+ sm_free(mn);
+ return;
+ }
+
/* skip past '@' */
*p++ = '\0';
cl = p;
@@ -901,6 +927,11 @@ fileclass(class, filename, fmt, safe, optional)
map.map_mname = mn;
map.map_mflags |= MF_FILECLASS;
+ if (tTd(37, 5))
+ sm_dprintf("fileclass: F{%s}: map class %s, key %s, spec %s\n",
+ mn, cl, key, spec);
+
+
/* parse map spec */
if (!map.map_class->map_parse(&map, spec))
{
@@ -1082,6 +1113,7 @@ makemailer(line)
return;
}
m->m_name = newstr(line);
+ m->m_qgrp = NOQGRP;
/* now scan through and assign info from the fields */
while (*p != '\0')
@@ -2064,6 +2096,10 @@ static struct optioninfo
# define O_SOFTBOUNCE 0xcf
{ "SoftBounce", O_SOFTBOUNCE, OI_NONE },
#endif /* _FFR_SOFT_BOUNCE */
+#if _FFR_SELECT_SHM
+# define O_SHMKEYFILE 0xd0
+ { "SharedMemoryKeyFile", O_SHMKEYFILE, OI_NONE },
+#endif /* _FFR_SELECT_SHM */
{ NULL, '\0', OI_NONE }
};
@@ -2636,11 +2672,11 @@ setoption(opt, val, safe, sticky, e)
case 'u': /* set default uid */
for (p = val; *p != '\0'; p++)
{
-#if _FFR_DOTTED_USERNAMES
+# if _FFR_DOTTED_USERNAMES
if (*p == '/' || *p == ':')
-#else /* _FFR_DOTTED_USERNAMES */
+# else /* _FFR_DOTTED_USERNAMES */
if (*p == '.' || *p == '/' || *p == ':')
-#endif /* _FFR_DOTTED_USERNAMES */
+# endif /* _FFR_DOTTED_USERNAMES */
{
*p++ = '\0';
break;
@@ -2729,6 +2765,9 @@ setoption(opt, val, safe, sticky, e)
break;
+#if _FFR_QUEUE_GROUP_SORTORDER
+ /* coordinate this with makequeue() */
+#endif /* _FFR_QUEUE_GROUP_SORTORDER */
case O_QUEUESORTORD: /* queue sorting order */
switch (*val)
{
@@ -2849,6 +2888,17 @@ setoption(opt, val, safe, sticky, e)
break;
case O_SAFEFILEENV: /* chroot() environ for writing to files */
+ if (*val == '\0')
+ break;
+
+ /* strip trailing slashes */
+ p = val + strlen(val) - 1;
+ while (p >= val && *p == '/')
+ *p-- = '\0';
+
+ if (*val == '\0')
+ break;
+
SafeFileEnv = newstr(val);
break;
@@ -2886,7 +2936,7 @@ setoption(opt, val, safe, sticky, e)
NiceQueueRun = atoi(val);
break;
- case O_SHMKEY : /* shared memory key */
+ case O_SHMKEY: /* shared memory key */
#if SM_CONF_SHM
ShmKey = atol(val);
#else /* SM_CONF_SHM */
@@ -2896,6 +2946,19 @@ setoption(opt, val, safe, sticky, e)
#endif /* SM_CONF_SHM */
break;
+#if _FFR_SELECT_SHM
+ case O_SHMKEYFILE: /* shared memory key file */
+# if SM_CONF_SHM
+ CANONIFY(val);
+ ShmKeyFile = newstr(val);
+# else /* SM_CONF_SHM */
+ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
+ "Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n",
+ OPTNAME);
+# endif /* SM_CONF_SHM */
+ break;
+#endif /* _FFR_SELECT_SHM */
+
#if _FFR_MAX_FORWARD_ENTRIES
case O_MAXFORWARD: /* max # of forward entries */
MaxForwardEntries = atoi(val);
@@ -2976,11 +3039,11 @@ setoption(opt, val, safe, sticky, e)
case O_RUNASUSER: /* run bulk of code as this user */
for (p = val; *p != '\0'; p++)
{
-#if _FFR_DOTTED_USERNAMES
+# if _FFR_DOTTED_USERNAMES
if (*p == '/' || *p == ':')
-#else /* _FFR_DOTTED_USERNAMES */
+# else /* _FFR_DOTTED_USERNAMES */
if (*p == '.' || *p == '/' || *p == ':')
-#endif /* _FFR_DOTTED_USERNAMES */
+# endif /* _FFR_DOTTED_USERNAMES */
{
*p++ = '\0';
break;
@@ -4128,6 +4191,7 @@ inittimeouts(val, sticky)
{
TimeOuts.to_connect = (time_t) 0 SECONDS;
TimeOuts.to_aconnect = (time_t) 0 SECONDS;
+ TimeOuts.to_iconnect = (time_t) 0 SECONDS;
TimeOuts.to_initial = (time_t) 5 MINUTES;
TimeOuts.to_helo = (time_t) 5 MINUTES;
TimeOuts.to_mail = (time_t) 10 MINUTES;
diff --git a/contrib/sendmail/src/sasl.c b/contrib/sendmail/src/sasl.c
index 9136f8a..869605c 100644
--- a/contrib/sendmail/src/sasl.c
+++ b/contrib/sendmail/src/sasl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -8,9 +8,10 @@
*
*/
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: sasl.c,v 8.12 2002/01/21 02:28:05 gshapiro Exp $")
+
#if SASL
-# include <sm/gen.h>
-SM_RCSID("@(#)$Id: sasl.c,v 8.11 2001/09/11 04:05:16 gshapiro Exp $")
# include <stdlib.h>
# include <sendmail.h>
# include <errno.h>
diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h
index 86a3c48..0bbddc4 100644
--- a/contrib/sendmail/src/sendmail.h
+++ b/contrib/sendmail/src/sendmail.h
@@ -48,7 +48,7 @@
#ifdef _DEFINE
# ifndef lint
-SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.902 2002/01/09 00:10:11 ca Exp $";
+SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.912 2002/04/02 16:43:26 ca Exp $";
# endif /* ! lint */
#endif /* _DEFINE */
@@ -444,7 +444,10 @@ struct mailer
extern void initerrmailers __P((void));
extern void makemailer __P((char *));
extern void makequeue __P((char *, bool));
-extern void runqueueevent __P((int));
+extern void runqueueevent __P((void));
+#if _FFR_QUEUE_RUN_PARANOIA
+extern bool checkqueuerunner __P((void));
+#endif /* _FFR_QUEUE_RUN_PARANOIA */
EXTERN MAILER *FileMailer; /* ptr to *file* mailer */
EXTERN MAILER *InclMailer; /* ptr to *include* mailer */
@@ -500,8 +503,11 @@ struct queuegrp
int qg_curnum; /* current number of queue for queue runs */
int qg_maxrcpt; /* max recipients per envelope, 0==no limit */
-#if 0
+ time_t qg_nextrun; /* time for next queue runs */
+#if _FFR_QUEUE_GROUP_SORTORDER
short qg_sortorder; /* how do we sort this queuerun */
+#endif /* _FFR_QUEUE_GROUP_SORTORDER */
+#if 0
long qg_wkrcptfact; /* multiplier for # recipients -> priority */
long qg_qfactor; /* slope of queue function */
bool qg_doqueuerun; /* XXX flag is it time to do a queuerun */
@@ -657,7 +663,7 @@ MCI
#define MCIF_SIZE 0x00000020 /* SIZE option supported */
#define MCIF_8BITMIME 0x00000040 /* BODY=8BITMIME supported */
#define MCIF_7BIT 0x00000080 /* strip this message to 7 bits */
-#define MCIF_MULTSTAT 0x00000100 /* MAIL11V3: handles MULT status */
+/* 0x00000100 unused, was MCIF_MULTSTAT: MAIL11V3: handles MULT status */
#define MCIF_INHEADER 0x00000200 /* currently outputing header */
#define MCIF_CVT8TO7 0x00000400 /* convert from 8 to 7 bits */
#define MCIF_DSN 0x00000800 /* DSN extension supported */
@@ -1493,6 +1499,7 @@ extern void set_delivery_mode __P((int, ENVELOPE *));
#define PXLF_MAPFROM 0x0001 /* map From_ to >From_ */
#define PXLF_STRIP8BIT 0x0002 /* strip 8th bit */
#define PXLF_HEADER 0x0004 /* map newlines in headers */
+#define PXLF_NOADDEOL 0x0008 /* if EOL not present, don't add one */
/*
** Privacy flags
@@ -1607,11 +1614,18 @@ extern char *validate_connection __P((SOCKADDR *, char *, ENVELOPE *));
#endif /* NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 */
-#if MILTER
/*
** Mail Filters (milter)
*/
+/*
+** 32-bit type used by milter
+** (needed by libmilter even if MILTER isn't defined)
+*/
+
+typedef SM_INT32 mi_int32;
+
+#if MILTER
# define SMFTO_WRITE 0 /* Timeout for sending information */
# define SMFTO_READ 1 /* Timeout waiting for a response */
# define SMFTO_EOM 2 /* Timeout for ACK/NAK to EOM */
@@ -1623,9 +1637,9 @@ struct milter
{
char *mf_name; /* filter name */
BITMAP256 mf_flags; /* MTA flags */
- unsigned long mf_fvers; /* filter version */
- unsigned long mf_fflags; /* filter flags */
- unsigned long mf_pflags; /* protocol flags */
+ mi_int32 mf_fvers; /* filter version */
+ mi_int32 mf_fflags; /* filter flags */
+ mi_int32 mf_pflags; /* protocol flags */
char *mf_conn; /* connection info */
int mf_sock; /* connected socket */
char mf_state; /* state of filter */
@@ -1656,13 +1670,6 @@ extern void setup_daemon_milters __P(());
#endif /* MILTER */
/*
-** 32-bit type used by milter
-** (needed by libmilter even if MILTER isn't defined)
-*/
-
-typedef SM_INT32 mi_int32;
-
-/*
** Vendor codes
**
** Vendors can customize sendmail to add special behaviour,
@@ -2170,6 +2177,9 @@ EXTERN gid_t RunAsGid; /* GID to become for bulk of run */
EXTERN gid_t EffGid; /* effective gid */
#if SM_CONF_SHM
EXTERN key_t ShmKey; /* shared memory key */
+# if _FFR_SELECT_SHM
+EXTERN char *ShmKeyFile; /* shared memory key file */
+# endif /* _FFR_SELECT_SHM */
#endif /* SM_CONF_SHM */
EXTERN pid_t CurrentPid; /* current process id */
EXTERN pid_t DaemonPid; /* process id of daemon */
@@ -2313,6 +2323,7 @@ extern void sendall __P((ENVELOPE *, int));
# define STATS_QUARANTINE 'q'
#endif /* _FFR_QUARANTINE */
#define STATS_REJECT 'r'
+#define STATS_CONNECT 'c'
extern void markstats __P((ENVELOPE *, ADDRESS *, int));
extern void clearstats __P((void));
diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c
index c6f63fb..029ab18 100644
--- a/contrib/sendmail/src/sfsasl.c
+++ b/contrib/sendmail/src/sfsasl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2002 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.86 2001/09/11 04:05:16 gshapiro Exp $")
+SM_RCSID("@(#)$Id: sfsasl.c,v 8.89 2002/02/22 04:41:28 ca Exp $")
#include <stdlib.h>
#include <sendmail.h>
#include <errno.h>
@@ -270,6 +270,7 @@ sasl_write(fp, buf, size)
{
while (outlen > 0)
{
+ /* XXX result == 0? */
ret = sm_io_write(so->fp, SM_TIME_DEFAULT,
&outbuf[total], outlen);
outlen -= ret;
@@ -552,12 +553,14 @@ tls_read(fp, buf, size)
}
if (err != NULL)
{
+ int save_errno;
+
+ save_errno = (errno == 0) ? EIO : errno;
again = MAX_TLS_IOS;
- if (errno == 0)
- errno = EIO;
if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS: read error=%s (%d)", err, r);
+ errno = save_errno;
}
return r;
}
@@ -636,12 +639,14 @@ tls_write(fp, buf, size)
}
if (err != NULL)
{
+ int save_errno;
+
+ save_errno = (errno == 0) ? EIO : errno;
again = MAX_TLS_IOS;
- if (errno == 0)
- errno = EIO;
if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS: write error=%s (%d)", err, r);
+ errno = save_errno;
}
return r;
}
diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c
index ab5d4ee..70bb693 100644
--- a/contrib/sendmail/src/srvrsmtp.c
+++ b/contrib/sendmail/src/srvrsmtp.c
@@ -16,7 +16,7 @@
# include <libmilter/mfdef.h>
#endif /* MILTER */
-SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.814 2002/01/08 00:56:22 ca Exp $")
+SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.819 2002/04/02 03:51:02 ca Exp $")
#if SASL || STARTTLS
# include <sys/time.h>
@@ -172,22 +172,22 @@ static char *CurSmtpClient; /* who's at the other end of channel */
#ifndef MAXBADCOMMANDS
# define MAXBADCOMMANDS 25 /* maximum number of bad commands */
-#endif
+#endif /* ! MAXBADCOMMANDS */
#ifndef MAXNOOPCOMMANDS
# define MAXNOOPCOMMANDS 20 /* max "noise" commands before slowdown */
-#endif
+#endif /* ! MAXNOOPCOMMANDS */
#ifndef MAXHELOCOMMANDS
# define MAXHELOCOMMANDS 3 /* max HELO/EHLO commands before slowdown */
-#endif
+#endif /* ! MAXHELOCOMMANDS */
#ifndef MAXVRFYCOMMANDS
# define MAXVRFYCOMMANDS 6 /* max VRFY/EXPN commands before slowdown */
-#endif
+#endif /* ! MAXVRFYCOMMANDS */
#ifndef MAXETRNCOMMANDS
# define MAXETRNCOMMANDS 8 /* max ETRN commands before slowdown */
-#endif
+#endif /* ! MAXETRNCOMMANDS */
#ifndef MAXTIMEOUT
# define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */
-#endif
+#endif /* ! MAXTIMEOUT */
#if SM_HEAP_CHECK
static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp",
@@ -535,7 +535,7 @@ smtp(nullserver, d_flags, e)
** Kerberos_v4
*/
-#if NETINET
+# if NETINET
in = macvalue(macid("{daemon_family}"), e);
if (in != NULL && strcmp(in, "inet") == 0)
{
@@ -560,7 +560,7 @@ smtp(nullserver, d_flags, e)
&saddr_l);
}
}
-#endif /* NETINET */
+# endif /* NETINET */
auth_type = NULL;
mechlist = NULL;
@@ -575,8 +575,8 @@ smtp(nullserver, d_flags, e)
/* XXX should these be options settable via .cf ? */
/* ssp.min_ssf = 0; is default due to memset() */
-# if STARTTLS
-# endif /* STARTTLS */
+# if STARTTLS
+# endif /* STARTTLS */
{
ssp.max_ssf = MaxSLBits;
ssp.maxbufsize = MAXOUTLEN;
@@ -613,7 +613,7 @@ smtp(nullserver, d_flags, e)
case SMFIR_REJECT:
if (MilterLogLevel > 3)
sm_syslog(LOG_INFO, e->e_id,
- "Milter: inititalization failed, rejecting commands");
+ "Milter: initialization failed, rejecting commands");
greetcode = "554";
nullserver = "Command rejected";
smtp.sm_milterize = false;
@@ -622,7 +622,7 @@ smtp(nullserver, d_flags, e)
case SMFIR_TEMPFAIL:
if (MilterLogLevel > 3)
sm_syslog(LOG_INFO, e->e_id,
- "Milter: inititalization failed, temp failing commands");
+ "Milter: initialization failed, temp failing commands");
tempfail = true;
smtp.sm_milterize = false;
break;
@@ -953,10 +953,10 @@ smtp(nullserver, d_flags, e)
{
/* restart dialogue */
n_helo = 0;
-#if PIPELINING
+# if PIPELINING
(void) sm_io_autoflush(InChannel,
OutChannel);
-#endif /* PIPELINING */
+# endif /* PIPELINING */
}
else
syserr("503 5.3.3 SASL TLS failed");
@@ -1688,7 +1688,7 @@ smtp(nullserver, d_flags, e)
if (response != NULL)
sm_free(response);
-#if _FFR_QUARANTINE
+# if _FFR_QUARANTINE
/*
** If quarantining by a connect/ehlo action,
** save between messages
@@ -1697,7 +1697,7 @@ smtp(nullserver, d_flags, e)
if (smtp.sm_quarmsg == NULL &&
e->e_quarmsg != NULL)
smtp.sm_quarmsg = newstr(e->e_quarmsg);
-#endif /* _FFR_QUARANTINE */
+# endif /* _FFR_QUARANTINE */
}
#endif /* MILTER */
gothello = true;
@@ -1727,7 +1727,6 @@ smtp(nullserver, d_flags, e)
** remember to update 'helpfile'
*/
-
message("250-ENHANCEDSTATUSCODES");
#if PIPELINING
if (bitset(SRV_OFFER_PIPE, features))
@@ -1858,7 +1857,10 @@ smtp(nullserver, d_flags, e)
/* do the processing */
SM_TRY
{
+ extern char *FullName;
+
QuickAbort = true;
+ SM_FREE_CLR(FullName);
/* must parse sender first */
delimptr = NULL;
diff --git a/contrib/sendmail/src/stats.c b/contrib/sendmail/src/stats.c
index 0ae8ff4..74f7f9a 100644
--- a/contrib/sendmail/src/stats.c
+++ b/contrib/sendmail/src/stats.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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: stats.c,v 8.52 2001/11/21 13:39:14 gshapiro Exp $")
+SM_RCSID("@(#)$Id: stats.c,v 8.54 2002/03/19 00:23:28 gshapiro Exp $")
#include <sendmail/mailstats.h>
@@ -65,10 +65,16 @@ markstats(e, to, type)
Stat.stat_cr++;
break;
+ case STATS_CONNECT:
+ if (to == NULL)
+ Stat.stat_cf++;
+ else
+ Stat.stat_ct++;
+ break;
+
case STATS_NORMAL:
if (to == NULL)
{
- Stat.stat_cf++;
if (e->e_from.q_mailer != NULL)
{
Stat.stat_nf[e->e_from.q_mailer->m_mno]++;
@@ -78,7 +84,6 @@ markstats(e, to, type)
}
else
{
- Stat.stat_ct++;
Stat.stat_nt[to->q_mailer->m_mno]++;
Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize);
}
diff --git a/contrib/sendmail/src/tls.c b/contrib/sendmail/src/tls.c
index 2eb0047..e2b1b14 100644
--- a/contrib/sendmail/src/tls.c
+++ b/contrib/sendmail/src/tls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -10,7 +10,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: tls.c,v 8.75 2001/09/11 04:05:17 gshapiro Exp $")
+SM_RCSID("@(#)$Id: tls.c,v 8.79 2002/03/21 22:24:13 gshapiro Exp $")
#if STARTTLS
# include <openssl/err.h>
@@ -26,9 +26,18 @@ SM_RCSID("@(#)$Id: tls.c,v 8.75 2001/09/11 04:05:17 gshapiro Exp $")
static RSA *rsa_tmp = NULL; /* temporary RSA key */
static RSA *tmp_rsa_key __P((SSL *, int, int));
# endif /* !TLS_NO_RSA */
+# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
static int tls_verify_cb __P((X509_STORE_CTX *));
+# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+static int tls_verify_cb __P((X509_STORE_CTX *, void *));
+# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
-static void apps_ssl_info_cb __P((SSL *, int , int));
+# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
+# define CONST097
+# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+# define CONST097 const
+# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+static void apps_ssl_info_cb __P((CONST097 SSL *, int , int));
# if !NO_DH
static DH *get_dh512 __P((void));
@@ -139,6 +148,8 @@ tls_rand_init(randfile, logl)
| SFF_NOGWFILES | SFF_NOWWFILES
| SFF_NOGRFILES | SFF_NOWRFILES
| SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
+ if (DontLockReadFiles)
+ sff |= SFF_NOLOCK;
if ((fd = safeopen(randfile, O_RDONLY, 0, sff)) >= 0)
{
if (fstat(fd, &st) < 0)
@@ -1308,7 +1319,7 @@ tmp_rsa_key(s, export, keylength)
static void
apps_ssl_info_cb(s, where, ret)
- SSL *s;
+ CONST097 SSL *s;
int where;
int ret;
{
@@ -1420,8 +1431,14 @@ tls_verify_log(ok, ctx)
*/
static int
+# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
tls_verify_cb(ctx)
X509_STORE_CTX *ctx;
+# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+tls_verify_cb(ctx, unused)
+ X509_STORE_CTX *ctx;
+ void *unused;
+# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
{
int ok;
diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c
index cc29982..1e028de 100644
--- a/contrib/sendmail/src/usersmtp.c
+++ b/contrib/sendmail/src/usersmtp.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: usersmtp.c,v 8.428 2002/01/08 00:56:23 ca Exp $")
+SM_RCSID("@(#)$Id: usersmtp.c,v 8.431 2002/04/03 00:23:25 gshapiro Exp $")
#include <sysexits.h>
@@ -73,6 +73,7 @@ smtpinit(m, mci, e, onlyhelo)
bool onlyhelo;
{
register int r;
+ int state;
register char *p;
register char *hn;
char *enhsc;
@@ -93,6 +94,7 @@ smtpinit(m, mci, e, onlyhelo)
if (CurHostName == NULL)
CurHostName = MyHostName;
SmtpNeedIntro = true;
+ state = mci->mci_state;
switch (mci->mci_state)
{
case MCIS_MAIL:
@@ -115,7 +117,7 @@ smtpinit(m, mci, e, onlyhelo)
/* FALLTHROUGH */
case MCIS_CLOSED:
- syserr("451 4.4.0 smtpinit: state CLOSED");
+ syserr("451 4.4.0 smtpinit: state CLOSED (was %d)", state);
return;
case MCIS_OPENING:
@@ -1903,15 +1905,11 @@ smtpmailfrom(m, mci, e)
{
/* communications failure */
mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
- smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
else if (r == SMTPCLOSING)
{
- /* service shutting down */
- mci_setstat(mci, EX_TEMPFAIL, ENHSCN(enhsc, "4.5.0"),
- SmtpReplyBuffer);
- smtpquit(m, mci, e);
+ /* service shutting down: handled by reply() */
return EX_TEMPFAIL;
}
else if (REPLYTYPE(r) == 4)
@@ -2307,7 +2305,8 @@ smtpdata(m, mci, e, ctladdr, xstart)
r = reply(m, mci, e, TimeOuts.to_datainit, NULL, &enhsc);
if (r < 0 || REPLYTYPE(r) == 4)
{
- smtpquit(m, mci, e);
+ if (r >= 0)
+ smtpquit(m, mci, e);
errno = mci->mci_errno;
return EX_TEMPFAIL;
}
@@ -2458,10 +2457,7 @@ smtpdata(m, mci, e, ctladdr, xstart)
return EX_OK;
r = reply(m, mci, e, TimeOuts.to_datafinal, NULL, &enhsc);
if (r < 0)
- {
- smtpquit(m, mci, e);
return EX_TEMPFAIL;
- }
mci->mci_state = MCIS_OPEN;
xstat = EX_NOTSTICKY;
if (r == 452)
@@ -2567,10 +2563,7 @@ smtpgetstat(m, mci, e)
/* check for the results of the transaction */
r = reply(m, mci, e, TimeOuts.to_datafinal, NULL, &enhsc);
if (r < 0)
- {
- smtpquit(m, mci, e);
return EX_TEMPFAIL;
- }
xstat = EX_NOTSTICKY;
if (REPLYTYPE(r) == 4)
status = EX_TEMPFAIL;
@@ -2624,6 +2617,9 @@ smtpquit(m, mci, e)
int rcode;
char *oldcurhost;
+ if (mci->mci_state == MCIS_CLOSED)
+ return;
+
oldcurhost = CurHostName;
CurHostName = mci->mci_host; /* XXX UGLY XXX */
if (CurHostName == NULL)
@@ -2646,15 +2642,12 @@ smtpquit(m, mci, e)
if (mci->mci_state != MCIS_ERROR &&
mci->mci_state != MCIS_QUITING)
{
- int origstate = mci->mci_state;
-
SmtpPhase = "client QUIT";
mci->mci_state = MCIS_QUITING;
smtpmessage("QUIT", m, mci);
(void) reply(m, mci, e, TimeOuts.to_quit, NULL, NULL);
SuprErrs = oldSuprErrs;
- if (mci->mci_state == MCIS_CLOSED ||
- origstate == MCIS_CLOSED)
+ if (mci->mci_state == MCIS_CLOSED)
goto end;
}
@@ -2729,23 +2722,19 @@ smtprset(m, mci, e)
smtpmessage("RSET", m, mci);
r = reply(m, mci, e, TimeOuts.to_rset, NULL, NULL);
if (r < 0)
- mci->mci_state = MCIS_ERROR;
- else
- {
- /*
- ** Any response is deemed to be acceptable.
- ** The standard does not state the proper action
- ** to take when a value other than 250 is received.
- **
- ** However, if 421 is returned for the RSET, leave
- ** mci_state as MCIS_SSD (set in reply()).
- */
-
- if (mci->mci_state != MCIS_SSD)
- mci->mci_state = MCIS_OPEN;
return;
- }
- smtpquit(m, mci, e);
+
+ /*
+ ** Any response is deemed to be acceptable.
+ ** The standard does not state the proper action
+ ** to take when a value other than 250 is received.
+ **
+ ** However, if 421 is returned for the RSET, leave
+ ** mci_state as MCIS_SSD (set in reply()).
+ */
+
+ if (mci->mci_state != MCIS_SSD)
+ mci->mci_state = MCIS_OPEN;
}
/*
** SMTPPROBE -- check the connection state
@@ -2777,7 +2766,7 @@ smtpprobe(mci)
SmtpPhase = "client probe";
smtpmessage("RSET", m, mci);
r = reply(m, mci, e, TimeOuts.to_miscshort, NULL, NULL);
- if (r < 0 || REPLYTYPE(r) != 2)
+ if (REPLYTYPE(r) != 2)
smtpquit(m, mci, e);
return r;
}
@@ -2853,6 +2842,15 @@ reply(m, mci, e, timeout, pfunc, enhstat)
{
if (mci->mci_errno == 0)
mci->mci_errno = EBADF;
+
+ /* errors on QUIT should be ignored */
+ if (strncmp(SmtpMsgBuffer, "QUIT", 4) == 0)
+ {
+ errno = mci->mci_errno;
+ return -1;
+ }
+ mci->mci_state = MCIS_ERROR;
+ smtpquit(m, mci, e);
errno = mci->mci_errno;
return -1;
}
@@ -2870,6 +2868,10 @@ reply(m, mci, e, timeout, pfunc, enhstat)
bool oldholderrs;
extern char MsgBuf[];
+ /* errors on QUIT should be ignored */
+ if (strncmp(SmtpMsgBuffer, "QUIT", 4) == 0)
+ return -1;
+
/* if the remote end closed early, fake an error */
errno = save_errno;
if (errno == 0)
@@ -2890,10 +2892,7 @@ reply(m, mci, e, timeout, pfunc, enhstat)
HoldErrs = true;
usrerr("451 4.4.1 reply: read error from %s",
CURHOSTNAME);
-
- /* errors on QUIT should not be persistent */
- if (strncmp(SmtpMsgBuffer, "QUIT", 4) != 0)
- mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf);
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf);
/* if debugging, pause so we can see state */
if (tTd(18, 100))
@@ -2993,7 +2992,8 @@ reply(m, mci, e, timeout, pfunc, enhstat)
(void) sm_strlcpy(SmtpError, SmtpReplyBuffer, sizeof SmtpError);
/* reply code 421 is "Service Shutting Down" */
- if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD)
+ if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD &&
+ mci->mci_state != MCIS_QUITING)
{
/* send the quit protocol */
mci->mci_state = MCIS_SSD;
diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c
index c11d085..e4a0530 100644
--- a/contrib/sendmail/src/util.c
+++ b/contrib/sendmail/src/util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2002 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.357 2001/11/28 19:19:27 gshapiro Exp $")
+SM_RCSID("@(#)$Id: util.c,v 8.360 2002/04/04 21:32:15 gshapiro Exp $")
#include <sysexits.h>
#include <sm/xtrap.h>
@@ -905,6 +905,7 @@ putline(l, mci)
** PXLF_MAPFROM -- map From_ to >From_.
** PXLF_STRIP8BIT -- strip 8th bit.
** PXLF_HEADER -- map bare newline in header to newline space.
+** PXLF_NOADDEOL -- don't add an EOL if one wasn't present.
**
** Returns:
** none
@@ -938,10 +939,15 @@ putxline(l, len, mci, pxflags)
end = l + len;
do
{
+ bool noeol = false;
+
/* find the end of the line */
p = memchr(l, '\n', end - l);
if (p == NULL)
+ {
p = end;
+ noeol = true;
+ }
if (TrafficLogFile != NULL)
(void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT,
@@ -1097,7 +1103,8 @@ putxline(l, len, mci, pxflags)
if (TrafficLogFile != NULL)
(void) sm_io_putc(TrafficLogFile, SM_TIME_DEFAULT,
'\n');
- if (sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
+ 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
@@ -1711,7 +1718,7 @@ dumpfd(fd, printclosed, logit)
return;
}
- i = fcntl(fd, F_GETFL, NULL);
+ i = fcntl(fd, F_GETFL, 0);
if (i != -1)
{
(void) sm_snprintf(p, SPACELEFT(buf, p), "fl=0x%x, ", i);
diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c
index 95c7ee2..ff31631 100644
--- a/contrib/sendmail/src/version.c
+++ b/contrib/sendmail/src/version.c
@@ -13,6 +13,6 @@
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: version.c,v 8.91 2002/01/13 18:23:00 ca Exp $")
+SM_RCSID("@(#)$Id: version.c,v 8.99 2002/04/04 22:20:06 ca Exp $")
-char Version[] = "8.12.2";
+char Version[] = "8.12.3";
OpenPOWER on IntegriCloud