Apply by doing: cd /usr/src patch -p0 < 001_sendmail.patch And then rebuild, install and restart sendmail: cd gnu/usr.sbin/sendmail make obj make depend make make install kill -HUP `sed 1q /var/run/sendmail.pid` Index: gnu/usr.sbin/sendmail/RELEASE_NOTES =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/RELEASE_NOTES,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/RELEASE_NOTES 2001/02/28 02:43:48 1.4 +++ gnu/usr.sbin/sendmail/RELEASE_NOTES 2001/05/29 01:31:10 1.5 @@ -1,11 +1,75 @@ SENDMAIL RELEASE NOTES - $Sendmail: RELEASE_NOTES,v 8.561.2.5.2.208 2001/02/26 21:24:54 gshapiro Exp $ + $Sendmail: 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 @@ 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. Index: gnu/usr.sbin/sendmail/cf/README =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/README,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- gnu/usr.sbin/sendmail/cf/README 2001/02/28 02:43:49 1.5 +++ gnu/usr.sbin/sendmail/cf/README 2001/05/29 01:31:10 1.6 @@ -3113,6 +3113,7 @@ 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 @@ 8 DNS based blacklists 9 special local rulesets (1 and 2) -$Revision: 1.5 $, Last updated $Date: 2001/02/28 02:43:49 $ +$Revision: 1.6 $, Last updated $Date: 2001/05/29 01:31:10 $ Index: gnu/usr.sbin/sendmail/cf/cf/Makefile =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/cf/Makefile,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- gnu/usr.sbin/sendmail/cf/cf/Makefile 2001/02/02 06:41:18 1.9 +++ gnu/usr.sbin/sendmail/cf/cf/Makefile 2001/05/29 01:31:11 1.10 @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.9 2001/02/02 06:41:18 tholo Exp $ +# $OpenBSD: Makefile,v 1.10 2001/05/29 01:31:11 millert Exp $ # # Makefile for configuration files. # -# $Sendmail: Makefile,v 8.40.8.4 2000/10/26 18:27:44 gshapiro Exp $ +# $Sendmail: Makefile,v 8.40.8.5 2001/04/12 22:39:52 gshapiro Exp $ # # @@ -110,7 +110,6 @@ ${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 \ Index: gnu/usr.sbin/sendmail/cf/m4/cfhead.m4 =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/m4/cfhead.m4,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/cf/m4/cfhead.m4 2001/02/28 02:43:50 1.4 +++ gnu/usr.sbin/sendmail/cf/m4/cfhead.m4 2001/05/29 01:31:11 1.5 @@ -223,7 +223,6 @@ _REC_TLS_ _REC_END_') define(`confSEVEN_BIT_INPUT', `False') -define(`confEIGHT_BIT_HANDLING', `pass8') define(`confALIAS_WAIT', `10') define(`confMIN_FREE_BLOCKS', `100') define(`confBLANK_SUB', `.') @@ -252,4 +251,4 @@ divert(0)dnl -VERSIONID(`$Sendmail: cfhead.m4,v 8.76.4.15 2001/02/14 04:07:20 gshapiro Exp $') +VERSIONID(`$Sendmail: cfhead.m4,v 8.76.4.16 2001/03/06 22:56:36 ca Exp $') Index: gnu/usr.sbin/sendmail/cf/m4/proto.m4 =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/m4/proto.m4,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/cf/m4/proto.m4 2001/01/15 21:08:57 1.3 +++ gnu/usr.sbin/sendmail/cf/m4/proto.m4 2001/05/29 01:31:11 1.4 @@ -13,7 +13,7 @@ # divert(0) -VERSIONID(`$Sendmail: proto.m4,v 8.446.2.5.2.38 2000/12/28 03:37:28 ca Exp $') +VERSIONID(`$Sendmail: proto.m4,v 8.446.2.5.2.41 2001/05/23 21:32:16 ca Exp $') MAILER(local)dnl @@ -77,6 +77,7 @@ 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 @@ _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 @@ 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< 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 @@ # 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 or:
dnl or:
(thanks to u in ${daemon_flags}) R $* $: $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
) @@ -1572,13 +1575,13 @@ R$* $| $* $: $2 R $* $: < ? $&{client_name} > $1 R $* $@ ...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 $* $@ R $* $#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve" -R $* $#error $@ 5.1.8 $: "501 Domain of sender address " $&f " does not exist" +R $* $#error $@ 5.1.8 $: "CODE553 Domain of sender address " $&f " does not exist" ifdef(`_ACCESS_TABLE_', `dnl R<$={Accept}> $* $# $1 R $* $#discard $: discard Index: gnu/usr.sbin/sendmail/cf/m4/version.m4 =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/m4/version.m4,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/cf/m4/version.m4 2001/02/28 02:43:50 1.4 +++ gnu/usr.sbin/sendmail/cf/m4/version.m4 2001/05/29 01:31:11 1.5 @@ -11,8 +11,8 @@ # the sendmail distribution. # # -VERSIONID(`$Sendmail: version.m4,v 8.39.4.26 2001/02/27 19:22:29 gshapiro Exp $') +VERSIONID(`$Sendmail: 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') Index: gnu/usr.sbin/sendmail/cf/ostype/aux.m4 =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/ostype/aux.m4,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/cf/ostype/aux.m4 2001/01/15 21:08:58 1.2 +++ gnu/usr.sbin/sendmail/cf/ostype/aux.m4 2001/05/29 01:31:11 1.3 @@ -13,7 +13,7 @@ # divert(0) -VERSIONID(`$Sendmail: aux.m4,v 8.16 1999/04/24 05:37:40 gshapiro Exp $') +VERSIONID(`$Sendmail: 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 Index: gnu/usr.sbin/sendmail/doc/op/op.me =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/doc/op/op.me,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- gnu/usr.sbin/sendmail/doc/op/op.me 2001/02/28 02:43:50 1.5 +++ gnu/usr.sbin/sendmail/doc/op/op.me 2001/05/29 01:31:11 1.6 @@ -9,7 +9,7 @@ .\" the sendmail distribution. .\" .\" -.\" $Sendmail: op.me,v 8.317.4.56 2001/02/15 23:38:16 ca Exp $ +.\" $Sendmail: 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 @@ .de Ve Version \\$2 .. -.Ve $Revision: 1.5 $ +.Ve $Revision: 1.6 $ .rm Ve .sp For Sendmail Version 8.11 @@ -2413,7 +2413,7 @@ .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 @@ 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 @@ .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 @@ ${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 @@ .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 @@ 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 @@ (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 @@ 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 @@ .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 @@ .\".sz 10 .\"Eric Allman .\".sp -.\"Version $Revision: 1.5 $ +.\"Version $Revision: 1.6 $ .\".ce 0 .bp 3 .ce Index: gnu/usr.sbin/sendmail/include/libmilter/milter.h =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/include/libmilter/milter.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/include/libmilter/milter.h 2001/01/15 21:09:01 1.2 +++ gnu/usr.sbin/sendmail/include/libmilter/milter.h 2001/05/29 01:31:12 1.3 @@ -7,7 +7,7 @@ * the sendmail distribution. * * - * $Sendmail: milter.h,v 8.24.16.8 2000/09/17 17:04:24 gshapiro Exp $ + * $Sendmail: milter.h,v 8.24.16.9 2001/03/02 21:22:48 geir Exp $ */ /* Index: gnu/usr.sbin/sendmail/libmilter/README =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/README,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- gnu/usr.sbin/sendmail/libmilter/README 2001/02/28 02:43:51 1.5 +++ gnu/usr.sbin/sendmail/libmilter/README 2001/05/29 01:31:12 1.6 @@ -10,7 +10,7 @@ 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 @@ 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 @@ char **envfrom; { struct mlfiPriv *priv; - int fd; + int fd = -1; /* allocate some private memory */ priv = malloc(sizeof *priv); @@ -244,6 +245,8 @@ 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 @@ /* eof */ -$Revision: 1.5 $, Last updated $Date: 2001/02/28 02:43:51 $ +$Revision: 1.6 $, Last updated $Date: 2001/05/29 01:31:12 $ Index: gnu/usr.sbin/sendmail/libmilter/libmilter.h =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/libmilter.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/libmilter/libmilter.h 2001/01/15 21:09:02 1.2 +++ gnu/usr.sbin/sendmail/libmilter/libmilter.h 2001/05/29 01:31:12 1.3 @@ -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[] = "@(#)$Sendmail: libmilter.h,v 8.3.6.10 2000/11/20 21:15:36 ca Exp $"; +static char MilterlId[] = "@(#)$Sendmail: 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 @@ #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 @@ /* 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 */ Index: gnu/usr.sbin/sendmail/libmilter/listener.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/listener.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/libmilter/listener.c 2001/02/28 02:43:51 1.3 +++ gnu/usr.sbin/sendmail/libmilter/listener.c 2001/05/29 01:31:12 1.4 @@ -9,7 +9,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: listener.c,v 8.38.2.1.2.21 2001/02/14 02:20:40 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: 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 @@ 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 @@ } 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 @@ memset(&cliaddr, '\0', sizeof cliaddr); connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen); + save_errno = errno; (void) smutex_unlock(&L_Mutex); /* @@ -610,14 +612,23 @@ { (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 @@ continue; } mcnt = 0; + acnt = 0; memset(ctx, '\0', sizeof *ctx); ctx->ctx_sd = connfd; ctx->ctx_dbg = dbg; Index: gnu/usr.sbin/sendmail/libmilter/main.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/main.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/libmilter/main.c 2001/01/15 21:09:02 1.2 +++ gnu/usr.sbin/sendmail/libmilter/main.c 2001/05/29 01:31:12 1.3 @@ -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[] = "@(#)$Sendmail: main.c,v 8.34.4.9 2000/09/09 02:23:03 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: main.c,v 8.34.4.11 2001/05/07 22:06:37 gshapiro Exp $"; #endif /* ! lint */ #if _FFR_MILTER @@ -131,9 +131,11 @@ return MI_SUCCESS; } + int smfi_main() { + signal(SIGPIPE, SIG_IGN); if (conn == NULL) { @@ -150,6 +152,7 @@ smfi->xxfi_name); return MI_FAILURE; } + /* Startup the listener */ if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS) Index: gnu/usr.sbin/sendmail/libmilter/sm_gethost.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/libmilter/sm_gethost.c 2001/02/28 02:43:51 1.3 +++ gnu/usr.sbin/sendmail/libmilter/sm_gethost.c 2001/05/29 01:31:13 1.4 @@ -9,7 +9,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: sm_gethost.c,v 8.7.8.6 2001/02/14 04:07:23 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: 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 @@ ** 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 @@ return; } # endif /* _FFR_FREEHOSTENT */ -#endif /* NEEDSGETIPNODE && NETINET6 && __RES < 19990909 */ +#endif /* NEEDSGETIPNODE && NETINET6 */ struct hostent * mi_gethostbyname(name, family) Index: gnu/usr.sbin/sendmail/mailstats/mailstats.8 =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/mailstats/mailstats.8,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- gnu/usr.sbin/sendmail/mailstats/mailstats.8 2001/03/01 20:20:39 1.6 +++ gnu/usr.sbin/sendmail/mailstats/mailstats.8 2001/05/29 01:31:13 1.7 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998 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. .\" .\" -.\" $Sendmail: mailstats.8,v 8.17.4.3 2000/12/29 18:12:20 gshapiro Exp $ +.\" $Sendmail: mailstats.8,v 8.17.4.6 2001/05/07 22:06:38 gshapiro Exp $ .\" -.Dd December 29, 2000 +.Dd May 7, 2001 .Dt MAILSTATS 1 .Os .Sh NAME Index: gnu/usr.sbin/sendmail/mailstats/mailstats.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/mailstats/mailstats.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/mailstats/mailstats.c 2001/02/28 02:43:52 1.3 +++ gnu/usr.sbin/sendmail/mailstats/mailstats.c 2001/05/29 01:31:13 1.4 @@ -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 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,14 +14,14 @@ #ifndef lint static char copyright[] = -"@(#) Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.\n\ +"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Sendmail: mailstats.c,v 8.53.16.12 2001/02/15 20:52:36 geir Exp $"; +static char id[] = "@(#)$Sendmail: mailstats.c,v 8.53.16.13 2001/05/07 22:06:38 gshapiro Exp $"; #endif /* ! lint */ #include Index: gnu/usr.sbin/sendmail/praliases/praliases.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/praliases/praliases.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/praliases/praliases.c 2001/02/28 02:43:52 1.4 +++ gnu/usr.sbin/sendmail/praliases/praliases.c 2001/05/29 01:31:13 1.5 @@ -21,7 +21,7 @@ #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Sendmail: praliases.c,v 8.59.4.18 2001/01/22 19:00:18 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: praliases.c,v 8.59.4.19 2001/02/28 02:37:57 ca Exp $"; #endif /* ! lint */ #include @@ -357,12 +357,20 @@ } else for (; *argv != NULL; ++argv) { + int get_res; + memset(&db_key, '\0', sizeof db_key); memset(&db_value, '\0', sizeof db_value); db_key.data = *argv; - db_key.size = strlen(*argv) + 1; - if (database->smdb_get(database, &db_key, - &db_value, 0) == SMDBE_OK) + db_key.size = strlen(*argv); + get_res = database->smdb_get(database, &db_key, &db_value, 0); + if (get_res == SMDBE_NOT_FOUND) + { + db_key.size++; + get_res = database->smdb_get(database, &db_key, + &db_value, 0); + } + if (get_res == SMDBE_OK) { printf("%.*s:%.*s\n", (int) db_key.size, Index: gnu/usr.sbin/sendmail/rmail/rmail.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/rmail/rmail.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/rmail/rmail.c 2001/02/28 02:43:52 1.4 +++ gnu/usr.sbin/sendmail/rmail/rmail.c 2001/05/29 01:31:13 1.5 @@ -12,14 +12,14 @@ #ifndef lint static char copyright[] = -"@(#) Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.\n\ +"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Sendmail: rmail.c,v 8.39.4.11 2001/02/14 04:07:25 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: rmail.c,v 8.39.4.12 2001/05/07 22:06:39 gshapiro Exp $"; #endif /* ! lint */ /* Index: gnu/usr.sbin/sendmail/sendmail/Makefile =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/Makefile,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- gnu/usr.sbin/sendmail/sendmail/Makefile 2001/02/11 22:35:18 1.11 +++ gnu/usr.sbin/sendmail/sendmail/Makefile 2001/05/05 22:00:17 1.12 @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.11 2001/02/11 22:35:18 millert Exp $ +# $OpenBSD: Makefile,v 1.12 2001/05/05 22:00:17 millert Exp $ PROG= sendmail @@ -12,6 +12,9 @@ # Work around broken name servers that return SERV_FAIL for AAAA records ENVDEF+= -D_FFR_WORKAROUND_BROKEN_NAMESERVERS + +# Since we have random PIDs we need to be careful to avoid filename collisions +ENVDEF+= -DFAST_PID_RECYCLE # To cause sendmail to drop privs in test mode (-bt) uncomment the following #ENVDEF+= -D_FFR_TESTMODE_DROP_PRIVS Index: gnu/usr.sbin/sendmail/sendmail/README =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/README,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- gnu/usr.sbin/sendmail/sendmail/README 2001/02/28 02:43:53 1.5 +++ gnu/usr.sbin/sendmail/sendmail/README 2001/05/29 01:31:13 1.6 @@ -9,7 +9,7 @@ # the sendmail distribution. # # -# $Sendmail: README,v 8.263.2.1.2.32 2001/01/29 23:45:22 gshapiro Exp $ +# $Sendmail: 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 @@ 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 @@ problems. You may want to turn this off if you have problems running sendmail. Reported by Jerry G. DeLapp . +Mac OS X (10.0.X) + From: Mike Zimmerman + 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 @@ version.c The version number and information about this version of sendmail. -(Version $Revision: 1.5 $, last update $Date: 2001/02/28 02:43:53 $ ) +(Version $Revision: 1.6 $, last update $Date: 2001/05/29 01:31:13 $ ) Index: gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS 2001/01/15 21:09:06 1.2 +++ gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS 2001/05/29 01:31:14 1.3 @@ -1,4 +1,4 @@ -# $Sendmail: TRACEFLAGS,v 8.29 1999/11/04 23:31:02 gshapiro Exp $ +# $Sendmail: 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 Index: gnu/usr.sbin/sendmail/sendmail/alias.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/alias.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/alias.c 2001/01/15 21:09:06 1.3 +++ gnu/usr.sbin/sendmail/sendmail/alias.c 2001/05/29 01:31:14 1.4 @@ -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 #ifndef lint -static char id[] = "@(#)$Sendmail: alias.c,v 8.142.4.9 2000/11/08 20:58:42 geir Exp $"; +static char id[] = "@(#)$Sendmail: alias.c,v 8.142.4.11 2001/05/03 17:24:01 gshapiro Exp $"; #endif /* ! lint */ # define SEPARATOR ':' @@ -405,8 +405,9 @@ 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 @@ 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 @@ /* 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 @@ } 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; Index: gnu/usr.sbin/sendmail/sendmail/arpadate.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/arpadate.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/sendmail/arpadate.c 2001/01/15 21:09:07 1.2 +++ gnu/usr.sbin/sendmail/sendmail/arpadate.c 2001/05/29 01:31:14 1.3 @@ -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[] = "@(#)$Sendmail: arpadate.c,v 8.23 1999/09/23 19:59:18 ca Exp $"; +static char id[] = "@(#)$Sendmail: arpadate.c,v 8.23.20.2 2001/05/07 22:07:26 gshapiro Exp $"; #endif /* ! lint */ #include @@ -117,11 +117,12 @@ *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); Index: gnu/usr.sbin/sendmail/sendmail/bf_portable.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/bf_portable.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/bf_portable.c 2001/02/28 02:43:53 1.3 +++ gnu/usr.sbin/sendmail/sendmail/bf_portable.c 2001/05/29 01:31:14 1.4 @@ -11,7 +11,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: bf_portable.c,v 8.25.4.5 2001/02/14 04:07:27 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: bf_portable.c,v 8.25.4.6 2001/05/03 17:24:01 gshapiro Exp $"; #endif /* ! lint */ #if SFIO @@ -28,9 +28,12 @@ #if !SFIO # include #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 @@ } /* 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 @@ 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 @@ /* check to see if there is an error on the stream */ err = ferror(fp); - (void) fflush(fp); /* @@ -379,8 +381,8 @@ 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)); Index: gnu/usr.sbin/sendmail/sendmail/bf_torek.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/bf_torek.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/bf_torek.c 2001/02/28 02:43:53 1.3 +++ gnu/usr.sbin/sendmail/sendmail/bf_torek.c 2001/05/29 01:31:14 1.4 @@ -11,7 +11,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: bf_torek.c,v 8.19.18.4 2001/02/14 04:07:27 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: bf_torek.c,v 8.19.18.6 2001/05/08 06:52:19 gshapiro Exp $"; #endif /* ! lint */ #if SFIO @@ -26,9 +26,12 @@ #include #include #include -#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 @@ } /* 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 @@ /* 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 @@ 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 @@ { /* 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 @@ { /* 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 @@ /* check to see if there is an error on the stream */ err = ferror(fp); - (void) fflush(fp); /* @@ -530,10 +532,10 @@ /* 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; } Index: gnu/usr.sbin/sendmail/sendmail/clock.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/clock.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/sendmail/clock.c 2001/01/15 21:09:07 1.2 +++ gnu/usr.sbin/sendmail/sendmail/clock.c 2001/05/29 01:31:14 1.3 @@ -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[] = "@(#)$Sendmail: clock.c,v 8.52.18.3 2000/09/17 17:04:26 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: clock.c,v 8.52.18.14 2001/05/17 18:12:28 gshapiro Exp $"; #endif /* ! lint */ #include @@ -21,6 +21,7 @@ # define sigmask(s) (1 << ((s) - 1)) #endif /* ! sigmask */ +static SIGFUNC_DECL tick __P((int)); static void endsleep __P((void)); @@ -42,7 +43,8 @@ ** 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 @@ void (*func)(); int arg; { - register EVENT **evp; register EVENT *ev; - auto time_t now; - int wasblocked; if (intvl <= 0) { @@ -61,34 +60,89 @@ 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; + LEAVE_CRITICAL(); - 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); - (void) setsignal(SIGALRM, tick); intvl = EventQueue->ev_time - now; (void) alarm((unsigned) intvl < 1 ? 1 : intvl); @@ -123,7 +177,9 @@ /* 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 @@ /* 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 @@ 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 @@ ** ** 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 @@ { 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 @@ 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 @@ 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 @@ */ -static bool SleepDone; +static bool volatile SleepDone; #ifndef SLEEP_T # define SLEEP_T unsigned int @@ -308,5 +480,11 @@ 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; } Index: gnu/usr.sbin/sendmail/sendmail/collect.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/collect.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/collect.c 2001/02/28 02:43:53 1.4 +++ gnu/usr.sbin/sendmail/sendmail/collect.c 2001/05/29 01:31:14 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: collect.c,v 8.136.4.15 2001/02/21 01:05:59 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: collect.c,v 8.136.4.21 2001/05/17 18:10:14 gshapiro Exp $"; #endif /* ! lint */ #include @@ -47,8 +47,8 @@ */ 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 @@ 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 @@ /* just put the character out */ if (!bitset(EF_TOOBIG, e->e_flags)) (void) putc(c, df); - /* FALLTHROUGH */ case MS_DISCARD: @@ -337,7 +338,7 @@ 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 @@ } /* reset global timer */ - clrevent(CollectTimeout); + if (CollectTimeout != NULL) + clrevent(CollectTimeout); if (headeronly) return; @@ -721,15 +723,37 @@ 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: Index: gnu/usr.sbin/sendmail/sendmail/conf.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/conf.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- gnu/usr.sbin/sendmail/sendmail/conf.c 2001/02/28 02:43:53 1.6 +++ gnu/usr.sbin/sendmail/sendmail/conf.c 2001/05/29 01:31:14 1.7 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: conf.c,v 8.646.2.2.2.69 2001/02/27 19:50:11 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: conf.c,v 8.646.2.2.2.86 2001/05/17 18:18:40 ca Exp $"; #endif /* ! lint */ #include @@ -976,7 +976,7 @@ st = stab(buf, ST_SERVICE, ST_ENTER); if (st->s_service[0] != NULL) - free((void *) st->s_service[0]); + sm_free((void *) st->s_service[0]); p = newstr(p); for (svcno = 0; svcno < MAXMAPSTACK; ) { @@ -1226,6 +1226,10 @@ ** SETSIGNAL -- set a signal handler ** ** This is essentially old BSD "signal(3)". +** +** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD +** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE +** DOING. */ sigfunc_t @@ -1233,14 +1237,16 @@ int sig; sigfunc_t handler; { +# if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) + struct sigaction n, o; +# endif /* defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) */ + /* ** First, try for modern signal calls ** and restartable syscalls */ # ifdef SA_RESTART - struct sigaction n, o; - memset(&n, '\0', sizeof n); # if USE_SA_SIGACTION n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler; @@ -1272,8 +1278,6 @@ ** go for a default */ - struct sigaction n, o; - memset(&n, '\0', sizeof n); n.sa_handler = handler; if (sigaction(sig, &n, &o) < 0) @@ -1283,6 +1287,73 @@ # endif /* SA_RESTART */ } /* +** ALLSIGNALS -- act on all signals +** +** Parameters: +** block -- whether to block or release all signals. +** +** Returns: +** none. +*/ + +void +allsignals(block) + bool block; +{ +# ifdef BSD4_3 +# ifndef sigmask +# define sigmask(s) (1 << ((s) - 1)) +# endif /* ! sigmask */ + if (block) + { + int mask = 0; + + mask |= sigmask(SIGALRM); + mask |= sigmask(SIGCHLD); + mask |= sigmask(SIGHUP); + mask |= sigmask(SIGINT); + mask |= sigmask(SIGTERM); + mask |= sigmask(SIGUSR1); + + (void) sigblock(mask); + } + else + sigsetmask(0); +# else /* BSD4_3 */ +# ifdef ALTOS_SYSTEM_V + if (block) + { + (void) sigset(SIGALRM, SIG_HOLD); + (void) sigset(SIGCHLD, SIG_HOLD); + (void) sigset(SIGHUP, SIG_HOLD); + (void) sigset(SIGINT, SIG_HOLD); + (void) sigset(SIGTERM, SIG_HOLD); + (void) sigset(SIGUSR1, SIG_HOLD); + } + else + { + (void) sigset(SIGALRM, SIG_DFL); + (void) sigset(SIGCHLD, SIG_DFL); + (void) sigset(SIGHUP, SIG_DFL); + (void) sigset(SIGINT, SIG_DFL); + (void) sigset(SIGTERM, SIG_DFL); + (void) sigset(SIGUSR1, SIG_DFL); + } +# else /* ALTOS_SYSTEM_V */ + sigset_t sset; + + (void) sigemptyset(&sset); + (void) sigaddset(&sset, SIGALRM); + (void) sigaddset(&sset, SIGCHLD); + (void) sigaddset(&sset, SIGHUP); + (void) sigaddset(&sset, SIGINT); + (void) sigaddset(&sset, SIGTERM); + (void) sigaddset(&sset, SIGUSR1); + (void) sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL); +# endif /* ALTOS_SYSTEM_V */ +# endif /* BSD4_3 */ +} + /* ** BLOCKSIGNAL -- hold a signal to prevent delivery ** ** Parameters: @@ -2441,7 +2512,7 @@ # if SPT_TYPE == SPT_SCO off_t seek_off; static int kmem = -1; - static int kmempid = -1; + static pid_t kmempid = -1; struct user u; # endif /* SPT_TYPE == SPT_SCO */ @@ -2619,6 +2690,10 @@ ** Side Effects: ** Picks up extant zombies. ** Control socket exits may restart/shutdown daemon. +** +** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD +** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE +** DOING. */ /* ARGSUSED0 */ @@ -2629,32 +2704,30 @@ int save_errno = errno; int st; pid_t pid; -#if HASWAITPID +# if HASWAITPID auto int status; int count; +# else /* HASWAITPID */ +# ifdef WNOHANG + union wait status; +# else /* WNOHANG */ + auto int status; +# endif /* WNOHANG */ +# endif /* HASWAITPID */ +# if HASWAITPID count = 0; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { st = status; if (count++ > 1000) - { - if (LogLevel > 0) - sm_syslog(LOG_ALERT, NOQID, - "reapchild: waitpid loop: pid=%d, status=%x", - pid, status); break; - } -#else /* HASWAITPID */ -# ifdef WNOHANG - union wait status; - +# else /* HASWAITPID */ +# ifdef WNOHANG while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0) { st = status.w_status; -# else /* WNOHANG */ - auto int status; - +# else /* WNOHANG */ /* ** Catch one zombie -- we will be re-invoked (we hope) if there ** are more. Unreliable signals probably break this, but this @@ -2665,8 +2738,8 @@ if ((pid = wait(&status)) > 0) { st = status; -# endif /* WNOHANG */ -#endif /* HASWAITPID */ +# endif /* WNOHANG */ +# endif /* HASWAITPID */ /* Drop PID and check if it was a control socket child */ if (proc_list_drop(pid) == PROC_CONTROL && WIFEXITED(st)) @@ -2674,21 +2747,17 @@ /* if so, see if we need to restart or shutdown */ if (WEXITSTATUS(st) == EX_RESTART) { - /* emulate a SIGHUP restart */ - sighup(0); - /* NOTREACHED */ + RestartRequest = "control socket"; } else if (WEXITSTATUS(st) == EX_SHUTDOWN) { /* emulate a SIGTERM shutdown */ - intsig(0); + ShutdownRequest = "control socket"; /* NOTREACHED */ } } } -#ifdef SYS5SIGNALS - (void) setsignal(SIGCHLD, reapchild); -#endif /* SYS5SIGNALS */ + FIX_SYSV_SIGNAL(sig, reapchild); errno = save_errno; return SIGFUNC_RETURN; } @@ -2753,18 +2822,14 @@ */ if (first) { - newenv = (char **) malloc(sizeof(char *) * (envlen + 2)); - if (newenv == NULL) - return -1; - + newenv = (char **) xalloc(sizeof(char *) * (envlen + 2)); first = FALSE; (void) memcpy(newenv, environ, sizeof(char *) * envlen); } else { - newenv = (char **) realloc((char *)environ, sizeof(char *) * (envlen + 2)); - if (newenv == NULL) - return -1; + newenv = (char **) xrealloc((char *)environ, + sizeof(char *) * (envlen + 2)); } /* actually add in the new entry */ @@ -4327,7 +4392,7 @@ ** Support IPv6 as well as IPv4. */ -#if NETINET6 && NEEDSGETIPNODE && __RES < 19990909 +#if NETINET6 && NEEDSGETIPNODE # ifndef AI_DEFAULT # define AI_DEFAULT 0 /* dummy */ @@ -4394,7 +4459,7 @@ return; } # endif /* _FFR_FREEHOSTENT */ -#endif /* NEEDSGETIPNODE && NETINET6 && __RES < 19990909 */ +#endif /* NEEDSGETIPNODE && NETINET6 */ struct hostent * sm_gethostbyname(name, family) @@ -4582,8 +4647,8 @@ # else /* NETINET6 */ hp = gethostbyaddr(addr, len, type); # endif /* NETINET6 */ - return hp; #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */ + return hp; } /* ** SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid @@ -4869,7 +4934,7 @@ if (tTd(0, 4)) dprintf("SIOCGLIFCONF failed: %s\n", errstring(errno)); (void) close(s); - free(lifc.lifc_buf); + sm_free(lifc.lifc_buf); return; } @@ -4903,7 +4968,7 @@ s = socket(af, SOCK_DGRAM, 0); if (s == -1) { - free(lifc.lifc_buf); + sm_free(lifc.lifc_buf); return; } @@ -5018,7 +5083,7 @@ # endif /* SIOCGLIFFLAGS */ (void) add_hostnames(sa); } - free(lifc.lifc_buf); + sm_free(lifc.lifc_buf); (void) close(s); #else /* NETINET6 && defined(SIOCGLIFCONF) */ # if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN @@ -5058,7 +5123,7 @@ if (tTd(0, 4)) dprintf("SIOCGIFCONF failed: %s\n", errstring(errno)); (void) close(s); - free(ifc.ifc_buf); + sm_free(ifc.ifc_buf); return; } @@ -5201,7 +5266,7 @@ (void) add_hostnames(sa); } - free(ifc.ifc_buf); + sm_free(ifc.ifc_buf); (void) close(s); # undef IFRFREF # endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */ @@ -5375,7 +5440,7 @@ /* String too small, redo with correct size */ bufsize += SnprfOverflow + 1; if (buf != buf0) - free(buf); + sm_free(buf); buf = xalloc(bufsize * sizeof (char)); } if ((strlen(buf) + idlen + 1) < SYSLOG_BUFSIZE) @@ -5532,6 +5597,9 @@ char *CompileOptions[] = { +#if EGD + "EGD", +#endif /* EGD */ #ifdef HESIOD "HESIOD", #endif /* HESIOD */ Index: gnu/usr.sbin/sendmail/sendmail/conf.h =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/conf.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- gnu/usr.sbin/sendmail/sendmail/conf.h 2001/02/28 02:43:53 1.8 +++ gnu/usr.sbin/sendmail/sendmail/conf.h 2001/05/29 01:31:14 1.9 @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Sendmail: conf.h,v 8.496.4.37 2001/02/12 21:40:16 gshapiro Exp $ + * $Sendmail: conf.h,v 8.496.4.43 2001/05/20 22:29:59 gshapiro Exp $ */ /* @@ -84,7 +84,7 @@ #define MAXMIMEARGS 20 /* max args in Content-Type: */ #define MAXMIMENESTING 20 /* max MIME multipart nesting */ #define QUEUESEGSIZE 1000 /* increment for queue size */ -#define MAXQFNAME 20 /* max qf file name length */ +#define MAXQFNAME 21 /* max qf file name length */ #define MACBUFSIZE 4096 /* max expanded macro buffer size */ #define TOBUFSIZE SM_ARG_MAX /* max buffer to hold address list */ #define MAXSHORTSTR 203 /* max short string length */ @@ -551,6 +551,9 @@ # undef _PATH_SENDMAILPID /* tmpfs /var/run added in 2.8 */ # define _PATH_SENDMAILPID "/var/run/sendmail.pid" # endif /* SOLARIS >= 20800 || (SOLARIS < 10000 && SOLARIS >= 208) */ +# if SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) +# define HASURANDOMDEV 1 /* /dev/[u]random added in S9 */ +# endif /* SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) */ # ifndef HASGETUSERSHELL # define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps pre-2.7 */ # endif /* ! HASGETUSERSHELL */ @@ -1002,6 +1005,7 @@ # undef SPT_TYPE # define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ # define HASSETLOGIN 1 /* has setlogin(2) */ +# define HASSETREUID 0 /* OpenBSD has broken setreuid(2) emulation */ # define HASURANDOMDEV 1 /* has /dev/urandom(4) */ # if OpenBSD < 199912 # define HASSTRL 0 /* strlcat(3) is broken in 2.5 and earlier */ @@ -1468,10 +1472,10 @@ # else /* (GLIBC_VERSION >= 0x201) */ # include /* IPv6 support */ # endif /* (GLIBC_VERSION >= 0x201) */ -# if (GLIBC_VERSION == 0x201 && !defined(NEEDSGETIPNODE)) +# if (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE)) /* Have APIs in , but no support in glibc */ # define NEEDSGETIPNODE 1 -# endif /* (GLIBC_VERSION == 0x201 && ! NEEDSGETIPNODE) */ +# endif /* (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE)) */ # undef GLIBC_VERSION # endif /* defined(__GLIBC__) && defined(__GLIBC_MINOR__) */ # endif /* NETINET6 */ @@ -2243,7 +2247,9 @@ /* general BSD defines */ #ifdef BSD # define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */ -# define HASSETREUID 1 /* has setreuid(2) call */ +# ifndef HASSETREUID +# define HASSETREUID 1 /* has setreuid(2) call */ +# endif /* ! HASSETREUID */ # define HASINITGROUPS 1 /* has initgroups(3) call */ # ifndef IP_SRCROUTE # define IP_SRCROUTE 1 /* can check IP source routing */ Index: gnu/usr.sbin/sendmail/sendmail/control.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/control.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/control.c 2001/02/28 02:43:53 1.3 +++ gnu/usr.sbin/sendmail/sendmail/control.c 2001/05/29 01:31:14 1.4 @@ -9,12 +9,34 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: control.c,v 8.44.14.15 2001/01/22 19:00:22 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: control.c,v 8.44.14.20 2001/05/03 17:24:03 gshapiro Exp $"; #endif /* ! lint */ #include +/* 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 @@ ** 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); } Index: gnu/usr.sbin/sendmail/sendmail/daemon.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/daemon.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- gnu/usr.sbin/sendmail/sendmail/daemon.c 2001/02/28 02:43:53 1.6 +++ gnu/usr.sbin/sendmail/sendmail/daemon.c 2001/05/29 01:31:14 1.7 @@ -16,9 +16,9 @@ #ifndef lint # ifdef DAEMON -static char id[] = "@(#)$Sendmail: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (with daemon mode)"; +static char id[] = "@(#)$Sendmail: daemon.c,v 8.401.4.61 2001/05/27 22:14:40 gshapiro Exp $ (with daemon mode)"; # else /* DAEMON */ -static char id[] = "@(#)$Sendmail: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (without daemon mode)"; +static char id[] = "@(#)$Sendmail: 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 @@ 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,7 +196,11 @@ 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 @@ /* see if we are rejecting connections */ (void) blocksignal(SIGALRM); + if (ShutdownRequest != NULL) + shutdown_daemon(); + else if (RestartRequest != NULL) + restart_daemon(); + timenow = curtime(); /* @@ -298,6 +309,12 @@ } } + /* 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; @@ -391,6 +408,11 @@ 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++) @@ -421,26 +443,20 @@ } # 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) (void) runqueue(TRUE, FALSE); @@ -677,6 +693,18 @@ ** 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), @@ -688,10 +716,6 @@ 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) @@ -1719,7 +1743,7 @@ { 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 @@ -2008,8 +2032,9 @@ 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; @@ -2022,7 +2047,7 @@ } else { - s = socket(addr.sa.sa_family, SOCK_STREAM, 0); + s = socket(clt_addr.sa.sa_family, SOCK_STREAM, 0); } if (s < 0) { @@ -2128,9 +2153,11 @@ 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; @@ -2316,6 +2343,12 @@ 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); } @@ -2416,6 +2449,124 @@ } # 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: @@ -2578,6 +2729,13 @@ 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); } Index: gnu/usr.sbin/sendmail/sendmail/deliver.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/deliver.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/deliver.c 2001/02/28 02:43:54 1.4 +++ gnu/usr.sbin/sendmail/sendmail/deliver.c 2001/05/29 01:31:14 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: deliver.c,v 8.600.2.1.2.66 2001/02/25 23:30:35 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: deliver.c,v 8.600.2.1.2.81 2001/05/23 02:15:42 ca Exp $"; #endif /* ! lint */ #include @@ -135,22 +135,31 @@ 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 @@ 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 @@ ** returns twice, once in parent and once in child. */ -int +pid_t dofork() { register pid_t pid = -1; @@ -1451,7 +1465,7 @@ if (l > tobufsize) { if (tobuf != NULL) - free(tobuf); + sm_free(tobuf); tobufsize = l; tobuf = xalloc(tobufsize); } @@ -1719,10 +1733,10 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ (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 @@ 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 @@ TrafficLogFile); if (c == '\n') (void) fputs(mci->mci_mailer->m_eol, - TrafficLogFile); + TrafficLogFile); } if (padc != EOF) { @@ -4375,6 +4402,11 @@ 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 @@ } 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 @@ (*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 @@ 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 @@ 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 @@ 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; Index: gnu/usr.sbin/sendmail/sendmail/envelope.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/envelope.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/envelope.c 2001/01/15 21:09:08 1.3 +++ gnu/usr.sbin/sendmail/sendmail/envelope.c 2001/05/29 01:31:15 1.4 @@ -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[] = "@(#)$Sendmail: envelope.c,v 8.180.14.6 2000/11/30 00:39:46 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: envelope.c,v 8.180.14.10 2001/05/03 17:24:06 gshapiro Exp $"; #endif /* ! lint */ #include @@ -132,7 +132,7 @@ */ 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 @@ /* 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 @@ "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 @@ } } 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 @@ { 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 @@ "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; Index: gnu/usr.sbin/sendmail/sendmail/err.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/err.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/sendmail/err.c 2001/01/15 21:09:08 1.2 +++ gnu/usr.sbin/sendmail/sendmail/err.c 2001/05/29 01:31:15 1.3 @@ -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[] = "@(#)$Sendmail: err.c,v 8.120.4.1 2000/05/25 18:56:15 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: err.c,v 8.120.4.2 2001/05/03 17:24:06 gshapiro Exp $"; #endif /* ! lint */ #include @@ -107,7 +107,7 @@ if (!panic && CurEnv != NULL) { if (CurEnv->e_message != NULL) - free(CurEnv->e_message); + sm_free(CurEnv->e_message); CurEnv->e_message = newstr(errtxt); } @@ -122,13 +122,13 @@ dprintf("syserr: ExitStat = %d\n", ExitStat); } - pw = sm_getpwuid(getuid()); + pw = sm_getpwuid(RealUid); if (pw != NULL) user = pw->pw_name; else { user = ubuf; - snprintf(ubuf, sizeof ubuf, "UID%d", (int) getuid()); + snprintf(ubuf, sizeof ubuf, "UID%d", (int) RealUid); } if (LogLevel > 0) @@ -237,7 +237,7 @@ case '5': case '6': if (CurEnv->e_message != NULL) - free(CurEnv->e_message); + sm_free(CurEnv->e_message); if (MsgBuf[0] == '6') { char buf[MAXLINE]; @@ -323,7 +323,7 @@ case '5': case '6': if (CurEnv->e_message != NULL) - free(CurEnv->e_message); + sm_free(CurEnv->e_message); if (MsgBuf[0] == '6') { char buf[MAXLINE]; @@ -392,7 +392,7 @@ case '5': if (CurEnv->e_message != NULL) - free(CurEnv->e_message); + sm_free(CurEnv->e_message); CurEnv->e_message = newstr(errtxt); break; } @@ -446,7 +446,7 @@ case '5': if (CurEnv->e_message != NULL) - free(CurEnv->e_message); + sm_free(CurEnv->e_message); CurEnv->e_message = newstr(errtxt); break; } Index: gnu/usr.sbin/sendmail/sendmail/headers.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/headers.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/headers.c 2001/02/28 02:43:54 1.4 +++ gnu/usr.sbin/sendmail/sendmail/headers.c 2001/05/29 01:31:15 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: headers.c,v 8.203.4.12 2001/01/22 19:00:22 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: headers.c,v 8.203.4.13 2001/05/03 17:24:06 gshapiro Exp $"; #endif /* ! lint */ #include @@ -341,7 +341,7 @@ } if ((sp = macvalue(macid("{currHeader}", NULL), e)) != NULL) - free(sp); + sm_free(sp); define(macid("{currHeader}", NULL), newstr(qval), e); define(macid("{hdr_name}", NULL), newstr(fname), e); (void) rscheck(rs, fvalue, NULL, e, stripcom, TRUE, 4, Index: gnu/usr.sbin/sendmail/sendmail/main.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/main.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- gnu/usr.sbin/sendmail/sendmail/main.c 2001/02/28 02:43:54 1.5 +++ gnu/usr.sbin/sendmail/sendmail/main.c 2001/05/29 01:31:15 1.6 @@ -21,7 +21,7 @@ #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Sendmail: main.c,v 8.485.4.44 2001/02/08 14:06:55 ca Exp $"; +static char id[] = "@(#)$Sendmail: main.c,v 8.485.4.60 2001/05/27 22:00:26 gshapiro Exp $"; #endif /* ! lint */ #define _DEFINE @@ -33,6 +33,10 @@ # include #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 @@ { "", "", 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 @@ /* 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 @@ 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 @@ 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 @@ } 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 @@ ** 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ FullName = addquotes(FullName); if (full != NULL) - free(full); + sm_free(full); } } @@ -1589,20 +1652,7 @@ #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 @@ { /* 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ ** ** 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 @@ 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 @@ if (LogLevel > 71) sm_syslog(LOG_DEBUG, e->e_id, "in background, pid=%d", - getpid()); + (int) getpid()); errno = 0; } @@ -2563,68 +2758,35 @@ } 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 Index: gnu/usr.sbin/sendmail/sendmail/map.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/map.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/map.c 2001/02/28 02:43:54 1.4 +++ gnu/usr.sbin/sendmail/sendmail/map.c 2001/05/29 01:31:15 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: map.c,v 8.414.4.39 2001/02/22 18:56:22 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: map.c,v 8.414.4.53 2001/05/04 01:29:00 gshapiro Exp $"; #endif /* ! lint */ #include @@ -370,7 +370,7 @@ /* need to malloc additional space */ buflen = len; if (buf != NULL) - free(buf); + sm_free(buf); buf = xalloc(buflen); } @@ -492,8 +492,9 @@ /* 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 @@ 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->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 @@ ** 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 @@ int *statp; { datum key, val; - int fd; + int dfd, pfd; char keybuf[MAXNAME + 1]; struct stat stbuf; @@ -1150,19 +1153,22 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { if (vp != NULL) { - free(vp); + sm_free(vp); vp = NULL; } buflen++; @@ -2225,7 +2232,7 @@ 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 @@ ret = map_rewrite(map, vp, vsize, av); if (vp != NULL) - free(vp); + sm_free(vp); return ret; } } @@ -2290,7 +2297,7 @@ { if (vp != NULL) { - free(vp); + sm_free(vp); vp = NULL; } keylen++; @@ -2308,11 +2315,11 @@ 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 @@ 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 @@ return FALSE; /* Save connection for reuse */ - s->s_ldap = lmap->ldap_ld; + s->s_lmap = map; return TRUE; } @@ -3036,6 +3048,13 @@ 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 @@ 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 @@ 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 @@ } *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 @@ } (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 @@ (void) ldap_abandon(lmap->ldap_ld, msgid); if (vp != NULL) - free(vp); + sm_free(vp); return NULL; } } @@ -3419,7 +3444,7 @@ 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 @@ 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 @@ } (void) ldap_abandon(lmap->ldap_ld, msgid); if (vp != NULL) - free(vp); + sm_free(vp); return NULL; } @@ -3532,7 +3557,7 @@ } (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 @@ lmap->ldap_res = NULL; } if (vp != NULL) - free(vp); + sm_free(vp); return NULL; } *statp = EX_OK; @@ -3569,9 +3594,13 @@ 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 @@ } *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 @@ if (bitset(MF_NOREWRITE, map->map_mflags)) { if (vp != NULL) - free(vp); + sm_free(vp); return ""; } @@ -3619,7 +3657,7 @@ result = map_rewrite(map, vp, strlen(vp), av); } if (vp != NULL) - free(vp); + sm_free(vp); } return result; } @@ -3664,9 +3702,9 @@ (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 @@ 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 @@ 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 @@ /* 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 @@ # 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 @@ { 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 @@ 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 @@ 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 @@ *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 @@ 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 @@ { char *np; int nl; + int save_errno; char nbuf[MAXNAME]; nl = strlen(name); @@ -5285,8 +5332,10 @@ # 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 @@ # 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 @@ *statp = EX_UNAVAILABLE; break; } + hesiod_free_list(HesiodContext, hp); return NULL; } # else /* HESIOD_INIT */ @@ -5413,7 +5460,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ (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 @@ 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 @@ 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 @@ *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; Index: gnu/usr.sbin/sendmail/sendmail/mci.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/mci.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- gnu/usr.sbin/sendmail/sendmail/mci.c 2001/01/15 21:09:09 1.2 +++ gnu/usr.sbin/sendmail/sendmail/mci.c 2001/05/29 01:31:15 1.3 @@ -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) 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: mci.c,v 8.133.10.7 2000/12/12 00:39:34 ca Exp $"; +static char id[] = "@(#)$Sendmail: mci.c,v 8.133.10.8 2001/05/03 17:24:10 gshapiro Exp $"; #endif /* ! lint */ #include @@ -422,7 +422,7 @@ mci->mci_status = dstat; if (mci->mci_rstatus != NULL) - free(mci->mci_rstatus); + sm_free(mci->mci_rstatus); if (rstat != NULL) rstat = newstr(rstat); mci->mci_rstatus = rstat; @@ -807,7 +807,7 @@ mci->mci_status = NULL; if (mci->mci_rstatus != NULL) - free(mci->mci_rstatus); + sm_free(mci->mci_rstatus); mci->mci_rstatus = NULL; rewind(fp); @@ -1026,6 +1026,8 @@ sizeof newpath - (newptr - newpath)); + if (StopRequest) + stop_sendmail(); ret = mci_traverse_persistent(action, newpath); if (ret < 0) break; @@ -1125,6 +1127,9 @@ /* skip directories */ if (hostname == NULL) return 0; + + if (StopRequest) + stop_sendmail(); if (!initflag) { Index: gnu/usr.sbin/sendmail/sendmail/milter.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/milter.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/milter.c 2001/02/28 02:43:54 1.4 +++ gnu/usr.sbin/sendmail/sendmail/milter.c 2001/05/29 01:31:15 1.5 @@ -9,7 +9,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: milter.c,v 8.50.4.44 2001/01/23 19:43:57 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: milter.c,v 8.50.4.46 2001/05/11 18:11:36 gshapiro Exp $"; #endif /* ! lint */ #if _FFR_MILTER @@ -62,7 +62,7 @@ !isascii(response[2]) || !isdigit(response[2])) \ { \ if (response != NULL) \ - free(response); \ + sm_free(response); \ response = newstr(default); \ } \ else \ @@ -74,7 +74,7 @@ { \ if (*ptr == '%' && *++ptr != '%') \ { \ - free(response); \ + sm_free(response); \ response = newstr(default); \ break; \ } \ @@ -354,7 +354,7 @@ if (milter_sysread(m, buf, expl, to, e) == NULL) { - free(buf); + sm_free(buf); return NULL; } @@ -1007,12 +1007,12 @@ 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 @@ } (void) milter_write(m, SMFIC_MACRO, buf, s, m->mf_timeout[SMFTO_WRITE], e); - free(buf); + sm_free(buf); } /* @@ -1836,7 +1836,7 @@ if (*state != SMFIR_REPLYCODE && response != NULL) { - free(response); + sm_free(response); response = NULL; } return response; @@ -1970,7 +1970,7 @@ "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(%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(%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_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 @@ /* 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 @@ *state = SMFIR_TEMPFAIL; if (response != NULL) { - free(response); + sm_free(response); response = NULL; } } @@ -2522,7 +2522,7 @@ 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 @@ 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 @@ *state = SMFIR_REJECT; if (response != NULL) { - free(response); + sm_free(response); response = NULL; } } @@ -3042,7 +3042,7 @@ /* 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 @@ /* send it over */ response = milter_command(SMFIC_RCPT, buf, s, MilterEnvRcptMacros, e, state); - free(buf); + sm_free(buf); return response; } /* @@ -3382,7 +3382,7 @@ if (rcmd != SMFIR_REPLYCODE && response != NULL) { - free(response); + sm_free(response); response = NULL; } @@ -3414,7 +3414,7 @@ *state = SMFIR_TEMPFAIL; if (response != NULL) { - free(response); + sm_free(response); response = NULL; } } @@ -3446,7 +3446,7 @@ *state = SMFIR_TEMPFAIL; if (response != NULL) { - free(response); + sm_free(response); response = NULL; } } Index: gnu/usr.sbin/sendmail/sendmail/parseaddr.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/parseaddr.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/parseaddr.c 2001/02/28 02:43:54 1.4 +++ gnu/usr.sbin/sendmail/sendmail/parseaddr.c 2001/05/29 01:31:15 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: parseaddr.c,v 8.234.4.11 2001/02/14 04:07:27 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: parseaddr.c,v 8.234.4.12 2001/05/03 17:24:11 gshapiro Exp $"; #endif /* ! lint */ #include @@ -1157,7 +1157,7 @@ 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 @@ if (i > rwbuflen) { if (rwbuf != NULL) - free(rwbuf); + sm_free(rwbuf); rwbuflen = i; rwbuf = (char *) xalloc(rwbuflen); } @@ -2461,7 +2461,7 @@ if (tTd(29, 9)) dprintf("maplocaluser: address unchanged\n"); if (a1 != NULL) - free(a1); + sm_free(a1); return; } @@ -2808,7 +2808,7 @@ QuickAbort = saveQuickAbort; setstat(rstat); if (buf != buf0) - free(buf); + sm_free(buf); if (rstat != EX_OK && QuickAbort) longjmp(TopFrame, 2); Index: gnu/usr.sbin/sendmail/sendmail/queue.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/queue.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/queue.c 2001/02/28 02:43:54 1.4 +++ gnu/usr.sbin/sendmail/sendmail/queue.c 2001/05/29 01:31:15 1.5 @@ -16,9 +16,9 @@ #ifndef lint # if QUEUE -static char id[] = "@(#)$Sendmail: queue.c,v 8.343.4.44 2001/02/22 00:55:35 ca Exp $ (with queueing)"; +static char id[] = "@(#)$Sendmail: queue.c,v 8.343.4.55 2001/05/03 23:37:11 gshapiro Exp $ (with queueing)"; # else /* QUEUE */ -static char id[] = "@(#)$Sendmail: queue.c,v 8.343.4.44 2001/02/22 00:55:35 ca Exp $ (without queueing)"; +static char id[] = "@(#)$Sendmail: 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 @@ fprintf(tfp, ".\n"); - if (fflush(tfp) < 0 || + if (fflush(tfp) != 0 || (SuperSafe && fsync(fileno(tfp)) < 0) || ferror(tfp)) { @@ -793,6 +793,12 @@ return TRUE; } /* child -- clean up signals */ + + /* Reset global flags */ + RestartRequest = NULL; + ShutdownRequest = NULL; + PendingSignal = 0; + clrcontrol(); proc_list_clear(); @@ -801,8 +807,8 @@ 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 @@ 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 @@ 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 @@ /* ** 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 @@ 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 @@ /* 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 @@ WorkQ = w; } if (WorkList != NULL) - free(WorkList); + sm_free(WorkList); WorkList = NULL; WorkListSize = 0; @@ -1464,8 +1480,8 @@ 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 @@ ** 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 @@ 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 @@ { register FILE *qfp; ADDRESS *ctladdr; - struct stat st; + struct stat st, stf; char *bp; int qfver = 0; long hdrsize = 0; @@ -1883,19 +1904,59 @@ } /* - ** 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 @@ } if (bp != buf) - free(bp); + sm_free(bp); } /* @@ -2351,7 +2412,11 @@ 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 @@ 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 @@ register int i; register char *p; + if (StopRequest) + stop_sendmail(); + fixcrlf(buf, TRUE); switch (buf[0]) { @@ -2680,7 +2751,8 @@ ** none. */ -static char Base60Code[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"; +static const char QueueIdChars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"; +# define QIC_LEN 60 void assign_queueid(e) @@ -2696,7 +2768,7 @@ 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 @@ } 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 @@ /* 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 @@ 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 @@ } 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); Index: gnu/usr.sbin/sendmail/sendmail/readcf.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/readcf.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- gnu/usr.sbin/sendmail/sendmail/readcf.c 2001/02/28 02:43:55 1.5 +++ gnu/usr.sbin/sendmail/sendmail/readcf.c 2001/05/29 01:31:16 1.6 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: readcf.c,v 8.382.4.38 2001/02/17 00:05:12 geir Exp $"; +static char id[] = "@(#)$Sendmail: readcf.c,v 8.382.4.40 2001/05/03 17:24:13 gshapiro Exp $"; #endif /* ! lint */ #include @@ -148,7 +148,7 @@ if (bp[0] == '#') { if (bp != buf) - free(bp); + sm_free(bp); continue; } @@ -545,7 +545,7 @@ syserr("unknown configuration line \"%s\"", bp); } if (bp != buf) - free(bp); + sm_free(bp); } if (ferror(cf)) { @@ -1269,7 +1269,7 @@ 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 @@ { "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 @@ 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 @@ 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 @@ case O_PIDFILE: if (PidFile != NULL) - free(PidFile); + sm_free(PidFile); PidFile = newstr(val); break; @@ -2688,7 +2688,7 @@ case O_DEADLETTER: if (DeadLetterDrop != NULL) - free(DeadLetterDrop); + sm_free(DeadLetterDrop); DeadLetterDrop = newstr(val); break; @@ -2778,7 +2778,7 @@ case O_CONTROLSOCKET: if (ControlSocketName != NULL) - free(ControlSocketName); + sm_free(ControlSocketName); ControlSocketName = newstr(val); break; @@ -2792,7 +2792,7 @@ case O_PROCTITLEPREFIX: if (ProcTitlePrefix != NULL) - free(ProcTitlePrefix); + sm_free(ProcTitlePrefix); ProcTitlePrefix = newstr(val); break; @@ -2818,13 +2818,13 @@ } #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 @@ #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 @@ 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); Index: gnu/usr.sbin/sendmail/sendmail/recipient.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/recipient.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/recipient.c 2001/02/28 02:43:55 1.3 +++ gnu/usr.sbin/sendmail/sendmail/recipient.c 2001/05/29 01:31:16 1.4 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: recipient.c,v 8.231.14.10 2001/02/14 04:07:30 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: recipient.c,v 8.231.14.11 2001/05/03 17:24:14 gshapiro Exp $"; #endif /* ! lint */ #include @@ -185,7 +185,7 @@ 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 @@ 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 @@ 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 @@ 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); } /* Index: gnu/usr.sbin/sendmail/sendmail/savemail.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/savemail.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/savemail.c 2001/02/28 02:43:55 1.4 +++ gnu/usr.sbin/sendmail/sendmail/savemail.c 2001/05/29 01:31:16 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: savemail.c,v 8.212.4.12 2001/01/07 19:31:05 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: savemail.c,v 8.212.4.13 2001/05/03 17:24:15 gshapiro Exp $"; #endif /* ! lint */ #include @@ -1413,7 +1413,7 @@ if (l > bplen) { if (bp != NULL) - free(bp); + sm_free(bp); bp = xalloc(l); bplen = l; } @@ -1466,7 +1466,7 @@ if (l > bplen) { if (bp != NULL) - free(bp); + sm_free(bp); bp = xalloc(l); bplen = l; } Index: gnu/usr.sbin/sendmail/sendmail/sendmail.h =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/sendmail.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- gnu/usr.sbin/sendmail/sendmail/sendmail.h 2001/02/28 02:43:55 1.5 +++ gnu/usr.sbin/sendmail/sendmail/sendmail.h 2001/05/29 01:31:16 1.6 @@ -20,7 +20,7 @@ #ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailId[] = "@(#)$Sendmail: sendmail.h,v 8.517.4.50 2001/02/22 18:56:24 gshapiro Exp $"; +static char SmailId[] = "@(#)$Sendmail: 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 @@ #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 @@ /* 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 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 @@ #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 @@ #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 @@ 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 @@ 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 @@ -1628,6 +1633,51 @@ /* 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. */ @@ -1664,9 +1714,9 @@ 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 */ @@ -1695,6 +1745,7 @@ 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 */ @@ -1710,7 +1761,7 @@ 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) */ @@ -1815,9 +1866,11 @@ #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 */ @@ -1827,6 +1880,7 @@ 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 */ @@ -1840,7 +1894,6 @@ 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 */ @@ -1878,6 +1931,7 @@ #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)); @@ -1974,6 +2028,7 @@ #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 *)); @@ -2000,7 +2055,7 @@ 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)); @@ -2014,6 +2069,11 @@ 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)); @@ -2028,7 +2088,6 @@ 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)); @@ -2048,11 +2107,10 @@ 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)); @@ -2074,9 +2132,9 @@ 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 *)); @@ -2084,13 +2142,13 @@ 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 @@ -2103,6 +2161,8 @@ 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 *)); Index: gnu/usr.sbin/sendmail/sendmail/sfsasl.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/sfsasl.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/sfsasl.c 2001/01/15 21:09:10 1.3 +++ gnu/usr.sbin/sendmail/sendmail/sfsasl.c 2001/05/29 01:31:16 1.4 @@ -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[] = "@(#)$Sendmail: sfsasl.c,v 8.17.4.13 2000/11/03 00:24:49 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: sfsasl.c,v 8.17.4.14 2001/05/03 17:24:16 gshapiro Exp $"; #endif /* ! lint */ #if SFIO @@ -28,7 +28,7 @@ # 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 @@ 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 @@ 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 @@ tc->fp = NULL; } - free(tc); + sm_free(tc); return retval; } # endif /* !SFIO */ @@ -335,15 +329,9 @@ 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 @@ 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 @@ 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 @@ tlsin->fp = NULL; fclose(*fin); *fin = save; - free(tlsout); + sm_free(tlsout); return -1; } *fout = fp; Index: gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c 2001/02/28 02:43:55 1.4 +++ gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c 2001/05/29 01:31:16 1.5 @@ -16,9 +16,9 @@ #ifndef lint # if SMTP -static char id[] = "@(#)$Sendmail: srvrsmtp.c,v 8.471.2.2.2.67 2001/01/07 19:31:05 gshapiro Exp $ (with SMTP)"; +static char id[] = "@(#)$Sendmail: srvrsmtp.c,v 8.471.2.2.2.77 2001/05/27 22:20:30 gshapiro Exp $ (with SMTP)"; # else /* SMTP */ -static char id[] = "@(#)$Sendmail: srvrsmtp.c,v 8.471.2.2.2.67 2001/01/07 19:31:05 gshapiro Exp $ (without SMTP)"; +static char id[] = "@(#)$Sendmail: 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 @@ # 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 @@ 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 @@ if (LogLevel > 9) tlslogerr(); } - tls_ok = FALSE; + tls_ok_srv = FALSE; SSL_free(srv_ssl); srv_ssl = NULL; @@ -1080,7 +1080,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ break; } if (response != NULL) - free(response); + sm_free(response); } # endif /* _FFR_MILTER */ if (Errors > 0) @@ -1745,7 +1746,7 @@ break; } if (response != NULL) - free(response); + sm_free(response); } # endif /* _FFR_MILTER */ @@ -1847,7 +1848,7 @@ break; } if (response != NULL) - free(response); + sm_free(response); } /* abort message filters that didn't get the body */ @@ -1858,7 +1859,7 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ { # 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 @@ 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 @@ ok = TRUE; } else -# endif /* EGD */ +# endif /* EGD */ if (randdef == RF_OK && strncasecmp(randfile, "file:", 5) == 0) { int fd; @@ -3288,7 +3291,39 @@ 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 @@ 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 @@ 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 @@ ** ** 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 Index: gnu/usr.sbin/sendmail/sendmail/stab.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/stab.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/stab.c 2001/01/15 21:09:10 1.3 +++ gnu/usr.sbin/sendmail/sendmail/stab.c 2001/05/29 01:31:16 1.4 @@ -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[] = "@(#)$Sendmail: stab.c,v 8.40.16.3 2000/10/09 02:46:12 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: stab.c,v 8.40.16.7 2001/05/07 22:06:41 gshapiro Exp $"; #endif /* ! lint */ #include @@ -160,8 +160,8 @@ break; #ifdef LDAPMAP - case ST_LDAP: - len = sizeof s->s_ldap; + case ST_LMAP: + len = sizeof s->s_lmap; break; #endif /* LDAPMAP */ Index: gnu/usr.sbin/sendmail/sendmail/udb.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/udb.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- gnu/usr.sbin/sendmail/sendmail/udb.c 2001/02/28 02:43:55 1.3 +++ gnu/usr.sbin/sendmail/sendmail/udb.c 2001/05/29 01:31:16 1.4 @@ -15,9 +15,9 @@ #ifndef lint # if USERDB -static char id[] = "@(#)$Sendmail: udb.c,v 8.111.16.1 2001/01/04 18:18:37 gshapiro Exp $ (with USERDB)"; +static char id[] = "@(#)$Sendmail: udb.c,v 8.111.16.2 2001/05/03 17:24:17 gshapiro Exp $ (with USERDB)"; # else /* USERDB */ -static char id[] = "@(#)$Sendmail: udb.c,v 8.111.16.1 2001/01/04 18:18:37 gshapiro Exp $ (without USERDB)"; +static char id[] = "@(#)$Sendmail: 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 @@ memmove(nuser, user, usersize); if (user != userbuf) - free(user); + sm_free(user); user = nuser; usersize += size; userleft += size; @@ -545,7 +545,7 @@ break; } if (user != userbuf) - free(user); + sm_free(user); } return EX_OK; } @@ -1055,11 +1055,11 @@ 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)) Index: gnu/usr.sbin/sendmail/sendmail/usersmtp.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/usersmtp.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/usersmtp.c 2001/02/28 02:43:55 1.4 +++ gnu/usr.sbin/sendmail/sendmail/usersmtp.c 2001/05/29 01:31:16 1.5 @@ -15,9 +15,9 @@ #ifndef lint # if SMTP -static char id[] = "@(#)$Sendmail: usersmtp.c,v 8.245.4.24 2001/02/21 00:59:09 gshapiro Exp $ (with SMTP)"; +static char id[] = "@(#)$Sendmail: usersmtp.c,v 8.245.4.33 2001/05/23 18:53:09 ca Exp $ (with SMTP)"; # else /* SMTP */ -static char id[] = "@(#)$Sendmail: usersmtp.c,v 8.245.4.24 2001/02/21 00:59:09 gshapiro Exp $ (without SMTP)"; +static char id[] = "@(#)$Sendmail: 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 @@ { 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 @@ 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 @@ { # 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ ** 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 @@ 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 @@ 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 @@ */ static jmp_buf CtxDataTimeout; +static EVENT *volatile DataTimeout = NULL; int smtpdata(m, mci, e) @@ -1759,13 +1747,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; Index: gnu/usr.sbin/sendmail/sendmail/util.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/util.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/util.c 2001/02/28 02:43:55 1.4 +++ gnu/usr.sbin/sendmail/sendmail/util.c 2001/05/29 01:31:16 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: util.c,v 8.225.2.1.2.19 2001/02/22 18:56:24 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: util.c,v 8.225.2.1.2.23 2001/05/17 18:10:18 gshapiro Exp $"; #endif /* ! lint */ #include @@ -378,15 +378,122 @@ 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 @@ } 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 @@ 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 @@ 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 @@ ** 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 @@ /* 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 @@ { /* allocate more space */ if (bp != NULL) - free(bp); + sm_free(bp); bp = xalloc(l); bl = l; } @@ -2199,7 +2318,7 @@ ** none */ -static struct procs *ProcListVec = NULL; +static struct procs *volatile ProcListVec = NULL; static int ProcListSize = 0; void @@ -2238,7 +2357,7 @@ { 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 @@ } 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 @@ 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 @@ ** ** 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 Index: gnu/usr.sbin/sendmail/sendmail/version.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/version.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/sendmail/version.c 2001/02/28 02:43:55 1.4 +++ gnu/usr.sbin/sendmail/sendmail/version.c 2001/05/29 01:31:16 1.5 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: version.c,v 8.43.4.30 2001/02/27 19:22:31 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: 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"; Index: gnu/usr.sbin/sendmail/smrsh/smrsh.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/smrsh/smrsh.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/smrsh/smrsh.c 2001/02/28 02:43:56 1.4 +++ gnu/usr.sbin/sendmail/smrsh/smrsh.c 2001/05/29 01:31:17 1.5 @@ -21,7 +21,7 @@ #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Sendmail: smrsh.c,v 8.31.4.8 2001/01/22 19:00:26 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: smrsh.c,v 8.31.4.9 2001/04/24 04:11:51 ca Exp $"; #endif /* ! lint */ /* @@ -173,7 +173,6 @@ */ prg = argv[0]; - par = argv[2]; if (argc != 3 || strcmp(argv[1], "-c") != 0) { @@ -183,6 +182,8 @@ #endif /* ! DEBUG */ exit(EX_USAGE); } + + par = argv[2]; /* ** Disallow special shell syntax. This is overly restrictive, Index: gnu/usr.sbin/sendmail/vacation/vacation.c =================================================================== RCS file: /cvs/src/gnu/usr.sbin/sendmail/vacation/vacation.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- gnu/usr.sbin/sendmail/vacation/vacation.c 2001/02/28 02:43:56 1.4 +++ gnu/usr.sbin/sendmail/vacation/vacation.c 2001/05/29 01:31:17 1.5 @@ -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 @@ #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Sendmail: vacation.c,v 8.68.4.16 2001/02/14 05:02:21 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: vacation.c,v 8.68.4.21 2001/05/07 22:06:41 gshapiro Exp $"; #endif /* ! lint */ + #include #include #include @@ -113,12 +114,16 @@ 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 @@ 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 @@ "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 @@ 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 @@ 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 @@ 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 @@ "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 @@ ** nothing. ** */ + static void eatmsg() { @@ -562,6 +594,7 @@ ** is name a substring of str? ** */ + bool nsearch(name, str) register char *name, *str; @@ -737,7 +770,6 @@ cur->len) == 0) return TRUE; } - return FALSE; } @@ -754,6 +786,7 @@ ** TRUE iff user has gotten a vacation message recently. ** */ + bool recent() { @@ -815,6 +848,7 @@ ** Side Effects: ** stores the reply interval in database. */ + void setinterval(interval) time_t interval; @@ -845,6 +879,7 @@ ** Side Effects: ** stores user/time in database. */ + void setreply(from, when) char *from; @@ -875,6 +910,7 @@ ** Side Effects: ** stores users in database. */ + void xclude(f) FILE *f; @@ -906,6 +942,7 @@ ** Side Effects: ** sends vacation reply. */ + void sendmessage(myname, msgfn, emptysender) char *myname; @@ -915,6 +952,7 @@ FILE *mfp, *sfp; int i; int pvect[2]; + char *pv[8]; char buf[MAXLINE]; mfp = fopen(msgfn, "r"); @@ -932,6 +970,16 @@ 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 @@ (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 @@ 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 @@ "", #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); }