2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +00:00

postfix-2.6-20080824

This commit is contained in:
Wietse Venema 2008-08-24 00:00:00 -05:00 committed by Viktor Dukhovni
parent acb84351c9
commit d2e427a653
31 changed files with 485 additions and 156 deletions

View File

@ -14569,3 +14569,43 @@ Apologies for any names omitted.
legitimate configurations that deliver mail to a symbolic
link in a directory with less restrictive permissions.
20080815
Feature: the milter_default_action parameter now accepts
the "quarantine" action. This works like "accept" but also
freezes the mail in the "hold" queue. File: milter/milter8.c.
Robustness: transition from setjmp()/longjmp() to the signal
mask saving/restoring versions sigsetjmp()/siglongjmp().
These functions have been around for 15 years, but they
have had bugs on supported platforms, so makedefs tests for
them. Files: makedefs, util/sys_defs.h, util/vstream.h.
20080822
Cleanup: the proxymap_service_name and proxywrite_service_name
parameters make the proxymap service names configurable.
This paves the way for a future option where the proxymap
services are accessible via TCP so that they can be shared
among multiple Postfix hosts. File: global/dict_proxy.c.
Feature: MacOS X support for kqueue style event handling,
with workaround for broken MacOS X versions. Files:
util/sys_defs.h, makedefs.
Cleanup: the makedefs script now keeps its test programs
in a directory makedefs.d, instead of inlining them as
fragile "here documents". Files: makedefs, makedefs.d/*.
20080823
Feature: IPv6 dns blocklist lookup. File: smtpd/smtpd_check.c.
20080824
Cleanup: untangled the MacOS X version dependent sections
in the makedefs script, to make future updates easier. File:
makedefs.
Cleanup: don't log multiple Milter "hold" actions for
the same message. File: cleanup/cleanup_milter.c.

View File

@ -250,10 +250,12 @@ The milter_default_action parameter specifies how Postfix handles Milter
application errors. The default action is to respond with a temporary error
status, so that the client will try again later. Specify "accept" if you want
to receive mail as if the filter does not exist, and "reject" to reject mail
with a permanent status.
with a permanent status. The "quarantine" action is like "accept" but freezes
the message in the "hold" queue, and is available with Postfix 2.6 or later.
/etc/postfix/main.cf:
# What to do in case of errors? Specify accept, reject, or tempfail.
# What to do in case of errors? Specify accept, reject, tempfail,
# or quarantine (Postfix 2.6 or later).
milter_default_action = tempfail
MMiilltteerr pprroottooccooll vveerrssiioonn

View File

@ -43,10 +43,17 @@ activity). Symptoms of Postfix SMTP mail server overload are:
Postfix 2.1), and tell users to connect to this instead of the public SMTP
service.
o NOTE: Broken DNS configurations also cause lengthy delays before
Postfix sends "220 hostname.example.com ...". In this case the delay
happens even when Postfix is not busy.
* The Postfix SMTP server logs an increased number of "lost connection after
CONNECT" events. This happens because remote SMTP clients disconnect before
Postfix answers the connection.
o NOTE: A portscan for open SMTP ports also results in "lost connection
..." logfile messages.
* Postfix 2.3 and later logs a warning that all server ports are busy:
Oct 3 20:39:27 spike postfix/master[28905]: warning: service "smtp"
@ -56,14 +63,6 @@ activity). Symptoms of Postfix SMTP mail server overload are:
condition, increase the process count in master.cf or reduce the
service time per client
NOTE: The first two symptoms may also happen without overload, for example:
* Broken DNS also causes lengthy delays before "220 hostname.example.com ..."
while the Postfix SMTP server tries to look up the client's hostname.
* A portscan for open SMTP ports also results in "lost connection ..."
logfile messages.
Legitimate mail that doesn't get through during an episode of overload is not
necessarily lost. It should still arrive once the situation returns to normal,
as long as the overload condition is temporary.
@ -86,7 +85,7 @@ keep up with the additional load.
Linux epoll(4), or Solaris /dev/poll).
* You can reduce the Postfix memory footprint by using cdb: lookup tables
instead of Berkeley DB.
instead of Berkeley DB's hash: or btree: tables.
1 /etc/postfix/main.cf:
2 # Raise the global process limit, 100 since Postfix 2.0.
@ -104,9 +103,11 @@ keep up with the additional load.
the SMTP server's "maxproc" field in master.cf, SMTP server processes will
report problems when connecting to policy server processes, because there
aren't enough of them. Examples of errors are "connection refused" or
"operation timed out". To fix, edit master.cf and specify a zero "maxproc"
field in all policy server entries; see line 6 in the example below. Issue
a "postfix reload" command to make the change effective.
"operation timed out".
To fix, edit master.cf and specify a zero "maxproc" field in all policy
server entries; see line 6 in the example below. Issue a "postfix reload"
command to make the change effective.
1 /etc/postfix/master.cf:
2 # =============================================================
@ -121,7 +122,7 @@ SSppeenndd lleessss ttiimmee ppeerr SSMMTTPP cclliieenn
When increasing the number of SMTP server processes is not practical, you can
improve Postfix server responsiveness by eliminating unnecessary work. When
Postfix spends less time per SMTP session, the same number of SMTP server
processes can service more clients in the same amount of time.
processes can service more clients.
* Eliminate non-functional RBL lookups (blocklists that are no longer in
operation). These lookups can degrade performance. Postfix logs a warning

View File

@ -11,6 +11,14 @@ instead, a new snapshot is released.
The mail_release_date configuration parameter (format: yyyymmdd)
specifies the release date of a stable release or snapshot release.
Incompatibility with snapshot 20080814
======================================
When a mailbox file is not owned by its recipient, the local and
virtual delivery agents now log a warning and defer delivery.
Specify "strict_mailbox_ownership = no" to ignore such ownership
discrepancies.
Incompatibility with snapshot 20080629
======================================

View File

@ -1,5 +1,5 @@
Wish list:
Force a panic when the VDA patch reduces the file size limit
under the message size. They break the code that marks a
recipient as "done", when that recipient was added late
@ -37,11 +37,12 @@ Wish list:
that it makes smtpd_mumble_restrictions available for local
and remote mail; the disadvantage is that it makes local
submissions more dependent on networking. One possibility
is to use "pickup -o content_filter=smtp:127.0.0.1". Another
is to have the pickup or cleanup server drive an SMTP client
directly; this would require extension of the mail_stream()
interface, plus a way to handle bounced/deferred recipients
intelligently.
is to use "pickup -o content_filter=smtp:127.0.0.1:10025";
we could also to suppress "mail loop" detection for loopback
connections. Another is to have the pickup or cleanup
server drive an SMTP client directly; this would require
extension of the mail_stream() interface, plus a way to
handle bounced/deferred recipients intelligently.
Consolidate duplicated code in *_server_accept_{pass,inet}().

View File

@ -425,12 +425,15 @@ Milter application errors. The default action is to respond with a
temporary error status, so that the client will try again later.
Specify "accept" if you want to receive mail as if the filter does
not exist, and "reject" to reject mail with a permanent status.
The "quarantine" action is like "accept" but freezes the message
in the "<a href="QSHAPE_README.html#hold_queue">hold" queue</a>, and is available with Postfix 2.6 or later.
</p>
<blockquote>
<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
# What to do in case of errors? Specify accept, reject, or tempfail.
# What to do in case of errors? Specify accept, reject, tempfail,
# or quarantine (Postfix 2.6 or later).
<a href="postconf.5.html#milter_default_action">milter_default_action</a> = tempfail
</pre>
</blockquote>

View File

@ -77,10 +77,25 @@ this affects end-user mail clients, enable the "submission" service
entry in <a href="master.5.html">master.cf</a> (present since Postfix 2.1), and tell users to
connect to this instead of the public SMTP service. </p>
<ul>
<li> <p> NOTE: Broken DNS configurations also cause lengthy delays
before Postfix sends "220 hostname.example.com ...". In this case
the delay happens even when Postfix is not busy. </p>
</ul>
<li> <p> The Postfix SMTP server logs an increased number of "lost
connection after CONNECT" events. This happens because remote SMTP
clients disconnect before Postfix answers the connection. </p>
<ul>
<li> <p> NOTE: A portscan for open SMTP ports also results in "lost
connection ..." logfile messages. </p>
</ul>
<li> <p> Postfix 2.3 and later logs a warning that all server ports
are busy: </p>
@ -95,21 +110,6 @@ Oct 3 20:39:27 spike postfix/master[28905]: warning: to avoid this
</ul>
<p> NOTE: The first two symptoms may also happen without overload,
for example: </p>
<ul>
<li> <p> Broken DNS also causes lengthy delays before "220
hostname.example.com
..." while the Postfix SMTP server tries to look up the client's
hostname. </p>
<li> <p> A portscan for open SMTP ports also results in "lost
connection ..." logfile messages. </p>
</ul>
<p> Legitimate mail that doesn't get through during an episode of
overload is not necessarily lost. It should still arrive once the
situation returns to normal, as long as the overload condition is
@ -138,7 +138,7 @@ filters (BSD kqueue(2), Linux epoll(4), or Solaris /dev/poll).
</p>
<li> <p> You can reduce the Postfix memory footprint by using <a href="CDB_README.html">cdb</a>:
lookup tables instead of Berkeley DB. </p>
lookup tables instead of Berkeley DB's hash: or btree: tables. </p>
<pre>
1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
@ -159,7 +159,9 @@ processes. When you raise the SMTP server's "maxproc" field in
<a href="master.5.html">master.cf</a>, SMTP server processes will report problems when connecting
to policy server processes, because there aren't enough of them.
Examples of errors are "connection refused" or "operation timed
out". To fix, edit <a href="master.5.html">master.cf</a> and specify a zero "maxproc" field
out". </p>
<p> To fix, edit <a href="master.5.html">master.cf</a> and specify a zero "maxproc" field
in all policy server entries; see line 6 in the example below.
Issue a "postfix reload" command to make the change effective. </p>
@ -180,8 +182,7 @@ Issue a "postfix reload" command to make the change effective. </p>
<p> When increasing the number of SMTP server processes is not
practical, you can improve Postfix server responsiveness by eliminating
unnecessary work. When Postfix spends less time per SMTP session, the
same number of SMTP server processes can service more clients in
the same amount of time. </p>
same number of SMTP server processes can service more clients. </p>
<ul>

View File

@ -1434,6 +1434,8 @@ operations. The time limit is enforced in the client. </p>
<p> The name of the <a href="scache.8.html">scache(8)</a> connection cache service. This service
maintains a limited pool of cached sessions. </p>
<p> This feature is available in Postfix 2.2 and later. </p>
</DD>
@ -5482,6 +5484,9 @@ with a permanent status code.</dd>
<dt>tempfail</dt> <dd>Reject all further commands in this session
with a temporary status code. </dd>
<dt>quarantine</dt> <dd>Like "accept", but freeze the message in
the "<a href="QSHAPE_README.html#hold_queue">hold" queue</a>. Available with Postfix 2.6 and later. </dd>
</dl>
<p> This feature is available in Postfix 2.3 and later. </p>
@ -6295,6 +6300,29 @@ This feature is available in Postfix 2.5 and later.
</p>
</DD>
<DT><b><a name="proxymap_service_name">proxymap_service_name</a>
(default: proxymap)</b></DT><DD>
<p> The name of the proxymap read-only table lookup service. This
service is normally implemented by the <a href="proxymap.8.html">proxymap(8)</a> daemon. </p>
<p> This feature is available in Postfix 2.6 and later. </p>
</DD>
<DT><b><a name="proxywrite_service_name">proxywrite_service_name</a>
(default: proxywrite)</b></DT><DD>
<p> The name of the proxywrite read-write table lookup service.
This service is normally implemented by the <a href="proxymap.8.html">proxymap(8)</a> daemon.
</p>
<p> This feature is available in Postfix 2.6 and later. </p>
</DD>
<DT><b><a name="qmgr_clog_warn_time">qmgr_clog_warn_time</a>

View File

@ -33,18 +33,22 @@
# Do not build with Linux EPOLL support.
# By default, EPOLL support is compiled in on platforms that
# are known to support it.
# .IP \fB-DNO_KQUEUE\fR
# Do not build with FreeBSD/NetBSD/OpenBSD KQUEUE support.
# By default, KQUEUE support is compiled in on platforms that
# are known to support it.
# .IP \fB-DNO_IPV6\fR
# Do not build with IPv6 support.
# By default, IPv6 support is compiled in on platforms that
# are known to have IPv6 support.
# .IP \fB-DNO_KQUEUE\fR
# Do not build with FreeBSD/NetBSD/OpenBSD/MacOSX KQUEUE support.
# By default, KQUEUE support is compiled in on platforms that
# are known to support it.
# .IP \fB-DNO_PCRE\fR
# Do not build with PCRE support.
# By default, PCRE support is compiled in when the \fBpcre-config\fR
# utility is installed.
# .IP \fB-DNO_SIGSETJMP\fR
# Use setjmp()/longjmp() instead of sigsetjmp()/siglongjmp().
# By default, Postfix uses sigsetjmp()/siglongjmp() when they
# appear to work.
# .RE
# .IP \fBDEBUG=\fIdebug_level\fR
# Specifies a non-default debugging level. The default is \fB-g\fR.
@ -168,7 +172,7 @@ case "$SYSTEM.$RELEASE" in
SunOS.5*) SYSTYPE=SUNOS5
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl"
# Solaris 5 added usleep() and POSIX regular expressions
# Solaris 2.5 added usleep() and POSIX regular expressions
case $RELEASE in
5.[0-4]) CCARGS="$CCARGS -DMISSING_USLEEP -DNO_POSIX_REGEXP";;
esac
@ -283,32 +287,12 @@ case "$SYSTEM.$RELEASE" in
# Kernel 2.6 added EPOLL
case "$RELEASE" in
2.[0-5].*) CCARGS="$CCARGS -DNO_EPOLL";;
esac
# Workaround for retarded libc
case "$RELEASE" in
2.6.*)
trap 'rm -f makedefs.test makedefs.test.o makedefs.test.c' 1 2 3 15
cat >makedefs.test.c <<EOF
#include <sys/types.h>
#include <sys/epoll.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int epoll_handle;
if ((epoll_handle = epoll_create(1)) < 0) {
perror("epoll_create");
exit(1);
}
exit(0);
}
EOF
${CC-gcc} -o makedefs.test makedefs.test.c || exit 1
./makedefs.test 2>/dev/null || CCARGS="$CCARGS -DNO_EPOLL"
rm -f makedefs.test makedefs.test.o makedefs.test.c;;
# Workaround for retarded libc
2.6.*) trap 'rm -f linux_epoll linux_epoll.o' 1 2 3 15
${CC-gcc} -o linux_epoll makedefs.d/linux_epoll.c || exit 1
./linux_epoll 2>/dev/null ||
CCARGS="$CCARGS -DNO_EPOLL"
rm -f linux_epoll linux_epoll.o;;
esac
;;
GNU.0*|GNU/kFreeBSD.[567]*)
@ -384,25 +368,38 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl"
;;
Rhapsody.5*|Darwin.*)
SYSTYPE=MACOSX
Darwin.*) SYSTYPE=MACOSX
# Use the native compiler by default
: ${CC=cc}
# Darwin > 1.3 uses awk and flat_namespace
case $RELEASE in
1.[0-3]) AWK=gawk
CCARGS="$CCARGS -DNO_IPV6"
;;
[2-6].*) AWK=awk
CCARGS="$CCARGS -DNO_IPV6"
SYSLIBS=-flat_namespace
;;
*) AWK=awk
SYSLIBS=-flat_namespace
CCARGS="$CCARGS -DBIND_8_COMPAT -DNO_NETINFO"
;;
esac
# Darwin 7 adds IPv6 support, BIND_8_COMPAT, NO_NETINFO
case $RELEASE in
[1-6].*) CCARGS="$CCARGS -DNO_IPV6"
;;
*) CCARGS="$CCARGS -DBIND_8_COMPAT -DNO_NETINFO"
;;
esac
# Darwin 8.11.1 has kqueue support, but let's play safe
case $RELEASE in
[1-8].*) CCARGS="$CCARGS -DNO_KQUEUE"
;;
*) trap 'rm -f macosx_kqueue macosx_kqueue.o' 1 2 3 15
${CC-gcc} -o macosx_kqueue makedefs.d/macosx_kqueue.c || exit 1
./macosx_kqueue 2>/dev/null ||
CCARGS="$CCARGS -DNO_KQUEUE"
rm -f macosx_kqueue macosx_kqueue.o
;;
esac
;;
"Mac OS".10*) SYSTYPE=MACOSX
Rhapsody.5*|"Mac OS".10*)
SYSTYPE=MACOSX
# Use the native compiler by default
: ${CC=cc}
AWK=gawk
@ -428,6 +425,19 @@ Rhapsody.5*|Darwin.*)
*) error "Unknown system type: $SYSTEM $RELEASE";;
esac
#
# sigsetjmp()/siglongjmp() can be "better" than setjmp()/longjmp()
# if used wisely (that is: almost never, just like signals).
# Unfortunately some implementations have been buggy in the past.
#
case "$CCARGS" in
*-DNO_SIGSETJMP*) ;;
*) trap 'rm -f sigsetjmp sigsetjmp.o' 1 2 3 15
${CC-gcc} -o sigsetjmp makedefs.d/sigsetjmp.c || exit 1
./sigsetjmp 2>/dev/null || CCARGS="$CCARGS -DNO_SIGSETJMP"
rm -f sigsetjmp sigsetjmp.o;;
esac
#
# OpenSSL has no configuration query utility, but we don't try to
# guess. We assume includes in /usr/include/openssl and libraries in

View File

@ -0,0 +1,16 @@
#include <sys/types.h>
#include <sys/epoll.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int epoll_handle;
if ((epoll_handle = epoll_create(1)) < 0) {
perror("epoll_create");
exit(1);
}
exit(0);
}

View File

@ -0,0 +1,45 @@
/* Adapted from libevent. */
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef EV_SET
#define EV_SET(kp, id, fi, fl, ffl, da, ud) do { \
struct kevent *__kp = (kp); \
__kp->ident = (id); \
__kp->filter = (fi); \
__kp->flags = (fl); \
__kp->fflags = (ffl); \
__kp->data = (da); \
__kp->udata = (ud); \
} while(0)
#endif
int main(int argc, char **argv)
{
int kq;
struct kevent test_change;
struct kevent test_result;
if ((kq = kqueue()) < 0) {
perror("kqueue");
exit(1);
}
#define TEST_FD (-1)
EV_SET(&test_change, TEST_FD, EVFILT_READ, EV_ADD, 0, 0, 0);
if (kevent(kq,
&test_change, sizeof(test_change) / sizeof(struct kevent),
&test_result, sizeof(test_result) / sizeof(struct kevent),
(struct timespec *) 0) != 1 ||
test_result.ident != TEST_FD ||
test_result.flags != EV_ERROR) {
fprintf(stderr, "kqueue is broken\n");
exit(1);
}
exit(0);
}

