summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgshapiro <gshapiro@FreeBSD.org>2001-05-28 17:08:52 +0000
committergshapiro <gshapiro@FreeBSD.org>2001-05-28 17:08:52 +0000
commit175e3eb50e42986bc6de77adab1f3e58878b2a88 (patch)
tree1ec4aca91c9838476ad6d1cda3cd7012d54b95da
parentfd136031ceff193a9faff1c5a1283bfd251e29a7 (diff)
parent5338b6ff5f88e435da457fd0ec979a333012a0ef (diff)
downloadFreeBSD-src-175e3eb50e42986bc6de77adab1f3e58878b2a88.zip
FreeBSD-src-175e3eb50e42986bc6de77adab1f3e58878b2a88.tar.gz
This commit was generated by cvs2svn to compensate for changes in r77349,
which included commits to RCS files with non-trunk default branches.
-rw-r--r--contrib/sendmail/RELEASE_NOTES68
-rw-r--r--contrib/sendmail/cf/README3
-rw-r--r--contrib/sendmail/cf/cf/Makefile3
-rw-r--r--contrib/sendmail/cf/m4/proto.m435
-rw-r--r--contrib/sendmail/cf/m4/version.m44
-rw-r--r--contrib/sendmail/cf/ostype/aux.m42
-rw-r--r--contrib/sendmail/cf/ostype/freebsd4.m419
-rw-r--r--contrib/sendmail/doc/op/op.me43
-rw-r--r--contrib/sendmail/include/libmilter/milter.h2
-rw-r--r--contrib/sendmail/libmilter/README11
-rw-r--r--contrib/sendmail/libmilter/libmilter.h7
-rw-r--r--contrib/sendmail/libmilter/listener.c26
-rw-r--r--contrib/sendmail/libmilter/main.c7
-rw-r--r--contrib/sendmail/libmilter/sm_gethost.c6
-rw-r--r--contrib/sendmail/mailstats/mailstats.810
-rw-r--r--contrib/sendmail/src/README22
-rw-r--r--contrib/sendmail/src/TRACEFLAGS3
-rw-r--r--contrib/sendmail/src/alias.c19
-rw-r--r--contrib/sendmail/src/arpadate.c15
-rw-r--r--contrib/sendmail/src/bf_portable.c20
-rw-r--r--contrib/sendmail/src/bf_torek.c34
-rw-r--r--contrib/sendmail/src/clock.c226
-rw-r--r--contrib/sendmail/src/collect.c54
-rw-r--r--contrib/sendmail/src/control.c53
-rw-r--r--contrib/sendmail/src/daemon.c208
-rw-r--r--contrib/sendmail/src/deliver.c102
-rw-r--r--contrib/sendmail/src/envelope.c16
-rw-r--r--contrib/sendmail/src/main.c370
-rw-r--r--contrib/sendmail/src/map.c218
-rw-r--r--contrib/sendmail/src/milter.c48
-rw-r--r--contrib/sendmail/src/parseaddr.c10
-rw-r--r--contrib/sendmail/src/queue.c150
-rw-r--r--contrib/sendmail/src/readcf.c50
-rw-r--r--contrib/sendmail/src/recipient.c15
-rw-r--r--contrib/sendmail/src/sendmail.h92
-rw-r--r--contrib/sendmail/src/sfsasl.c44
-rw-r--r--contrib/sendmail/src/srvrsmtp.c98
-rw-r--r--contrib/sendmail/src/stab.c8
-rw-r--r--contrib/sendmail/src/udb.c12
-rw-r--r--contrib/sendmail/src/usersmtp.c95
-rw-r--r--contrib/sendmail/src/util.c149
-rw-r--r--contrib/sendmail/src/version.c4
-rw-r--r--contrib/sendmail/vacation/vacation.c141
43 files changed, 1820 insertions, 702 deletions
diff --git a/contrib/sendmail/RELEASE_NOTES b/contrib/sendmail/RELEASE_NOTES
index 77f0e08..c720a2f 100644
--- a/contrib/sendmail/RELEASE_NOTES
+++ b/contrib/sendmail/RELEASE_NOTES
@@ -1,11 +1,75 @@
SENDMAIL RELEASE NOTES
- $Id: RELEASE_NOTES,v 8.561.2.5.2.208 2001/02/26 21:24:54 gshapiro Exp $
+ $Id: RELEASE_NOTES,v 8.561.2.5.2.235 2001/05/27 21:39:16 gshapiro Exp $
This listing shows the version of the sendmail binary, the version
of the sendmail configuration files, the date of release, and a
summary of the changes in that release.
+8.11.4/8.11.4 2001/05/28
+ Clean up signal handling routines to reduce the chances of heap
+ corruption and other potential race conditions.
+ Terminating and restarting the daemon may not be
+ instantaneous due to this change. Also, non-root users can
+ no longer send out-of-band signals. Problem reported by
+ Michal Zalewski of BindView.
+ If LogLevel is greater than 9 and SASL fails to negotiate an
+ encryption layer, avoid core dump logging the encryption
+ strength. Problem noted by Miroslav Zubcic of Crol.
+ If a server offers "AUTH=" and "AUTH " and the list of mechanisms is
+ different in those two lines, sendmail might not have
+ recognized (and used) all of the offered mechanisms.
+ Fix an IP address lookup problem on Solaris 2.0 - 2.3. Patch
+ from Kenji Miyake.
+ This time, really don't use the .. directory when expanding
+ QueueDirectory wildcards.
+ If a process is interrupted while closing a map, don't try to close
+ the same map again while exiting.
+ Allow local mailers (F=l) to contact remote hosts (e.g., via
+ LMTP). Problem noted by Norbert Klasen of the University
+ of Tuebingen.
+ If Timeout.QueueReturn was set to a value less the time it took
+ to write a new queue file (e.g., 0 seconds), the bounce
+ message would be lost. Problem noted by Lorraine L Goff of
+ Oklahoma State University.
+ Pass map argument vector into map rewriting engine for the regex
+ and prog map types. Problem noted by Stephen Gildea of
+ InTouch Systems, Inc.
+ When closing an LDAP map due to a temporary error, close all of the
+ other LDAP maps which share the original map's connection
+ to the LDAP server. Patch from Victor Duchovni of
+ Morgan Stanley.
+ To detect changes of NDBM aliases files check the timestamp of the
+ .pag file instead of the .dir file. Problem noted by Neil
+ Rickert of Northern Illinois University.
+ Don't treat temporary hesiod lookup failures as permanent. Patch
+ from Werner Wiethege.
+ If ClientPortOptions is set, make sure to create the outgoing socket
+ with the family set in that option. Patch from Sean Farley.
+ Avoid a segmentation fault trying to dereference a NULL pointer
+ when logging a MaxHopCount exceeded error with an empty
+ recipient list. Problem noted by Chris Adams of HiWAAY
+ Internet Services.
+ Fix DSN for "Too many hops" bounces. Problem noticed by Ulrich
+ Windl of the Universitaet Regensburg.
+ Fix DSN for "mail loops back to me" bounces. Problem noticed by
+ Kari Hurtta of the Finnish Meteorological Institute.
+ Portability:
+ OpenBSD has a broken setreuid() implementation.
+ CONFIG: Undo change from 8.11.1: change 501 SMTP reply code back
+ to 553 since it is allowed by DRUMS.
+ CONFIG: Add OSTYPE(freebsd4) for FreeBSD 4.X.
+ DEVTOOLS: install.sh did not properly handle paths in the source
+ file name argument. Noted by Kari Hurtta of the Finnish
+ Meteorological Institute.
+ DEVTOOLS: Add FAST_PID_RECYCLE to compile time options for OpenBSD
+ since it generates random process ids.
+ PRALIASES: Add back adaptive algorithm to deal with different endings
+ of entries in the database (with/without trailing '\0').
+ Patch from John Beck of Sun Microsystems.
+ New Files:
+ cf/ostype/freebsd4.m4
+
8.11.3/8.11.3 2001/02/27
Prevent a segmentation fault when a bogus value was used in the
LDAPDefaultSpec option's -r, -s, or -M flags and if a bogus
@@ -2651,7 +2715,7 @@ summary of the changes in that release.
CONFIG: new FEATURE(relay_based_on_MX) to allow relaying based on
the MX records of the host portion of an incoming recipient.
CONFIG: new FEATURE(access_db) which turns on the access database
- feature. This database give you the ability to allow
+ feature. This database gives you the ability to allow
or refuse to accept mail from specified domains for
administrative reasons. By default, names that are listed
as "OK" in the access db are domain names, not host names.
diff --git a/contrib/sendmail/cf/README b/contrib/sendmail/cf/README
index 1ac7907..4e68134 100644
--- a/contrib/sendmail/cf/README
+++ b/contrib/sendmail/cf/README
@@ -3113,6 +3113,7 @@ that all domains in the envelope are fully qualified if the message is
relayed to another MTA. It will also enforce the normal address syntax
rules and log error messages. Additionally, by using the M=a modifier
you can require authentication before messages are accepted by the MSA.
+Notice: Do NOT use the 'a' modifier on a public accessible MTA!
Finally, the M=E modifier shown above disables ETRN as required by RFC
2476.
@@ -3277,4 +3278,4 @@ M4 DIVERSIONS
8 DNS based blacklists
9 special local rulesets (1 and 2)
-$Revision: 8.383.2.1.2.42 $, Last updated $Date: 2001/02/15 23:40:10 $
+$Revision: 8.383.2.1.2.43 $, Last updated $Date: 2001/05/24 16:41:53 $
diff --git a/contrib/sendmail/cf/cf/Makefile b/contrib/sendmail/cf/cf/Makefile
index 7a7c6d9..6bc9207 100644
--- a/contrib/sendmail/cf/cf/Makefile
+++ b/contrib/sendmail/cf/cf/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for configuration files.
#
-# $Id: Makefile,v 8.40.8.4 2000/10/26 18:27:44 gshapiro Exp $
+# $Id: Makefile,v 8.40.8.5 2001/04/12 22:39:52 gshapiro Exp $
#
#
@@ -117,7 +117,6 @@ M4FILES=\
${CFDIR}/ostype/aix4.m4 \
${CFDIR}/ostype/altos.m4 \
${CFDIR}/ostype/amdahl-uts.m4 \
- ${CFDIR}/ostype/aux.m4 \
${CFDIR}/ostype/bsd4.3.m4 \
${CFDIR}/ostype/bsd4.4.m4 \
${CFDIR}/ostype/bsdi.m4 \
diff --git a/contrib/sendmail/cf/m4/proto.m4 b/contrib/sendmail/cf/m4/proto.m4
index d21aba4..4f10e4c 100644
--- a/contrib/sendmail/cf/m4/proto.m4
+++ b/contrib/sendmail/cf/m4/proto.m4
@@ -13,7 +13,7 @@ divert(-1)
#
divert(0)
-VERSIONID(`$Id: proto.m4,v 8.446.2.5.2.38 2000/12/28 03:37:28 ca Exp $')
+VERSIONID(`$Id: proto.m4,v 8.446.2.5.2.41 2001/05/23 21:32:16 ca Exp $')
MAILER(local)dnl
@@ -77,6 +77,7 @@ dnl required to "rename" the check_* rulesets...
define(`_U_',ifdef(`_DELAY_CHECKS_',`',`_'))
dnl default relaying denied message
ifdef(`confRELAY_MSG', `', `define(`confRELAY_MSG', `"550 Relaying denied"')')
+define(`CODE553', `553')
divert(0)dnl
# override file safeties - setting this option compromises system security,
@@ -221,7 +222,7 @@ include(_CF_DIR_`m4/version.m4')
_OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
# 8-bit data handling
-_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `adaptive')
+_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
# wait for alias file rebuild (default units: minutes)
_OPTION(AliasWait, `confALIAS_WAIT', `5m')
@@ -867,26 +868,26 @@ R$* $: $>Parse1 $1 final parsing
SParse0
R<@> $@ <@> special case error msgs
-R$* : $* ; <@> $#error $@ 5.1.3 $: "501 List:; syntax illegal for recipient addresses"
+R$* : $* ; <@> $#error $@ 5.1.3 $: "CODE553 List:; syntax illegal for recipient addresses"
R@ <@ $* > < @ $1 > catch "@@host" bogosity
-R<@ $+> $#error $@ 5.1.3 $: "501 User address required"
+R<@ $+> $#error $@ 5.1.3 $: "CODE553 User address required"
R$* $: <> $1
R<> $* < @ [ $+ ] > $* $1 < @ [ $2 ] > $3
-R<> $* <$* : $* > $* $#error $@ 5.1.3 $: "501 Colon illegal in host name part"
+R<> $* <$* : $* > $* $#error $@ 5.1.3 $: "CODE553 Colon illegal in host name part"
R<> $* $1
-R$* < @ . $* > $* $#error $@ 5.1.2 $: "501 Invalid host name"
-R$* < @ $* .. $* > $* $#error $@ 5.1.2 $: "501 Invalid host name"
+R$* < @ . $* > $* $#error $@ 5.1.2 $: "CODE553 Invalid host name"
+R$* < @ $* .. $* > $* $#error $@ 5.1.2 $: "CODE553 Invalid host name"
dnl comma only allowed before @; this check is not complete
-R$* , $~O $* $#error $@ 5.1.2 $: "501 Invalid route address"
+R$* , $~O $* $#error $@ 5.1.2 $: "CODE553 Invalid route address"
# now delete the local info -- note $=O to find characters that cause forwarding
R$* < @ > $* $@ $>Parse0 $>canonify $1 user@ => user
R< @ $=w . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ...
R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here
-R< @ $+ > $#error $@ 5.1.3 $: "501 User address required"
+R< @ $+ > $#error $@ 5.1.3 $: "CODE553 User address required"
R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ...
R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo"
-R< @ *LOCAL* > $#error $@ 5.1.3 $: "501 User address required"
+R< @ *LOCAL* > $#error $@ 5.1.3 $: "CODE553 User address required"
R$* $=O $* < @ *LOCAL* >
$@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ...
R$* < @ *LOCAL* > $: $1
@@ -935,8 +936,10 @@ R<@> $+ $: $1
R<!> $+ $: $1
R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4
R< error : $- $+ > $* $#error $@ $(dequote $1 $) $: $2
-R< $+ > $+ < @ $+ > $: $>Recurse $1',
-`dnl')
+ifdef(`_NO_VIRTUSER_RECURSION_',
+`R< $+ > $+ < @ $+ > $: $>ParseLocal $>Parse0 $>canonify $1',
+`R< $+ > $+ < @ $+ > $: $>Recurse $1')
+dnl', `dnl')
# short circuit local delivery so forwarded email works
ifdef(`_MAILER_usenet_', `dnl
@@ -1013,7 +1016,7 @@ R$* < @ $* > $* $: $>MailerToTriple < $S > $1 < @ $2 > $3 glue on smarthost nam
# deal with other remote names
ifdef(`_MAILER_smtp_',
`R$* < @$* > $* $#_SMTP_ $@ $2 $: $1 < @ $2 > $3 user@host.domain',
-`R$* < @$* > $* $#error $@ 5.1.2 $: "501 Unrecognized host name " $2')
+`R$* < @$* > $* $#error $@ 5.1.2 $: "CODE553 Unrecognized host name " $2')
# handle locally delivered names
R$=L $#_LOCAL_ $: @ $1 special local names
@@ -1522,7 +1525,7 @@ dnl workspace: < ? $&{client_name} > <user@localhost|host>
dnl or: <address>
dnl or: <?> <address> (thanks to u in ${daemon_flags})
R<? $=w> $* $: $2 local client: ok
-R<? $+> <$+> $#error $@ 5.5.4 $: "501 Real domain name required for sender address"
+R<? $+> <$+> $#error $@ 5.5.4 $: "CODE553 Real domain name required for sender address"
dnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
R<?> $* $: $1')
dnl workspace: address (or <address>)
@@ -1572,13 +1575,13 @@ dnl remove daemon_flags
R$* $| $* $: $2
R<?> $* $: < ? $&{client_name} > $1
R<?> $* $@ <OK> ...local unqualed ok
-R<? $+> $* $#error $@ 5.5.4 $: "501 Domain name required for sender address " $&f
+R<? $+> $* $#error $@ 5.5.4 $: "CODE553 Domain name required for sender address " $&f
...remote is not')
# check results
R<?> $* $: @ $1 mark address: nothing known about it
R<OK> $* $@ <OK>
R<TEMP> $* $#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
-R<PERM> $* $#error $@ 5.1.8 $: "501 Domain of sender address " $&f " does not exist"
+R<PERM> $* $#error $@ 5.1.8 $: "CODE553 Domain of sender address " $&f " does not exist"
ifdef(`_ACCESS_TABLE_', `dnl
R<$={Accept}> $* $# $1
R<DISCARD> $* $#discard $: discard
diff --git a/contrib/sendmail/cf/m4/version.m4 b/contrib/sendmail/cf/m4/version.m4
index 05f275b..98afcb6 100644
--- a/contrib/sendmail/cf/m4/version.m4
+++ b/contrib/sendmail/cf/m4/version.m4
@@ -11,8 +11,8 @@ divert(-1)
# the sendmail distribution.
#
#
-VERSIONID(`$Id: version.m4,v 8.39.4.26 2001/02/27 19:22:29 gshapiro Exp $')
+VERSIONID(`$Id: version.m4,v 8.39.4.29 2001/05/27 21:39:20 gshapiro Exp $')
#
divert(0)
# Configuration version number
-DZ8.11.3`'ifdef(`confCF_VERSION', `/confCF_VERSION')
+DZ8.11.4`'ifdef(`confCF_VERSION', `/confCF_VERSION')
diff --git a/contrib/sendmail/cf/ostype/aux.m4 b/contrib/sendmail/cf/ostype/aux.m4
index ff7f19a..8c18dea 100644
--- a/contrib/sendmail/cf/ostype/aux.m4
+++ b/contrib/sendmail/cf/ostype/aux.m4
@@ -13,7 +13,7 @@ divert(-1)
#
divert(0)
-VERSIONID(`$Id: aux.m4,v 8.16 1999/04/24 05:37:40 gshapiro Exp $')
+VERSIONID(`$Id: a-ux.m4,v 8.1 2001/04/12 22:29:58 gshapiro Exp $')
ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl
ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')dnl
_DEFIFNOT(`LOCAL_MAILER_FLAGS', `mn9')dnl
diff --git a/contrib/sendmail/cf/ostype/freebsd4.m4 b/contrib/sendmail/cf/ostype/freebsd4.m4
new file mode 100644
index 0000000..b84a1e2
--- /dev/null
+++ b/contrib/sendmail/cf/ostype/freebsd4.m4
@@ -0,0 +1,19 @@
+divert(-1)
+#
+# Copyright (c) 2001 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.
+#
+#
+
+divert(0)
+VERSIONID(`$Id: freebsd4.m4,v 1.1 2001/03/21 22:44:58 ca Exp $')
+ifdef(`STATUS_FILE',, `define(`STATUS_FILE', `/var/log/sendmail.st')')dnl
+dnl turn on S flag for local mailer
+MODIFY_MAILER_FLAGS(`LOCAL', `+S')dnl
+ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /usr/libexec/mail.local)')dnl
+ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail $u')')dnl
+ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -z -a$g $h!rmail ($u)')')dnl
diff --git a/contrib/sendmail/doc/op/op.me b/contrib/sendmail/doc/op/op.me
index 3c27ebd..591ac01 100644
--- a/contrib/sendmail/doc/op/op.me
+++ b/contrib/sendmail/doc/op/op.me
@@ -9,7 +9,7 @@
.\" the sendmail distribution.
.\"
.\"
-.\" $Id: op.me,v 8.317.4.56 2001/02/15 23:38:16 ca Exp $
+.\" $Id: op.me,v 8.317.4.64 2001/05/24 16:45:49 ca Exp $
.\"
.\" eqn op.me | pic | troff -me
.eh 'SMM:08-%''Sendmail Installation and Operation Guide'
@@ -53,7 +53,7 @@ eric@Sendmail.COM
.de Ve
Version \\$2
..
-.Ve $Revision: 8.317.4.56 $
+.Ve $Revision: 8.317.4.64 $
.rm Ve
.sp
For Sendmail Version 8.11
@@ -2413,7 +2413,7 @@ option divided by the difference in the current load average and the
.b QueueLA
option
plus one
-exceeds the priority of the message \(em
+is less than the priority of the message \(em
that is, the message is queued iff:
.EQ
pri > { bold QueueFactor } over { LA - { bold QueueLA } + 1 }
@@ -2455,7 +2455,7 @@ Legal modes are:
i deliver interactively (synchronously)
b deliver in background (asynchronously)
q queue only (don't deliver)
-d defer delvery attempts (don't deliver)
+d defer delivery attempts (don't deliver)
.)b
There are tradeoffs.
Mode
@@ -3357,13 +3357,14 @@ The
.b $#
syntax should
.i only
-be used in ruleset zero
-or a subroutine of ruleset zero.
+be used in ruleset zero,
+a subroutine of ruleset zero,
+or rulesets that return decisions (e.g., check_rcpt).
It causes evaluation of the ruleset to terminate immediately,
and signals to
.i sendmail
that the address has completely resolved.
-The complete syntax is:
+The complete syntax for ruleset 0 is:
.(b
\fB$#\fP\fImailer\fP \fB$@\fP\fIhost\fP \fB$:\fP\fIuser\fP
.)b
@@ -5299,7 +5300,7 @@ i.e., not the header field-name; see also
${hdr_name} and ${currHeader}.
The header is treated as a structured field,
that is,
-comments (in parentheses) are deleted before processing,
+text in parentheses is deleted before processing,
unless the second form
.b $>+
is used.
@@ -5498,6 +5499,8 @@ Defaults to space (i.e., no change is made).
.ip CACERTPath
[no short name]
Path to directory with certificates of CAs.
+This directory directory must contain the hashes of each CA certificate
+as filenames (or as links to them).
.ip CACERTFile
[no short name]
File containing one CA certificate.
@@ -5700,6 +5703,12 @@ The modifiers that are marked with "(.cf)" have only
effect in the standard configuration file, in which
they are available via
.b ${daemon_flags} .
+Notice: Do
+.b not
+use the ``a'' modifier on a public accessible MTA!
+It should only be used for a MSA that is accessed by authorized
+users for initial mail submission.
+Users must authenticate to use a MSA which has this option turned on.
The flags ``c'' and ``C'' can change the default for
hostname canonification in the
.i sendmail.cf
@@ -6825,13 +6834,13 @@ Don't change this unless your system uses a different UNIX mailbox format
(very unlikely).
.ip UnsafeGroupWrites
[no short name]
-If set,
+If set (default),
:include: and .forward files that are group writable are considered
.q unsafe ,
that is,
they cannot reference programs or write directly to files.
World writable :include: and .forward files
-are always unsafe..
+are always unsafe.
.ip UseErrorsTo
[l]
If there is an
@@ -8705,6 +8714,14 @@ can contain several certificates of CAs.
The DNs of these certificates are sent
to the client during the TLS handshake (as part of the
CertificateRequest) as the list of acceptable CAs.
+The CACERTPath directory must contain the hashes of each CA certificate
+as filenames (or as links to them).
+Symbolic links can be generated with the following
+two (Bourne) shell commands:
+.(b
+C=FileName_of_CA_Certificate
+ln -s $C `openssl x509 -noout -hash < $C`.0
+.)b
An X.509 certificate is also required for authentication in client mode
(ClientCertFile), however,
.i sendmail
@@ -9259,10 +9276,6 @@ after a disastrous disk crash.
.ip $
A macro definition.
The values of certain macros
-(as of this writing, only
-.b $r
-and
-.b $s )
are passed through to the queue run phase.
.ip B
The body type.
@@ -9412,7 +9425,7 @@ replace it with a blank sheet for double-sided output.
.\".sz 10
.\"Eric Allman
.\".sp
-.\"Version $Revision: 8.317.4.56 $
+.\"Version $Revision: 8.317.4.64 $
.\".ce 0
.bp 3
.ce
diff --git a/contrib/sendmail/include/libmilter/milter.h b/contrib/sendmail/include/libmilter/milter.h
index 786d0e4..f4c9f27 100644
--- a/contrib/sendmail/include/libmilter/milter.h
+++ b/contrib/sendmail/include/libmilter/milter.h
@@ -7,7 +7,7 @@
* the sendmail distribution.
*
*
- * $Id: milter.h,v 8.24.16.8 2000/09/17 17:04:24 gshapiro Exp $
+ * $Id: milter.h,v 8.24.16.9 2001/03/02 21:22:48 geir Exp $
*/
/*
diff --git a/contrib/sendmail/libmilter/README b/contrib/sendmail/libmilter/README
index 7c052ca..461d64f 100644
--- a/contrib/sendmail/libmilter/README
+++ b/contrib/sendmail/libmilter/README
@@ -10,7 +10,7 @@ file. It is necessary to first build libmilter.a, which can be done by
issuing the './Build' command in SRCDIR/libmilter .
NOTE: Both libmilter and the callouts in sendmail are marked as an FFR (For
-Future Release). If you intend to use them in 8.10.X, you must compiled
+Future Release). If you intend to use them in 8.11.X, you must compiled
both libmilter and sendmail with -D_FFR_MILTER defined. You can do this by
adding the following to your devtools/Site/site.config.m4 file:
@@ -97,7 +97,8 @@ T=S:10s;R:10s;E:5m
where 's' is seconds and 'm' is minutes.
Which filters are invoked and their sequencing is handled by the
-InputMailFilters option.
+InputMailFilters option. Note: if InputMailFilters is not defined no filters
+will be used.
O InputMailFilters=filter1, filter2, filter3
@@ -223,7 +224,7 @@ mlfi_envfrom(ctx, envfrom)
char **envfrom;
{
struct mlfiPriv *priv;
- int fd;
+ int fd = -1;
/* allocate some private memory */
priv = malloc(sizeof *priv);
@@ -244,6 +245,8 @@ mlfi_envfrom(ctx, envfrom)
if ((fd = mkstemp(priv->mlfi_fname)) < 0 ||
(priv->mlfi_fp = fdopen(fd, "w+")) == NULL)
{
+ if (fd >= 0)
+ (void) close(fd);
free(priv->mlfi_fname);
free(priv);
return SMFIS_TEMPFAIL;
@@ -421,4 +424,4 @@ main(argc, argv)
/* eof */
-$Revision: 8.9.2.1.2.14 $, Last updated $Date: 2001/02/21 23:08:19 $
+$Revision: 8.9.2.1.2.17 $, Last updated $Date: 2001/04/11 18:32:58 $
diff --git a/contrib/sendmail/libmilter/libmilter.h b/contrib/sendmail/libmilter/libmilter.h
index 358ba64..886cc4d 100644
--- a/contrib/sendmail/libmilter/libmilter.h
+++ b/contrib/sendmail/libmilter/libmilter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -17,7 +17,7 @@
# define EXTERN
# define INIT(x) = x
# ifndef lint
-static char MilterlId[] = "@(#)$Id: libmilter.h,v 8.3.6.10 2000/11/20 21:15:36 ca Exp $";
+static char MilterlId[] = "@(#)$Id: libmilter.h,v 8.3.6.14 2001/05/27 14:31:12 ca Exp $";
# endif /* ! lint */
#else /* _DEFINE */
# define EXTERN extern
@@ -58,7 +58,7 @@ typedef pthread_mutex_t smutex_t;
#define MILTER_VERSION 100
/* some defaults */
-#define MI_TIMEOUT 1800 /* default timeout for read/write */
+#define MI_TIMEOUT 7210 /* default timeout for read/write */
#define MI_CHK_TIME 5 /* checking whether to terminate */
#if SOMAXCONN > 20
@@ -70,6 +70,7 @@ typedef pthread_mutex_t smutex_t;
/* maximum number of repeated failures in mi_listener() */
#define MAX_FAILS_M 16 /* malloc() */
#define MAX_FAILS_T 16 /* thread creation */
+#define MAX_FAILS_A 16 /* accept() */
/* internal "commands", i.e., error codes */
#define SMFIC_TIMEOUT ((char) 1) /* timeout */
diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c
index 6a1a801..6a59955 100644
--- a/contrib/sendmail/libmilter/listener.c
+++ b/contrib/sendmail/libmilter/listener.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: listener.c,v 8.38.2.1.2.21 2001/02/14 02:20:40 gshapiro Exp $";
+static char id[] = "@(#)$Id: listener.c,v 8.38.2.1.2.22 2001/05/16 17:15:58 ca Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -515,6 +515,8 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
int ret = MI_SUCCESS;
int mcnt = 0;
int tcnt = 0;
+ int acnt = 0;
+ int save_errno = 0;
sthread_t thread_id;
_SOCK_ADDR cliaddr;
SOCKADDR_LEN_T socksize;
@@ -574,10 +576,9 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
}
if (r < 0)
{
- int err = errno;
-
+ save_errno = errno;
(void) smutex_unlock(&L_Mutex);
- if (err == EINTR)
+ if (save_errno == EINTR)
continue;
ret = MI_FAILURE;
break;
@@ -593,6 +594,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
memset(&cliaddr, '\0', sizeof cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr,
&clilen);
+ save_errno = errno;
(void) smutex_unlock(&L_Mutex);
/*
@@ -610,14 +612,23 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
{
(void) close(connfd);
connfd = INVALID_SOCKET;
- errno = EINVAL;
+ save_errno = EINVAL;
}
if (!ValidSocket(connfd))
{
smi_log(SMI_LOG_ERR,
- "%s: accept() returned invalid socket",
- smfi->xxfi_name);
+ "%s: accept() returned invalid socket (%s)",
+ smfi->xxfi_name, strerror(save_errno));
+ if (save_errno == EINTR)
+ continue;
+ acnt++;
+ MI_SLEEP(acnt);
+ if (acnt >= MAX_FAILS_A)
+ {
+ ret = MI_FAILURE;
+ break;
+ }
continue;
}
@@ -643,6 +654,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
continue;
}
mcnt = 0;
+ acnt = 0;
memset(ctx, '\0', sizeof *ctx);
ctx->ctx_sd = connfd;
ctx->ctx_dbg = dbg;
diff --git a/contrib/sendmail/libmilter/main.c b/contrib/sendmail/libmilter/main.c
index 7ea1ba7..6afebdb 100644
--- a/contrib/sendmail/libmilter/main.c
+++ b/contrib/sendmail/libmilter/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: main.c,v 8.34.4.9 2000/09/09 02:23:03 gshapiro Exp $";
+static char id[] = "@(#)$Id: main.c,v 8.34.4.11 2001/05/07 22:06:37 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -131,9 +131,11 @@ smfi_setbacklog(obacklog)
return MI_SUCCESS;
}
+
int
smfi_main()
{
+
signal(SIGPIPE, SIG_IGN);
if (conn == NULL)
{
@@ -151,6 +153,7 @@ smfi_main()
return MI_FAILURE;
}
+
/* Startup the listener */
if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
return MI_FAILURE;
diff --git a/contrib/sendmail/libmilter/sm_gethost.c b/contrib/sendmail/libmilter/sm_gethost.c
index 32c8faf..a4fc665 100644
--- a/contrib/sendmail/libmilter/sm_gethost.c
+++ b/contrib/sendmail/libmilter/sm_gethost.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: sm_gethost.c,v 8.7.8.6 2001/02/14 04:07:23 gshapiro Exp $";
+static char id[] = "@(#)$Id: sm_gethost.c,v 8.7.8.10 2001/05/09 20:57:12 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -29,7 +29,7 @@ static char id[] = "@(#)$Id: sm_gethost.c,v 8.7.8.6 2001/02/14 04:07:23 gshapiro
** Support IPv6 as well as IPv4.
*/
-#if NETINET6 && NEEDSGETIPNODE && __RES < 19990909
+#if NETINET6 && NEEDSGETIPNODE
# ifndef AI_V4MAPPED
# define AI_V4MAPPED 0 /* dummy */
@@ -75,7 +75,7 @@ freehostent(h)
return;
}
# endif /* _FFR_FREEHOSTENT */
-#endif /* NEEDSGETIPNODE && NETINET6 && __RES < 19990909 */
+#endif /* NEEDSGETIPNODE && NETINET6 */
struct hostent *
mi_gethostbyname(name, family)
diff --git a/contrib/sendmail/mailstats/mailstats.8 b/contrib/sendmail/mailstats/mailstats.8
index 5122bd0..5ecde7c 100644
--- a/contrib/sendmail/mailstats/mailstats.8
+++ b/contrib/sendmail/mailstats/mailstats.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
.\" All rights reserved.
.\"
.\" By using this file, you agree to the terms and conditions set
@@ -6,9 +6,9 @@
.\" the sendmail distribution.
.\"
.\"
-.\" $Id: mailstats.8,v 8.17.4.3 2000/12/29 18:12:20 gshapiro Exp $
+.\" $Id: mailstats.8,v 8.17.4.6 2001/05/07 22:06:38 gshapiro Exp $
.\"
-.TH MAILSTATS 1 "$Date: 2000/12/29 18:12:20 $"
+.TH MAILSTATS 8 "$Date: 2001/05/07 22:06:38 $"
.SH NAME
mailstats
\- display mail statistics
@@ -61,11 +61,11 @@ The name of the mailer.
.RE
.PP
After this display, a line totaling the values for all of the mailers
-is displayed (preceeded with a ``T''),
+is displayed (preceded with a ``T''),
separated from the previous information by a line containing only equals
(``='')
characters.
-Another line preceeded with a ``C'' lists the number of connections.
+Another line preceded with a ``C'' lists the number of connections.
.PP
The options are as follows:
.TP
diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README
index fc8917a..53380d5 100644
--- a/contrib/sendmail/src/README
+++ b/contrib/sendmail/src/README
@@ -9,7 +9,7 @@
# the sendmail distribution.
#
#
-# $Id: README,v 8.263.2.1.2.32 2001/01/29 23:45:22 gshapiro Exp $
+# $Id: README,v 8.263.2.1.2.35 2001/05/09 20:58:32 gshapiro Exp $
#
This directory contains the source files for sendmail(TM).
@@ -459,6 +459,9 @@ SNPRINTF_IS_BROKEN
Set this if your system has an snprintf() implementation
which does not NUL terminate the string being filled in.
Use test/t_snprintf.c to test your system.
+NEEDSGETIPNODE Set this if your system supports IPv6 but doesn't include
+ the getipnodeby{name,addr}() functions. Set automatically
+ for Linux's glibc.
+-----------------------+
| COMPILE-TIME FEATURES |
@@ -1448,6 +1451,21 @@ 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)
+ From: Mike Zimmerman <zimmy@torrentnet.com>
+ From scratch here is what Darwin users need to do to the standard
+ 10.0.0, 10.0.1 install to get sendmail working.
+ From http://www.macosx.com/forums/showthread.php?s=6dac0e9e1f3fd118a4870a8a9b559491&threadid=2242:
+ 1. chmod g-w / /private /private/etc
+ 2. Properly set HOSTNAME in /etc/hostconfig to your FQDN:
+ HOSTNAME=-my.domain.com-
+ 3. Edit /etc/rc.boot:
+ hostname my.domain.com
+ domainname domain.com
+ 4. Edit /System/Library/StartupItems/Sendmail/Sendmail:
+ Remove the "&" after the sendmail command:
+ /usr/sbin/sendmail -bd -q1h
+
GNU getopt
I'm told that GNU getopt has a problem in that it gets confused
by the double call. Use the version in conf.c instead.
@@ -1688,4 +1706,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.263.2.1.2.32 $, last update $Date: 2001/01/29 23:45:22 $ )
+(Version $Revision: 8.263.2.1.2.35 $, last update $Date: 2001/05/09 20:58:32 $ )
diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS
index b48e75d..09f7d35 100644
--- a/contrib/sendmail/src/TRACEFLAGS
+++ b/contrib/sendmail/src/TRACEFLAGS
@@ -1,4 +1,4 @@
-# $Id: TRACEFLAGS,v 8.29 1999/11/04 23:31:02 gshapiro Exp $
+# $Id: TRACEFLAGS,v 8.29.16.1 2001/05/03 17:24:00 gshapiro Exp $
0, 1 main.c main skip background fork
0, 4 main.c main canonical name, UUCP node name, a.k.a.s
0, 15 main.c main print configuration
@@ -75,6 +75,7 @@
62 multiple file descriptor checking
63 queue.c runqueue process watching
64 multiple Milter
+67 conf.c signals
80 content length
81 sun remote mode
91 mci.c syslogging of MCI cache information
diff --git a/contrib/sendmail/src/alias.c b/contrib/sendmail/src/alias.c
index 4c6a174..070da59 100644
--- a/contrib/sendmail/src/alias.c
+++ b/contrib/sendmail/src/alias.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 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>
#ifndef lint
-static char id[] = "@(#)$Id: alias.c,v 8.142.4.9 2000/11/08 20:58:42 geir Exp $";
+static char id[] = "@(#)$Id: alias.c,v 8.142.4.11 2001/05/03 17:24:01 gshapiro Exp $";
#endif /* ! lint */
# define SEPARATOR ':'
@@ -405,8 +405,9 @@ aliaswait(map, ext, isopen)
dprintf("aliaswait: sleeping for %u seconds\n",
sleeptime);
+ map->map_mflags |= MF_CLOSING;
map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
(void) sleep(sleeptime);
sleeptime *= 2;
if (sleeptime > 60)
@@ -449,8 +450,9 @@ aliaswait(map, ext, isopen)
SuprErrs = TRUE;
if (isopen)
{
+ map->map_mflags |= MF_CLOSING;
map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
}
(void) rebuildaliases(map, TRUE);
isopen = map->map_class->map_open(map, O_RDONLY);
@@ -595,8 +597,9 @@ rebuildaliases(map, automatic)
/* add distinguished entries and close the database */
if (bitset(MF_OPEN, map->map_mflags))
{
+ map->map_mflags |= MF_CLOSING;
map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
}
/* restore the old signals */
@@ -827,11 +830,11 @@ readaliases(map, af, announcestats, logstats)
}
if (al.q_paddr != NULL)
- free(al.q_paddr);
+ sm_free(al.q_paddr);
if (al.q_host != NULL)
- free(al.q_host);
+ sm_free(al.q_host);
if (al.q_user != NULL)
- free(al.q_user);
+ sm_free(al.q_user);
}
CurEnv->e_to = NULL;
diff --git a/contrib/sendmail/src/arpadate.c b/contrib/sendmail/src/arpadate.c
index c265cdb..c67c3b9 100644
--- a/contrib/sendmail/src/arpadate.c
+++ b/contrib/sendmail/src/arpadate.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: arpadate.c,v 8.23 1999/09/23 19:59:18 ca Exp $";
+static char id[] = "@(#)$Id: arpadate.c,v 8.23.20.2 2001/05/07 22:07:26 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -117,11 +117,12 @@ arpadate(ud)
*q++ = *p++;
/*
- * should really get the timezone from the time in "ud" (which
- * is only different if a non-null arg was passed which is different
- * from the current time), but for all practical purposes, returning
- * the current local zone will do (its all that is ever needed).
- */
+ ** should really get the timezone from the time in "ud" (which
+ ** is only different if a non-null arg was passed which is different
+ ** from the current time), but for all practical purposes, returning
+ ** the current local zone will do (its all that is ever needed).
+ */
+
gmt = *gmtime(&t);
lt = localtime(&t);
diff --git a/contrib/sendmail/src/bf_portable.c b/contrib/sendmail/src/bf_portable.c
index 3c09cec..f14077f 100644
--- a/contrib/sendmail/src/bf_portable.c
+++ b/contrib/sendmail/src/bf_portable.c
@@ -11,7 +11,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: bf_portable.c,v 8.25.4.5 2001/02/14 04:07:27 gshapiro Exp $";
+static char id[] = "@(#)$Id: bf_portable.c,v 8.25.4.6 2001/05/03 17:24:01 gshapiro Exp $";
#endif /* ! lint */
#if SFIO
@@ -28,9 +28,12 @@ static char id[] = "@(#)$Id: bf_portable.c,v 8.25.4.5 2001/02/14 04:07:27 gshapi
#if !SFIO
# include <stdio.h>
#endif /* !SFIO */
-#ifndef BF_STANDALONE
+#ifdef BF_STANDALONE
+# define sm_free free
+# define xalloc malloc
+#else /* BF_STANDALONE */
# include "sendmail.h"
-#endif /* ! BF_STANDALONE */
+#endif /* BF_STANDALONE */
#include "bf_portable.h"
#include "bf.h"
@@ -95,7 +98,7 @@ bfopen(filename, fmode, bsize, flags)
}
/* Allocate memory */
- bfp = (struct bf *)malloc(sizeof(struct bf));
+ bfp = (struct bf *)xalloc(sizeof(struct bf));
if (bfp == NULL)
{
(void) fclose(retval);
@@ -110,10 +113,10 @@ bfopen(filename, fmode, bsize, flags)
filename, (long) sizeof(struct bf));
l = strlen(filename) + 1;
- bfp->bf_filename = (char *)malloc(l);
+ bfp->bf_filename = (char *)xalloc(l);
if (bfp->bf_filename == NULL)
{
- free(bfp);
+ sm_free(bfp);
(void) fclose(retval);
/* don't care about errors */
@@ -224,7 +227,6 @@ bfrewind(fp)
/* check to see if there is an error on the stream */
err = ferror(fp);
-
(void) fflush(fp);
/*
@@ -379,8 +381,8 @@ bfclose(fp)
if (!bfp->bf_committed)
retval = unlink(bfp->bf_filename);
- free(bfp->bf_filename);
- free(bfp);
+ sm_free(bfp->bf_filename);
+ sm_free(bfp);
if (tTd(58, 8))
dprintf("bfclose: freed %ld\n",
(long) sizeof(struct bf));
diff --git a/contrib/sendmail/src/bf_torek.c b/contrib/sendmail/src/bf_torek.c
index d58abc9..f74aecd 100644
--- a/contrib/sendmail/src/bf_torek.c
+++ b/contrib/sendmail/src/bf_torek.c
@@ -11,7 +11,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: bf_torek.c,v 8.19.18.4 2001/02/14 04:07:27 gshapiro Exp $";
+static char id[] = "@(#)$Id: bf_torek.c,v 8.19.18.6 2001/05/08 06:52:19 gshapiro Exp $";
#endif /* ! lint */
#if SFIO
@@ -26,9 +26,12 @@ static char id[] = "@(#)$Id: bf_torek.c,v 8.19.18.4 2001/02/14 04:07:27 gshapiro
#include <string.h>
#include <errno.h>
#include <stdio.h>
-#ifndef BF_STANDALONE
+#ifdef BF_STANDALONE
+# define sm_free free
+# define xalloc malloc
+#else /* BF_STANDALONE */
# include "sendmail.h"
-#endif /* ! BF_STANDALONE */
+#endif /* BF_STANDALONE */
#include "bf_torek.h"
#include "bf.h"
@@ -90,7 +93,7 @@ bfopen(filename, fmode, bsize, flags)
}
/* Allocate memory */
- bfp = (struct bf *)malloc(sizeof(struct bf));
+ bfp = (struct bf *)xalloc(sizeof(struct bf));
if (bfp == NULL)
{
errno = ENOMEM;
@@ -100,10 +103,10 @@ bfopen(filename, fmode, bsize, flags)
/* A zero bsize is valid, just don't allocate memory */
if (bsize > 0)
{
- bfp->bf_buf = (char *)malloc(bsize);
+ bfp->bf_buf = (char *)xalloc(bsize);
if (bfp->bf_buf == NULL)
{
- free(bfp);
+ sm_free(bfp);
errno = ENOMEM;
return NULL;
}
@@ -119,12 +122,12 @@ bfopen(filename, fmode, bsize, flags)
bfp->bf_bufsize = bsize;
bfp->bf_buffilled = 0;
l = strlen(filename) + 1;
- bfp->bf_filename = (char *)malloc(l);
+ bfp->bf_filename = (char *)xalloc(l);
if (bfp->bf_filename == NULL)
{
- free(bfp);
if (bfp->bf_buf != NULL)
- free(bfp->bf_buf);
+ sm_free(bfp->bf_buf);
+ sm_free(bfp);
errno = ENOMEM;
return NULL;
}
@@ -142,10 +145,10 @@ bfopen(filename, fmode, bsize, flags)
{
/* Just in case free() sets errno */
save_errno = errno;
- free(bfp);
- free(bfp->bf_filename);
+ sm_free(bfp->bf_filename);
if (bfp->bf_buf != NULL)
- free(bfp->bf_buf);
+ sm_free(bfp->bf_buf);
+ sm_free(bfp);
errno = save_errno;
return NULL;
}
@@ -285,7 +288,7 @@ bfcommit(fp)
{
/* Don't need buffer anymore; free it */
bfp->bf_bufsize = 0;
- free(bfp->bf_buf);
+ sm_free(bfp->bf_buf);
}
return 0;
}
@@ -317,7 +320,6 @@ bfrewind(fp)
/* check to see if there is an error on the stream */
err = ferror(fp);
-
(void) fflush(fp);
/*
@@ -530,10 +532,10 @@ _bfclose(cookie)
/* Need to free the buffer */
if (bfp->bf_bufsize > 0)
- free(bfp->bf_buf);
+ sm_free(bfp->bf_buf);
/* Finally, free the structure */
- free(bfp);
+ sm_free(bfp);
return 0;
}
diff --git a/contrib/sendmail/src/clock.c b/contrib/sendmail/src/clock.c
index 8788291..bf5ef1c 100644
--- a/contrib/sendmail/src/clock.c
+++ b/contrib/sendmail/src/clock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: clock.c,v 8.52.18.3 2000/09/17 17:04:26 gshapiro Exp $";
+static char id[] = "@(#)$Id: clock.c,v 8.52.18.14 2001/05/17 18:12:28 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -21,6 +21,7 @@ static char id[] = "@(#)$Id: clock.c,v 8.52.18.3 2000/09/17 17:04:26 gshapiro Ex
# define sigmask(s) (1 << ((s) - 1))
#endif /* ! sigmask */
+static SIGFUNC_DECL tick __P((int));
static void endsleep __P((void));
@@ -42,7 +43,8 @@ static void endsleep __P((void));
** none.
*/
-EVENT *FreeEventList; /* list of free events */
+static EVENT *volatile EventQueue; /* head of event queue */
+static EVENT *volatile FreeEventList; /* list of free events */
EVENT *
setevent(intvl, func, arg)
@@ -50,10 +52,7 @@ setevent(intvl, func, arg)
void (*func)();
int arg;
{
- register EVENT **evp;
register EVENT *ev;
- auto time_t now;
- int wasblocked;
if (intvl <= 0)
{
@@ -61,33 +60,88 @@ setevent(intvl, func, arg)
return NULL;
}
+ ENTER_CRITICAL();
+ if (FreeEventList == NULL)
+ {
+ FreeEventList = (EVENT *) xalloc(sizeof *FreeEventList);
+ FreeEventList->ev_link = NULL;
+ }
+ LEAVE_CRITICAL();
+
+ ev = sigsafe_setevent(intvl, func, arg);
+
+ if (tTd(5, 5))
+ dprintf("setevent: intvl=%ld, for=%ld, func=%lx, arg=%d, ev=%lx\n",
+ (long) intvl, (long) (curtime() + intvl),
+ (u_long) func, arg,
+ ev == NULL ? 0 : (u_long) ev);
+
+ return ev;
+}
+
+/*
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+*/
+
+EVENT *
+sigsafe_setevent(intvl, func, arg)
+ time_t intvl;
+ void (*func)();
+ int arg;
+{
+ register EVENT **evp;
+ register EVENT *ev;
+ auto time_t now;
+ int wasblocked;
+
+ if (intvl <= 0)
+ return NULL;
+
wasblocked = blocksignal(SIGALRM);
now = curtime();
/* search event queue for correct position */
- for (evp = &EventQueue; (ev = *evp) != NULL; evp = &ev->ev_link)
+ for (evp = (EVENT **) (&EventQueue);
+ (ev = *evp) != NULL;
+ evp = &ev->ev_link)
{
if (ev->ev_time >= now + intvl)
break;
}
- /* insert new event */
- ev = FreeEventList;
- if (ev == NULL)
- ev = (EVENT *) xalloc(sizeof *ev);
+ ENTER_CRITICAL();
+ if (FreeEventList == NULL)
+ {
+ /*
+ ** This shouldn't happen. If called from setevent(),
+ ** we have just malloced a FreeEventList entry. If
+ ** called from a signal handler, it should have been
+ ** from an existing event which tick() just added to the
+ ** FreeEventList.
+ */
+
+ LEAVE_CRITICAL();
+ return NULL;
+ }
else
+ {
+ ev = FreeEventList;
FreeEventList = ev->ev_link;
+ }
+ LEAVE_CRITICAL();
+
+ /* insert new event */
ev->ev_time = now + intvl;
ev->ev_func = func;
ev->ev_arg = arg;
ev->ev_pid = getpid();
+ ENTER_CRITICAL();
ev->ev_link = *evp;
*evp = ev;
-
- if (tTd(5, 5))
- dprintf("setevent: intvl=%ld, for=%ld, func=%lx, arg=%d, ev=%lx\n",
- (long) intvl, (long)(now + intvl), (u_long) func,
- arg, (u_long) ev);
+ LEAVE_CRITICAL();
(void) setsignal(SIGALRM, tick);
intvl = EventQueue->ev_time - now;
@@ -123,7 +177,9 @@ clrevent(ev)
/* find the parent event */
wasblocked = blocksignal(SIGALRM);
- for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link)
+ for (evp = (EVENT **) (&EventQueue);
+ *evp != NULL;
+ evp = &(*evp)->ev_link)
{
if (*evp == ev)
break;
@@ -132,9 +188,11 @@ clrevent(ev)
/* now remove it */
if (*evp != NULL)
{
+ ENTER_CRITICAL();
*evp = ev->ev_link;
ev->ev_link = FreeEventList;
FreeEventList = ev;
+ LEAVE_CRITICAL();
}
/* restore clocks and pick up anything spare */
@@ -178,9 +236,11 @@ clear_events()
for (ev = EventQueue; ev->ev_link != NULL; ev = ev->ev_link)
continue;
+ ENTER_CRITICAL();
ev->ev_link = FreeEventList;
FreeEventList = EventQueue;
EventQueue = NULL;
+ LEAVE_CRITICAL();
/* restore clocks and pick up anything spare */
if (wasblocked == 0)
@@ -201,6 +261,10 @@ clear_events()
**
** Side Effects:
** calls the next function in EventQueue.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
*/
/* ARGSUSED */
@@ -210,27 +274,67 @@ tick(sig)
{
register time_t now;
register EVENT *ev;
- int mypid = getpid();
+ pid_t mypid;
int save_errno = errno;
(void) alarm(0);
- now = curtime();
+ FIX_SYSV_SIGNAL(sig, tick);
+
+ errno = save_errno;
+ CHECK_CRITICAL(sig);
+
+ mypid = getpid();
+ while (PendingSignal != 0)
+ {
+ int sigbit;
+ int sig;
+
+ if (bitset(PEND_SIGHUP, PendingSignal))
+ {
+ sigbit = PEND_SIGHUP;
+ sig = SIGHUP;
+ }
+ else if (bitset(PEND_SIGINT, PendingSignal))
+ {
+ sigbit = PEND_SIGINT;
+ sig = SIGINT;
+ }
+ else if (bitset(PEND_SIGTERM, PendingSignal))
+ {
+ sigbit = PEND_SIGTERM;
+ sig = SIGTERM;
+ }
+ else if (bitset(PEND_SIGUSR1, PendingSignal))
+ {
+ sigbit = PEND_SIGUSR1;
+ sig = SIGUSR1;
+ }
+ else
+ {
+ /* If we get here, we are in trouble */
+ abort();
+ }
+ PendingSignal &= ~sigbit;
+ kill(mypid, sig);
+ }
+
+ now = curtime();
if (tTd(5, 4))
dprintf("tick: now=%ld\n", (long) now);
- /* reset signal in case System V semantics */
- (void) setsignal(SIGALRM, tick);
while ((ev = EventQueue) != NULL &&
(ev->ev_time <= now || ev->ev_pid != mypid))
{
void (*f)();
int arg;
- int pid;
+ pid_t pid;
/* process the event on the top of the queue */
+ ENTER_CRITICAL();
ev = EventQueue;
EventQueue = EventQueue->ev_link;
+ LEAVE_CRITICAL();
if (tTd(5, 6))
dprintf("tick: ev=%lx, func=%lx, arg=%d, pid=%d\n",
(u_long) ev, (u_long) ev->ev_func,
@@ -240,9 +344,11 @@ tick(sig)
f = ev->ev_func;
arg = ev->ev_arg;
pid = ev->ev_pid;
+ ENTER_CRITICAL();
ev->ev_link = FreeEventList;
FreeEventList = ev;
- if (pid != getpid())
+ LEAVE_CRITICAL();
+ if (pid != mypid)
continue;
if (EventQueue != NULL)
{
@@ -264,6 +370,72 @@ tick(sig)
return SIGFUNC_RETURN;
}
/*
+** PEND_SIGNAL -- Add a signal to the pending signal list
+**
+** Parameters:
+** sig -- signal to add
+**
+** Returns:
+** none.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+*/
+
+void
+pend_signal(sig)
+ int sig;
+{
+ int sigbit;
+ int save_errno = errno;
+
+ /*
+ ** Don't want to interrupt something critical, hence delay
+ ** the alarm for one second. Hopefully, by then we
+ ** will be out of the critical section. If not, then
+ ** we will just delay again. The events to be run will
+ ** still all be run, maybe just a little bit late.
+ */
+
+ switch (sig)
+ {
+ case SIGHUP:
+ sigbit = PEND_SIGHUP;
+ break;
+
+ case SIGINT:
+ sigbit = PEND_SIGINT;
+ break;
+
+ case SIGTERM:
+ sigbit = PEND_SIGTERM;
+ break;
+
+ case SIGUSR1:
+ sigbit = PEND_SIGUSR1;
+ break;
+
+ case SIGALRM:
+ /* don't have to pend these */
+ sigbit = 0;
+ break;
+
+ default:
+ /* If we get here, we are in trouble */
+ abort();
+
+ /* NOTREACHED */
+ break;
+ }
+
+ if (sigbit != 0)
+ PendingSignal |= sigbit;
+ (void) setsignal(SIGALRM, tick);
+ (void) alarm(1);
+ errno = save_errno;
+}
+ /*
** SLEEP -- a version of sleep that works with this stuff
**
** Because sleep uses the alarm facility, I must reimplement
@@ -281,7 +453,7 @@ tick(sig)
*/
-static bool SleepDone;
+static bool volatile SleepDone;
#ifndef SLEEP_T
# define SLEEP_T unsigned int
@@ -308,5 +480,11 @@ sleep(intvl)
static void
endsleep()
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
SleepDone = TRUE;
}
diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c
index d1c7f1c..e9a2006 100644
--- a/contrib/sendmail/src/collect.c
+++ b/contrib/sendmail/src/collect.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: collect.c,v 8.136.4.15 2001/02/21 01:05:59 gshapiro Exp $";
+static char id[] = "@(#)$Id: collect.c,v 8.136.4.21 2001/05/17 18:10:14 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -47,8 +47,8 @@ static void eatfrom __P((char *volatile, ENVELOPE *));
*/
static jmp_buf CtxCollectTimeout;
-static bool CollectProgress;
-static EVENT *CollectTimeout;
+static bool volatile CollectProgress;
+static EVENT *volatile CollectTimeout = NULL;
/* values for input state machine */
#define IS_NORM 0 /* middle of line */
@@ -212,10 +212,12 @@ collect(fp, smtpmode, hdrp, e)
if (TrafficLogFile != NULL && !headeronly)
{
if (istate == IS_BOL)
- (void) fprintf(TrafficLogFile, "%05d <<< ",
- (int) getpid());
+ (void) fprintf(TrafficLogFile,
+ "%05d <<< ",
+ (int) getpid());
if (c == EOF)
- (void) fprintf(TrafficLogFile, "[EOF]\n");
+ (void) fprintf(TrafficLogFile,
+ "[EOF]\n");
else
(void) putc(c, TrafficLogFile);
}
@@ -312,7 +314,6 @@ bufferchar:
/* just put the character out */
if (!bitset(EF_TOOBIG, e->e_flags))
(void) putc(c, df);
-
/* FALLTHROUGH */
case MS_DISCARD:
@@ -337,7 +338,7 @@ bufferchar:
memmove(buf, obuf, bp - obuf);
bp = &buf[bp - obuf];
if (obuf != bufbuf)
- free(obuf);
+ sm_free(obuf);
}
if (c >= 0200 && c <= 0237)
{
@@ -479,7 +480,8 @@ readerr:
}
/* reset global timer */
- clrevent(CollectTimeout);
+ if (CollectTimeout != NULL)
+ clrevent(CollectTimeout);
if (headeronly)
return;
@@ -721,15 +723,37 @@ static void
collecttimeout(timeout)
time_t timeout;
{
- /* if no progress was made, die now */
- if (!CollectProgress)
+ int save_errno = errno;
+
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ if (CollectProgress)
+ {
+ /* reset the timeout */
+ CollectTimeout = sigsafe_setevent(timeout, collecttimeout,
+ timeout);
+ CollectProgress = FALSE;
+ }
+ else
+ {
+ /* event is done */
+ CollectTimeout = NULL;
+ }
+
+ /* if no progress was made or problem resetting event, die now */
+ if (CollectTimeout == NULL)
+ {
+ errno = ETIMEDOUT;
longjmp(CtxCollectTimeout, 1);
+ }
- /* otherwise reset the timeout */
- CollectTimeout = setevent(timeout, collecttimeout, timeout);
- CollectProgress = FALSE;
+ errno = save_errno;
}
-/*
+ /*
** DFERROR -- signal error on writing the data file.
**
** Parameters:
diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c
index 95506ab..b30c63f 100644
--- a/contrib/sendmail/src/control.c
+++ b/contrib/sendmail/src/control.c
@@ -9,11 +9,33 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: control.c,v 8.44.14.15 2001/01/22 19:00:22 gshapiro Exp $";
+static char id[] = "@(#)$Id: control.c,v 8.44.14.20 2001/05/03 17:24:03 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
+/* values for cmd_code */
+# define CMDERROR 0 /* bad command */
+# define CMDRESTART 1 /* restart daemon */
+# define CMDSHUTDOWN 2 /* end daemon */
+# define CMDHELP 3 /* help */
+# define CMDSTATUS 4 /* daemon status */
+
+struct cmd
+{
+ char *cmd_name; /* command name */
+ int cmd_code; /* internal code, see below */
+};
+
+static struct cmd CmdTab[] =
+{
+ { "help", CMDHELP },
+ { "restart", CMDRESTART },
+ { "shutdown", CMDSHUTDOWN },
+ { "status", CMDSTATUS },
+ { NULL, CMDERROR }
+};
+
int ControlSocket = -1;
@@ -208,34 +230,19 @@ clrcontrol()
** none.
*/
-struct cmd
-{
- char *cmd_name; /* command name */
- int cmd_code; /* internal code, see below */
-};
-
-/* values for cmd_code */
-# define CMDERROR 0 /* bad command */
-# define CMDRESTART 1 /* restart daemon */
-# define CMDSHUTDOWN 2 /* end daemon */
-# define CMDHELP 3 /* help */
-# define CMDSTATUS 4 /* daemon status */
-
-static struct cmd CmdTab[] =
-{
- { "help", CMDHELP },
- { "restart", CMDRESTART },
- { "shutdown", CMDSHUTDOWN },
- { "status", CMDSTATUS },
- { NULL, CMDERROR }
-};
-
static jmp_buf CtxControlTimeout;
static void
controltimeout(timeout)
time_t timeout;
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
longjmp(CtxControlTimeout, 1);
}
diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c
index f4b07d4..1fdd3d7 100644
--- a/contrib/sendmail/src/daemon.c
+++ b/contrib/sendmail/src/daemon.c
@@ -16,9 +16,9 @@
#ifndef lint
# ifdef DAEMON
-static char id[] = "@(#)$Id: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (with daemon mode)";
+static char id[] = "@(#)$Id: daemon.c,v 8.401.4.61 2001/05/27 22:14:40 gshapiro Exp $ (with daemon mode)";
# else /* DAEMON */
-static char id[] = "@(#)$Id: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (without daemon mode)";
+static char id[] = "@(#)$Id: daemon.c,v 8.401.4.61 2001/05/27 22:14:40 gshapiro Exp $ (without daemon mode)";
# endif /* DAEMON */
#endif /* ! lint */
@@ -87,6 +87,8 @@ typedef struct daemon DAEMON_T;
static void connecttimeout __P((void));
static int opendaemonsocket __P((struct daemon *, bool));
static u_short setupdaemon __P((SOCKADDR *));
+static SIGFUNC_DECL sighup __P((int));
+static void restart_daemon __P((void));
/*
** DAEMON.C -- routines to use when running as a daemon.
@@ -194,6 +196,10 @@ getrequests(e)
ControlSocketName, errstring(errno));
(void) setsignal(SIGCHLD, reapchild);
+ (void) setsignal(SIGHUP, sighup);
+
+ /* workaround: can't seem to release the signal in the parent */
+ (void) releasesignal(SIGHUP);
/* write the pid to file */
log_sendmail_pid(e);
@@ -235,6 +241,11 @@ getrequests(e)
/* see if we are rejecting connections */
(void) blocksignal(SIGALRM);
+ if (ShutdownRequest != NULL)
+ shutdown_daemon();
+ else if (RestartRequest != NULL)
+ restart_daemon();
+
timenow = curtime();
/*
@@ -296,6 +307,12 @@ getrequests(e)
}
}
+ /* May have been sleeping above, check again */
+ if (ShutdownRequest != NULL)
+ shutdown_daemon();
+ else if (RestartRequest != NULL)
+ restart_daemon();
+
if (timenow >= last_disk_space_check)
{
bool logged = FALSE;
@@ -389,6 +406,11 @@ getrequests(e)
fd_set readfds;
struct timeval timeout;
+ if (ShutdownRequest != NULL)
+ shutdown_daemon();
+ else if (RestartRequest != NULL)
+ restart_daemon();
+
FD_ZERO(&readfds);
for (idx = 0; idx < ndaemons; idx++)
@@ -419,24 +441,18 @@ getrequests(e)
}
# endif /* NETUNIX */
- /*
- ** if one socket is closed, set the timeout
- ** to 5 seconds (so it might get reopened soon),
- ** otherwise (all sockets open) 60.
- */
-
- idx = 0;
- while (idx < ndaemons && Daemons[idx].d_socket >= 0)
- idx++;
- if (idx < ndaemons)
- timeout.tv_sec = 5;
- else
- timeout.tv_sec = 60;
+ timeout.tv_sec = 5;
timeout.tv_usec = 0;
t = select(highest + 1, FDSET_CAST &readfds,
NULL, NULL, &timeout);
+ /* Did someone signal while waiting? */
+ if (ShutdownRequest != NULL)
+ shutdown_daemon();
+ else if (RestartRequest != NULL)
+ restart_daemon();
+
if (DoQueueRun)
@@ -675,6 +691,18 @@ getrequests(e)
** Verify calling user id if possible here.
*/
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
+ (void) releasesignal(SIGALRM);
+ (void) releasesignal(SIGCHLD);
+ (void) setsignal(SIGCHLD, SIG_DFL);
+ (void) setsignal(SIGHUP, SIG_DFL);
+ (void) setsignal(SIGTERM, intsig);
+
+
if (!control)
{
define(macid("{daemon_addr}", NULL),
@@ -686,10 +714,6 @@ getrequests(e)
newstr(status), &BlankEnvelope);
}
- (void) releasesignal(SIGALRM);
- (void) releasesignal(SIGCHLD);
- (void) setsignal(SIGCHLD, SIG_DFL);
- (void) setsignal(SIGHUP, intsig);
for (idx = 0; idx < ndaemons; idx++)
{
if (Daemons[idx].d_socket >= 0)
@@ -1709,7 +1733,7 @@ makeconnection(host, port, mci, e)
{
STRUCTCOPY(ClientAddr, clt_addr);
if (clt_addr.sa.sa_family == AF_UNSPEC)
- clt_addr.sa.sa_family = InetMode;
+ clt_addr.sa.sa_family = family;
switch (clt_addr.sa.sa_family)
{
# if NETINET
@@ -1998,8 +2022,9 @@ gothostent:
for (;;)
{
if (tTd(16, 1))
- dprintf("makeconnection (%s [%s])\n",
- host, anynet_ntoa(&addr));
+ dprintf("makeconnection (%s [%s].%d (%d))\n",
+ host, anynet_ntoa(&addr), ntohs(port),
+ addr.sa.sa_family);
/* save for logging */
CurHostAddr = addr;
@@ -2012,7 +2037,7 @@ gothostent:
}
else
{
- s = socket(addr.sa.sa_family, SOCK_STREAM, 0);
+ s = socket(clt_addr.sa.sa_family, SOCK_STREAM, 0);
}
if (s < 0)
{
@@ -2118,9 +2143,11 @@ gothostent:
int i;
if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0)
- ev = setevent(TimeOuts.to_iconnect, connecttimeout, 0);
+ ev = setevent(TimeOuts.to_iconnect,
+ connecttimeout, 0);
else if (TimeOuts.to_connect != 0)
- ev = setevent(TimeOuts.to_connect, connecttimeout, 0);
+ ev = setevent(TimeOuts.to_connect,
+ connecttimeout, 0);
else
ev = NULL;
@@ -2306,6 +2333,12 @@ gothostent:
static void
connecttimeout()
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
errno = ETIMEDOUT;
longjmp(CtxConnectTimeout, 1);
}
@@ -2406,6 +2439,124 @@ int makeconnection_ds(mux_path, mci)
}
# endif /* NETUNIX */
/*
+** SIGHUP -- handle a SIGHUP signal
+**
+** Parameters:
+** sig -- incoming signal.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Sets RestartRequest which should cause the daemon
+** to restart.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+*/
+
+/* ARGSUSED */
+static SIGFUNC_DECL
+sighup(sig)
+ int sig;
+{
+ int save_errno = errno;
+
+ FIX_SYSV_SIGNAL(sig, sighup);
+ RestartRequest = "signal";
+ errno = save_errno;
+ return SIGFUNC_RETURN;
+}
+ /*
+** RESTART_DAEMON -- Performs a clean restart of the daemon
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** restarts the daemon or exits if restart fails.
+*/
+
+static void
+restart_daemon()
+{
+ int i;
+ int save_errno;
+ char *reason;
+ sigfunc_t oalrm, ochld, ohup, oint, opipe, oterm, ousr1;
+ extern int DtableSize;
+
+ allsignals(TRUE);
+
+ reason = RestartRequest;
+ RestartRequest = NULL;
+ PendingSignal = 0;
+
+ if (SaveArgv[0][0] != '/')
+ {
+ if (LogLevel > 3)
+ sm_syslog(LOG_INFO, NOQID,
+ "could not restart: need full path");
+ finis(FALSE, EX_OSFILE);
+ }
+ if (LogLevel > 3)
+ sm_syslog(LOG_INFO, NOQID, "restarting %s due to %s",
+ SaveArgv[0],
+ reason == NULL ? "implicit call" : reason);
+
+ closecontrolsocket(TRUE);
+ if (drop_privileges(TRUE) != EX_OK)
+ {
+ if (LogLevel > 0)
+ sm_syslog(LOG_ALERT, NOQID,
+ "could not set[ug]id(%d, %d): %m",
+ RunAsUid, RunAsGid);
+ finis(FALSE, EX_OSERR);
+ }
+
+ /* arrange for all the files to be closed */
+ for (i = 3; i < DtableSize; i++)
+ {
+ register int j;
+
+ if ((j = fcntl(i, F_GETFD, 0)) != -1)
+ (void) fcntl(i, F_SETFD, j | FD_CLOEXEC);
+ }
+
+ /* need to allow signals before execve() so make them harmless */
+ oalrm = setsignal(SIGALRM, SIG_DFL);
+ ochld = setsignal(SIGCHLD, SIG_DFL);
+ ohup = setsignal(SIGHUP, SIG_DFL);
+ oint = setsignal(SIGINT, SIG_DFL);
+ opipe = setsignal(SIGPIPE, SIG_DFL);
+ oterm = setsignal(SIGTERM, SIG_DFL);
+ ousr1 = setsignal(SIGUSR1, SIG_DFL);
+ allsignals(FALSE);
+
+ (void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron);
+ save_errno = errno;
+
+ /* restore signals */
+ allsignals(TRUE);
+ (void) setsignal(SIGALRM, oalrm);
+ (void) setsignal(SIGCHLD, ochld);
+ (void) setsignal(SIGHUP, ohup);
+ (void) setsignal(SIGINT, oint);
+ (void) setsignal(SIGPIPE, opipe);
+ (void) setsignal(SIGTERM, oterm);
+ (void) setsignal(SIGUSR1, ousr1);
+
+ errno = save_errno;
+ if (LogLevel > 0)
+ sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %m",
+ SaveArgv[0]);
+ finis(FALSE, EX_OSFILE);
+}
+ /*
** MYHOSTNAME -- return the name of this host.
**
** Parameters:
@@ -2568,6 +2719,13 @@ static jmp_buf CtxAuthTimeout;
static void
authtimeout()
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
longjmp(CtxAuthTimeout, 1);
}
diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c
index 689ceeb..347b7a5 100644
--- a/contrib/sendmail/src/deliver.c
+++ b/contrib/sendmail/src/deliver.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: deliver.c,v 8.600.2.1.2.66 2001/02/25 23:30:35 gshapiro Exp $";
+static char id[] = "@(#)$Id: deliver.c,v 8.600.2.1.2.81 2001/05/23 02:15:42 ca Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -135,22 +135,31 @@ sendall(e, mode)
if (e->e_hopcount > MaxHopCount)
{
+ char *recip;
+
+ if (e->e_sendqueue != NULL &&
+ e->e_sendqueue->q_paddr != NULL)
+ recip = e->e_sendqueue->q_paddr;
+ else
+ recip = "(nobody)";
+
errno = 0;
#if QUEUE
queueup(e, mode == SM_QUEUE || mode == SM_DEFER);
#endif /* QUEUE */
e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
ExitStat = EX_UNAVAILABLE;
- syserr("554 5.0.0 Too many hops %d (%d max): from %s via %s, to %s",
- e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
- RealHostName == NULL ? "localhost" : RealHostName,
- e->e_sendqueue->q_paddr);
+ syserr("554 5.4.6 Too many hops %d (%d max): from %s via %s, to %s",
+ e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
+ RealHostName == NULL ? "localhost" : RealHostName,
+ recip);
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
if (QS_IS_DEAD(q->q_state))
continue;
q->q_state = QS_BADADDR;
q->q_status = "5.4.6";
+ q->q_rstatus = "554 5.4.6 Too many hops";
}
return;
}
@@ -635,6 +644,11 @@ sendall(e, mode)
return;
}
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
/*
** Since we have accepted responsbility for the message,
** change the SIGTERM handler. intsig() (the old handler)
@@ -931,7 +945,7 @@ dup_queue_file(e, ee, type)
** returns twice, once in parent and once in child.
*/
-int
+pid_t
dofork()
{
register pid_t pid = -1;
@@ -1451,7 +1465,7 @@ deliver(e, firstto)
if (l > tobufsize)
{
if (tobuf != NULL)
- free(tobuf);
+ sm_free(tobuf);
tobufsize = l;
tobuf = xalloc(tobufsize);
}
@@ -1719,10 +1733,10 @@ tryhost:
m->m_name);
i = makeconnection(hostbuf, port, mci, e);
}
+ mci->mci_errno = errno;
mci->mci_lastuse = curtime();
mci->mci_deliveries = 0;
mci->mci_exitstat = i;
- mci->mci_errno = errno;
# if NAMED_BIND
mci->mci_herrno = h_errno;
# endif /* NAMED_BIND */
@@ -1913,6 +1927,11 @@ tryhost:
struct stat stb;
extern int DtableSize;
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
if (e->e_lockfp != NULL)
(void) close(fileno(e->e_lockfp));
@@ -2511,7 +2530,9 @@ reconnect: /* after switching to an authenticated connection */
mci->mci_host,
macvalue(macid("{auth_type}",
NULL), e),
- *ssf);
+ result == SASL_OK ? *ssf
+ : 0);
+
/*
** only switch to encrypted connection
** if a security layer has been negotiated
@@ -3041,6 +3062,12 @@ static jmp_buf EndWaitTimeout;
static void
endwaittimeout()
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
errno = ETIMEDOUT;
longjmp(EndWaitTimeout, 1);
}
@@ -3059,6 +3086,19 @@ endmailer(mci, e, pv)
mci_unlock_host(mci);
+ /* close output to mailer */
+ if (mci->mci_out != NULL)
+ (void) fclose(mci->mci_out);
+
+ /* copy any remaining input to transcript */
+ if (mci->mci_in != NULL && mci->mci_state != MCIS_ERROR &&
+ e->e_xfp != NULL)
+ {
+ while (sfgets(buf, sizeof buf, mci->mci_in,
+ TimeOuts.to_quit, "Draining Input") != NULL)
+ (void) fputs(buf, e->e_xfp);
+ }
+
#if SASL
/* shutdown SASL */
if (bitset(MCIF_AUTHACT, mci->mci_flags))
@@ -3073,19 +3113,6 @@ endmailer(mci, e, pv)
(void) endtlsclt(mci);
#endif /* STARTTLS */
- /* close output to mailer */
- if (mci->mci_out != NULL)
- (void) fclose(mci->mci_out);
-
- /* copy any remaining input to transcript */
- if (mci->mci_in != NULL && mci->mci_state != MCIS_ERROR &&
- e->e_xfp != NULL)
- {
- while (sfgets(buf, sizeof buf, mci->mci_in,
- TimeOuts.to_quit, "Draining Input") != NULL)
- (void) fputs(buf, e->e_xfp);
- }
-
/* now close the input */
if (mci->mci_in != NULL)
(void) fclose(mci->mci_in);
@@ -3375,7 +3402,7 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e)
if (status != EX_OK && (status != EX_TEMPFAIL || e->e_message == NULL))
{
if (e->e_message != NULL)
- free(e->e_message);
+ sm_free(e->e_message);
e->e_message = newstr(statmsg + off);
}
errno = 0;
@@ -3947,7 +3974,7 @@ putbody(mci, e, separator)
TrafficLogFile);
if (c == '\n')
(void) fputs(mci->mci_mailer->m_eol,
- TrafficLogFile);
+ TrafficLogFile);
}
if (padc != EOF)
{
@@ -4375,6 +4402,11 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
int err;
volatile int oflags = O_WRONLY|O_APPEND;
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
if (e->e_lockfp != NULL)
(void) close(fileno(e->e_lockfp));
@@ -4391,7 +4423,8 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
}
if (TimeOuts.to_fileopen > 0)
- ev = setevent(TimeOuts.to_fileopen, mailfiletimeout, 0);
+ ev = setevent(TimeOuts.to_fileopen,
+ mailfiletimeout, 0);
else
ev = NULL;
@@ -4705,7 +4738,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
(*e->e_putbody)(&mcibuf, e, NULL);
putline("\n", &mcibuf);
- if (fflush(f) < 0 ||
+ if (fflush(f) != 0 ||
(SuperSafe && fsync(fileno(f)) < 0) ||
ferror(f))
{
@@ -4755,6 +4788,13 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
static void
mailfiletimeout()
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
longjmp(CtxMailfileTimeout, 1);
}
/*
@@ -4802,17 +4842,19 @@ hostsignature(m, host)
dprintf("hostsignature(%s)\n", host);
/*
- ** If local delivery, just return a constant.
+ ** If local delivery (and not remote), just return a constant.
*/
- if (bitnset(M_LOCALMAILER, m->m_flags))
+ p = m->m_mailer;
+ if (bitnset(M_LOCALMAILER, m->m_flags) &&
+ strcmp(p, "[IPC]") != 0 &&
+ strcmp(p, "[TCP]") != 0)
return "localhost";
/*
** Check to see if this uses IPC -- if not, it can't have MX records.
*/
- p = m->m_mailer;
if (strcmp(p, "[IPC]") != 0 &&
strcmp(p, "[TCP]") != 0)
{
@@ -4920,7 +4962,7 @@ hostsignature(m, host)
if (s->s_hostsig != NULL)
{
(void) strlcpy(p, s->s_hostsig, len);
- free(s->s_hostsig);
+ sm_free(s->s_hostsig);
s->s_hostsig = p;
hl = strlen(p);
p += hl;
diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c
index a708589..bed63e4 100644
--- a/contrib/sendmail/src/envelope.c
+++ b/contrib/sendmail/src/envelope.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: envelope.c,v 8.180.14.6 2000/11/30 00:39:46 gshapiro Exp $";
+static char id[] = "@(#)$Id: envelope.c,v 8.180.14.10 2001/05/03 17:24:06 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -132,7 +132,7 @@ dropenvelope(e, fulldrop)
*/
now = curtime();
- if (now > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
+ if (now >= e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
message_timeout = TRUE;
if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
@@ -150,7 +150,7 @@ dropenvelope(e, fulldrop)
/* see if a notification is needed */
if (bitset(QPINGONFAILURE, q->q_flags) &&
- ((message_timeout && QS_IS_QUEUEUP(q->q_state)) ||
+ ((message_timeout && QS_IS_UNDELIVERED(q->q_state)) ||
QS_IS_BADADDR(q->q_state) ||
(TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
!bitset(EF_RESPONSE, e->e_flags))))
@@ -192,7 +192,7 @@ dropenvelope(e, fulldrop)
"Cannot send message for %s",
pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
if (e->e_message != NULL)
- free(e->e_message);
+ sm_free(e->e_message);
e->e_message = newstr(buf);
message(buf);
e->e_flags |= EF_CLRQUEUE;
@@ -210,7 +210,7 @@ dropenvelope(e, fulldrop)
}
}
else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 &&
- now > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
+ now >= e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
{
if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
e->e_class >= 0 &&
@@ -222,7 +222,7 @@ dropenvelope(e, fulldrop)
{
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
- if (QS_IS_QUEUEUP(q->q_state) &&
+ if (QS_IS_UNDELIVERED(q->q_state) &&
#if _FFR_NODELAYDSN_ON_HOLD
!bitnset(M_HOLD, q->q_mailer->m_flags) &&
#endif /* _FFR_NODELAYDSN_ON_HOLD */
@@ -239,7 +239,7 @@ dropenvelope(e, fulldrop)
"Warning: could not send message for past %s",
pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
if (e->e_message != NULL)
- free(e->e_message);
+ sm_free(e->e_message);
e->e_message = newstr(buf);
message(buf);
e->e_flags |= EF_WARNING;
diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c
index bf976e0..34d5041 100644
--- a/contrib/sendmail/src/main.c
+++ b/contrib/sendmail/src/main.c
@@ -21,7 +21,7 @@ static char copyright[] =
#endif /* ! lint */
#ifndef lint
-static char id[] = "@(#)$Id: main.c,v 8.485.4.44 2001/02/08 14:06:55 ca Exp $";
+static char id[] = "@(#)$Id: main.c,v 8.485.4.60 2001/05/27 22:00:26 gshapiro Exp $";
#endif /* ! lint */
#define _DEFINE
@@ -33,6 +33,10 @@ static char id[] = "@(#)$Id: main.c,v 8.485.4.44 2001/02/08 14:06:55 ca Exp $";
# include <arpa/inet.h>
#endif /* NETINET || NETINET6 */
+static SIGFUNC_DECL intindebug __P((int));
+static SIGFUNC_DECL quiesce __P((int));
+static SIGFUNC_DECL sigusr1 __P((int));
+static SIGFUNC_DECL term_daemon __P((int));
static void dump_class __P((STAB *, int));
static void obsolete __P((char **));
static void testmodeline __P((char *, ENVELOPE *));
@@ -76,7 +80,6 @@ ADDRESS NullAddress = /* a null address */
{ "", "", NULL, "" };
char *CommandLineArgs; /* command line args for pid file */
bool Warn_Q_option = FALSE; /* warn about Q option use */
-char **SaveArgv; /* argument vector for re-execing */
static int MissingFds = 0; /* bit map of fds missing on startup */
#ifdef NGROUPS_MAX
@@ -161,6 +164,14 @@ main(argc, argv, envp)
/* avoid null pointer dereferences */
TermEscape.te_rv_on = TermEscape.te_rv_off = "";
+ /*
+ ** Seed the random number generator.
+ ** Used for queue file names, picking a queue directory, and
+ ** MX randomization.
+ */
+
+ seed_random();
+
/* do machine-dependent initializations */
init_md(argc, argv);
@@ -218,14 +229,6 @@ main(argc, argv, envp)
checkfd012("after openlog");
#endif /* XDEBUG */
- /*
- ** Seed the random number generator.
- ** Used for queue file names, picking a queue directory, and
- ** MX randomization.
- */
-
- seed_random();
-
tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
#ifdef NGROUPS_MAX
@@ -242,8 +245,13 @@ main(argc, argv, envp)
setstat(dp);
# ifdef SIGUSR1
- /* arrange to dump state on user-1 signal */
- (void) setsignal(SIGUSR1, sigusr1);
+ /* Only allow root (or non-set-*-ID binaries) to use SIGUSR1 */
+ if (getuid() == 0 ||
+ (getuid() == geteuid() && getgid() == getegid()))
+ {
+ /* arrange to dump state on user-1 signal */
+ (void) setsignal(SIGUSR1, sigusr1);
+ }
# endif /* SIGUSR1 */
/* initialize for setproctitle */
@@ -300,17 +308,23 @@ main(argc, argv, envp)
}
opterr = 1;
+#if LOG
if (sysloglabel != NULL)
{
-#if LOG
+ /* Sanitize the string */
+ for (p = sysloglabel; *p != '\0'; p++)
+ {
+ if (!isascii(*p) || !isprint(*p) || *p == '%')
+ *p = '*';
+ }
closelog();
# ifdef LOG_MAIL
openlog(sysloglabel, LOG_PID, LOG_MAIL);
# else /* LOG_MAIL */
openlog(sysloglabel, LOG_PID);
# endif /* LOG_MAIL */
-#endif /* LOG */
}
+#endif /* LOG */
/* set up the blank envelope */
BlankEnvelope.e_puthdr = putheader;
@@ -349,6 +363,7 @@ main(argc, argv, envp)
** if running non-setuid binary as non-root, pretend
** we are the RunAsUid
*/
+
if (RealUid != 0 && geteuid() == RealUid)
{
if (tTd(47, 1))
@@ -471,11 +486,8 @@ main(argc, argv, envp)
/* prime the child environment */
setuserenv("AGENT", "sendmail");
-
- if (setsignal(SIGINT, SIG_IGN) != SIG_IGN)
- (void) setsignal(SIGINT, intsig);
- (void) setsignal(SIGTERM, intsig);
(void) setsignal(SIGPIPE, SIG_IGN);
+
OldUmask = umask(022);
OpMode = MD_DELIVER;
FullName = getextenv("NAME");
@@ -1025,6 +1037,59 @@ main(argc, argv, envp)
ConfigFileRead = TRUE;
vendor_post_defaults(CurEnv);
+ /* Remove the ability for a normal user to send signals */
+ if (RealUid != 0 &&
+ RealUid != geteuid())
+ {
+ uid_t new_uid = geteuid();
+
+#if HASSETREUID
+ /*
+ ** Since we can differentiate between uid and euid,
+ ** make the uid a different user so the real user
+ ** can't send signals. However, it doesn't need to be
+ ** root (euid has root).
+ */
+
+ if (new_uid == 0)
+ new_uid = DefUid;
+ if (tTd(47, 5))
+ dprintf("Changing real uid to %d\n", (int) new_uid);
+ if (setreuid(new_uid, geteuid()) < 0)
+ {
+ syserr("main: setreuid(%d, %d) failed",
+ (int) new_uid, (int) geteuid());
+ finis(FALSE, EX_OSERR);
+ /* NOTREACHED */
+ }
+ if (tTd(47, 10))
+ dprintf("Now running as e/ruid %d:%d\n",
+ (int) geteuid(), (int) getuid());
+#else /* HASSETREUID */
+ /*
+ ** Have to change both effective and real so need to
+ ** change them both to effective to keep privs.
+ */
+
+ if (tTd(47, 5))
+ dprintf("Changing uid to %d\n", (int) new_uid);
+ if (setuid(new_uid) < 0)
+ {
+ syserr("main: setuid(%d) failed", (int) new_uid);
+ finis(FALSE, EX_OSERR);
+ /* NOTREACHED */
+ }
+ if (tTd(47, 10))
+ dprintf("Now running as e/ruid %d:%d\n",
+ (int) geteuid(), (int) getuid());
+#endif /* HASSETREUID */
+ }
+
+ /* set up the basic signal handlers */
+ if (setsignal(SIGINT, SIG_IGN) != SIG_IGN)
+ (void) setsignal(SIGINT, intsig);
+ (void) setsignal(SIGTERM, intsig);
+
/* Enforce use of local time (null string overrides this) */
if (TimeZoneSpec == NULL)
unsetenv("TZ");
@@ -1184,6 +1249,7 @@ main(argc, argv, envp)
case MD_VERIFY:
CurEnv->e_errormode = EM_PRINT;
HoldErrs = FALSE;
+
/* arrange to exit cleanly on hangup signal */
if (setsignal(SIGHUP, SIG_IGN) == (sigfunc_t) SIG_DFL)
(void) setsignal(SIGHUP, intsig);
@@ -1205,10 +1271,7 @@ main(argc, argv, envp)
if (SaveArgv[0] == NULL || SaveArgv[0][0] != '/')
sm_syslog(LOG_WARNING, NOQID,
"daemon invoked without full pathname; kill -1 won't work");
- (void) setsignal(SIGHUP, sighup);
-
- /* workaround: can't seem to release the signal in the parent */
- (void) releasesignal(SIGHUP);
+ (void) setsignal(SIGTERM, term_daemon);
break;
case MD_INITALIAS:
@@ -1247,7 +1310,7 @@ main(argc, argv, envp)
FullName = addquotes(FullName);
if (full != NULL)
- free(full);
+ sm_free(full);
}
}
@@ -1589,20 +1652,7 @@ main(argc, argv, envp)
#if SMTP
# if STARTTLS
- /*
- ** basic TLS initialization
- ** ignore result for now
- */
- SSL_library_init();
- SSL_load_error_strings();
-# if 0
- /* this is currently a macro for SSL_library_init */
- SSLeay_add_ssl_algorithms();
-# endif /* 0 */
-
- /* initialize PRNG */
- tls_ok = tls_rand_init(RandFile, 7);
-
+ tls_ok = init_tls_library();
# endif /* STARTTLS */
#endif /* SMTP */
@@ -1698,10 +1748,13 @@ main(argc, argv, envp)
{
/* write the pid to file */
log_sendmail_pid(CurEnv);
+ (void) setsignal(SIGTERM, term_daemon);
for (;;)
{
(void) pause();
- if (DoQueueRun)
+ if (ShutdownRequest != NULL)
+ shutdown_daemon();
+ else if (DoQueueRun)
(void) runqueue(TRUE, FALSE);
}
}
@@ -1996,21 +2049,89 @@ main(argc, argv, envp)
/* NOTREACHED */
return ExitStat;
}
+ /*
+** QUIESCE -- signal handler for SIGPIPE
+**
+** Parameters:
+** sig -- incoming signal.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Sets StopRequest which should cause the mailq/hoststatus
+** display to stop.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+*/
/* ARGSUSED */
-SIGFUNC_DECL
+static SIGFUNC_DECL
quiesce(sig)
int sig;
{
- clear_events();
- finis(FALSE, EX_OK);
+ int save_errno = errno;
+
+ FIX_SYSV_SIGNAL(sig, quiesce);
+ StopRequest = TRUE;
+ errno = save_errno;
+ return SIGFUNC_RETURN;
+}
+ /*
+** STOP_SENDMAIL -- Stop the running program
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** exits.
+*/
+
+void
+stop_sendmail()
+{
+ /* reset uid for process accounting */
+ endpwent();
+ (void) setuid(RealUid);
+ exit(EX_OK);
}
+ /*
+** INTINDEBUG -- signal handler for SIGINT in -bt mode
+**
+** Parameters:
+** sig -- incoming signal.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** longjmps back to test mode loop.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+**
+** XXX: More work is needed for this signal handler.
+*/
+
/* ARGSUSED */
-SIGFUNC_DECL
+static SIGFUNC_DECL
intindebug(sig)
int sig;
{
+ int save_errno = errno;
+
+ FIX_SYSV_SIGNAL(sig, intindebug);
+ errno = save_errno;
+ CHECK_CRITICAL(sig);
+
+ errno = save_errno;
longjmp(TopFrame, 1);
return SIGFUNC_RETURN;
}
@@ -2033,6 +2154,9 @@ finis(drop, exitstat)
bool drop;
volatile int exitstat;
{
+ /* Still want to process new timeouts added below */
+ clear_events();
+ releasesignal(SIGALRM);
if (tTd(2, 1))
{
@@ -2082,7 +2206,7 @@ finis(drop, exitstat)
if (LogLevel > 78)
sm_syslog(LOG_DEBUG, CurEnv->e_id,
"finis, pid=%d",
- getpid());
+ (int) getpid());
if (exitstat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET)
exitstat = EX_OK;
@@ -2094,6 +2218,71 @@ finis(drop, exitstat)
exit(exitstat);
}
/*
+** TERM_DEAMON -- SIGTERM handler for the daemon
+**
+** Parameters:
+** sig -- signal number.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Sets ShutdownRequest which will hopefully trigger
+** the daemon to exit.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+*/
+
+/* ARGSUSED */
+static SIGFUNC_DECL
+term_daemon(sig)
+ int sig;
+{
+ int save_errno = errno;
+
+ FIX_SYSV_SIGNAL(sig, term_daemon);
+ ShutdownRequest = "signal";
+ errno = save_errno;
+ return SIGFUNC_RETURN;
+}
+ /*
+** SHUTDOWN_DAEMON -- Performs a clean shutdown of the daemon
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** closes control socket, exits.
+*/
+
+void
+shutdown_daemon()
+{
+ char *reason;
+
+ allsignals(TRUE);
+
+ reason = ShutdownRequest;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
+ if (LogLevel > 79)
+ sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt");
+
+ FileName = NULL;
+ closecontrolsocket(TRUE);
+#ifdef XLA
+ xla_all_end();
+#endif /* XLA */
+
+ finis(FALSE, EX_OK);
+}
+ /*
** INTSIG -- clean up on interrupt
**
** This just arranges to exit. It pessimizes in that it
@@ -2107,6 +2296,12 @@ finis(drop, exitstat)
**
** Side Effects:
** Unlocks the current job.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+**
+** XXX: More work is needed for this signal handler.
*/
/* ARGSUSED */
@@ -2115,15 +2310,15 @@ intsig(sig)
int sig;
{
bool drop = FALSE;
+ int save_errno = errno;
- clear_events();
+ FIX_SYSV_SIGNAL(sig, intsig);
+ errno = save_errno;
+ CHECK_CRITICAL(sig);
+ allsignals(TRUE);
if (sig != 0 && LogLevel > 79)
sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt");
FileName = NULL;
- closecontrolsocket(TRUE);
-#ifdef XLA
- xla_all_end();
-#endif /* XLA */
/* Clean-up on aborted stdin message submission */
if (CurEnv->e_id != NULL &&
@@ -2324,7 +2519,7 @@ disconnect(droplev, e)
if (LogLevel > 71)
sm_syslog(LOG_DEBUG, e->e_id,
"in background, pid=%d",
- getpid());
+ (int) getpid());
errno = 0;
}
@@ -2563,69 +2758,36 @@ dumpstate(when)
}
sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- end of state dump ---");
}
-
+ /*
+** SIGUSR1 -- Signal a request to dump state.
+**
+** Parameters:
+** sig -- calling signal.
+**
+** Returns:
+** none.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
+**
+** XXX: More work is needed for this signal handler.
+*/
/* ARGSUSED */
-SIGFUNC_DECL
+static SIGFUNC_DECL
sigusr1(sig)
int sig;
{
+ int save_errno = errno;
+
+ FIX_SYSV_SIGNAL(sig, sigusr1);
+ errno = save_errno;
+ CHECK_CRITICAL(sig);
dumpstate("user signal");
+ errno = save_errno;
return SIGFUNC_RETURN;
}
-
-
-/* ARGSUSED */
-SIGFUNC_DECL
-sighup(sig)
- int sig;
-{
- int i;
- extern int DtableSize;
-
- clear_events();
- (void) alarm(0);
- if (SaveArgv[0][0] != '/')
- {
- if (LogLevel > 3)
- sm_syslog(LOG_INFO, NOQID,
- "could not restart: need full path");
- finis(FALSE, EX_OSFILE);
- }
- if (LogLevel > 3)
- sm_syslog(LOG_INFO, NOQID, "restarting %s %s",
- sig == 0 ? "due to control command" : "on signal",
- SaveArgv[0]);
-
- /* Control socket restart? */
- if (sig != 0)
- (void) releasesignal(SIGHUP);
-
- closecontrolsocket(TRUE);
- if (drop_privileges(TRUE) != EX_OK)
- {
- if (LogLevel > 0)
- sm_syslog(LOG_ALERT, NOQID,
- "could not set[ug]id(%d, %d): %m",
- RunAsUid, RunAsGid);
- finis(FALSE, EX_OSERR);
- }
-
- /* arrange for all the files to be closed */
- for (i = 3; i < DtableSize; i++)
- {
- register int j;
-
- if ((j = fcntl(i, F_GETFD, 0)) != -1)
- (void) fcntl(i, F_SETFD, j | FD_CLOEXEC);
- }
-
- (void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron);
- if (LogLevel > 0)
- sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %m",
- SaveArgv[0]);
- finis(FALSE, EX_OSFILE);
-}
/*
** DROP_PRIVILEGES -- reduce privileges to those of the RunAsUser option
**
diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c
index 4a10c81..fc0d07f 100644
--- a/contrib/sendmail/src/map.c
+++ b/contrib/sendmail/src/map.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: map.c,v 8.414.4.39 2001/02/22 18:56:22 gshapiro Exp $";
+static char id[] = "@(#)$Id: map.c,v 8.414.4.53 2001/05/04 01:29:00 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -370,7 +370,7 @@ map_rewrite(map, s, slen, av)
/* need to malloc additional space */
buflen = len;
if (buf != NULL)
- free(buf);
+ sm_free(buf);
buf = xalloc(buflen);
}
@@ -492,8 +492,9 @@ map_init(s, unused)
/* if already open, close it (for nested open) */
if (bitset(MF_OPEN, map->map_mflags))
{
+ map->map_mflags |= MF_CLOSING;
map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
}
(void) rebuildaliases(map, FALSE);
@@ -627,6 +628,7 @@ map_close(s, unused)
if (!bitset(MF_VALID, map->map_mflags) ||
!bitset(MF_OPEN, map->map_mflags) ||
+ bitset(MF_CLOSING, map->map_mflags) ||
map->map_pid != getpid())
return;
@@ -635,8 +637,9 @@ map_close(s, unused)
map->map_mname == NULL ? "NULL" : map->map_mname,
map->map_file == NULL ? "NULL" : map->map_file);
+ map->map_mflags |= MF_CLOSING;
map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
}
/*
** GETCANONNAME -- look up name using service switch
@@ -1079,7 +1082,7 @@ ndbm_map_open(map, mode)
** map_mtime to be set
*/
- if (fstat(dfd, &st) >= 0)
+ if (fstat(pfd, &st) >= 0)
map->map_mtime = st.st_mtime;
if (mode == O_RDONLY)
@@ -1130,7 +1133,7 @@ ndbm_map_lookup(map, name, av, statp)
int *statp;
{
datum key, val;
- int fd;
+ int dfd, pfd;
char keybuf[MAXNAME + 1];
struct stat stbuf;
@@ -1150,19 +1153,22 @@ ndbm_map_lookup(map, name, av, statp)
key.dptr = keybuf;
}
lockdbm:
- fd = dbm_dirfno((DBM *) map->map_db1);
- if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, map->map_file, ".dir", LOCK_SH);
- if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
+ dfd = dbm_dirfno((DBM *) map->map_db1);
+ if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+ (void) lockfile(dfd, map->map_file, ".dir", LOCK_SH);
+ pfd = dbm_pagfno((DBM *) map->map_db1);
+ if (pfd < 0 || fstat(pfd, &stbuf) < 0 ||
+ stbuf.st_mtime > map->map_mtime)
{
/* Reopen the database to sync the cache */
int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
: O_RDONLY;
- if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, map->map_file, ".dir", LOCK_UN);
+ if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+ (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
+ map->map_mflags |= MF_CLOSING;
map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
if (map->map_class->map_open(map, omode))
{
map->map_mflags |= MF_OPEN;
@@ -1201,8 +1207,8 @@ lockdbm:
if (val.dptr != NULL)
map->map_mflags &= ~MF_TRY0NULL;
}
- if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
- (void) lockfile(fd, map->map_file, ".dir", LOCK_UN);
+ if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+ (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
if (val.dptr == NULL)
return NULL;
if (bitset(MF_MATCHONLY, map->map_mflags))
@@ -1272,7 +1278,7 @@ ndbm_map_store(map, lhs, rhs)
if (data.dsize + old.dsize + 2 > bufsiz)
{
if (buf != NULL)
- (void) free(buf);
+ sm_free(buf);
bufsiz = data.dsize + old.dsize + 2;
buf = xalloc(bufsiz);
}
@@ -1803,8 +1809,9 @@ db_map_lookup(map, name, av, statp)
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
(void) lockfile(fd, buf, ".db", LOCK_UN);
+ map->map_mflags |= MF_CLOSING;
map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
if (map->map_class->map_open(map, omode))
{
map->map_mflags |= MF_OPEN;
@@ -1983,7 +1990,7 @@ db_map_store(map, lhs, rhs)
if (data.size + old.size + 2 > (size_t)bufsiz)
{
if (buf != NULL)
- (void) free(buf);
+ sm_free(buf);
bufsiz = data.size + old.size + 2;
buf = xalloc(bufsiz);
}
@@ -2141,7 +2148,7 @@ nis_map_open(map, mode)
dprintf("nis_map_open: yp_match(@, %s, %s) => %s\n",
map->map_domain, map->map_file, yperr_string(yperr));
if (vp != NULL)
- free(vp);
+ sm_free(vp);
if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
{
@@ -2211,7 +2218,7 @@ nis_map_lookup(map, name, av, statp)
{
if (vp != NULL)
{
- free(vp);
+ sm_free(vp);
vp = NULL;
}
buflen++;
@@ -2225,7 +2232,7 @@ nis_map_lookup(map, name, av, statp)
if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
map->map_mflags &= ~(MF_VALID|MF_OPEN);
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return NULL;
}
if (bitset(MF_MATCHONLY, map->map_mflags))
@@ -2236,7 +2243,7 @@ nis_map_lookup(map, name, av, statp)
ret = map_rewrite(map, vp, vsize, av);
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return ret;
}
}
@@ -2290,7 +2297,7 @@ nis_getcanonname(name, hbsize, statp)
{
if (vp != NULL)
{
- free(vp);
+ sm_free(vp);
vp = NULL;
}
keylen++;
@@ -2308,11 +2315,11 @@ nis_getcanonname(name, hbsize, statp)
else
*statp = EX_UNAVAILABLE;
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return FALSE;
}
(void) strlcpy(host_record, vp, sizeof host_record);
- free(vp);
+ sm_free(vp);
if (tTd(38, 44))
dprintf("got record `%s'\n", host_record);
if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof cbuf))
@@ -2850,10 +2857,15 @@ ldapmap_open(map, mode)
lmap = (LDAPMAP_STRUCT *) map->map_db1;
s = ldapmap_findconn(lmap);
- if (s->s_ldap != NULL)
+ if (s->s_lmap != NULL)
{
/* Already have a connection open to this LDAP server */
- lmap->ldap_ld = s->s_ldap;
+ lmap->ldap_ld = ((LDAPMAP_STRUCT *)s->s_lmap->map_db1)->ldap_ld;
+
+ /* Add this map as head of linked list */
+ lmap->ldap_next = s->s_lmap;
+ s->s_lmap = map;
+
if (tTd(38, 2))
dprintf("using cached connection\n");
return TRUE;
@@ -2867,7 +2879,7 @@ ldapmap_open(map, mode)
return FALSE;
/* Save connection for reuse */
- s->s_ldap = lmap->ldap_ld;
+ s->s_lmap = map;
return TRUE;
}
@@ -3036,6 +3048,13 @@ static void
ldaptimeout(sig_no)
int sig_no;
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
longjmp(LDAPTimeout, 1);
}
@@ -3059,20 +3078,25 @@ ldapmap_close(map)
if (lmap->ldap_ld == NULL)
return;
+ /* Close the LDAP connection */
+ ldap_unbind(lmap->ldap_ld);
+
+ /* Mark all the maps that share the connection as closed */
s = ldapmap_findconn(lmap);
- /* Check if already closed */
- if (s->s_ldap == NULL)
- return;
+ while (s->s_lmap != NULL)
+ {
+ MAP *smap = s->s_lmap;
- /* If same as saved connection, stored connection is going away */
- if (s->s_ldap == lmap->ldap_ld)
- s->s_ldap = NULL;
+ if (tTd(38, 2) && smap != map)
+ dprintf("ldapmap_close(%s): closed %s (shared LDAP connection)\n",
+ map->map_mname, smap->map_mname);
- if (lmap->ldap_ld != NULL)
- {
- ldap_unbind(lmap->ldap_ld);
+ smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ lmap = (LDAPMAP_STRUCT *) smap->map_db1;
lmap->ldap_ld = NULL;
+ s->s_lmap = lmap->ldap_next;
+ lmap->ldap_next = NULL;
}
}
@@ -3214,7 +3238,10 @@ ldapmap_lookup(map, name, av, statp)
lmap->ldap_attrsonly);
if (msgid == -1)
{
+ int save_errno;
+
errno = ldapmap_geterrno(lmap->ldap_ld) + E_LDAPBASE;
+ save_errno = errno;
if (!bitset(MF_OPTIONAL, map->map_mflags))
{
if (bitset(MF_NODEFER, map->map_mflags))
@@ -3226,16 +3253,14 @@ ldapmap_lookup(map, name, av, statp)
}
*statp = EX_TEMPFAIL;
#ifdef LDAP_SERVER_DOWN
- if (errno == LDAP_SERVER_DOWN)
+ errno = save_errno;
+ if (errno == LDAP_SERVER_DOWN + E_LDAPBASE)
{
- int save_errno = errno;
-
/* server disappeared, try reopen on next search */
- map->map_class->map_close(map);
- map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
- errno = save_errno;
+ ldapmap_close(map);
}
#endif /* LDAP_SERVER_DOWN */
+ errno = save_errno;
return NULL;
}
@@ -3265,7 +3290,7 @@ ldapmap_lookup(map, name, av, statp)
}
(void) ldap_abandon(lmap->ldap_ld, msgid);
if (vp != NULL)
- free(vp);
+ sm_free(vp);
if (tTd(38, 25))
dprintf("ldap search found multiple on a single match query\n");
return NULL;
@@ -3348,7 +3373,7 @@ ldapmap_lookup(map, name, av, statp)
(void) ldap_abandon(lmap->ldap_ld,
msgid);
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return NULL;
}
}
@@ -3419,7 +3444,7 @@ ldapmap_lookup(map, name, av, statp)
snprintf(tmp, vsize, "%s%c%s",
vp, map->map_coldelim,
attr);
- free(vp);
+ sm_free(vp);
vp = tmp;
}
# if USING_NETSCAPE_LDAP
@@ -3465,8 +3490,8 @@ ldapmap_lookup(map, name, av, statp)
snprintf(tmp, vsize, "%s%c%s",
vp, map->map_coldelim, vp_tmp);
- free(vp);
- free(vp_tmp);
+ sm_free(vp);
+ sm_free(vp_tmp);
vp = tmp;
}
errno = ldapmap_geterrno(lmap->ldap_ld);
@@ -3502,7 +3527,7 @@ ldapmap_lookup(map, name, av, statp)
}
(void) ldap_abandon(lmap->ldap_ld, msgid);
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return NULL;
}
@@ -3532,7 +3557,7 @@ ldapmap_lookup(map, name, av, statp)
}
(void) ldap_abandon(lmap->ldap_ld, msgid);
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return NULL;
}
ldap_msgfree(lmap->ldap_res);
@@ -3557,7 +3582,7 @@ ldapmap_lookup(map, name, av, statp)
lmap->ldap_res = NULL;
}
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return NULL;
}
*statp = EX_OK;
@@ -3569,9 +3594,13 @@ ldapmap_lookup(map, name, av, statp)
errno = ldapmap_geterrno(lmap->ldap_ld);
if (errno != LDAP_SUCCESS)
{
+ int save_errno;
+
/* Must be an error */
if (ret != 0)
errno += E_LDAPBASE;
+ save_errno = errno;
+
if (!bitset(MF_OPTIONAL, map->map_mflags))
{
if (bitset(MF_NODEFER, map->map_mflags))
@@ -3583,7 +3612,16 @@ ldapmap_lookup(map, name, av, statp)
}
*statp = EX_TEMPFAIL;
if (vp != NULL)
- free(vp);
+ sm_free(vp);
+#ifdef LDAP_SERVER_DOWN
+ errno = save_errno;
+ if (errno == LDAP_SERVER_DOWN + E_LDAPBASE)
+ {
+ /* server disappeared, try reopen on next search */
+ ldapmap_close(map);
+ }
+#endif /* LDAP_SERVER_DOWN */
+ errno = save_errno;
return NULL;
}
@@ -3601,7 +3639,7 @@ ldapmap_lookup(map, name, av, statp)
if (bitset(MF_NOREWRITE, map->map_mflags))
{
if (vp != NULL)
- free(vp);
+ sm_free(vp);
return "";
}
@@ -3619,7 +3657,7 @@ ldapmap_lookup(map, name, av, statp)
result = map_rewrite(map, vp, strlen(vp), av);
}
if (vp != NULL)
- free(vp);
+ sm_free(vp);
}
return result;
}
@@ -3664,9 +3702,9 @@ ldapmap_findconn(lmap)
(lmap->ldap_binddn == NULL ? "" : lmap->ldap_binddn),
CONDELSE,
(lmap->ldap_secret == NULL ? "" : lmap->ldap_secret),
- getpid());
- s = stab(nbuf, ST_LDAP, ST_ENTER);
- free(nbuf);
+ (int) getpid());
+ s = stab(nbuf, ST_LMAP, ST_ENTER);
+ sm_free(nbuf);
return s;
}
/*
@@ -4309,6 +4347,7 @@ ldapmap_clear(lmap)
lmap->ldap_filter = NULL;
lmap->ldap_attr[0] = NULL;
lmap->ldap_res = NULL;
+ lmap->ldap_next = NULL;
}
/*
** LDAPMAP_SET_DEFAULTS -- Read default map spec from LDAPDefaults in .cf
@@ -4357,12 +4396,12 @@ ldapmap_set_defaults(spec)
syserr("readcf: option LDAPDefaultSpec: Do not set non-LDAP specific flags");
if (map.map_app != NULL)
{
- free(map.map_app);
+ sm_free(map.map_app);
map.map_app = NULL;
}
if (map.map_tapp != NULL)
{
- free(map.map_tapp);
+ sm_free(map.map_tapp);
map.map_tapp = NULL;
}
}
@@ -4594,9 +4633,16 @@ static jmp_buf PHTimeout;
/* ARGSUSED */
static void
-ph_timeout_func(sig_no)
- int sig_no;
+ph_timeout(sig)
+ int sig;
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
longjmp(PHTimeout, 1);
}
#else /* _FFR_PHMAP_TIMEOUT */
@@ -4695,7 +4741,7 @@ ph_map_open(map, mode)
# endif /* ETIMEDOUT */
goto ph_map_open_abort;
}
- ev = setevent(pmap->ph_timeout, ph_timeout_func, 0);
+ ev = setevent(pmap->ph_timeout, ph_timeout, 0);
}
if (!OpenQiSock(tmp, &(pmap->ph_sockfd)) &&
!Sock2FILEs(pmap->ph_sockfd, &(pmap->ph_to_server),
@@ -4714,7 +4760,7 @@ ph_map_open(map, mode)
{
if (fprintf(pmap->ph_to_server,
"id sendmail+phmap\n") < 0 ||
- fflush(pmap->ph_to_server) < 0 ||
+ fflush(pmap->ph_to_server) != 0 ||
(server_data = ReadQi(pmap->ph_from_server,
&j)) == NULL ||
server_data->code != 200)
@@ -4727,7 +4773,7 @@ ph_map_open(map, mode)
if (server_data != NULL)
FreeQIR(server_data);
#endif /* _FFR_PHMAP_TIMEOUT */
- free(hostlist);
+ sm_free(hostlist);
return TRUE;
}
#if _FFR_PHMAP_TIMEOUT
@@ -4759,7 +4805,7 @@ ph_map_open(map, mode)
sm_syslog(LOG_NOTICE, CurEnv->e_id,
"ph_map_open: %s: cannot connect to PH server",
map->map_mname);
- free(hostlist);
+ sm_free(hostlist);
return FALSE;
}
@@ -4814,7 +4860,7 @@ ph_map_lookup(map, key, args, pstat)
*pstat = EX_TEMPFAIL;
goto ph_map_lookup_abort;
}
- ev = setevent(pmap->ph_timeout, ph_timeout_func, 0);
+ ev = setevent(pmap->ph_timeout, ph_timeout, 0);
}
#endif /* _FFR_PHMAP_TIMEOUT */
@@ -4883,7 +4929,7 @@ ph_map_lookup(map, key, args, pstat)
if (fprintf(pmap->ph_to_server, "query %s=%s return email\n",
tmp2, fmtkey) < 0)
message = "qi query command failed";
- else if (fflush(pmap->ph_to_server) < 0)
+ else if (fflush(pmap->ph_to_server) != 0)
message = "qi fflush failed";
else if ((server_data = ReadQi(pmap->ph_from_server,
&j)) == NULL)
@@ -5271,6 +5317,7 @@ hes_map_lookup(map, name, av, statp)
{
char *np;
int nl;
+ int save_errno;
char nbuf[MAXNAME];
nl = strlen(name);
@@ -5285,8 +5332,10 @@ hes_map_lookup(map, name, av, statp)
# else /* HESIOD_INIT */
hp = hes_resolve(np, map->map_file);
# endif /* HESIOD_INIT */
+ save_errno = errno;
if (np != nbuf)
- free(np);
+ sm_free(np);
+ errno = save_errno;
}
else
{
@@ -5297,11 +5346,8 @@ hes_map_lookup(map, name, av, statp)
# endif /* HESIOD_INIT */
}
# ifdef HESIOD_INIT
- if (hp == NULL)
- return NULL;
- if (*hp == NULL)
+ if (hp == NULL || *hp == NULL)
{
- hesiod_free_list(HesiodContext, hp);
switch (errno)
{
case ENOENT:
@@ -5316,6 +5362,7 @@ hes_map_lookup(map, name, av, statp)
*statp = EX_UNAVAILABLE;
break;
}
+ hesiod_free_list(HesiodContext, hp);
return NULL;
}
# else /* HESIOD_INIT */
@@ -5413,7 +5460,7 @@ ni_map_lookup(map, name, av, statp)
res = map_rewrite(map, name, strlen(name), NULL);
else
res = map_rewrite(map, propval, strlen(propval), av);
- free(propval);
+ sm_free(propval);
return res;
}
@@ -5461,12 +5508,12 @@ ni_getcanonname(name, hbsize, statp)
if (hbsize >= strlen(vptr))
{
(void) strlcpy(name, vptr, hbsize);
- free(vptr);
+ sm_free(vptr);
*statp = EX_OK;
return TRUE;
}
*statp = EX_UNAVAILABLE;
- free(vptr);
+ sm_free(vptr);
return FALSE;
}
@@ -6352,7 +6399,7 @@ prog_map_lookup(map, name, av, statp)
if (bitset(MF_MATCHONLY, map->map_mflags))
rval = map_rewrite(map, name, strlen(name), NULL);
else
- rval = map_rewrite(map, buf, strlen(buf), NULL);
+ rval = map_rewrite(map, buf, strlen(buf), av);
/* now flush any additional output */
while ((i = read(fd, buf, sizeof buf)) > 0)
@@ -6543,8 +6590,9 @@ seq_map_close(map)
if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags))
continue;
+ mm->map_mflags |= MF_CLOSING;
mm->map_class->map_close(mm);
- mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
}
}
@@ -6892,8 +6940,8 @@ regex_map_init(map, ap)
(void) regerror(regerr, map_p->regex_pattern_buf,
errbuf, ERRBUF_SIZE);
syserr("pattern-compile-error: %s\n", errbuf);
- free(map_p->regex_pattern_buf);
- free(map_p);
+ sm_free(map_p->regex_pattern_buf);
+ sm_free(map_p);
return FALSE;
}
@@ -6919,8 +6967,8 @@ regex_map_init(map, ap)
if (substrings >= MAX_MATCH)
{
syserr("too many substrings, %d max\n", MAX_MATCH);
- free(map_p->regex_pattern_buf);
- free(map_p);
+ sm_free(map_p->regex_pattern_buf);
+ sm_free(map_p);
return FALSE;
}
if (sub_param != NULL && sub_param[0] != '\0')
@@ -6965,7 +7013,7 @@ regex_map_rewrite(map, s, slen, av)
if (bitset(MF_MATCHONLY, map->map_mflags))
return map_rewrite(map, av[0], strlen(av[0]), NULL);
else
- return map_rewrite(map, s, slen, NULL);
+ return map_rewrite(map, s, slen, av);
}
char *
@@ -7194,7 +7242,11 @@ nsd_map_lookup(map, name, av, statp)
*statp = EX_TEMPFAIL;
return NULL;
}
- if (r == NS_BADREQ || r == NS_NOPERM)
+ if (r == NS_BADREQ
+# ifdef NS_NOPERM
+ || r == NS_NOPERM
+# endif /* NS_NOPERM */
+ )
{
*statp = EX_CONFIG;
return NULL;
diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c
index 0698573..f4ce5b8 100644
--- a/contrib/sendmail/src/milter.c
+++ b/contrib/sendmail/src/milter.c
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: milter.c,v 8.50.4.44 2001/01/23 19:43:57 gshapiro Exp $";
+static char id[] = "@(#)$Id: milter.c,v 8.50.4.46 2001/05/11 18:11:36 gshapiro Exp $";
#endif /* ! lint */
#if _FFR_MILTER
@@ -62,7 +62,7 @@ static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
!isascii(response[2]) || !isdigit(response[2])) \
{ \
if (response != NULL) \
- free(response); \
+ sm_free(response); \
response = newstr(default); \
} \
else \
@@ -74,7 +74,7 @@ static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
{ \
if (*ptr == '%' && *++ptr != '%') \
{ \
- free(response); \
+ sm_free(response); \
response = newstr(default); \
break; \
} \
@@ -354,7 +354,7 @@ milter_read(m, cmd, rlen, to, e)
if (milter_sysread(m, buf, expl, to, e) == NULL)
{
- free(buf);
+ sm_free(buf);
return NULL;
}
@@ -1007,12 +1007,12 @@ milter_open(m, parseonly, e)
continue;
}
if (tTd(64, 5))
- dprintf("X%s: error connecting to filter\n",
- m->mf_name);
+ dprintf("X%s: error connecting to filter: %s\n",
+ m->mf_name, errstring(save_errno));
if (LogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "X%s: error connecting to filter",
- m->mf_name);
+ "X%s: error connecting to filter: %s",
+ m->mf_name, errstring(save_errno));
milter_error(m);
# if _FFR_FREEHOSTENT && NETINET6
if (hp != NULL)
@@ -1681,7 +1681,7 @@ milter_send_macros(m, macros, cmd, e)
}
(void) milter_write(m, SMFIC_MACRO, buf, s,
m->mf_timeout[SMFTO_WRITE], e);
- free(buf);
+ sm_free(buf);
}
/*
@@ -1836,7 +1836,7 @@ milter_send_command(m, command, data, sz, e, state)
if (*state != SMFIR_REPLYCODE &&
response != NULL)
{
- free(response);
+ sm_free(response);
response = NULL;
}
return response;
@@ -1970,7 +1970,7 @@ milter_negotiate(m, e)
"milter_negotiate(%s): returned %c instead of %c",
m->mf_name, rcmd, SMFIC_OPTNEG);
if (response != NULL)
- free(response);
+ sm_free(response);
milter_error(m);
return -1;
}
@@ -1986,7 +1986,7 @@ milter_negotiate(m, e)
"milter_negotiate(%s): did not return valid info",
m->mf_name);
if (response != NULL)
- free(response);
+ sm_free(response);
milter_error(m);
return -1;
}
@@ -2005,7 +2005,7 @@ milter_negotiate(m, e)
"milter_negotiate(%s): did not return enough info",
m->mf_name);
if (response != NULL)
- free(response);
+ sm_free(response);
milter_error(m);
return -1;
}
@@ -2014,7 +2014,7 @@ milter_negotiate(m, e)
MILTER_LEN_BYTES);
(void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
MILTER_LEN_BYTES);
- free(response);
+ sm_free(response);
response = NULL;
m->mf_fvers = ntohl(fvers);
@@ -2178,7 +2178,7 @@ milter_headers(m, e, state)
/* send it over */
response = milter_send_command(m, SMFIC_HEADER, buf,
s, e, state);
- free(buf);
+ sm_free(buf);
if (m->mf_state == SMFS_ERROR ||
m->mf_state == SMFS_DONE ||
*state != SMFIR_CONTINUE)
@@ -2280,7 +2280,7 @@ milter_body(m, e, state)
*state = SMFIR_TEMPFAIL;
if (response != NULL)
{
- free(response);
+ sm_free(response);
response = NULL;
}
}
@@ -2522,7 +2522,7 @@ milter_changeheader(response, rlen, e)
if (h != sysheader && h->h_value != NULL)
{
e->e_msgsize -= strlen(h->h_value);
- free(h->h_value);
+ sm_free(h->h_value);
}
if (*val == '\0')
@@ -2889,7 +2889,7 @@ milter_connect(hostname, addr, e, state)
response = milter_command(SMFIC_CONNECT, buf, s,
MilterConnectMacros, e, state);
- free(buf);
+ sm_free(buf);
/*
** If this message connection is done for,
@@ -2916,7 +2916,7 @@ milter_connect(hostname, addr, e, state)
*state = SMFIR_REJECT;
if (response != NULL)
{
- free(response);
+ sm_free(response);
response = NULL;
}
}
@@ -3042,7 +3042,7 @@ milter_envfrom(args, e, state)
/* send it over */
response = milter_command(SMFIC_MAIL, buf, s,
MilterEnvFromMacros, e, state);
- free(buf);
+ sm_free(buf);
/*
** If filter rejects/discards a per message command,
@@ -3106,7 +3106,7 @@ milter_envrcpt(args, e, state)
/* send it over */
response = milter_command(SMFIC_RCPT, buf, s,
MilterEnvRcptMacros, e, state);
- free(buf);
+ sm_free(buf);
return response;
}
/*
@@ -3382,7 +3382,7 @@ milter_data(e, state)
if (rcmd != SMFIR_REPLYCODE &&
response != NULL)
{
- free(response);
+ sm_free(response);
response = NULL;
}
@@ -3414,7 +3414,7 @@ finishup:
*state = SMFIR_TEMPFAIL;
if (response != NULL)
{
- free(response);
+ sm_free(response);
response = NULL;
}
}
@@ -3446,7 +3446,7 @@ finishup:
*state = SMFIR_TEMPFAIL;
if (response != NULL)
{
- free(response);
+ sm_free(response);
response = NULL;
}
}
diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c
index 0a2d8ad..adbb8b1 100644
--- a/contrib/sendmail/src/parseaddr.c
+++ b/contrib/sendmail/src/parseaddr.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: parseaddr.c,v 8.234.4.11 2001/02/14 04:07:27 gshapiro Exp $";
+static char id[] = "@(#)$Id: parseaddr.c,v 8.234.4.12 2001/05/03 17:24:11 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -1157,7 +1157,7 @@ rewrite(pvp, ruleset, reclevel, e)
if ((size_t) trsize > pvpb1_size)
{
if (pvpb1 != NULL)
- free(pvpb1);
+ sm_free(pvpb1);
pvpb1 = (char **)xalloc(trsize);
pvpb1_size = trsize;
}
@@ -1583,7 +1583,7 @@ map_lookup(smap, key, argvect, pstat, e)
if (i > rwbuflen)
{
if (rwbuf != NULL)
- free(rwbuf);
+ sm_free(rwbuf);
rwbuflen = i;
rwbuf = (char *) xalloc(rwbuflen);
}
@@ -2461,7 +2461,7 @@ maplocaluser(a, sendq, aliaslevel, e)
if (tTd(29, 9))
dprintf("maplocaluser: address unchanged\n");
if (a1 != NULL)
- free(a1);
+ sm_free(a1);
return;
}
@@ -2808,7 +2808,7 @@ rscheck(rwset, p1, p2, e, rmcomm, cnt, logl, host)
QuickAbort = saveQuickAbort;
setstat(rstat);
if (buf != buf0)
- free(buf);
+ sm_free(buf);
if (rstat != EX_OK && QuickAbort)
longjmp(TopFrame, 2);
diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c
index f94498e..6a66cf6 100644
--- a/contrib/sendmail/src/queue.c
+++ b/contrib/sendmail/src/queue.c
@@ -16,9 +16,9 @@
#ifndef lint
# if QUEUE
-static char id[] = "@(#)$Id: queue.c,v 8.343.4.44 2001/02/22 00:55:35 ca Exp $ (with queueing)";
+static char id[] = "@(#)$Id: queue.c,v 8.343.4.55 2001/05/03 23:37:11 gshapiro Exp $ (with queueing)";
# else /* QUEUE */
-static char id[] = "@(#)$Id: queue.c,v 8.343.4.44 2001/02/22 00:55:35 ca Exp $ (without queueing)";
+static char id[] = "@(#)$Id: queue.c,v 8.343.4.55 2001/05/03 23:37:11 gshapiro Exp $ (without queueing)";
# endif /* QUEUE */
#endif /* ! lint */
@@ -507,7 +507,7 @@ queueup(e, announce)
fprintf(tfp, ".\n");
- if (fflush(tfp) < 0 ||
+ if (fflush(tfp) != 0 ||
(SuperSafe && fsync(fileno(tfp)) < 0) ||
ferror(tfp))
{
@@ -793,6 +793,12 @@ run_single_queue(queuedir, forkflag, verbose)
return TRUE;
}
/* child -- clean up signals */
+
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
clrcontrol();
proc_list_clear();
@@ -801,8 +807,8 @@ run_single_queue(queuedir, forkflag, verbose)
PROC_QUEUE_CHILD);
(void) releasesignal(SIGCHLD);
(void) setsignal(SIGCHLD, SIG_DFL);
- (void) setsignal(SIGHUP, intsig);
-
+ (void) setsignal(SIGHUP, SIG_DFL);
+ (void) setsignal(SIGTERM, intsig);
}
sm_setproctitle(TRUE, CurEnv, "running queue: %s",
@@ -811,7 +817,7 @@ run_single_queue(queuedir, forkflag, verbose)
if (LogLevel > 69 || tTd(63, 99))
sm_syslog(LOG_DEBUG, NOQID,
"runqueue %s, pid=%d, forkflag=%d",
- qid_printqueue(queuedir), getpid(), forkflag);
+ qid_printqueue(queuedir), (int) getpid(), forkflag);
/*
** Release any resources used by the daemon code.
@@ -953,10 +959,10 @@ run_single_queue(queuedir, forkflag, verbose)
if (pid != 0)
(void) waitfor(pid);
}
- free(w->w_name);
+ sm_free(w->w_name);
if (w->w_host)
- free(w->w_host);
- free((char *) w);
+ sm_free(w->w_host);
+ sm_free((char *) w);
}
/* exit without the usual cleanup */
@@ -969,6 +975,16 @@ run_single_queue(queuedir, forkflag, verbose)
/*
** RUNQUEUEEVENT -- stub for use in setevent
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
*/
static void
@@ -1061,10 +1077,10 @@ orderq(queuedir, doall)
register WORK *nw = w->w_next;
WorkQ = nw;
- free(w->w_name);
+ sm_free(w->w_name);
if (w->w_host != NULL)
- free(w->w_host);
- free((char *) w);
+ sm_free(w->w_host);
+ sm_free((char *) w);
w = nw;
}
@@ -1312,9 +1328,9 @@ orderq(queuedir, doall)
/* don't even bother sorting this job in */
if (tTd(41, 49))
dprintf("skipping %s (%x)\n", w->w_name, i);
- free(w->w_name);
+ sm_free(w->w_name);
if (w->w_host)
- free(w->w_host);
+ sm_free(w->w_host);
wn--;
}
}
@@ -1415,7 +1431,7 @@ orderq(queuedir, doall)
WorkQ = w;
}
if (WorkList != NULL)
- free(WorkList);
+ sm_free(WorkList);
WorkList = NULL;
WorkListSize = 0;
@@ -1464,8 +1480,8 @@ grow_wlist(queuedir)
else
{
int newsize = WorkListSize + QUEUESEGSIZE;
- WORK *newlist = (WORK *) realloc((char *)WorkList,
- (unsigned)sizeof(WORK) * (newsize + 1));
+ WORK *newlist = (WORK *) xrealloc((char *)WorkList,
+ (unsigned)sizeof(WORK) * (newsize + 1));
if (newlist != NULL)
{
@@ -1762,6 +1778,11 @@ dowork(queuedir, id, forkflag, requeueflag, e)
** can recover on interrupt.
*/
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
/* set basic modes, etc. */
(void) alarm(0);
clearstats();
@@ -1782,7 +1803,7 @@ dowork(queuedir, id, forkflag, requeueflag, e)
if (LogLevel > 76)
sm_syslog(LOG_DEBUG, e->e_id,
"dowork, pid=%d",
- getpid());
+ (int) getpid());
/* don't use the headers from sendmail.cf... */
e->e_header = NULL;
@@ -1838,7 +1859,7 @@ readqf(e)
{
register FILE *qfp;
ADDRESS *ctladdr;
- struct stat st;
+ struct stat st, stf;
char *bp;
int qfver = 0;
long hdrsize = 0;
@@ -1883,19 +1904,59 @@ readqf(e)
}
/*
- ** Check the queue file for plausibility to avoid attacks.
+ ** Prevent locking race condition.
+ **
+ ** Process A: readqf(): qfp = fopen(qffile)
+ ** Process B: queueup(): rename(tf, qf)
+ ** Process B: unlocks(tf)
+ ** Process A: lockfile(qf);
+ **
+ ** Process A (us) has the old qf file (before the rename deleted
+ ** the directory entry) and will be delivering based on old data.
+ ** This can lead to multiple deliveries of the same recipients.
+ **
+ ** Catch this by checking if the underlying qf file has changed
+ ** *after* acquiring our lock and if so, act as though the file
+ ** was still locked (i.e., just return like the lockfile() case
+ ** above.
*/
- if (fstat(fileno(qfp), &st) < 0)
+ if (stat(qf, &stf) < 0 ||
+ fstat(fileno(qfp), &st) < 0)
{
/* must have been being processed by someone else */
if (tTd(40, 8))
- dprintf("readqf(%s): fstat failure (%s)\n",
+ dprintf("readqf(%s): [f]stat failure (%s)\n",
qf, errstring(errno));
(void) fclose(qfp);
return FALSE;
}
+ if (st.st_nlink != stf.st_nlink ||
+ st.st_dev != stf.st_dev ||
+ st.st_ino != stf.st_ino ||
+# if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
+ st.st_gen != stf.st_gen ||
+# endif /* HAS_ST_GEN && 0 */
+ st.st_uid != stf.st_uid ||
+ st.st_gid != stf.st_gid ||
+ st.st_size != stf.st_size)
+ {
+ /* changed after opened */
+ if (Verbose)
+ printf("%s: changed\n", e->e_id);
+ if (tTd(40, 8))
+ dprintf("%s: changed\n", e->e_id);
+ if (LogLevel > 19)
+ sm_syslog(LOG_DEBUG, e->e_id, "changed");
+ (void) fclose(qfp);
+ return FALSE;
+ }
+
+ /*
+ ** Check the queue file for plausibility to avoid attacks.
+ */
+
qsafe = S_IWOTH|S_IWGRP;
#if _FFR_QUEUE_FILE_MODE
if (bitset(S_IWGRP, QueueFileMode))
@@ -2243,7 +2304,7 @@ readqf(e)
}
if (bp != buf)
- free(bp);
+ sm_free(bp);
}
/*
@@ -2351,7 +2412,11 @@ printqueue()
int i, nrequests = 0;
for (i = 0; i < NumQueues; i++)
+ {
+ if (StopRequest)
+ stop_sendmail();
nrequests += print_single_queue(i);
+ }
if (NumQueues > 1)
printf("\t\tTotal Requests: %d\n", nrequests);
}
@@ -2467,6 +2532,9 @@ print_single_queue(queuedir)
char bodytype[MAXNAME + 1];
char qf[MAXPATHLEN];
+ if (StopRequest)
+ stop_sendmail();
+
printf("%12s", w->w_name + 2);
(void) snprintf(qf, sizeof qf, "%s/%s", qd, w->w_name);
f = fopen(qf, "r");
@@ -2499,6 +2567,9 @@ print_single_queue(queuedir)
register int i;
register char *p;
+ if (StopRequest)
+ stop_sendmail();
+
fixcrlf(buf, TRUE);
switch (buf[0])
{
@@ -2680,7 +2751,8 @@ queuename(e, type)
** none.
*/
-static char Base60Code[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx";
+static const char QueueIdChars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx";
+# define QIC_LEN 60
void
assign_queueid(e)
@@ -2696,7 +2768,7 @@ assign_queueid(e)
return;
/* see if we need to get a new base time/pid */
- if (cX >= 60 || LastQueueTime == 0 || LastQueuePid != pid)
+ if (cX >= QIC_LEN || LastQueueTime == 0 || LastQueuePid != pid)
{
time_t then = LastQueueTime;
@@ -2714,16 +2786,16 @@ assign_queueid(e)
}
if (tTd(7, 50))
dprintf("assign_queueid: random_offset = %ld (%d)\n",
- random_offset, (int)(cX + random_offset) % 60);
+ random_offset, (int)(cX + random_offset) % QIC_LEN);
tm = gmtime(&LastQueueTime);
- idbuf[0] = Base60Code[tm->tm_year % 60];
- idbuf[1] = Base60Code[tm->tm_mon];
- idbuf[2] = Base60Code[tm->tm_mday];
- idbuf[3] = Base60Code[tm->tm_hour];
- idbuf[4] = Base60Code[tm->tm_min];
- idbuf[5] = Base60Code[tm->tm_sec];
- idbuf[6] = Base60Code[((int)cX++ + random_offset) % 60];
+ idbuf[0] = QueueIdChars[tm->tm_year % QIC_LEN];
+ idbuf[1] = QueueIdChars[tm->tm_mon];
+ idbuf[2] = QueueIdChars[tm->tm_mday];
+ idbuf[3] = QueueIdChars[tm->tm_hour];
+ idbuf[4] = QueueIdChars[tm->tm_min];
+ idbuf[5] = QueueIdChars[tm->tm_sec];
+ idbuf[6] = QueueIdChars[((int)cX++ + random_offset) % QIC_LEN];
(void) snprintf(&idbuf[7], sizeof idbuf - 7, "%05d",
(int) LastQueuePid);
e->e_id = newstr(idbuf);
@@ -3056,7 +3128,7 @@ chkqdir(name, sff)
/* skip over . and .. directories */
if (name[0] == '.' &&
- (name[1] == '\0' || (name[2] == '.' && name[3] == '\0')))
+ (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
return FALSE;
# if HASLSTAT
if (lstat(name, &statb) < 0)
@@ -3137,9 +3209,9 @@ multiqueue_cache()
for (i = 0; i < NumQueues; i++)
{
if (QPaths[i].qp_name != NULL)
- (void) free(QPaths[i].qp_name);
+ sm_free(QPaths[i].qp_name);
}
- (void) free((char *)QPaths);
+ sm_free((char *)QPaths);
QPaths = NULL;
NumQueues = 0;
}
@@ -3232,9 +3304,9 @@ multiqueue_cache()
}
else if (slotsleft < 1)
{
- QPaths = (QPATHS *)realloc((char *)QPaths,
- (sizeof *QPaths) *
- (NumQueues + 10));
+ QPaths = (QPATHS *)xrealloc((char *)QPaths,
+ (sizeof *QPaths) *
+ (NumQueues + 10));
if (QPaths == NULL)
{
(void) closedir(dp);
diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c
index fa99423..f8aefd1 100644
--- a/contrib/sendmail/src/readcf.c
+++ b/contrib/sendmail/src/readcf.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: readcf.c,v 8.382.4.38 2001/02/17 00:05:12 geir Exp $";
+static char id[] = "@(#)$Id: readcf.c,v 8.382.4.40 2001/05/03 17:24:13 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -148,7 +148,7 @@ readcf(cfname, safe, e)
if (bp[0] == '#')
{
if (bp != buf)
- free(bp);
+ sm_free(bp);
continue;
}
@@ -545,7 +545,7 @@ readcf(cfname, safe, e)
syserr("unknown configuration line \"%s\"", bp);
}
if (bp != buf)
- free(bp);
+ sm_free(bp);
}
if (ferror(cf))
{
@@ -1269,7 +1269,7 @@ makemailer(line)
if (s->s_mailer != NULL)
{
i = s->s_mailer->m_mno;
- free(s->s_mailer);
+ sm_free(s->s_mailer);
}
else
{
@@ -1548,9 +1548,7 @@ static struct optioninfo
{ "RemoteMode", '>', OI_NONE },
#endif /* defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) */
{ "SevenBitInput", '7', OI_SAFE },
-#if MIME8TO7
{ "EightBitMode", '8', OI_SAFE },
-#endif /* MIME8TO7 */
{ "AliasFile", 'A', OI_NONE },
{ "AliasWait", 'a', OI_NONE },
{ "BlankSub", 'B', OI_NONE },
@@ -1898,8 +1896,8 @@ setoption(opt, val, safe, sticky, e)
SevenBitInput = atobool(val);
break;
-#if MIME8TO7
case '8': /* handling of 8-bit input */
+#if MIME8TO7
switch (*val)
{
case 'm': /* convert 8-bit, convert MIME */
@@ -1936,8 +1934,10 @@ setoption(opt, val, safe, sticky, e)
syserr("Unknown 8-bit mode %c", *val);
finis(FALSE, EX_USAGE);
}
- break;
+#else /* MIME8TO7 */
+ printf("Warning: Option EightBitMode requires MIME8TO7 support\n");
#endif /* MIME8TO7 */
+ break;
case 'A': /* set default alias file */
if (val[0] == '\0')
@@ -2641,7 +2641,7 @@ setoption(opt, val, safe, sticky, e)
case O_PIDFILE:
if (PidFile != NULL)
- free(PidFile);
+ sm_free(PidFile);
PidFile = newstr(val);
break;
@@ -2688,7 +2688,7 @@ setoption(opt, val, safe, sticky, e)
case O_DEADLETTER:
if (DeadLetterDrop != NULL)
- free(DeadLetterDrop);
+ sm_free(DeadLetterDrop);
DeadLetterDrop = newstr(val);
break;
@@ -2778,7 +2778,7 @@ setoption(opt, val, safe, sticky, e)
case O_CONTROLSOCKET:
if (ControlSocketName != NULL)
- free(ControlSocketName);
+ sm_free(ControlSocketName);
ControlSocketName = newstr(val);
break;
@@ -2792,7 +2792,7 @@ setoption(opt, val, safe, sticky, e)
case O_PROCTITLEPREFIX:
if (ProcTitlePrefix != NULL)
- free(ProcTitlePrefix);
+ sm_free(ProcTitlePrefix);
ProcTitlePrefix = newstr(val);
break;
@@ -2818,13 +2818,13 @@ setoption(opt, val, safe, sticky, e)
}
#endif /* _FFR_ALLOW_SASLINFO */
if (SASLInfo != NULL)
- free(SASLInfo);
+ sm_free(SASLInfo);
SASLInfo = newstr(val);
break;
case O_SASLMECH:
if (AuthMechanisms != NULL)
- free(AuthMechanisms);
+ sm_free(AuthMechanisms);
if (*val != '\0')
AuthMechanisms = newstr(val);
else
@@ -2886,63 +2886,63 @@ setoption(opt, val, safe, sticky, e)
#if STARTTLS
case O_SRVCERTFILE:
if (SrvCERTfile != NULL)
- free(SrvCERTfile);
+ sm_free(SrvCERTfile);
SrvCERTfile = newstr(val);
break;
case O_SRVKEYFILE:
if (Srvkeyfile != NULL)
- free(Srvkeyfile);
+ sm_free(Srvkeyfile);
Srvkeyfile = newstr(val);
break;
case O_CLTCERTFILE:
if (CltCERTfile != NULL)
- free(CltCERTfile);
+ sm_free(CltCERTfile);
CltCERTfile = newstr(val);
break;
case O_CLTKEYFILE:
if (Cltkeyfile != NULL)
- free(Cltkeyfile);
+ sm_free(Cltkeyfile);
Cltkeyfile = newstr(val);
break;
case O_CACERTFILE:
if (CACERTfile != NULL)
- free(CACERTfile);
+ sm_free(CACERTfile);
CACERTfile = newstr(val);
break;
case O_CACERTPATH:
if (CACERTpath != NULL)
- free(CACERTpath);
+ sm_free(CACERTpath);
CACERTpath = newstr(val);
break;
case O_DHPARAMS:
if (DHParams != NULL)
- free(DHParams);
+ sm_free(DHParams);
DHParams = newstr(val);
break;
# if _FFR_TLS_1
case O_DHPARAMS5:
if (DHParams5 != NULL)
- free(DHParams5);
+ sm_free(DHParams5);
DHParams5 = newstr(val);
break;
case O_CIPHERLIST:
if (CipherList != NULL)
- free(CipherList);
+ sm_free(CipherList);
CipherList = newstr(val);
break;
# endif /* _FFR_TLS_1 */
case O_RANDFILE:
if (RandFile != NULL)
- free(RandFile);
+ sm_free(RandFile);
RandFile= newstr(val);
break;
@@ -3272,7 +3272,7 @@ strtorwset(p, endp, stabmode)
char *h = NULL;
if (RuleSetNames[ruleset] != NULL)
- free(RuleSetNames[ruleset]);
+ sm_free(RuleSetNames[ruleset]);
if (delim != '\0' && (h = strchr(q, delim)) != NULL)
*h = '\0';
RuleSetNames[ruleset] = newstr(q);
diff --git a/contrib/sendmail/src/recipient.c b/contrib/sendmail/src/recipient.c
index 258e7e2..bfed632 100644
--- a/contrib/sendmail/src/recipient.c
+++ b/contrib/sendmail/src/recipient.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: recipient.c,v 8.231.14.10 2001/02/14 04:07:30 gshapiro Exp $";
+static char id[] = "@(#)$Id: recipient.c,v 8.231.14.11 2001/05/03 17:24:14 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -185,7 +185,7 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e)
e->e_to = oldto;
if (bufp != buf)
- free(bufp);
+ sm_free(bufp);
#if _FFR_ADDR_TYPE
define(macid("{addr_type}", NULL), NULL, e);
#endif /* _FFR_ADDR_TYPE */
@@ -293,7 +293,7 @@ removefromlist(list, sendq, e)
e->e_to = oldto;
if (bufp != buf)
- free(bufp);
+ sm_free(bufp);
#if _FFR_ADDR_TYPE
define(macid("{addr_type}", NULL), NULL, e);
#endif /* _FFR_ADDR_TYPE */
@@ -780,7 +780,7 @@ recipient(a, sendq, aliaslevel, e)
done:
a->q_flags |= QTHISPASS;
if (buf != buf0)
- free(buf);
+ sm_free(buf);
/*
** If we are at the top level, check to see if this has
@@ -1573,6 +1573,13 @@ resetuid:
static void
includetimeout()
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
longjmp(CtxIncludeTimeout, 1);
}
/*
diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h
index ffb0b33..17f379f 100644
--- a/contrib/sendmail/src/sendmail.h
+++ b/contrib/sendmail/src/sendmail.h
@@ -20,7 +20,7 @@
#ifdef _DEFINE
# define EXTERN
# ifndef lint
-static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.50 2001/02/22 18:56:24 gshapiro Exp $";
+static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.64 2001/05/23 17:49:13 ca Exp $";
# endif /* ! lint */
#else /* _DEFINE */
# define EXTERN extern
@@ -881,6 +881,7 @@ MAP
#define MF_DEFER 0x00080000 /* don't lookup map in defer mode */
#define MF_SINGLEMATCH 0x00100000 /* successful only if match one key */
#define MF_NOREWRITE 0x00200000 /* don't rewrite result, return as-is */
+#define MF_CLOSING 0x00400000 /* map is being closed */
#define DYNOPENMAP(map) if (!bitset(MF_OPEN, (map)->map_mflags)) \
{ \
@@ -969,6 +970,9 @@ struct ldapmap_struct
/* args for ldap_result */
struct timeval ldap_timeout;
LDAPMessage *ldap_res;
+
+ /* Linked list of maps sharing the same LDAP binding */
+ MAP *ldap_next;
};
typedef struct ldapmap_struct LDAPMAP_STRUCT;
@@ -1076,7 +1080,7 @@ struct symtab
struct hdrinfo sv_header; /* header metainfo */
char *sv_service[MAXMAPSTACK]; /* service switch */
#ifdef LDAPMAP
- LDAP *sv_ldap; /* LDAP connection */
+ MAP *sv_lmap; /* Maps for LDAP connection */
#endif /* LDAPMAP */
#if _FFR_MILTER
struct milter *sv_milter; /* milter filter name */
@@ -1101,7 +1105,7 @@ typedef struct symtab STAB;
#define ST_SERVICE 11 /* service switch entry */
#define ST_HEADER 12 /* special header flags */
#ifdef LDAPMAP
-# define ST_LDAP 13 /* LDAP connection */
+# define ST_LMAP 13 /* List head of maps for LDAP connection */
#endif /* LDAPMAP */
#if _FFR_MILTER
# define ST_MILTER 14 /* milter filter */
@@ -1122,7 +1126,7 @@ typedef struct symtab STAB;
#define s_service s_value.sv_service
#define s_header s_value.sv_header
#ifdef LDAPMAP
-# define s_ldap s_value.sv_ldap
+# define s_lmap s_value.sv_lmap
#endif /* LDAPMAP */
#if _FFR_MILTER
# define s_milter s_value.sv_milter
@@ -1151,7 +1155,7 @@ struct event
void (*ev_func)__P((int));
/* function to call */
int ev_arg; /* argument to ev_func */
- int ev_pid; /* pid that set this event */
+ pid_t ev_pid; /* pid that set this event */
struct event *ev_link; /* link to next item */
};
@@ -1161,6 +1165,7 @@ typedef struct event EVENT;
extern void clrevent __P((EVENT *));
extern void clear_events __P((void));
extern EVENT *setevent __P((time_t, void(*)(), int));
+extern EVENT *sigsafe_setevent __P((time_t, void(*)(), int));
/*
** Operation, send, error, and MIME modes
@@ -1626,6 +1631,51 @@ extern void inittimeouts __P((char *, bool));
/* variables */
extern u_char tTdvect[100]; /* trace vector */
/*
+** Critical signal sections
+*/
+
+#define PEND_SIGHUP 0x0001
+#define PEND_SIGINT 0x0002
+#define PEND_SIGTERM 0x0004
+#define PEND_SIGUSR1 0x0008
+
+#define ENTER_CRITICAL() InCriticalSection++
+
+#define LEAVE_CRITICAL() \
+do \
+{ \
+ if (InCriticalSection > 0) \
+ InCriticalSection--; \
+} while (0)
+
+#define CHECK_CRITICAL(sig) \
+{ \
+ if (InCriticalSection > 0 && (sig) != 0) \
+ { \
+ pend_signal((sig)); \
+ return SIGFUNC_RETURN; \
+ } \
+}
+
+/* reset signal in case System V semantics */
+#ifdef SYS5SIGNALS
+# define FIX_SYSV_SIGNAL(sig, handler) \
+{ \
+ if ((sig) != 0) \
+ (void) setsignal((sig), (handler)); \
+}
+#else /* SYS5SIGNALS */
+# define FIX_SYSV_SIGNAL(sig, handler) { /* EMPTY */ }
+#endif /* SYS5SIGNALS */
+
+/* variables */
+EXTERN u_int volatile InCriticalSection; /* >0 if in a critical section */
+EXTERN int volatile PendingSignal; /* pending signal to resend */
+
+/* functions */
+extern void pend_signal __P((int));
+
+ /*
** Miscellaneous information.
*/
@@ -1662,9 +1712,9 @@ EXTERN bool CheckAliases; /* parse addresses during newaliases */
EXTERN bool ChownAlwaysSafe; /* treat chown(2) as safe */
EXTERN bool ColonOkInAddr; /* single colon legal in address */
EXTERN bool ConfigFileRead; /* configuration file has been read */
-EXTERN bool DataProgress; /* have we sent anything since last check */
+EXTERN bool volatile DataProgress; /* have we sent anything since last check */
EXTERN bool DisConnected; /* running with OutChannel redirected to xf */
-EXTERN bool DoQueueRun; /* non-interrupt time queue run needed */
+EXTERN bool volatile DoQueueRun; /* non-interrupt time queue run needed */
EXTERN bool DontExpandCnames; /* do not $[...$] expand CNAMEs */
EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */
EXTERN bool DontLockReadFiles; /* don't read lock support files */
@@ -1693,6 +1743,7 @@ EXTERN bool SendMIMEErrors; /* send error messages in MIME format */
EXTERN bool SevenBitInput; /* force 7-bit data on input */
EXTERN bool SingleLineFromHeader; /* force From: header to be one line */
EXTERN bool SingleThreadDelivery; /* single thread hosts on delivery */
+EXTERN bool volatile StopRequest; /* stop sending output */
EXTERN bool SuperSafe; /* be extra careful, even if expensive */
EXTERN bool SuprErrs; /* set if we are suppressing errors */
EXTERN bool TryNullMXList; /* if we are the best MX, try host directly */
@@ -1708,7 +1759,7 @@ EXTERN char SpaceSub; /* substitution for <lwsp> */
EXTERN int CheckpointInterval; /* queue file checkpoint interval */
EXTERN int ConfigLevel; /* config file level */
EXTERN int ConnRateThrottle; /* throttle for SMTP connection rate */
-EXTERN int CurChildren; /* current number of daemonic children */
+EXTERN int volatile CurChildren; /* current number of daemonic children */
EXTERN int CurrentLA; /* current load average */
EXTERN int DefaultNotify; /* default DSN notification flags */
EXTERN int Errors; /* set if errors (local to single pass) */
@@ -1813,9 +1864,11 @@ EXTERN time_t QueueMaxDelay; /* maximum queue delay */
#endif /* _FFR_QUEUEDELAY */
EXTERN char *RealHostName; /* name of host we are talking to */
EXTERN char *RealUserName; /* real user name of caller */
+EXTERN char *volatile RestartRequest;/* a sendmail restart has been requested */
EXTERN char *RunAsUserName; /* user to become for bulk of run */
EXTERN char *SafeFileEnv; /* chroot location for file delivery */
EXTERN char *ServiceSwitchFile; /* backup service switch */
+EXTERN char *volatile ShutdownRequest;/* a sendmail shutdown has been requested */
EXTERN char *SmtpGreeting; /* SMTP greeting message (old $e macro) */
EXTERN char *SmtpPhase; /* current phase in SMTP processing */
EXTERN char SmtpError[MAXLINE]; /* save failure error messages */
@@ -1825,6 +1878,7 @@ EXTERN char *UdbSpec; /* user database source spec */
EXTERN char *UnixFromLine; /* UNIX From_ line (old $l macro) */
EXTERN char **ExternalEnviron; /* input environment */
/* saved user environment */
+EXTERN char **SaveArgv; /* argument vector for re-execing */
EXTERN BITMAP256 DontBlameSendmail; /* DontBlameSendmail bits */
#if SFIO
EXTERN Sfio_t *InChannel; /* input connection */
@@ -1838,7 +1892,6 @@ EXTERN FILE *TrafficLogFile; /* file in which to log all traffic */
EXTERN void *HesiodContext;
#endif /* HESIOD */
EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */
-EXTERN EVENT *EventQueue; /* head of event queue */
EXTERN MAILER *LocalMailer; /* ptr to local mailer */
EXTERN MAILER *ProgMailer; /* ptr to program mailer */
EXTERN MAILER *FileMailer; /* ptr to *file* mailer */
@@ -1876,6 +1929,7 @@ extern int sasl_encode64 __P((const char *, unsigned, char *, unsigned, unsigned
#if STARTTLS
extern void apps_ssl_info_cb __P((SSL *, int , int));
+extern bool init_tls_library __P((void));
extern bool inittls __P((SSL_CTX **, u_long, bool, char *, char *, char *, char *, char *));
extern bool initclttls __P((void));
extern bool initsrvtls __P((void));
@@ -1972,6 +2026,7 @@ extern char *milter_data __P((ENVELOPE *, char *));
#endif /* _FFR_MILTER */
extern char *addquotes __P((char *));
+extern void allsignals __P((bool));
extern char *arpadate __P((char *));
extern bool atobool __P((char *));
extern int atooct __P((char *));
@@ -1998,7 +2053,7 @@ extern char *defcharset __P((ENVELOPE *));
extern char *denlstring __P((char *, bool, bool));
extern void disconnect __P((int, ENVELOPE *));
extern bool dns_getcanonname __P((char *, int, bool, int *));
-extern int dofork __P((void));
+extern pid_t dofork __P((void));
extern int drop_privileges __P((bool));
extern int dsntoexitstat __P((char *));
extern void dumpfd __P((int, bool, bool));
@@ -2012,6 +2067,11 @@ extern struct passwd *finduser __P((char *, bool *));
extern void finis __P((bool, volatile int));
extern void fixcrlf __P((char *, bool));
extern long freediskspace __P((char *, long *));
+#if NETINET6 && NEEDSGETIPNODE
+# if _FFR_FREEHOSTENT
+extern void freehostent __P((struct hostent *));
+# endif /* _FFR_FREEHOSTENT */
+#endif /* NEEDSGETIPNODE && NETINET6 */
extern char *get_column __P((char *, int, int, char *, int));
extern char *getauthinfo __P((int, bool *));
extern char *getcfname __P((void));
@@ -2026,7 +2086,6 @@ extern void inithostmaps __P((void));
extern void initmacros __P((ENVELOPE *));
extern void initsetproctitle __P((int, char **, char **));
extern void init_vendor_macros __P((ENVELOPE *));
-extern SIGFUNC_DECL intindebug __P((int));
extern SIGFUNC_DECL intsig __P((int));
extern bool isloopback __P((SOCKADDR sa));
extern void load_if_names __P((void));
@@ -2046,11 +2105,10 @@ extern void printmailer __P((MAILER *));
extern void printopenfds __P((bool));
extern void printqueue __P((void));
extern void printrules __P((void));
-extern int prog_open __P((char **, int *, ENVELOPE *));
+extern pid_t prog_open __P((char **, int *, ENVELOPE *));
extern void putline __P((char *, MCI *));
extern void putxline __P((char *, size_t, MCI *, int));
extern void queueup_macros __P((int, FILE *, ENVELOPE *));
-extern SIGFUNC_DECL quiesce __P((int));
extern void readcf __P((char *, bool, ENVELOPE *));
extern SIGFUNC_DECL reapchild __P((int));
extern int releasesignal __P((int));
@@ -2072,9 +2130,9 @@ extern char *sfgets __P((char *, int, FILE *, time_t, char *));
extern char *shortenstring __P((const char *, int));
extern char *shorten_hostname __P((char []));
extern bool shorten_rfc822_string __P((char *, size_t));
-extern SIGFUNC_DECL sigusr1 __P((int));
-extern SIGFUNC_DECL sighup __P((int));
+extern void shutdown_daemon __P((void));
extern void sm_dopr __P((char *, const char *, va_list));
+extern void sm_free __P((void *));
extern struct hostent *sm_gethostbyname __P((char *, int));
extern struct hostent *sm_gethostbyaddr __P((char *, int, int));
extern int sm_getla __P((ENVELOPE *));
@@ -2082,13 +2140,13 @@ extern struct passwd *sm_getpwnam __P((char *));
extern struct passwd *sm_getpwuid __P((UID_T));
extern void sm_setproctitle __P((bool, ENVELOPE *, const char *, ...));
extern int sm_strcasecmp __P((const char *, const char *));
+extern void stop_sendmail __P((void));
extern bool strcontainedin __P((char *, char *));
extern void stripquotes __P((char *));
extern int switch_map_find __P((char *, char *[], short []));
extern bool transienterror __P((int));
extern void tTflag __P((char *));
extern void tTsetup __P((u_char *, int, char *));
-extern SIGFUNC_DECL tick __P((int));
extern char *ttypath __P((void));
extern void unlockqueue __P((ENVELOPE *));
#if !HASUNSETENV
@@ -2101,6 +2159,8 @@ extern void vendor_pre_defaults __P((ENVELOPE *));
extern int waitfor __P((pid_t));
extern bool writable __P((char *, ADDRESS *, long));
extern char *xalloc __P((int));
+extern char *xcalloc __P((size_t, size_t));
+extern char *xrealloc __P((void *, size_t));
extern void xputs __P((const char *));
extern char *xtextify __P((char *, char *));
extern bool xtextok __P((char *));
diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c
index c09e4e8..17e90be 100644
--- a/contrib/sendmail/src/sfsasl.c
+++ b/contrib/sendmail/src/sfsasl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -9,7 +9,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: sfsasl.c,v 8.17.4.13 2000/11/03 00:24:49 gshapiro Exp $";
+static char id[] = "@(#)$Id: sfsasl.c,v 8.17.4.14 2001/05/03 17:24:16 gshapiro Exp $";
#endif /* ! lint */
#if SFIO
@@ -28,7 +28,7 @@ static char id[] = "@(#)$Id: sfsasl.c,v 8.17.4.13 2000/11/03 00:24:49 gshapiro E
# include "sfsasl.h"
/* how to deallocate a buffer allocated by SASL */
-# define SASL_DEALLOC(b) free(b)
+# define SASL_DEALLOC(b) sm_free(b)
static ssize_t
sasl_read(f, buf, size, disc)
@@ -134,14 +134,8 @@ sfdcsasl(fin, fout, conn)
return 0;
}
- if ((saslin = (Sasldisc_t *) malloc(sizeof(Sasldisc_t))) == NULL)
- return -1;
- if ((saslout = (Sasldisc_t *) malloc(sizeof(Sasldisc_t))) == NULL)
- {
- free(saslin);
- return -1;
- }
-
+ saslin = (Sasldisc_t *) xalloc(sizeof(Sasldisc_t));
+ saslout = (Sasldisc_t *) xalloc(sizeof(Sasldisc_t));
saslin->disc.readf = sasl_read;
saslin->disc.writef = sasl_write;
saslin->disc.seekf = NULL;
@@ -158,8 +152,8 @@ sfdcsasl(fin, fout, conn)
if (sfdisc(fin, (Sfdisc_t *) saslin) != (Sfdisc_t *) saslin ||
sfdisc(fout, (Sfdisc_t *) saslout) != (Sfdisc_t *) saslout)
{
- free(saslin);
- free(saslout);
+ sm_free(saslin);
+ sm_free(saslout);
return -1;
}
return 0;
@@ -310,7 +304,7 @@ tls_close(cookie)
tc->fp = NULL;
}
- free(tc);
+ sm_free(tc);
return retval;
}
# endif /* !SFIO */
@@ -336,14 +330,8 @@ sfdctls(fin, fout, con)
if (con == NULL)
return 0;
- if ((tlsin = (Tlsdisc_t *) malloc(sizeof(Tlsdisc_t))) == NULL)
- return -1;
- if ((tlsout = (Tlsdisc_t *) malloc(sizeof(Tlsdisc_t))) == NULL)
- {
- free(tlsin);
- return -1;
- }
-
+ tlsin = (Tlsdisc_t *) xalloc(sizeof(Tlsdisc_t));
+ tlsout = (Tlsdisc_t *) xalloc(sizeof(Tlsdisc_t));
# if SFIO
tlsin->disc.readf = tls_read;
tlsin->disc.writef = tls_write;
@@ -362,15 +350,15 @@ sfdctls(fin, fout, con)
if (rfd < 0 || wfd < 0 ||
SSL_set_rfd(con, rfd) <= 0 || SSL_set_wfd(con, wfd) <= 0)
{
- free(tlsin);
- free(tlsout);
+ sm_free(tlsin);
+ sm_free(tlsout);
return -1;
}
if (sfdisc(fin, (Sfdisc_t *) tlsin) != (Sfdisc_t *) tlsin ||
sfdisc(fout, (Sfdisc_t *) tlsout) != (Sfdisc_t *) tlsout)
{
- free(tlsin);
- free(tlsout);
+ sm_free(tlsin);
+ sm_free(tlsout);
return -1;
}
# else /* SFIO */
@@ -379,7 +367,7 @@ sfdctls(fin, fout, con)
fp = funopen(tlsin, tls_read, tls_write, NULL, tls_close);
if (fp == NULL)
{
- free(tlsin);
+ sm_free(tlsin);
return -1;
}
*fin = fp;
@@ -396,7 +384,7 @@ sfdctls(fin, fout, con)
tlsin->fp = NULL;
fclose(*fin);
*fin = save;
- free(tlsout);
+ sm_free(tlsout);
return -1;
}
*fout = fp;
diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c
index 72d22c0..f655565 100644
--- a/contrib/sendmail/src/srvrsmtp.c
+++ b/contrib/sendmail/src/srvrsmtp.c
@@ -16,9 +16,9 @@
#ifndef lint
# if SMTP
-static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.67 2001/01/07 19:31:05 gshapiro Exp $ (with SMTP)";
+static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.77 2001/05/27 22:20:30 gshapiro Exp $ (with SMTP)";
# else /* SMTP */
-static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.67 2001/01/07 19:31:05 gshapiro Exp $ (without SMTP)";
+static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.77 2001/05/27 22:20:30 gshapiro Exp $ (without SMTP)";
# endif /* SMTP */
#endif /* ! lint */
@@ -44,7 +44,7 @@ static SSL_CTX *srv_ctx = NULL;
# if !TLS_NO_RSA
static RSA *rsa = NULL;
# endif /* !TLS_NO_RSA */
-static bool tls_ok = FALSE;
+static bool tls_ok_srv = FALSE;
static int tls_verify_cb __P((X509_STORE_CTX *));
# if !TLS_NO_RSA
# define RSA_KEYLENGTH 512
@@ -966,7 +966,7 @@ smtp(nullserver, d_flags, e)
message("503 5.5.0 TLS not available");
break;
}
- if (!tls_ok)
+ if (!tls_ok_srv)
{
message("454 4.3.3 TLS not available after start");
break;
@@ -1038,7 +1038,7 @@ smtp(nullserver, d_flags, e)
if (LogLevel > 9)
tlslogerr();
}
- tls_ok = FALSE;
+ tls_ok_srv = FALSE;
SSL_free(srv_ssl);
srv_ssl = NULL;
@@ -1080,7 +1080,7 @@ smtp(nullserver, d_flags, e)
QuickAbort = saveQuickAbort;
SuprErrs = saveSuprErrs;
- tls_ok = FALSE; /* don't offer STARTTLS again */
+ tls_ok_srv = FALSE; /* don't offer STARTTLS again */
gothello = FALSE; /* discard info */
n_helo = 0;
OneXact = TRUE; /* only one xaction this run */
@@ -1100,7 +1100,7 @@ smtp(nullserver, d_flags, e)
sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
&ext_ssf) == SASL_OK;
if (mechlist != NULL)
- free(mechlist);
+ sm_free(mechlist);
mechlist = NULL;
if (sasl_ok)
{
@@ -1301,7 +1301,7 @@ smtp(nullserver, d_flags, e)
message("250-AUTH %s", mechlist);
# endif /* SASL */
# if STARTTLS
- if (tls_ok && usetls)
+ if (tls_ok_srv && usetls)
message("250-STARTTLS");
# endif /* STARTTLS */
message("250 HELP");
@@ -1525,7 +1525,8 @@ smtp(nullserver, d_flags, e)
goto undo_subproc_no_pm;
if (MaxMessageSize > 0 &&
- (e->e_msgsize > MaxMessageSize || e->e_msgsize < 0))
+ (e->e_msgsize > MaxMessageSize ||
+ e->e_msgsize < 0))
{
usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
MaxMessageSize);
@@ -1567,7 +1568,7 @@ smtp(nullserver, d_flags, e)
break;
}
if (response != NULL)
- free(response);
+ sm_free(response);
}
# endif /* _FFR_MILTER */
if (Errors > 0)
@@ -1745,7 +1746,7 @@ smtp(nullserver, d_flags, e)
break;
}
if (response != NULL)
- free(response);
+ sm_free(response);
}
# endif /* _FFR_MILTER */
@@ -1847,7 +1848,7 @@ smtp(nullserver, d_flags, e)
break;
}
if (response != NULL)
- free(response);
+ sm_free(response);
}
/* abort message filters that didn't get the body */
@@ -1858,7 +1859,7 @@ smtp(nullserver, d_flags, e)
/* redefine message size */
if ((q = macvalue(macid("{msg_size}", NULL), e))
!= NULL)
- free(q);
+ sm_free(q);
snprintf(inp, sizeof inp, "%ld", e->e_msgsize);
define(macid("{msg_size}", NULL), newstr(inp), e);
if (Errors > 0)
@@ -2163,16 +2164,12 @@ smtp(nullserver, d_flags, e)
else
*--id = '@';
- if ((new = (QUEUE_CHAR *)malloc(sizeof(QUEUE_CHAR))) == NULL)
- {
- syserr("500 5.5.0 ETRN out of memory");
- break;
- }
+ new = (QUEUE_CHAR *)xalloc(sizeof(QUEUE_CHAR));
new->queue_match = id;
new->queue_next = NULL;
QueueLimitRecipient = new;
ok = runqueue(TRUE, FALSE);
- free(QueueLimitRecipient);
+ sm_free(QueueLimitRecipient);
QueueLimitRecipient = NULL;
if (ok && Errors == 0)
message("250 2.0.0 Queuing for node %s started", p);
@@ -2357,8 +2354,8 @@ checksmtpattack(pcounter, maxcount, waitnow, cname, e)
if (*pcounter == maxcount && LogLevel > 5)
{
sm_syslog(LOG_INFO, e->e_id,
- "%.100s: %.40s attack?",
- CurSmtpClient, cname);
+ "%.100s: possible SMTP attack: command=%.40s, count=%d",
+ CurSmtpClient, cname, *pcounter);
}
s = 1 << (*pcounter - maxcount);
if (s >= MAXTIMEOUT)
@@ -2604,7 +2601,8 @@ mail_esmtp_args(kp, vp, e)
dprintf("auth=\"%.100s\" trusted\n", pbuf);
e->e_auth_param = newstr(auth_param);
}
- free(auth_param);
+ sm_free(auth_param);
+
/* reset values */
Errors = 0;
QuickAbort = saveQuickAbort;
@@ -2848,6 +2846,12 @@ runinchild(label, e)
/* child */
InChild = TRUE;
QuickAbort = FALSE;
+
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
clearstats();
clearenvelope(e, FALSE);
assign_queueid(e);
@@ -2992,7 +2996,6 @@ tls_rand_init(randfile, logl)
{
# ifndef HASURANDOMDEV
/* not required if /dev/urandom exists, OpenSSL does it internally */
-
#define RF_OK 0 /* randfile OK */
#define RF_MISS 1 /* randfile == NULL || *randfile == '\0' */
#define RF_UNKNOWN 2 /* unknown prefix for randfile */
@@ -3017,7 +3020,7 @@ tls_rand_init(randfile, logl)
ok = FALSE;
done = RI_FAIL;
randdef = (randfile == NULL || *randfile == '\0') ? RF_MISS : RF_OK;
-# if EGD
+# if EGD
if (randdef == RF_OK && strncasecmp(randfile, "egd:", 4) == 0)
{
randfile += 4;
@@ -3031,7 +3034,7 @@ tls_rand_init(randfile, logl)
ok = TRUE;
}
else
-# endif /* EGD */
+# endif /* EGD */
if (randdef == RF_OK && strncasecmp(randfile, "file:", 5) == 0)
{
int fd;
@@ -3288,7 +3291,39 @@ tls_safe_f(var, sff)
else if (req) \
ok = FALSE; \
}
+ /*
+** INIT_TLS_LIBRARY -- calls functions which setup TLS library for global use
+**
+** Parameters:
+** none.
+**
+** Returns:
+** succeeded?
+**
+** Side Effects:
+** Sets tls_ok_srv static, even when called from main()
+*/
+
+bool
+init_tls_library()
+{
+ /*
+ ** basic TLS initialization
+ ** ignore result for now
+ */
+
+ SSL_library_init();
+ SSL_load_error_strings();
+# if 0
+ /* this is currently a macro for SSL_library_init */
+ SSLeay_add_ssl_algorithms();
+# endif /* 0 */
+
+ /* initialize PRNG */
+ tls_ok_srv = tls_rand_init(RandFile, 7);
+ return tls_ok_srv;
+}
/*
** INITTLS -- initialize TLS
**
@@ -3471,6 +3506,8 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
"TLS: error: SSL_CTX_new(SSLv23_server_method()) failed");
+ if (LogLevel > 9)
+ tlslogerr();
return FALSE;
}
}
@@ -3481,6 +3518,8 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
"TLS: error: SSL_CTX_new(SSLv23_client_method()) failed");
+ if (LogLevel > 9)
+ tlslogerr();
return FALSE;
}
}
@@ -3802,15 +3841,18 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
**
** Returns:
** succeeded?
+**
+** Side Effects:
+** sets tls_ok_srv static, even when called from main()
*/
bool
initsrvtls()
{
- tls_ok = inittls(&srv_ctx, TLS_I_SRV, TRUE, SrvCERTfile, Srvkeyfile,
- CACERTpath, CACERTfile, DHParams);
- return tls_ok;
+ tls_ok_srv = inittls(&srv_ctx, TLS_I_SRV, TRUE, SrvCERTfile,
+ Srvkeyfile, CACERTpath, CACERTfile, DHParams);
+ return tls_ok_srv;
}
/*
** TLS_GET_INFO -- get information about TLS connection
diff --git a/contrib/sendmail/src/stab.c b/contrib/sendmail/src/stab.c
index 1249f9d..82775bc 100644
--- a/contrib/sendmail/src/stab.c
+++ b/contrib/sendmail/src/stab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: stab.c,v 8.40.16.3 2000/10/09 02:46:12 gshapiro Exp $";
+static char id[] = "@(#)$Id: stab.c,v 8.40.16.7 2001/05/07 22:06:41 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -160,8 +160,8 @@ stab(name, type, op)
break;
#ifdef LDAPMAP
- case ST_LDAP:
- len = sizeof s->s_ldap;
+ case ST_LMAP:
+ len = sizeof s->s_lmap;
break;
#endif /* LDAPMAP */
diff --git a/contrib/sendmail/src/udb.c b/contrib/sendmail/src/udb.c
index 9b8ccd0..d835326 100644
--- a/contrib/sendmail/src/udb.c
+++ b/contrib/sendmail/src/udb.c
@@ -15,9 +15,9 @@
#ifndef lint
# if USERDB
-static char id[] = "@(#)$Id: udb.c,v 8.111.16.1 2001/01/04 18:18:37 gshapiro Exp $ (with USERDB)";
+static char id[] = "@(#)$Id: udb.c,v 8.111.16.2 2001/05/03 17:24:17 gshapiro Exp $ (with USERDB)";
# else /* USERDB */
-static char id[] = "@(#)$Id: udb.c,v 8.111.16.1 2001/01/04 18:18:37 gshapiro Exp $ (without USERDB)";
+static char id[] = "@(#)$Id: udb.c,v 8.111.16.2 2001/05/03 17:24:17 gshapiro Exp $ (without USERDB)";
# endif /* USERDB */
#endif /* ! lint */
@@ -290,7 +290,7 @@ udbexpand(a, sendq, aliaslevel, e)
memmove(nuser, user, usersize);
if (user != userbuf)
- free(user);
+ sm_free(user);
user = nuser;
usersize += size;
userleft += size;
@@ -545,7 +545,7 @@ udbexpand(a, sendq, aliaslevel, e)
break;
}
if (user != userbuf)
- free(user);
+ sm_free(user);
}
return EX_OK;
}
@@ -1055,11 +1055,11 @@ _udbx_init(e)
errstring(errno));
up->udb_type = UDB_EOLIST;
if (up->udb_dbname != spec)
- free(up->udb_dbname);
+ sm_free(up->udb_dbname);
goto tempfail;
}
if (up->udb_dbname != spec)
- free(up->udb_dbname);
+ sm_free(up->udb_dbname);
break;
}
if (tTd(28, 1))
diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c
index 83034dc..a1aeac5 100644
--- a/contrib/sendmail/src/usersmtp.c
+++ b/contrib/sendmail/src/usersmtp.c
@@ -15,9 +15,9 @@
#ifndef lint
# if SMTP
-static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.24 2001/02/21 00:59:09 gshapiro Exp $ (with SMTP)";
+static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.33 2001/05/23 18:53:09 ca Exp $ (with SMTP)";
# else /* SMTP */
-static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.24 2001/02/21 00:59:09 gshapiro Exp $ (without SMTP)";
+static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.33 2001/05/23 18:53:09 ca Exp $ (without SMTP)";
# endif /* SMTP */
#endif /* ! lint */
@@ -199,7 +199,8 @@ tryhelo:
{
syserr("553 5.3.5 %s config error: mail loops back to me (MX problem?)",
CurHostName);
- mci_setstat(mci, EX_CONFIG, "5.3.5", "system config error");
+ mci_setstat(mci, EX_CONFIG, "5.3.5",
+ "553 5.3.5 system config error");
mci->mci_errno = 0;
smtpquit(m, mci, e);
return;
@@ -303,15 +304,9 @@ str_union(s1, s2)
l1 = strlen(s1);
l2 = strlen(s2);
rl = l1 + l2;
- res = (char *)malloc(rl + 2);
- if (res == NULL)
- {
- if (l1 > l2)
- return s1;
- return s2;
- }
+ res = (char *)xalloc(rl + 2);
(void) strlcpy(res, s1, rl);
- hr = res;
+ hr = res + l1;
h1 = s2;
h = s2;
@@ -374,7 +369,7 @@ helo_options(line, firstline, m, mci, e)
{
# if SASL
if (mci->mci_saslcap != NULL)
- free(mci->mci_saslcap);
+ sm_free(mci->mci_saslcap);
mci->mci_saslcap = NULL;
# endif /* SASL */
return;
@@ -424,7 +419,7 @@ helo_options(line, firstline, m, mci, e)
h = mci->mci_saslcap;
mci->mci_saslcap = str_union(h, p);
if (h != mci->mci_saslcap)
- free(h);
+ sm_free(h);
mci->mci_flags |= MCIF_AUTH;
}
else
@@ -432,14 +427,9 @@ helo_options(line, firstline, m, mci, e)
int l;
l = strlen(p) + 1;
- mci->mci_saslcap = (char *)malloc(l);
-
- /* XXX this may be leaked */
- if (mci->mci_saslcap != NULL)
- {
- (void) strlcpy(mci->mci_saslcap, p, l);
- mci->mci_flags |= MCIF_AUTH;
- }
+ mci->mci_saslcap = (char *)xalloc(l);
+ (void) strlcpy(mci->mci_saslcap, p, l);
+ mci->mci_flags |= MCIF_AUTH;
}
}
}
@@ -501,7 +491,7 @@ getsasldata(line, firstline, m, mci, e)
{
if (mci->mci_sasl_string_len <= len)
{
- free(mci->mci_sasl_string);
+ sm_free(mci->mci_sasl_string);
mci->mci_sasl_string = xalloc(len + 1);
}
}
@@ -511,7 +501,7 @@ getsasldata(line, firstline, m, mci, e)
memcpy(mci->mci_sasl_string, out, len);
mci->mci_sasl_string[len] = '\0';
mci->mci_sasl_string_len = len;
- free(out);
+ sm_free(out);
return;
}
@@ -728,7 +718,8 @@ getsimple(context, id, result, len)
** workaround: don't free() it here
** this can cause a memory leak!
*/
- free(authid);
+
+ sm_free(authid);
# endif /* SASL > 10522 */
authid = NULL;
addedrealm = addrealm;
@@ -804,9 +795,7 @@ getsecret(conn, context, id, psecret)
authpass = newstr(h);
}
len = strlen(authpass);
- *psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len + 1);
- if (*psecret == NULL)
- return SASL_FAIL;
+ *psecret = (sasl_secret_t *) xalloc(sizeof(sasl_secret_t) + len + 1);
(void) strlcpy((*psecret)->data, authpass, len + 1);
(*psecret)->len = len;
return SASL_OK;
@@ -1057,9 +1046,7 @@ intersect(s1, s2)
l1 = strlen(s1);
l2 = strlen(s2);
rl = min(l1, l2);
- res = (char *)malloc(rl + 1);
- if (res == NULL)
- return NULL;
+ res = (char *)xalloc(rl + 1);
*res = '\0';
if (rl == 0) /* at least one string empty? */
return res;
@@ -1751,6 +1738,7 @@ smtprcpt(to, m, mci, e)
*/
static jmp_buf CtxDataTimeout;
+static EVENT *volatile DataTimeout = NULL;
int
smtpdata(m, mci, e)
@@ -1759,13 +1747,13 @@ smtpdata(m, mci, e)
register ENVELOPE *e;
{
register int r;
- register EVENT *ev;
int rstat;
int xstat;
time_t timeout;
char *enhsc;
enhsc = NULL;
+
/*
** Send the data.
** First send the command and check that it is ok.
@@ -1840,27 +1828,29 @@ smtpdata(m, mci, e)
else
timeout = DATA_PROGRESS_TIMEOUT;
- ev = setevent(timeout, datatimeout, 0);
+ DataTimeout = setevent(timeout, datatimeout, 0);
- if (tTd(18, 101))
- {
- /* simulate a DATA timeout */
- (void) sleep(1);
- }
-
/*
** Output the actual message.
*/
(*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
+
+ if (tTd(18, 101))
+ {
+ /* simulate a DATA timeout */
+ (void) sleep(2);
+ }
+
(*e->e_putbody)(mci, e, NULL);
/*
** Cleanup after sending message.
*/
- clrevent(ev);
+ if (DataTimeout != NULL)
+ clrevent(DataTimeout);
# if _FFR_CATCH_BROKEN_MTAS
{
@@ -1938,7 +1928,7 @@ smtpdata(m, mci, e)
mci_setstat(mci, xstat, ENHSCN(enhsc, smtptodsn(r)),
SmtpReplyBuffer);
if (e->e_statmsg != NULL)
- free(e->e_statmsg);
+ sm_free(e->e_statmsg);
if (bitset(MCIF_ENHSTAT, mci->mci_flags) &&
(r = isenhsc(SmtpReplyBuffer + 4, ' ')) > 0)
r += 5;
@@ -1963,10 +1953,17 @@ smtpdata(m, mci, e)
static void
datatimeout()
{
+ int save_errno = errno;
+
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
if (DataProgress)
{
time_t timeout;
- register EVENT *ev;
/* check back again later */
if (tTd(18, 101))
@@ -1977,14 +1974,24 @@ datatimeout()
else
timeout = DATA_PROGRESS_TIMEOUT;
+ /* reset the timeout */
+ DataTimeout = sigsafe_setevent(timeout, datatimeout, 0);
DataProgress = FALSE;
- ev = setevent(timeout, datatimeout, 0);
}
else
{
- /* no progress, give up */
+ /* event is done */
+ DataTimeout = NULL;
+ }
+
+ /* if no progress was made or problem resetting event, die now */
+ if (DataTimeout == NULL)
+ {
+ errno = ETIMEDOUT;
longjmp(CtxDataTimeout, 1);
}
+
+ errno = save_errno;
}
/*
** SMTPGETSTAT -- get status code from DATA in LMTP
@@ -2027,7 +2034,7 @@ smtpgetstat(m, mci, e)
else
status = EX_PROTOCOL;
if (e->e_statmsg != NULL)
- free(e->e_statmsg);
+ sm_free(e->e_statmsg);
if (bitset(MCIF_ENHSTAT, mci->mci_flags) &&
(r = isenhsc(SmtpReplyBuffer + 4, ' ')) > 0)
r += 5;
diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c
index 6b301cb..f023865 100644
--- a/contrib/sendmail/src/util.c
+++ b/contrib/sendmail/src/util.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: util.c,v 8.225.2.1.2.19 2001/02/22 18:56:24 gshapiro Exp $";
+static char id[] = "@(#)$Id: util.c,v 8.225.2.1.2.23 2001/05/17 18:10:18 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
@@ -378,15 +378,122 @@ xalloc(sz)
if (sz <= 0)
sz = 1;
+ ENTER_CRITICAL();
p = malloc((unsigned) sz);
+ LEAVE_CRITICAL();
if (p == NULL)
{
syserr("!Out of memory!!");
- /* exit(EX_UNAVAILABLE); */
+
+ /* NOTREACHED */
+ exit(EX_UNAVAILABLE);
+ }
+ return p;
+}
+ /*
+** XREALLOC -- Reallocate memory and bitch wildly on failure.
+**
+** THIS IS A CLUDGE. This should be made to give a proper
+** error -- but after all, what can we do?
+**
+** Parameters:
+** ptr -- original area.
+** sz -- size of new area to allocate.
+**
+** Returns:
+** pointer to data region.
+**
+** Side Effects:
+** Memory is allocated.
+*/
+
+char *
+xrealloc(ptr, sz)
+ void *ptr;
+ size_t sz;
+{
+ register char *p;
+
+ /* some systems can't handle size zero mallocs */
+ if (sz <= 0)
+ sz = 1;
+
+ ENTER_CRITICAL();
+ p = realloc(ptr, (unsigned) sz);
+ LEAVE_CRITICAL();
+ if (p == NULL)
+ {
+ syserr("!Out of memory!!");
+
+ /* NOTREACHED */
+ exit(EX_UNAVAILABLE);
}
return p;
}
/*
+** XCALLOC -- Allocate memory and bitch wildly on failure.
+**
+** THIS IS A CLUDGE. This should be made to give a proper
+** error -- but after all, what can we do?
+**
+** Parameters:
+** num -- number of items to allocate
+** sz -- size of new area to allocate.
+**
+** Returns:
+** pointer to data region.
+**
+** Side Effects:
+** Memory is allocated.
+*/
+
+char *
+xcalloc(num, sz)
+ size_t num;
+ size_t sz;
+{
+ register char *p;
+
+ /* some systems can't handle size zero mallocs */
+ if (num <= 0)
+ num = 1;
+ if (sz <= 0)
+ sz = 1;
+
+ ENTER_CRITICAL();
+ p = calloc((unsigned) num, (unsigned) sz);
+ LEAVE_CRITICAL();
+ if (p == NULL)
+ {
+ syserr("!Out of memory!!");
+
+ /* NOTREACHED */
+ exit(EX_UNAVAILABLE);
+ }
+ return p;
+}
+ /*
+** SM_FREE -- Free memory safely.
+**
+** Parameters:
+** ptr -- area to free
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Memory is freed.
+*/
+
+void
+sm_free(ptr)
+ void *ptr;
+{
+ ENTER_CRITICAL();
+ free(ptr);
+ LEAVE_CRITICAL();
+}
+ /*
** COPYPLIST -- copy list of pointers.
**
** This routine is the equivalent of newstr for lists of
@@ -502,13 +609,13 @@ log_sendmail_pid(e)
}
else
{
- long pid;
+ pid_t pid;
extern char *CommandLineArgs;
- pid = (long) getpid();
+ pid = getpid();
/* write the process id on line 1 */
- fprintf(pidf, "%ld\n", pid);
+ fprintf(pidf, "%ld\n", (long) pid);
/* line 2 contains all command line flags */
fprintf(pidf, "%s\n", CommandLineArgs);
@@ -1212,6 +1319,13 @@ static void
readtimeout(timeout)
time_t timeout;
{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
longjmp(CtxReadTimeout, 1);
}
/*
@@ -1271,7 +1385,7 @@ fgetfolded(buf, n, f)
memmove(nbp, bp, p - bp);
p = &nbp[p - bp];
if (bp != buf)
- free(bp);
+ sm_free(bp);
bp = nbp;
n = nn - (p - bp);
}
@@ -1836,13 +1950,13 @@ shorten_hostname(host)
** pid of the process -- -1 if it failed.
*/
-int
+pid_t
prog_open(argv, pfd, e)
char **argv;
int *pfd;
ENVELOPE *e;
{
- int pid;
+ pid_t pid;
int i;
int save_errno;
int fdv[2];
@@ -1874,6 +1988,11 @@ prog_open(argv, pfd, e)
/* child -- close stdin */
(void) close(0);
+ /* Reset global flags */
+ RestartRequest = NULL;
+ ShutdownRequest = NULL;
+ PendingSignal = 0;
+
/* stdout goes back to parent */
(void) close(fdv[0]);
if (dup2(fdv[1], 1) < 0)
@@ -2119,7 +2238,7 @@ denlstring(s, strict, logattacks)
{
/* allocate more space */
if (bp != NULL)
- free(bp);
+ sm_free(bp);
bp = xalloc(l);
bl = l;
}
@@ -2199,7 +2318,7 @@ path_is_dir(pathname, createflag)
** none
*/
-static struct procs *ProcListVec = NULL;
+static struct procs *volatile ProcListVec = NULL;
static int ProcListSize = 0;
void
@@ -2238,7 +2357,7 @@ proc_list_add(pid, task, type)
{
memmove(npv, ProcListVec,
ProcListSize * sizeof (struct procs));
- free(ProcListVec);
+ sm_free(ProcListVec);
}
for (i = ProcListSize; i < ProcListSize + PROC_LIST_SEG; i++)
{
@@ -2252,7 +2371,7 @@ proc_list_add(pid, task, type)
}
ProcListVec[i].proc_pid = pid;
if (ProcListVec[i].proc_task != NULL)
- free(ProcListVec[i].proc_task);
+ sm_free(ProcListVec[i].proc_task);
ProcListVec[i].proc_task = newstr(task);
ProcListVec[i].proc_type = type;
@@ -2283,7 +2402,7 @@ proc_list_set(pid, task)
if (ProcListVec[i].proc_pid == pid)
{
if (ProcListVec[i].proc_task != NULL)
- free(ProcListVec[i].proc_task);
+ sm_free(ProcListVec[i].proc_task);
ProcListVec[i].proc_task = newstr(task);
break;
}
@@ -2297,6 +2416,10 @@ proc_list_set(pid, task)
**
** Returns:
** type of process
+**
+** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+** DOING.
*/
int
diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c
index 60a42c6..3b4c4e8 100644
--- a/contrib/sendmail/src/version.c
+++ b/contrib/sendmail/src/version.c
@@ -12,7 +12,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: version.c,v 8.43.4.30 2001/02/27 19:22:31 gshapiro Exp $";
+static char id[] = "@(#)$Id: version.c,v 8.43.4.33 2001/05/27 21:39:21 gshapiro Exp $";
#endif /* ! lint */
-char Version[] = "8.11.3";
+char Version[] = "8.11.4";
diff --git a/contrib/sendmail/vacation/vacation.c b/contrib/sendmail/vacation/vacation.c
index b58b87e..42ae04f 100644
--- a/contrib/sendmail/vacation/vacation.c
+++ b/contrib/sendmail/vacation/vacation.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1987, 1993
* The Regents of the University of California. All rights reserved.
@@ -13,7 +13,7 @@
#ifndef lint
static char copyright[] =
-"@(#) Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.\n\
+"@(#) Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.\n\
All rights reserved.\n\
Copyright (c) 1983, 1987, 1993\n\
The Regents of the University of California. All rights reserved.\n\
@@ -21,9 +21,10 @@ static char copyright[] =
#endif /* ! lint */
#ifndef lint
-static char id[] = "@(#)$Id: vacation.c,v 8.68.4.16 2001/02/14 05:02:21 gshapiro Exp $";
+static char id[] = "@(#)$Id: vacation.c,v 8.68.4.21 2001/05/07 22:06:41 gshapiro Exp $";
#endif /* ! lint */
+
#include <ctype.h>
#include <stdlib.h>
#include <syslog.h>
@@ -113,12 +114,16 @@ static void eatmsg __P((void));
eatmsg(); \
return excode; \
}
+
int
main(argc, argv)
int argc;
char **argv;
{
bool iflag, emptysender, exclude;
+#if _FFR_BLACKBOX
+ bool runasuser = FALSE;
+#endif /* _FFR_BLACKBOX */
#if _FFR_LISTDB
bool lflag = FALSE;
#endif /* _FFR_LISTDB */
@@ -129,8 +134,8 @@ main(argc, argv)
time_t interval;
struct passwd *pw;
ALIAS *cur;
- char *dbfilename = VDB;
- char *msgfilename = VMSG;
+ char *dbfilename = NULL;
+ char *msgfilename = NULL;
char *name;
SMDB_USER_INFO user_info;
static char rnamebuf[MAXNAME];
@@ -173,11 +178,11 @@ main(argc, argv)
"Unknown UID %d", (int) RealUid);
RunAsUserName = RealUserName = rnamebuf;
-#ifdef LOG_MAIL
+# ifdef LOG_MAIL
openlog("vacation", LOG_PID, LOG_MAIL);
-#else /* LOG_MAIL */
+# else /* LOG_MAIL */
openlog("vacation", LOG_PID);
-#endif /* LOG_MAIL */
+# endif /* LOG_MAIL */
opterr = 0;
iflag = FALSE;
@@ -186,19 +191,7 @@ main(argc, argv)
interval = INTERVAL_UNDEF;
*From = '\0';
-#if _FFR_DEBUG && _FFR_LISTDB
-# define OPTIONS "a:df:Iilm:r:s:t:xz"
-#else /* _FFR_DEBUG && _FFR_LISTDB */
-# if _FFR_DEBUG
-# define OPTIONS "a:df:Iim:r:s:t:xz"
-# else /* _FFR_DEBUG */
-# if _FFR_LISTDB
-# define OPTIONS "a:f:Iilm:r:s:t:xz"
-# else /* _FFR_LISTDB */
-# define OPTIONS "a:f:Iim:r:s:t:xz"
-# endif /* _FFR_LISTDB */
-# endif /* _FFR_DEBUG */
-#endif /* _FFR_DEBUG && _FFR_LISTDB */
+#define OPTIONS "a:df:Iilm:r:s:t:Uxz"
while (mfail == 0 && ufail == 0 &&
(ch = getopt(argc, argv, OPTIONS)) != -1)
@@ -218,12 +211,11 @@ main(argc, argv)
break;
#if _FFR_DEBUG
- case 'd': /* debug mode */
+ case 'd': /* debug mode */
msglog = &debuglog;
break;
#endif /* _FFR_DEBUG */
-
case 'f': /* alternate database */
dbfilename = optarg;
break;
@@ -261,6 +253,12 @@ main(argc, argv)
case 't': /* SunOS: -t1d (default expire) */
break;
+#if _FFR_BLACKBOX
+ case 'U': /* run as single user mode */
+ runasuser = TRUE;
+ break;
+#endif /* _FFR_BLACKBOX */
+
case 'x':
exclude = TRUE;
break;
@@ -301,34 +299,67 @@ main(argc, argv)
"vacation: no such user uid %u.\n", getuid());
EXITM(EX_NOUSER);
}
+ name = pw->pw_name;
+ user_info.smdbu_id = pw->pw_uid;
+ user_info.smdbu_group_id = pw->pw_gid;
+ (void) strlcpy(user_info.smdbu_name, pw->pw_name,
+ SMDB_MAX_USER_NAME_LEN);
+ if (chdir(pw->pw_dir) != 0)
+ {
+ msglog(LOG_NOTICE, "vacation: no such directory %s.\n",
+ pw->pw_dir);
+ EXITM(EX_NOINPUT);
+ }
}
#if _FFR_BLACKBOX
- name = *argv;
-#else /* _FFR_BLACKBOX */
+ else if (runasuser)
+ {
+ name = *argv;
+ if (dbfilename == NULL || msgfilename == NULL)
+ {
+ msglog(LOG_NOTICE,
+ "vacation: -U requires setting both -f and -m\n");
+ EXITM(EX_NOINPUT);
+ }
+ user_info.smdbu_id = pw->pw_uid;
+ user_info.smdbu_group_id = pw->pw_gid;
+ (void) strlcpy(user_info.smdbu_name, pw->pw_name,
+ SMDB_MAX_USER_NAME_LEN);
+ }
+#endif /* _FFR_BLACKBOX */
else if ((pw = getpwnam(*argv)) == NULL)
{
msglog(LOG_ERR, "vacation: no such user %s.\n", *argv);
EXITM(EX_NOUSER);
}
- name = pw->pw_name;
- if (chdir(pw->pw_dir) != 0)
+ else
{
- msglog(LOG_NOTICE,
- "vacation: no such directory %s.\n", pw->pw_dir);
- EXITM(EX_NOINPUT);
+ name = pw->pw_name;
+ if (chdir(pw->pw_dir) != 0)
+ {
+ msglog(LOG_NOTICE, "vacation: no such directory %s.\n",
+ pw->pw_dir);
+ EXITM(EX_NOINPUT);
+ }
+ user_info.smdbu_id = pw->pw_uid;
+ user_info.smdbu_group_id = pw->pw_gid;
+ (void) strlcpy(user_info.smdbu_name, pw->pw_name,
+ SMDB_MAX_USER_NAME_LEN);
}
-#endif /* _FFR_BLACKBOX */
- user_info.smdbu_id = pw->pw_uid;
- user_info.smdbu_group_id = pw->pw_gid;
- (void) strlcpy(user_info.smdbu_name, pw->pw_name,
- SMDB_MAX_USER_NAME_LEN);
+
+ if (dbfilename == NULL)
+ dbfilename = VDB;
+ if (msgfilename == NULL)
+ msgfilename = VMSG;
sff = SFF_CREAT;
#if _FFR_BLACKBOX
if (getegid() != getgid())
+ {
+ /* Allow a set-group-id vacation binary */
RunAsGid = user_info.smdbu_group_id = getegid();
-
- sff |= SFF_NOPATHCHECK|SFF_OPENASROOT;
+ sff |= SFF_NOPATHCHECK|SFF_OPENASROOT;
+ }
#endif /* _FFR_BLACKBOX */
result = smdb_open_database(&Db, dbfilename,
@@ -407,6 +438,7 @@ main(argc, argv)
** nothing.
**
*/
+
static void
eatmsg()
{
@@ -562,6 +594,7 @@ findme:
** is name a substring of str?
**
*/
+
bool
nsearch(name, str)
register char *name, *str;
@@ -737,7 +770,6 @@ junkmail(from)
cur->len) == 0)
return TRUE;
}
-
return FALSE;
}
@@ -754,6 +786,7 @@ junkmail(from)
** TRUE iff user has gotten a vacation message recently.
**
*/
+
bool
recent()
{
@@ -815,6 +848,7 @@ recent()
** Side Effects:
** stores the reply interval in database.
*/
+
void
setinterval(interval)
time_t interval;
@@ -845,6 +879,7 @@ setinterval(interval)
** Side Effects:
** stores user/time in database.
*/
+
void
setreply(from, when)
char *from;
@@ -875,6 +910,7 @@ setreply(from, when)
** Side Effects:
** stores users in database.
*/
+
void
xclude(f)
FILE *f;
@@ -906,6 +942,7 @@ xclude(f)
** Side Effects:
** sends vacation reply.
*/
+
void
sendmessage(myname, msgfn, emptysender)
char *myname;
@@ -915,6 +952,7 @@ sendmessage(myname, msgfn, emptysender)
FILE *mfp, *sfp;
int i;
int pvect[2];
+ char *pv[8];
char buf[MAXLINE];
mfp = fopen(msgfn, "r");
@@ -932,6 +970,16 @@ sendmessage(myname, msgfn, emptysender)
msglog(LOG_ERR, "vacation: pipe: %s", errstring(errno));
exit(EX_OSERR);
}
+ pv[0] = "sendmail";
+ pv[1] = "-oi";
+ pv[2] = "-f";
+ if (emptysender)
+ pv[3] = "<>";
+ else
+ pv[3] = myname;
+ pv[4] = "--";
+ pv[5] = From;
+ pv[6] = NULL;
i = fork();
if (i < 0)
{
@@ -944,10 +992,7 @@ sendmessage(myname, msgfn, emptysender)
(void) close(pvect[0]);
(void) close(pvect[1]);
(void) fclose(mfp);
- if (emptysender)
- myname = "<>";
- (void) execl(_PATH_SENDMAIL, "sendmail", "-oi",
- "-f", myname, "--", From, NULL);
+ (void) execv(_PATH_SENDMAIL, pv);
msglog(LOG_ERR, "vacation: can't exec %s: %s",
_PATH_SENDMAIL, errstring(errno));
exit(EX_UNAVAILABLE);
@@ -974,7 +1019,8 @@ sendmessage(myname, msgfn, emptysender)
void
usage()
{
- msglog(LOG_NOTICE, "uid %u: usage: vacation [-i] [-a alias]%s [-f db]%s [-m msg] [-r interval] [-s sender] [-t time] [-x] [-z] login\n",
+ msglog(LOG_NOTICE,
+ "uid %u: usage: vacation [-a alias]%s [-f db] [-i]%s [-m msg] [-r interval] [-s sender] [-t time]%s [-x] [-z] login\n",
getuid(),
#if _FFR_DEBUG
" [-d]",
@@ -982,10 +1028,15 @@ usage()
"",
#endif /* _FFR_DEBUG */
#if _FFR_LISTDB
- " [-l]"
+ " [-l]",
#else /* _FFR_LISTDB */
- ""
+ "",
#endif /* _FFR_LISTDB */
+#if _FFR_BLACKBOX
+ " [-U]"
+#else /* _FFR_BLACKBOX */
+ ""
+#endif /* _FFR_BLACKBOX */
);
exit(EX_USAGE);
}
OpenPOWER on IntegriCloud