View File

@ -0,0 +1,37 @@
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
static int count = 0;
int main(int argc, char **argv)
{
sigjmp_buf env;
int retval;
switch (retval = sigsetjmp(env, 1)) {
case 0:
siglongjmp(env, 12345);
case 12345:
break;
default:
fprintf(stderr, "Error: siglongjmp ignores second argument\n");
exit(1);
}
switch (retval = sigsetjmp(env, 1)) {
case 0:
if (count++ > 0) {
fprintf(stderr, "Error: not overriding siglongjmp(env, 0)\n");
exit(1);
}
siglongjmp(env, 0);
case 1:
break;
default:
fprintf(stderr, "Error: overriding siglongjmp(env, 0) with %d\n",
retval);
exit(1);
}
exit(0);
}

View File

@ -794,6 +794,8 @@ This feature is available in Postfix 2.3 and later.
.SH connection_cache_service_name (default: scache)
The name of the \fBscache\fR(8) connection cache service. This service
maintains a limited pool of cached sessions.
.PP
This feature is available in Postfix 2.2 and later.
.SH connection_cache_status_update_time (default: 600s)
How frequently the \fBscache\fR(8) server logs usage statistics with
connection cache hit and miss rates for logical destinations and for
@ -3041,6 +3043,9 @@ with a permanent status code.
.IP "tempfail"
Reject all further commands in this session
with a temporary status code.
.IP "quarantine"
Like "accept", but freeze the message in
the "hold" queue. Available with Postfix 2.6 and later.
.PP
This feature is available in Postfix 2.3 and later.
.SH milter_end_of_data_macros (default: see postconf -n output)
@ -3506,6 +3511,16 @@ files should be stored under the Postfix-owned data_directory.
Table references that don't begin with proxy: are ignored.
.PP
This feature is available in Postfix 2.5 and later.
.SH proxymap_service_name (default: proxymap)
The name of the proxymap read-only table lookup service. This
service is normally implemented by the \fBproxymap\fR(8) daemon.
.PP
This feature is available in Postfix 2.6 and later.
.SH proxywrite_service_name (default: proxywrite)
The name of the proxywrite read-write table lookup service.
This service is normally implemented by the \fBproxymap\fR(8) daemon.
.PP
This feature is available in Postfix 2.6 and later.
.SH qmgr_clog_warn_time (default: 300s)
The minimal delay between warnings that a specific destination is
clogging up the Postfix active queue. Specify 0 to disable.

View File

@ -333,6 +333,8 @@ while (<>) {
s;\bprocess_name\b;<a href="postconf.5.html#process_name">$&</a>;g;
s;\bpropagate_unmatched_extensions\b;<a href="postconf.5.html#propagate_unmatched_extensions">$&</a>;g;
s;\bproxy_inter[-</bB>]*\n* *[<bB>]*faces\b;<a href="postconf.5.html#proxy_interfaces">$&</a>;g;
s;\bproxymap_service_name\b;<a href="postconf.5.html#proxymap_service_name">$&</a>;g;
s;\bproxywrite_service_name\b;<a href="postconf.5.html#proxywrite_service_name">$&</a>;g;
s;\bproxy_read_maps\b;<a href="postconf.5.html#proxy_read_maps">$&</a>;g;
s;\bproxy_write_maps\b;<a href="postconf.5.html#proxy_write_maps">$&</a>;g;
s;\bqmgr_clog_warn_time\b;<a href="postconf.5.html#qmgr_clog_warn_time">$&</a>;g;

View File

@ -425,12 +425,15 @@ Milter application errors. The default action is to respond with a
temporary error status, so that the client will try again later.
Specify "accept" if you want to receive mail as if the filter does
not exist, and "reject" to reject mail with a permanent status.
The "quarantine" action is like "accept" but freezes the message
in the "hold" queue, and is available with Postfix 2.6 or later.
</p>
<blockquote>
<pre>
/etc/postfix/main.cf:
# What to do in case of errors? Specify accept, reject, or tempfail.
# What to do in case of errors? Specify accept, reject, tempfail,
# or quarantine (Postfix 2.6 or later).
milter_default_action = tempfail
</pre>
</blockquote>

View File

@ -77,10 +77,25 @@ this affects end-user mail clients, enable the "submission" service
entry in master.cf (present since Postfix 2.1), and tell users to
connect to this instead of the public SMTP service. </p>
<ul>
<li> <p> NOTE: Broken DNS configurations also cause lengthy delays
before Postfix sends "220 hostname.example.com ...". In this case
the delay happens even when Postfix is not busy. </p>
</ul>
<li> <p> The Postfix SMTP server logs an increased number of "lost
connection after CONNECT" events. This happens because remote SMTP
clients disconnect before Postfix answers the connection. </p>
<ul>
<li> <p> NOTE: A portscan for open SMTP ports also results in "lost
connection ..." logfile messages. </p>
</ul>
<li> <p> Postfix 2.3 and later logs a warning that all server ports
are busy: </p>
@ -95,21 +110,6 @@ Oct 3 20:39:27 spike postfix/master[28905]: warning: to avoid this
</ul>
<p> NOTE: The first two symptoms may also happen without overload,
for example: </p>
<ul>
<li> <p> Broken DNS also causes lengthy delays before "220
hostname.example.com
..." while the Postfix SMTP server tries to look up the client's
hostname. </p>
<li> <p> A portscan for open SMTP ports also results in "lost
connection ..." logfile messages. </p>
</ul>
<p> Legitimate mail that doesn't get through during an episode of
overload is not necessarily lost. It should still arrive once the
situation returns to normal, as long as the overload condition is
@ -138,7 +138,7 @@ filters (BSD kqueue(2), Linux epoll(4), or Solaris /dev/poll).
</p>
<li> <p> You can reduce the Postfix memory footprint by using cdb:
lookup tables instead of Berkeley DB. </p>
lookup tables instead of Berkeley DB's hash: or btree: tables. </p>
<pre>
1 /etc/postfix/main.cf:
@ -159,7 +159,9 @@ processes. When you raise the SMTP server's "maxproc" field in
master.cf, SMTP server processes will report problems when connecting
to policy server processes, because there aren't enough of them.
Examples of errors are "connection refused" or "operation timed
out". To fix, edit master.cf and specify a zero "maxproc" field
out". </p>
<p> To fix, edit master.cf and specify a zero "maxproc" field
in all policy server entries; see line 6 in the example below.
Issue a "postfix reload" command to make the change effective. </p>
@ -180,8 +182,7 @@ Issue a "postfix reload" command to make the change effective. </p>
<p> When increasing the number of SMTP server processes is not
practical, you can improve Postfix server responsiveness by eliminating
unnecessary work. When Postfix spends less time per SMTP session, the
same number of SMTP server processes can service more clients in
the same amount of time. </p>
same number of SMTP server processes can service more clients. </p>
<ul>

View File

@ -8221,6 +8221,8 @@ The table is not searched by hostname for robustness reasons. </p>
<p> The name of the scache(8) connection cache service. This service
maintains a limited pool of cached sessions. </p>
<p> This feature is available in Postfix 2.2 and later. </p>
%PARAM connection_cache_ttl_limit 2s
<p> The maximal time-to-live value that the scache(8) connection
@ -10401,6 +10403,9 @@ with a permanent status code.</dd>
<dt>tempfail</dt> <dd>Reject all further commands in this session
with a temporary status code. </dd>
<dt>quarantine</dt> <dd>Like "accept", but freeze the message in
the "hold" queue. Available with Postfix 2.6 and later. </dd>
</dl>
<p> This feature is available in Postfix 2.3 and later. </p>
@ -11614,3 +11619,19 @@ details.
The default setting is not backwards compatible. </p>
<p> This feature is available in Postfix 2.5.3 and later. </p>
%PARAM proxymap_service_name proxymap
<p> The name of the proxymap read-only table lookup service. This
service is normally implemented by the proxymap(8) daemon. </p>
<p> This feature is available in Postfix 2.6 and later. </p>
%PARAM proxywrite_service_name proxywrite
<p> The name of the proxywrite read-write table lookup service.
This service is normally implemented by the proxymap(8) daemon.
</p>
<p> This feature is available in Postfix 2.6 and later. </p>

View File

@ -927,7 +927,7 @@ void cleanup_message(CLEANUP_STATE *state, int type, const char *buf, ssize_t
/*
* XXX Workaround: truncate a long message header so that we don't exceed
* the Milter request size limit of 65535.
* the default Sendmail libmilter request size limit of 65535.
*/
#define KLUDGE_HEADER_LIMIT 60000
if ((cleanup_milters || state->milters)

View File

@ -1399,6 +1399,8 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
switch (resp[0]) {
case 'H':
/* XXX Should log the reason here. */
if (state->flags & CLEANUP_FLAG_HOLD)
return (0);
state->flags |= CLEANUP_FLAG_HOLD;
action = "milter-hold";
text = "milter triggers HOLD action";

View File

@ -308,38 +308,53 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
int server_flags;
int status;
const char *service;
const char *relative_path;
char *relative_path;
char *kludge = 0;
char *prefix;
CLNT_STREAM **pstream;
/*
* Sanity checks.
* If this map can't be proxied then we silently do a direct open. This
* allows sites to benefit from proxying the virtual mailbox maps without
* unnecessary pain.
*/
if (dict_flags & DICT_FLAG_NO_PROXY)
return (dict_open(map, open_flags, dict_flags));
/*
* Use a shared stream for proxied table lookups of the same type.
*
* XXX A complete implementation would also allow O_RDWR without O_CREAT.
* But we must not pass on every possible set of flags to the proxy
* server; only sets that make sense. For now, the flags are passed
* implicitly by choosing between the proxymap or proxywrite service.
*
* XXX Use absolute pathname to make this work from non-daemon processes.
*/
if (open_flags == O_RDONLY) {
pstream = &proxymap_stream;
service = MAIL_SERVICE_PROXYMAP;
relative_path = MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYMAP;
service = var_proxymap_service;
} else if (open_flags == (O_RDWR | O_CREAT)) {
pstream = &proxywrite_stream;
service = MAIL_SERVICE_PROXYWRITE;
relative_path = MAIL_CLASS_PRIVATE "/" MAIL_SERVICE_PROXYWRITE;
service = var_proxywrite_service;
} else
msg_fatal("%s: %s map open requires O_RDONLY or O_RDWR|O_CREAT mode",
map, DICT_TYPE_PROXY);
/*
* OK. If this map can't be proxied then we silently do a direct open.
* This allows sites to benefit from proxying the virtual mailbox maps
* without unnecessary pain.
*/
if (dict_flags & DICT_FLAG_NO_PROXY)
return (dict_open(map, open_flags, dict_flags));
if (*pstream == 0) {
relative_path = concatenate(MAIL_CLASS_PRIVATE "/",
service, (char *) 0);
if (access(relative_path, F_OK) == 0)
prefix = MAIL_CLASS_PRIVATE;
else
prefix = kludge = concatenate(var_queue_dir, "/",
MAIL_CLASS_PRIVATE, (char *) 0);
*pstream = clnt_stream_create(prefix, service, var_ipc_idle_limit,
var_ipc_ttl_limit);
if (kludge)
myfree(kludge);
myfree(relative_path);
}
/*
* Local initialization.
@ -352,23 +367,6 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
dict_proxy->dict.close = dict_proxy_close;
dict_proxy->in_flags = dict_flags;
dict_proxy->result = vstring_alloc(10);
/*
* Use a shared stream for proxied table lookups of the same type.
*
* XXX Use absolute pathname to make this work from non-daemon processes.
*/
if (*pstream == 0) {
if (access(relative_path, F_OK) == 0)
prefix = MAIL_CLASS_PRIVATE;
else
prefix = kludge = concatenate(var_queue_dir, "/",
MAIL_CLASS_PRIVATE, (char *) 0);
*pstream = clnt_stream_create(prefix, service, var_ipc_idle_limit,
var_ipc_ttl_limit);
if (kludge)
myfree(kludge);
}
dict_proxy->clnt = *pstream;
dict_proxy->service = service;

View File

@ -91,6 +91,8 @@
/* char *var_flush_service;
/* char *var_verify_service;
/* char *var_trace_service;
/* char *var_proxymap_service;
/* char *var_proxywrite_service;
/* int var_db_create_buf;
/* int var_db_read_buf;
/* int var_mime_maxdepth;
@ -266,6 +268,8 @@ char *var_error_service;
char *var_flush_service;
char *var_verify_service;
char *var_trace_service;
char *var_proxymap_service;
char *var_proxywrite_service;
int var_db_create_buf;
int var_db_read_buf;
int var_mime_maxdepth;
@ -541,6 +545,8 @@ void mail_params_init()
VAR_FLUSH_SERVICE, DEF_FLUSH_SERVICE, &var_flush_service, 1, 0,
VAR_VERIFY_SERVICE, DEF_VERIFY_SERVICE, &var_verify_service, 1, 0,
VAR_TRACE_SERVICE, DEF_TRACE_SERVICE, &var_trace_service, 1, 0,
VAR_PROXYMAP_SERVICE, DEF_PROXYMAP_SERVICE, &var_proxymap_service, 1, 0,
VAR_PROXYWRITE_SERVICE, DEF_PROXYWRITE_SERVICE, &var_proxywrite_service, 1, 0,
VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0,
0,
};

View File

@ -2498,6 +2498,17 @@ extern char *var_vrfy_xport_maps;
#define DEF_TRACE_SERVICE MAIL_SERVICE_TRACE
extern char *var_trace_service;
/*
* Proxymappers.
*/
#define VAR_PROXYMAP_SERVICE "proxymap_service_name"
#define DEF_PROXYMAP_SERVICE MAIL_SERVICE_PROXYMAP
extern char *var_proxymap_service;
#define VAR_PROXYWRITE_SERVICE "proxywrite_service_name"
#define DEF_PROXYWRITE_SERVICE MAIL_SERVICE_PROXYWRITE
extern char *var_proxywrite_service;
/*
* Mailbox/maildir delivery errors that cause delivery to be tried again.
*/

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20080814"
#define MAIL_RELEASE_DATE "20080824"
#define MAIL_VERSION_NUMBER "2.6"
#ifdef SNAPSHOT

View File

@ -505,6 +505,8 @@ static int milter8_conf_error(MILTER8 *milter)
}
if (strcasecmp(milter->def_action, "accept") == 0) {
reply = 0;
} else if (strcasecmp(milter->def_action, "quarantine") == 0) {
reply = "H";
} else {
reply = "451 4.3.5 Server configuration problem - try again later";
}
@ -537,6 +539,8 @@ static int milter8_comm_error(MILTER8 *milter)
reply = "550 5.5.0 Service unavailable";
} else if (strcasecmp(milter->def_action, "tempfail") == 0) {
reply = "451 4.7.1 Service unavailable - try again later";
} else if (strcasecmp(milter->def_action, "quarantine") == 0) {
reply = "H";
} else {
msg_warn("milter %s: unrecognized default action: %s",
milter->m.name, milter->def_action);

View File

@ -19,6 +19,9 @@
/* .IP "\fB-a accept|tempfail|reject|discard|skip|\fIddd x.y.z text\fR"
/* Specifies a non-default reply for the MTA command specified
/* with \fB-c\fR. The default is \fBtempfail\fR.
/* .IP "\fB-A address\fR"
/* Add the specified recipient address. Multiple -A options
/* are supported.
/* .IP "\fB-d\fI level\fR"
/* Enable libmilter debugging at the specified level.
/* .IP "\fB-c connect|helo|mail|rcpt|data|header|eoh|body|eom|unknown|close|abort\fR"
@ -146,6 +149,10 @@ static char *body_file;
#endif
#define MAX_RCPT 10
int rcpt_count = 0;
char *rcpt_addr[MAX_RCPT];
static int test_reply(SMFICTX *ctx, int code)
{
(void) fflush(stdout); /* In case output redirected. */
@ -288,12 +295,19 @@ static sfsistat test_eom(SMFICTX *ctx)
#endif
#ifdef SMFIR_INSHEADER
if (ins_hdr && smfi_insheader(ctx, ins_idx, ins_hdr, ins_val) == MI_FAILURE)
fprintf(stderr, "smfi_insheader failed");
fprintf(stderr, "smfi_insheader failed\n");
#endif
#ifdef SMFIR_CHGHEADER
if (chg_hdr && smfi_chgheader(ctx, chg_hdr, chg_idx, chg_val) == MI_FAILURE)
fprintf(stderr, "smfi_chgheader failed");
fprintf(stderr, "smfi_chgheader failed\n");
#endif
{
int count;
for (count = 0; count < rcpt_count; count++)
if (smfi_addrcpt(ctx, rcpt_addr[count]) == MI_FAILURE)
fprintf(stderr, "smfi_addrcpt `%s' failed\n", rcpt_addr[count]);
}
return (test_reply(ctx, test_eom_reply));
}
@ -464,11 +478,18 @@ int main(int argc, char **argv)
char *noreply = 0;
const struct noproto_map *np;
while ((ch = getopt(argc, argv, "a:c:C:d:i:lm:M:n:N:p:r:R:v")) > 0) {
while ((ch = getopt(argc, argv, "a:A:c:C:d:i:lm:M:n:N:p:r:R:v")) > 0) {
switch (ch) {
case 'a':
action = optarg;
break;
case 'A':
if (rcpt_count >= MAX_RCPT) {
fprintf(stderr, "too many -A options\n");
exit(1);
}
rcpt_addr[rcpt_count++] = optarg;
break;
case 'c':
command = optarg;
break;

View File

@ -3115,27 +3115,49 @@ static int reject_rbl_addr(SMTPD_STATE *state, const char *rbl_domain,
int i;
SMTPD_RBL_STATE *rbl;
const char *reply_addr;
struct addrinfo *res;
unsigned char *ipv6_addr;
if (msg_verbose)
msg_info("%s: %s %s", myname, reply_class, addr);
/*
* IPv4 / IPv6-mapped IPv4 (if supported) only for now
*/
if (valid_ipv6_hostaddr(addr, DONT_GRIPE))
return SMTPD_CHECK_DUNNO;
query = vstring_alloc(100);
/*
* Reverse the client IPV4 address, tack on the RBL domain name and query
* the DNS for an A record.
* Reverse the client IPV6 address, represented as 32 hexadecimal
* nibbles. We use the binary address to avoid tricky code. Asking for an
* AAAA record makes no sense here. Just like with IPv4 we use the lookup
* result as a bit mask, not as an IP address.
*/
query = vstring_alloc(100);
octets = argv_split(addr, ".");
for (i = octets->argc - 1; i >= 0; i--) {
vstring_strcat(query, octets->argv[i]);
vstring_strcat(query, ".");
#ifdef PF_INET6
if (valid_ipv6_hostaddr(addr, DONT_GRIPE)) {
if (hostaddr_to_sockaddr(addr, (char *) 0, 0, &res) != 0
|| res->ai_family != PF_INET6)
msg_fatal("%s: unable to convert address %s", myname, addr);
ipv6_addr = (unsigned char *) &SOCK_ADDR_IN6_ADDR(res->ai_addr);
for (i = sizeof(SOCK_ADDR_IN6_ADDR(res->ai_addr)) - 1; i >= 0; i--)
vstring_sprintf_append(query, "%x.%x.",
ipv6_addr[i] & 0xf, ipv6_addr[i] >> 4);
freeaddrinfo(res);
} else
#endif
/*
* Reverse the client IPV4 address, represented as four decimal octet
* values. We use the textual address for convenience.
*/
{
octets = argv_split(addr, ".");
for (i = octets->argc - 1; i >= 0; i--) {
vstring_strcat(query, octets->argv[i]);
vstring_strcat(query, ".");
}
argv_free(octets);
}
argv_free(octets);
/*
* Tack on the RBL domain name and query the DNS for an A record.
*/
vstring_strcat(query, rbl_domain);
reply_addr = split_at(STR(query), '=');
rbl = (SMTPD_RBL_STATE *) ctable_locate(smtpd_rbl_cache, STR(query));

View File

@ -53,10 +53,16 @@
/* transport is currently limited to one of the following:
/* .RS
/* .IP inet
/* servername has the form "host:port".
/* servername has the form "inet:host:port".
/* .IP local
/* servername has the form "local:private/servicename" or
/* "local:public/servicename". This is the preferred way to
/* specify Postfix daemons that are configured as "unix" in
/* master.cf.
/* .IP unix
/* servername has the form "private/servicename" or
/* "public/servicename".
/* servername has the form "unix:private/servicename" or
/* "unix:public/servicename". This does not work on Solaris,
/* where Postfix uses STREAMS instead of UNIX-domain sockets.
/* .RE
/* .IP timeout
/* The time limit for sending, receiving, or for connecting

View File

@ -54,14 +54,14 @@
int stream_send_fd(int fd, int sendfd)
{
#ifdef STREAM_CONNECTIONS
const char *myname = "stream_send_fd";
#ifdef STREAM_CONNECTIONS
if (ioctl(fd, I_SENDFD, sendfd) < 0)
msg_fatal("%s: send file descriptor %d: %m", myname, sendfd);
return (0);
#else
msg_fatal("stream connections are not implemented");
msg_fatal("stream connections are not implemented");
#endif
}

View File

@ -223,6 +223,11 @@
#define NATIVE_DAEMON_DIR "/usr/libexec/postfix"
#define SOCKADDR_SIZE socklen_t
#define SOCKOPT_SIZE socklen_t
#ifndef NO_KQUEUE
# define EVENTS_STYLE EVENTS_STYLE_KQUEUE
# define USE_SYSV_POLL
#endif
#endif
/*
@ -1271,6 +1276,10 @@ extern int inet_pton(int, const char *, void *);
#define EVENTS_STYLE_DEVPOLL 3 /* Solaris /dev/poll */
#define EVENTS_STYLE_EPOLL 4 /* Linux epoll */
#if !defined(USE_SYSV_POLL) && (EVENTS_STYLE != EVENTS_STYLE_SELECT)
#error "need USE_SYSV_POLL with EVENTS_STYLE != EVENTS_STYLE_SELECT"
#endif
/*
* Defaults for all systems.
*/

View File

@ -1250,7 +1250,8 @@ void vstream_control(VSTREAM *stream, int name,...)
break;
case VSTREAM_CTL_EXCEPT:
if (stream->jbuf == 0)
stream->jbuf = (jmp_buf *) mymalloc(sizeof(jmp_buf));
stream->jbuf =
(VSTREAM_JMP_BUF *) mymalloc(sizeof(VSTREAM_JMP_BUF));
break;
#ifdef VSTREAM_CTL_DUPFD

View File

@ -33,6 +33,12 @@
typedef ssize_t (*VSTREAM_FN) (int, void *, size_t, int, void *);
typedef int (*VSTREAM_WAITPID_FN) (pid_t, WAIT_STATUS_T *, int);
#ifdef NO_SIGSETJMP
#define VSTREAM_JMP_BUF jmp_buf
#else
#define VSTREAM_JMP_BUF sigjmp_buf
#endif
typedef struct VSTREAM {
VBUF buf; /* generic intelligent buffer */
int fd; /* file handle, no 256 limit */
@ -48,7 +54,7 @@ typedef struct VSTREAM {
pid_t pid; /* vstream_popen/close() */
VSTREAM_WAITPID_FN waitpid_fn; /* vstream_popen/close() */
int timeout; /* read/write timout */
jmp_buf *jbuf; /* exception handling */
VSTREAM_JMP_BUF *jbuf; /* exception handling */
struct timeval iotime; /* time of last fill/flush */
/* At bottom for Postfix 2.4 binary compatibility. */
ssize_t req_bufsize; /* write buffer size */
@ -152,9 +158,18 @@ extern ssize_t vstream_peek(VSTREAM *);
/*
* Exception handling. We use pointer to jmp_buf to avoid a lot of unused
* baggage for streams that don't need this functionality.
*
* XXX sigsetjmp()/siglongjmp() save and restore the signal mask which can
* avoid surprises in code that manipulates signals, but unfortunately some
* systems have bugs in their implementation.
*/
#ifdef NO_SIGSETJMP
#define vstream_setjmp(stream) setjmp((stream)->jbuf[0])
#define vstream_longjmp(stream, val) longjmp((stream)->jbuf[0], (val))
#else
#define vstream_setjmp(stream) sigsetjmp((stream)->jbuf[0], 1)
#define vstream_longjmp(stream, val) siglongjmp((stream)->jbuf[0], (val))
#endif
/*
* Tweaks and workarounds.