2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-09-02 23:25:31 +00:00

postfix-2.3-20050829

This commit is contained in:
Wietse Venema
2005-08-29 00:00:00 -05:00
committed by Viktor Dukhovni
parent 3fb1ad8ad5
commit 04571e906b
50 changed files with 983 additions and 475 deletions

View File

@@ -11062,12 +11062,60 @@ Apologies for any names omitted.
Cleanup: HOLD action executes only once, to reduce noise Cleanup: HOLD action executes only once, to reduce noise
in the logfile. Files: cleanup/cleanup_message.c, smtpd/smtpd.c. in the logfile. Files: cleanup/cleanup_message.c, smtpd/smtpd.c.
Open problems: 20050806
Med: when the cleanup server bounces local mail that should Workaround: accept(2) fails with EPROTO when the client
be content inspected, the resulting DSN should be content already disconnected (SunOS 5.5.1). File: sane_accept.c.
inspected, otherwise a local user can bypass content
inspection. 20050815
Workaround: old Solaris compilers can't link an archive
without globally visible symbols. File: tls/tls_misc.c.
20050825
Feature: message_reject_characters and message_strip_characters
specify what characters in message content Postfix will
reject or remove. Based on patch by John Fawcett. Files:
cleanup/cleanup_message.c, cleanup/cleanup_init.c.
Safety: when the cleanup server rejects the content of mail
that is submitted with the Postfix sendmail command, or
re-queued with "postsuper -r", strip the message body from
the bounce message to reduce the risks from harmful content.
Files: cleanup/cleanup_envelope.c, cleanup/cleanup_bounce.c.
Feature: the smtpd_proxy_filter parameter value can now be
prefixed with "unix:" (for UNIX-domain socket) and "inet:"
(for TCP socket). TCP sockets are the default. Patch by
Edwin Kremer. File: smtpd/smtpd_proxy.c.
20050828
Bugfix: after adding DSN support, error notification was
broken for too large mail that was submitted with the Postfix
sendmail command, forwarded by the local(8) delivery agent,
or re-queued with "postsuper -r". The message would be saved
to the "corrupt" queue.
The mistake was to leave the truncated message in the
incoming queue and to ask the queue manager to notify the
sender; this was not possible because the queue manager
cannot (and should not) handle truncated queue files.
The fix is to have the cleanup server send the bounce
message, just like it did before DSN support was added. As
a side effect, Postfix will no longer send DSN_SUCCESS
notices after virtual aliasing, when the cleanup server
bounces all the recipients of the message anyway. This
could be called a feature. File: cleanup/cleanup_bounce.c.
Also needed for this fix: a new vstream_fpurge() routine
that discards unread/written data from a VSTREAM. It's
needed before cleanup_bounce() can seek to the start of the
queue file after a file size error. File: util/vstream.c.
Open problems:
Look for systems with XPG basename() declared in <libgen.h>, Look for systems with XPG basename() declared in <libgen.h>,
and prepare for phasing out the Postfix-supplied one. and prepare for phasing out the Postfix-supplied one.

View File

@@ -84,7 +84,7 @@ Postfix has two Sendmail-compatible command-line options for DSN support.
PPoossttffiixx VVEERRPP ssuuppppoorrtt ccoommppaattiibbiilliittyy PPoossttffiixx VVEERRPP ssuuppppoorrtt ccoommppaattiibbiilliittyy
With Postfix versions before 2.3, the sendmail(1) commands uses the -V command- With Postfix versions before 2.3, the sendmail(1) command uses the -V command-
line option to request VERP-style delivery. In order to request VERP style line option to request VERP-style delivery. In order to request VERP style
delivery with Postfix 2.3 and later, you must specify -XV instead of -V. delivery with Postfix 2.3 and later, you must specify -XV instead of -V.

View File

@@ -12,7 +12,8 @@ differences between these implementations.
The main feature of interest is that IPv6 uses 128-bit IP addresses instead of The main feature of interest is that IPv6 uses 128-bit IP addresses instead of
the 32-bit addresses used by IPv4. It can therefore accommodate a much larger the 32-bit addresses used by IPv4. It can therefore accommodate a much larger
number of hosts and networks without ugly kluges such as NAT. A side benefit of number of hosts and networks without ugly kluges such as NAT. A side benefit of
the much larger address space is that it makes network scanning unpractical. the much larger address space is that it makes random network scanning
unpractical.
Postfix uses the same SMTP protocol over IPv6 as it already uses over the older Postfix uses the same SMTP protocol over IPv6 as it already uses over the older
IPv4 network, and does AAAA record lookups in the DNS in addition to the older IPv4 network, and does AAAA record lookups in the DNS in addition to the older

View File

@@ -17,6 +17,30 @@ Incompatibility with Postfix 2.1 and earlier
If you upgrade from Postfix 2.1 or earlier, read RELEASE_NOTES-2.2 If you upgrade from Postfix 2.1 or earlier, read RELEASE_NOTES-2.2
before proceeding. before proceeding.
Incompatibility with snapshot 20050828
======================================
When a header/body_checks or message_reject_characters rule rejects
mail that was submitted with the Postfix sendmail command (or
re-queued with "postsuper -r"), the returned message is now limited
to just the message headers, to avoid the risk of exposure to harmful
content in the message body or attachments.
When the cleanup server rejects the content or size of mail that
was submitted with the Postfix sendmail command, forwarded with the
local(8) delivery agent, or that was re-queued with "postsuper -r",
Postfix no longer sends DSN SUCCESS notification of virtual alias
expansions. Since all the recipients are reported as failed, the
SUCCESS notification seems redundant.
Major changes with snapshot 20050828
====================================
Configurable filters to reject or remove unwanted characters in
email content. The message_reject_characters and message_strip_characters
parameters understand the usual C-like escape sequences: \a \b \f
\n \r \t \v \ddd (up to three octal digits) and \\.
Incompatibility with snapshot 20050726 Incompatibility with snapshot 20050726
====================================== ======================================

View File

@@ -37,9 +37,8 @@
# By default the canonical(5) mapping affects both message # By default the canonical(5) mapping affects both message
# header addresses (i.e. addresses that appear inside mes- # header addresses (i.e. addresses that appear inside mes-
# sages) and message envelope addresses (for example, the # sages) and message envelope addresses (for example, the
# addresses that are used in SMTP protocol commands). Think # addresses that are used in SMTP protocol commands). This
# Sendmail rule set S3, if you like. This is controlled # is controlled with the canonical_classes parameter.
# with the canonical_classes parameter.
# #
# NOTE: Postfix versions 2.2 and later rewrite message head- # NOTE: Postfix versions 2.2 and later rewrite message head-
# ers from remote SMTP clients only if the client matches # ers from remote SMTP clients only if the client matches

View File

@@ -34,9 +34,9 @@
# address can have its own mailbox. # address can have its own mailbox.
# #
# Virtual aliasing is applied only to recipient envelope # Virtual aliasing is applied only to recipient envelope
# addresses, and does not affect message headers. Think # addresses, and does not affect message headers. Use
# Sendmail rule set S0, if you like. Use canonical(5) map- # canonical(5) mapping to rewrite header and envelope
# ping to rewrite header and envelope addresses in general. # addresses in general.
# #
# Normally, the virtual(5) alias table is specified as a # Normally, the virtual(5) alias table is specified as a
# text file that serves as input to the postmap(1) command. # text file that serves as input to the postmap(1) command.

View File

@@ -139,7 +139,7 @@ as discussed in the next section. </p>
<h2> <a name="compat">Postfix VERP support compatibility</a> </h2> <h2> <a name="compat">Postfix VERP support compatibility</a> </h2>
<p> With Postfix versions before 2.3, the <a href="sendmail.1.html">sendmail(1)</a> commands uses <p> With Postfix versions before 2.3, the <a href="sendmail.1.html">sendmail(1)</a> command uses
the -V command-line option to request VERP-style delivery. In order the -V command-line option to request VERP-style delivery. In order
to request VERP style delivery with Postfix 2.3 and later, you must to request VERP style delivery with Postfix 2.3 and later, you must
specify -XV instead of -V. </p> specify -XV instead of -V. </p>

View File

@@ -30,7 +30,8 @@ between these implementations. </p>
addresses instead of the 32-bit addresses used by IPv4. It can addresses instead of the 32-bit addresses used by IPv4. It can
therefore accommodate a much larger number of hosts and networks therefore accommodate a much larger number of hosts and networks
without ugly kluges such as NAT. A side benefit of the much larger without ugly kluges such as NAT. A side benefit of the much larger
address space is that it makes network scanning unpractical. </p> address space is that it makes random network scanning unpractical.
</p>
<p> Postfix uses the same SMTP protocol over IPv6 as it already <p> Postfix uses the same SMTP protocol over IPv6 as it already
uses over the older IPv4 network, and does AAAA record lookups in uses over the older IPv4 network, and does AAAA record lookups in

View File

@@ -43,9 +43,8 @@ CANONICAL(5) CANONICAL(5)
By default the <a href="canonical.5.html"><b>canonical</b>(5)</a> mapping affects both message By default the <a href="canonical.5.html"><b>canonical</b>(5)</a> mapping affects both message
header addresses (i.e. addresses that appear inside mes- header addresses (i.e. addresses that appear inside mes-
sages) and message envelope addresses (for example, the sages) and message envelope addresses (for example, the
addresses that are used in SMTP protocol commands). Think addresses that are used in SMTP protocol commands). This
Sendmail rule set <b>S3</b>, if you like. This is controlled is controlled with the <b><a href="postconf.5.html#canonical_classes">canonical_classes</a></b> parameter.
with the <b><a href="postconf.5.html#canonical_classes">canonical_classes</a></b> parameter.
NOTE: Postfix versions 2.2 and later rewrite message head- NOTE: Postfix versions 2.2 and later rewrite message head-
ers from remote SMTP clients only if the client matches ers from remote SMTP clients only if the client matches

View File

@@ -125,6 +125,16 @@ CLEANUP(8) CLEANUP(8)
non-MIME message headers in attached messages, as non-MIME message headers in attached messages, as
described in the <b><a href="postconf.5.html#header_checks">header_checks</a></b>(5) manual page. described in the <b><a href="postconf.5.html#header_checks">header_checks</a></b>(5) manual page.
Available in Postfix version 2.3 and later:
<b><a href="postconf.5.html#message_reject_characters">message_reject_characters</a> (empty)</b>
The set of characters that Postfix will reject in
message content.
<b><a href="postconf.5.html#message_strip_characters">message_strip_characters</a> (empty)</b>
The set of characters that Postfix will remove from
message content.
<b>MIME PROCESSING CONTROLS</b> <b>MIME PROCESSING CONTROLS</b>
Available in Postfix version 2.0 and later: Available in Postfix version 2.0 and later:

View File

@@ -324,6 +324,8 @@ LDAP_TABLE(5) LDAP_TABLE(5)
NOTE: DO NOT define this parameter for <a href="local.8.html">local(8)</a> NOTE: DO NOT define this parameter for <a href="local.8.html">local(8)</a>
aliases. aliases.
This feature is available in Postfix 2.1 and later.
<b>result_attribute (default: maildrop)</b> <b>result_attribute (default: maildrop)</b>
The attribute(s) Postfix will read from any direc- The attribute(s) Postfix will read from any direc-
tory entries returned by the lookup, to be resolved tory entries returned by the lookup, to be resolved

View File

@@ -4110,6 +4110,25 @@ Specify 0 when mail delivery should be tried only once.
</p> </p>
</DD>
<DT><b><a name="message_reject_characters">message_reject_characters</a>
(default: empty)</b></DT><DD>
<p> The set of characters that Postfix will reject in message
content. The usual C-like escape sequences are recognized: <tt>\a
\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and
<tt>\\</tt>. </p>
<p> Example: </p>
<pre>
<a href="postconf.5.html#message_reject_characters">message_reject_characters</a> = \0
</pre>
<p> This feature is available in Postfix 2.3 and later. </p>
</DD> </DD>
<DT><b><a name="message_size_limit">message_size_limit</a> <DT><b><a name="message_size_limit">message_size_limit</a>
@@ -4120,6 +4139,25 @@ The maximal size in bytes of a message, including envelope information.
</p> </p>
</DD>
<DT><b><a name="message_strip_characters">message_strip_characters</a>
(default: empty)</b></DT><DD>
<p> The set of characters that Postfix will remove from message
content. The usual C-like escape sequences are recognized: <tt>\a
\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and
<tt>\\</tt>. </p>
<p> Example: </p>
<pre>
<a href="postconf.5.html#message_strip_characters">message_strip_characters</a> = \0
</pre>
<p> This feature is available in Postfix 2.3 and later. </p>
</DD> </DD>
<DT><b><a name="mime_boundary_length_limit">mime_boundary_length_limit</a> <DT><b><a name="mime_boundary_length_limit">mime_boundary_length_limit</a>
@@ -7938,12 +7976,18 @@ The proxy receives all mail from the Postfix SMTP server, and is
supposed to give the result to another Postfix SMTP server process. supposed to give the result to another Postfix SMTP server process.
</p> </p>
<p> Specify host:port. The host can be specified as an IP address <p> Specify "host:port" or "inet:host:port" for a TCP endpoint, or
or as a symbolic name; no MX lookups are done. When no host or "unix:pathname" for a UNIX-domain endpoint. The host can be specified
host: are specified, the local machine is assumed. </p> as an IP address or as a symbolic name; no MX lookups are done.
When no "host" or "host:" are specified, the local machine is
assumed. Pathname interpretation is relative to the Postfix queue
directory. </p>
<p> This feature is available in Postfix 2.1 and later. </p> <p> This feature is available in Postfix 2.1 and later. </p>
<p> The "inet:" and "unix:" prefixes are available in Postfix 2.3
and later. </p>
</DD> </DD>

View File

@@ -40,9 +40,9 @@ VIRTUAL(5) VIRTUAL(5)
address can have its own mailbox. address can have its own mailbox.
Virtual aliasing is applied only to recipient envelope Virtual aliasing is applied only to recipient envelope
addresses, and does not affect message headers. Think addresses, and does not affect message headers. Use
Sendmail rule set <b>S0</b>, if you like. Use <a href="canonical.5.html"><b>canonical</b>(5)</a> map- <a href="canonical.5.html"><b>canonical</b>(5)</a> mapping to rewrite header and envelope
ping to rewrite header and envelope addresses in general. addresses in general.
Normally, the <a href="virtual.5.html"><b>virtual</b>(5)</a> alias table is specified as a Normally, the <a href="virtual.5.html"><b>virtual</b>(5)</a> alias table is specified as a
text file that serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command. text file that serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command.
@@ -138,7 +138,7 @@ VIRTUAL(5) VIRTUAL(5)
<a href="virtual.8.html"><b>virtual</b>(8)</a> mail delivery agent. With virtual mailbox <a href="virtual.8.html"><b>virtual</b>(8)</a> mail delivery agent. With virtual mailbox
domains, each recipient address can have its own mailbox. domains, each recipient address can have its own mailbox.
With a <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>, the virtual domain has its With a virtual alias domain, the virtual domain has its
own user name space. Local (i.e. non-virtual) usernames own user name space. Local (i.e. non-virtual) usernames
are not visible in a <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>. In particular, are not visible in a <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>. In particular,
local <a href="aliases.5.html"><b>aliases</b>(5)</a> and local mailing lists are not visible local <a href="aliases.5.html"><b>aliases</b>(5)</a> and local mailing lists are not visible
@@ -172,7 +172,7 @@ VIRTUAL(5) VIRTUAL(5)
rejects mail for <i>unknown-user</i>@<i>virtual-alias.domain</i> as rejects mail for <i>unknown-user</i>@<i>virtual-alias.domain</i> as
undeliverable. undeliverable.
Instead of specifying the <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a> name via Instead of specifying the virtual alias domain name via
the <b><a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a></b> table, you may also specify it via the <b><a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a></b> table, you may also specify it via
the <b>main.cf <a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a></b> configuration parameter. the <b>main.cf <a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a></b> configuration parameter.
This latter parameter uses the same syntax as the <b>main.cf</b> This latter parameter uses the same syntax as the <b>main.cf</b>

View File

@@ -40,8 +40,7 @@ done in a slightly different way as described below under
By default the \fBcanonical\fR(5) mapping affects both message By default the \fBcanonical\fR(5) mapping affects both message
header addresses (i.e. addresses that appear inside messages) header addresses (i.e. addresses that appear inside messages)
and message envelope addresses (for example, the addresses and message envelope addresses (for example, the addresses
that are used in SMTP protocol commands). Think Sendmail that are used in SMTP protocol commands). This is controlled with
rule set \fBS3\fR, if you like. This is controlled with
the \fBcanonical_classes\fR parameter. the \fBcanonical_classes\fR parameter.
NOTE: Postfix versions 2.2 and later rewrite message headers NOTE: Postfix versions 2.2 and later rewrite message headers

View File

@@ -304,6 +304,8 @@ It is best not to use LDAP to store the domains eligible
for LDAP lookups. for LDAP lookups.
NOTE: DO NOT define this parameter for local(8) aliases. NOTE: DO NOT define this parameter for local(8) aliases.
This feature is available in Postfix 2.1 and later.
.IP "\fBresult_attribute (default: maildrop)\fR" .IP "\fBresult_attribute (default: maildrop)\fR"
The attribute(s) Postfix will read from any directory The attribute(s) Postfix will read from any directory
entries returned by the lookup, to be resolved to an email entries returned by the lookup, to be resolved to an email

View File

@@ -506,7 +506,7 @@ and changed the default to none.
Specify a list of network/netmask patterns, separated by commas Specify a list of network/netmask patterns, separated by commas
and/or whitespace. The mask specifies the number of bits in the and/or whitespace. The mask specifies the number of bits in the
network part of a host address. You can also specify hostnames or network part of a host address. You can also specify hostnames or
\&.domain names (the initial dot causes the domain to match any name \e&.domain names (the initial dot causes the domain to match any name
below it), "/file/name" or "type:table" patterns. A "/file/name" below it), "/file/name" or "type:table" patterns. A "/file/name"
pattern is replaced by its contents; a "type:table" lookup table pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup is matched when a table entry matches a lookup string (the lookup
@@ -2231,8 +2231,42 @@ Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
The default time unit is d (days). The default time unit is d (days).
.PP .PP
Specify 0 when mail delivery should be tried only once. Specify 0 when mail delivery should be tried only once.
.SH message_reject_characters (default: empty)
The set of characters that Postfix will reject in message
content. The usual C-like escape sequences are recognized: \ea
\eb \ef \en \er \et \ev \e\fIddd\fR (up to three octal digits) and
\e\e.
.PP
Example:
.PP
.nf
.na
.ft C
message_reject_characters = \e0
.fi
.ad
.ft R
.PP
This feature is available in Postfix 2.3 and later.
.SH message_size_limit (default: 10240000) .SH message_size_limit (default: 10240000)
The maximal size in bytes of a message, including envelope information. The maximal size in bytes of a message, including envelope information.
.SH message_strip_characters (default: empty)
The set of characters that Postfix will remove from message
content. The usual C-like escape sequences are recognized: \ea
\eb \ef \en \er \et \ev \e\fIddd\fR (up to three octal digits) and
\e\e.
.PP
Example:
.PP
.nf
.na
.ft C
message_strip_characters = \e0
.fi
.ad
.ft R
.PP
This feature is available in Postfix 2.3 and later.
.SH mime_boundary_length_limit (default: 2048) .SH mime_boundary_length_limit (default: 2048)
The maximal length of MIME multipart boundary strings. The MIME The maximal length of MIME multipart boundary strings. The MIME
processor is unable to distinguish between boundary strings that processor is unable to distinguish between boundary strings that
@@ -3867,7 +3901,7 @@ is backwards compatible with Postfix 2.0.
Specify a list of network/netmask patterns, separated by commas Specify a list of network/netmask patterns, separated by commas
and/or whitespace. The mask specifies the number of bits in the and/or whitespace. The mask specifies the number of bits in the
network part of a host address. You can also specify hostnames or network part of a host address. You can also specify hostnames or
\&.domain names (the initial dot causes the domain to match any name \e&.domain names (the initial dot causes the domain to match any name
below it), "/file/name" or "type:table" patterns. A "/file/name" below it), "/file/name" or "type:table" patterns. A "/file/name"
pattern is replaced by its contents; a "type:table" lookup table pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup is matched when a table entry matches a lookup string (the lookup
@@ -3893,7 +3927,7 @@ By default, no clients are allowed to specify XCLIENT.
Specify a list of network/netmask patterns, separated by commas Specify a list of network/netmask patterns, separated by commas
and/or whitespace. The mask specifies the number of bits in the and/or whitespace. The mask specifies the number of bits in the
network part of a host address. You can also specify hostnames or network part of a host address. You can also specify hostnames or
\&.domain names (the initial dot causes the domain to match any name \e&.domain names (the initial dot causes the domain to match any name
below it), "/file/name" or "type:table" patterns. A "/file/name" below it), "/file/name" or "type:table" patterns. A "/file/name"
pattern is replaced by its contents; a "type:table" lookup table pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup is matched when a table entry matches a lookup string (the lookup
@@ -3918,7 +3952,7 @@ By default, no clients are allowed to specify XFORWARD.
Specify a list of network/netmask patterns, separated by commas Specify a list of network/netmask patterns, separated by commas
and/or whitespace. The mask specifies the number of bits in the and/or whitespace. The mask specifies the number of bits in the
network part of a host address. You can also specify hostnames or network part of a host address. You can also specify hostnames or
\&.domain names (the initial dot causes the domain to match any name \e&.domain names (the initial dot causes the domain to match any name
below it), "/file/name" or "type:table" patterns. A "/file/name" below it), "/file/name" or "type:table" patterns. A "/file/name"
pattern is replaced by its contents; a "type:table" lookup table pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup is matched when a table entry matches a lookup string (the lookup
@@ -4517,11 +4551,17 @@ The hostname and TCP port of the mail filtering proxy server.
The proxy receives all mail from the Postfix SMTP server, and is The proxy receives all mail from the Postfix SMTP server, and is
supposed to give the result to another Postfix SMTP server process. supposed to give the result to another Postfix SMTP server process.
.PP .PP
Specify host:port. The host can be specified as an IP address Specify "host:port" or "inet:host:port" for a TCP endpoint, or
or as a symbolic name; no MX lookups are done. When no host or "unix:pathname" for a UNIX-domain endpoint. The host can be specified
host: are specified, the local machine is assumed. as an IP address or as a symbolic name; no MX lookups are done.
When no "host" or "host:" are specified, the local machine is
assumed. Pathname interpretation is relative to the Postfix queue
directory.
.PP .PP
This feature is available in Postfix 2.1 and later. This feature is available in Postfix 2.1 and later.
.PP
The "inet:" and "unix:" prefixes are available in Postfix 2.3
and later.
.SH smtpd_proxy_timeout (default: 100s) .SH smtpd_proxy_timeout (default: 100s)
The time limit for connecting to a proxy filter and for sending or The time limit for connecting to a proxy filter and for sending or
receiving information. When a connection fails the client gets a receiving information. When a connection fails the client gets a
@@ -5112,7 +5152,7 @@ or smtpd_tls_cert_file.
.PP .PP
A certificate supplied here must be usable as SSL server A certificate supplied here must be usable as SSL server
certificate and hence pass the "openssl verify -purpose sslserver certificate and hence pass the "openssl verify -purpose sslserver
\&..." test. \e&..." test.
.PP .PP
Example: Example:
.PP .PP

View File

@@ -38,7 +38,7 @@ can have its own mailbox.
.PP .PP
Virtual aliasing is applied only to recipient Virtual aliasing is applied only to recipient
envelope addresses, and does not affect message headers. envelope addresses, and does not affect message headers.
Think Sendmail rule set \fBS0\fR, if you like. Use \fBcanonical\fR(5) Use \fBcanonical\fR(5)
mapping to rewrite header and envelope addresses in general. mapping to rewrite header and envelope addresses in general.
Normally, the \fBvirtual\fR(5) alias table is specified as a text file Normally, the \fBvirtual\fR(5) alias table is specified as a text file

View File

@@ -118,6 +118,14 @@ message headers, as described in the \fBheader_checks\fR(5) manual page.
Optional lookup tables for content inspection of non-MIME message Optional lookup tables for content inspection of non-MIME message
headers in attached messages, as described in the \fBheader_checks\fR(5) headers in attached messages, as described in the \fBheader_checks\fR(5)
manual page. manual page.
.PP
Available in Postfix version 2.3 and later:
.IP "\fBmessage_reject_characters (empty)\fR"
The set of characters that Postfix will reject in message
content.
.IP "\fBmessage_strip_characters (empty)\fR"
The set of characters that Postfix will remove from message
content.
.SH "MIME PROCESSING CONTROLS" .SH "MIME PROCESSING CONTROLS"
.na .na
.nf .nf

View File

@@ -43,6 +43,7 @@ while(<>) {
$block =~ s/<\/DD>/\n/g; $block =~ s/<\/DD>/\n/g;
$block =~ s/<DL>/\n/g; $block =~ s/<DL>/\n/g;
$block =~ s/<\/DL>/\n/g; $block =~ s/<\/DL>/\n/g;
$block =~ s/\\/\\e/g;
$block =~ s/<b>/\\fB/g; $block =~ s/<b>/\\fB/g;
$block =~ s/<i>/\\fI/g; $block =~ s/<i>/\\fI/g;
$block =~ s/<\/b>/\\fR/g; $block =~ s/<\/b>/\\fR/g;

View File

@@ -234,7 +234,9 @@ while (<>) {
s;\bmax_use\b;<a href="postconf.5.html#max_use">$&</a>;g; s;\bmax_use\b;<a href="postconf.5.html#max_use">$&</a>;g;
s;\bmaxi[-</bB>]*\n*[ <bB>]*mal_backoff_time\b;<a href="postconf.5.html#maximal_backoff_time">$&</a>;g; s;\bmaxi[-</bB>]*\n*[ <bB>]*mal_backoff_time\b;<a href="postconf.5.html#maximal_backoff_time">$&</a>;g;
s;\bmaxi[-</bB>]*\n*[ <bB>]*mal_queue_lifetime\b;<a href="postconf.5.html#maximal_queue_lifetime">$&</a>;g; s;\bmaxi[-</bB>]*\n*[ <bB>]*mal_queue_lifetime\b;<a href="postconf.5.html#maximal_queue_lifetime">$&</a>;g;
s;\bmessage_reject_characters\b;<a href="postconf.5.html#message_reject_characters">$&</a>;g;
s;\bmessage_size_limit\b;<a href="postconf.5.html#message_size_limit">$&</a>;g; s;\bmessage_size_limit\b;<a href="postconf.5.html#message_size_limit">$&</a>;g;
s;\bmessage_strip_characters\b;<a href="postconf.5.html#message_strip_characters">$&</a>;g;
s;\bmime_boundary_length_limit\b;<a href="postconf.5.html#mime_boundary_length_limit">$&</a>;g; s;\bmime_boundary_length_limit\b;<a href="postconf.5.html#mime_boundary_length_limit">$&</a>;g;
s;\bmime_header_checks\b;<a href="postconf.5.html#mime_header_checks">$&</a>;g; s;\bmime_header_checks\b;<a href="postconf.5.html#mime_header_checks">$&</a>;g;
s;\bmime_nesting_limit\b;<a href="postconf.5.html#mime_nesting_limit">$&</a>;g; s;\bmime_nesting_limit\b;<a href="postconf.5.html#mime_nesting_limit">$&</a>;g;

View File

@@ -44,6 +44,9 @@
# Do not ask the user for parameter settings. Installation parameters # Do not ask the user for parameter settings. Installation parameters
# are specified via one of the non-interactive methods described # are specified via one of the non-interactive methods described
# below. # below.
# .IP -package
# Build a ready-to-install package. This requires that a
# non-default install_root parameter is specified.
# INSTALLATION PARAMETER INPUT METHODS # INSTALLATION PARAMETER INPUT METHODS
# .ad # .ad
# .fi # .fi

View File

@@ -139,7 +139,7 @@ as discussed in the next section. </p>
<h2> <a name="compat">Postfix VERP support compatibility</a> </h2> <h2> <a name="compat">Postfix VERP support compatibility</a> </h2>
<p> With Postfix versions before 2.3, the sendmail(1) commands uses <p> With Postfix versions before 2.3, the sendmail(1) command uses
the -V command-line option to request VERP-style delivery. In order the -V command-line option to request VERP-style delivery. In order
to request VERP style delivery with Postfix 2.3 and later, you must to request VERP style delivery with Postfix 2.3 and later, you must
specify -XV instead of -V. </p> specify -XV instead of -V. </p>

View File

@@ -30,7 +30,8 @@ between these implementations. </p>
addresses instead of the 32-bit addresses used by IPv4. It can addresses instead of the 32-bit addresses used by IPv4. It can
therefore accommodate a much larger number of hosts and networks therefore accommodate a much larger number of hosts and networks
without ugly kluges such as NAT. A side benefit of the much larger without ugly kluges such as NAT. A side benefit of the much larger
address space is that it makes network scanning unpractical. </p> address space is that it makes random network scanning unpractical.
</p>
<p> Postfix uses the same SMTP protocol over IPv6 as it already <p> Postfix uses the same SMTP protocol over IPv6 as it already
uses over the older IPv4 network, and does AAAA record lookups in uses over the older IPv4 network, and does AAAA record lookups in

View File

@@ -34,8 +34,7 @@
# By default the \fBcanonical\fR(5) mapping affects both message # By default the \fBcanonical\fR(5) mapping affects both message
# header addresses (i.e. addresses that appear inside messages) # header addresses (i.e. addresses that appear inside messages)
# and message envelope addresses (for example, the addresses # and message envelope addresses (for example, the addresses
# that are used in SMTP protocol commands). Think Sendmail # that are used in SMTP protocol commands). This is controlled with
# rule set \fBS3\fR, if you like. This is controlled with
# the \fBcanonical_classes\fR parameter. # the \fBcanonical_classes\fR parameter.
# #
# NOTE: Postfix versions 2.2 and later rewrite message headers # NOTE: Postfix versions 2.2 and later rewrite message headers

View File

@@ -292,6 +292,8 @@
# for LDAP lookups. # for LDAP lookups.
# #
# NOTE: DO NOT define this parameter for local(8) aliases. # NOTE: DO NOT define this parameter for local(8) aliases.
#
# This feature is available in Postfix 2.1 and later.
# .IP "\fBresult_attribute (default: maildrop)\fR" # .IP "\fBresult_attribute (default: maildrop)\fR"
# The attribute(s) Postfix will read from any directory # The attribute(s) Postfix will read from any directory
# entries returned by the lookup, to be resolved to an email # entries returned by the lookup, to be resolved to an email

View File

@@ -4979,12 +4979,18 @@ The proxy receives all mail from the Postfix SMTP server, and is
supposed to give the result to another Postfix SMTP server process. supposed to give the result to another Postfix SMTP server process.
</p> </p>
<p> Specify host:port. The host can be specified as an IP address <p> Specify "host:port" or "inet:host:port" for a TCP endpoint, or
or as a symbolic name; no MX lookups are done. When no host or "unix:pathname" for a UNIX-domain endpoint. The host can be specified
host: are specified, the local machine is assumed. </p> as an IP address or as a symbolic name; no MX lookups are done.
When no "host" or "host:" are specified, the local machine is
assumed. Pathname interpretation is relative to the Postfix queue
directory. </p>
<p> This feature is available in Postfix 2.1 and later. </p> <p> This feature is available in Postfix 2.1 and later. </p>
<p> The "inet:" and "unix:" prefixes are available in Postfix 2.3
and later. </p>
%PARAM smtpd_proxy_timeout 100s %PARAM smtpd_proxy_timeout 100s
<p> <p>
@@ -8505,3 +8511,33 @@ examples are shown in the ADDRESS_REWRITING_README and
STANDARD_CONFIGURATION_README documents. </p> STANDARD_CONFIGURATION_README documents. </p>
<p> This feature is available in Postfix 2.2 and later. </p> <p> This feature is available in Postfix 2.2 and later. </p>
%PARAM message_reject_characters empty
<p> The set of characters that Postfix will reject in message
content. The usual C-like escape sequences are recognized: <tt>\a
\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and
<tt>\\</tt>. </p>
<p> Example: </p>
<pre>
message_reject_characters = \0
</pre>
<p> This feature is available in Postfix 2.3 and later. </p>
%PARAM message_strip_characters empty
<p> The set of characters that Postfix will remove from message
content. The usual C-like escape sequences are recognized: <tt>\a
\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and
<tt>\\</tt>. </p>
<p> Example: </p>
<pre>
message_strip_characters = \0
</pre>
<p> This feature is available in Postfix 2.3 and later. </p>

View File

@@ -32,7 +32,7 @@
# .PP # .PP
# Virtual aliasing is applied only to recipient # Virtual aliasing is applied only to recipient
# envelope addresses, and does not affect message headers. # envelope addresses, and does not affect message headers.
# Think Sendmail rule set \fBS0\fR, if you like. Use \fBcanonical\fR(5) # Use \fBcanonical\fR(5)
# mapping to rewrite header and envelope addresses in general. # mapping to rewrite header and envelope addresses in general.
# #
# Normally, the \fBvirtual\fR(5) alias table is specified as a text file # Normally, the \fBvirtual\fR(5) alias table is specified as a text file

View File

@@ -190,7 +190,6 @@ cleanup_bounce.o: ../../include/attr.h
cleanup_bounce.o: ../../include/been_here.h cleanup_bounce.o: ../../include/been_here.h
cleanup_bounce.o: ../../include/bounce.h cleanup_bounce.o: ../../include/bounce.h
cleanup_bounce.o: ../../include/cleanup_user.h cleanup_bounce.o: ../../include/cleanup_user.h
cleanup_bounce.o: ../../include/deliver_completed.h
cleanup_bounce.o: ../../include/deliver_request.h cleanup_bounce.o: ../../include/deliver_request.h
cleanup_bounce.o: ../../include/dict.h cleanup_bounce.o: ../../include/dict.h
cleanup_bounce.o: ../../include/dsn.h cleanup_bounce.o: ../../include/dsn.h
@@ -317,6 +316,7 @@ cleanup_init.o: ../../include/name_mask.h
cleanup_init.o: ../../include/nvtable.h cleanup_init.o: ../../include/nvtable.h
cleanup_init.o: ../../include/resolve_clnt.h cleanup_init.o: ../../include/resolve_clnt.h
cleanup_init.o: ../../include/string_list.h cleanup_init.o: ../../include/string_list.h
cleanup_init.o: ../../include/stringops.h
cleanup_init.o: ../../include/sys_defs.h cleanup_init.o: ../../include/sys_defs.h
cleanup_init.o: ../../include/tok822.h cleanup_init.o: ../../include/tok822.h
cleanup_init.o: ../../include/vbuf.h cleanup_init.o: ../../include/vbuf.h

View File

@@ -100,6 +100,14 @@
/* Optional lookup tables for content inspection of non-MIME message /* Optional lookup tables for content inspection of non-MIME message
/* headers in attached messages, as described in the \fBheader_checks\fR(5) /* headers in attached messages, as described in the \fBheader_checks\fR(5)
/* manual page. /* manual page.
/* .PP
/* Available in Postfix version 2.3 and later:
/* .IP "\fBmessage_reject_characters (empty)\fR"
/* The set of characters that Postfix will reject in message
/* content.
/* .IP "\fBmessage_strip_characters (empty)\fR"
/* The set of characters that Postfix will remove from message
/* content.
/* MIME PROCESSING CONTROLS /* MIME PROCESSING CONTROLS
/* .ad /* .ad
/* .fi /* .fi

View File

@@ -35,6 +35,7 @@ typedef struct CLEANUP_STATE {
VSTRING *attr_buf; /* storage for named attribute */ VSTRING *attr_buf; /* storage for named attribute */
VSTRING *temp1; /* scratch buffer, local use only */ VSTRING *temp1; /* scratch buffer, local use only */
VSTRING *temp2; /* scratch buffer, local use only */ VSTRING *temp2; /* scratch buffer, local use only */
VSTRING *stripped_buf; /* character stripped input */
VSTREAM *dst; /* current output stream */ VSTREAM *dst; /* current output stream */
MAIL_STREAM *handle; /* mail stream handle */ MAIL_STREAM *handle; /* mail stream handle */
char *queue_name; /* queue name */ char *queue_name; /* queue name */
@@ -69,6 +70,7 @@ typedef struct CLEANUP_STATE {
int dsn_ret; /* DSN full/hdrs */ int dsn_ret; /* DSN full/hdrs */
int dsn_notify; /* DSN never/delay/fail/success */ int dsn_notify; /* DSN never/delay/fail/success */
char *dsn_orcpt; /* DSN original recipient */ char *dsn_orcpt; /* DSN original recipient */
char *verp_delims; /* VERP delimiters (optional) */
} CLEANUP_STATE; } CLEANUP_STATE;
/* /*
@@ -98,6 +100,12 @@ extern int cleanup_masq_flags;
extern MAPS *cleanup_send_bcc_maps; extern MAPS *cleanup_send_bcc_maps;
extern MAPS *cleanup_rcpt_bcc_maps; extern MAPS *cleanup_rcpt_bcc_maps;
/*
* Character filters.
*/
extern VSTRING *cleanup_reject_chars;
extern VSTRING *cleanup_strip_chars;
/* /*
* Address canonicalization fine control. * Address canonicalization fine control.
*/ */
@@ -120,7 +128,7 @@ extern MAPS *cleanup_rcpt_bcc_maps;
extern int cleanup_ext_prop_mask; extern int cleanup_ext_prop_mask;
/* /*
* Saved queue file name, so the file can be removed in case of a fatal * Saved queue file names, so the files can be removed in case of a fatal
* run-time error. * run-time error.
*/ */
extern char *cleanup_path; extern char *cleanup_path;

View File

@@ -191,7 +191,6 @@ int cleanup_flush(CLEANUP_STATE *state)
{ {
int status; int status;
char *junk; char *junk;
VSTRING *bounce_junk;
VSTRING *trace_junk; VSTRING *trace_junk;
/* /*
@@ -205,41 +204,49 @@ int cleanup_flush(CLEANUP_STATE *state)
} }
/* /*
* If there was an error that requires us to generate a bounce message, * Status sanitization. Always report success when the discard flag was
* create bounce logfile records and reset the error flag in case of * raised by some user-specified access rule.
* success. Leave it up to the queue manager to deliver the bad news. We */
* can't do that ourselves, because there may also be a trace file lying if (state->flags & CLEANUP_FLAG_DISCARD)
* around (with DSN SUCCESS notifications) that also needs to be reported state->errs = 0;
* to the sender, and we must be able to undo the entire cleanup request
* including bounce and trace logfiles if some error happens. /*
* If there was an error that requires us to generate a bounce message
* (mail submitted with the Postfix sendmail command, mail forwarded by
* the local(8) delivery agent, or mail re-queued with "postsuper -r"),
* send a bounce notification, reset the error flags in case of success,
* and request deletion of the the incoming queue file and of the
* optional DSN SUCCESS records from virtual alias expansion.
* *
* An incomplete message should never be bounced: it was canceled by the * XXX It would make no sense to knowingly report success after we already
* client, and may not even have an address to bounce to. * have bounced all recipients, especially because the information in the
* DSN SUCCESS notice is completely redundant compared to the information
* in the bounce notice (however, both may be incomplete when the queue
* file size would exceed the safety limit).
* *
* If we are responsible for generating a bounce message, we must report * An alternative is to keep the DSN SUCCESS records and to delegate bounce
* success to the client unless the bounce message file could not be * notification to the queue manager, just like we already delegate
* written (which is just as bad as not being able to write the message * success notification. This requires that we leave the undeliverable
* queue file in the first place). * message in the incoming queue; versions up to 20050726 did exactly
* that. Unfortunately, this broke with over-size queue files, because
* the queue manager cannot handle incomplete queue files (and it should
* not try to do so).
*/ */
#define CAN_BOUNCE() \ #define CAN_BOUNCE() \
((state->errs & CLEANUP_STAT_MASK_CANT_BOUNCE) == 0 \ ((state->errs & CLEANUP_STAT_MASK_CANT_BOUNCE) == 0 \
&& state->sender != 0 \ && state->sender != 0 \
&& (state->flags & CLEANUP_FLAG_BOUNCE) != 0) && (state->flags & CLEANUP_FLAG_BOUNCE) != 0)
if (state->errs != 0 && (state->flags & CLEANUP_FLAG_DISCARD) == 0 if (state->errs != 0 && CAN_BOUNCE())
&& CAN_BOUNCE())
cleanup_bounce(state); cleanup_bounce(state);
/* /*
* If there are no errors, be very picky about queue file write errors
* because we are about to tell the sender that it can throw away its
* copy of the message.
*
* Optionally, place the message on hold, but only if the message was * Optionally, place the message on hold, but only if the message was
* received successfully. This involves renaming the queue file before * received successfully and only if it's not being discarded for other
* "finishing" it (or else the queue manager would open it for delivery) * reasons. This involves renaming the queue file before "finishing" it
* and updating our own idea of the queue file name for error recovery * (or else the queue manager would grab it too early) and updating our
* and for error reporting purposes. * own idea of the queue file name for error recovery and for error
* reporting purposes.
*/ */
if (state->errs == 0 && (state->flags & CLEANUP_FLAG_DISCARD) == 0) { if (state->errs == 0 && (state->flags & CLEANUP_FLAG_DISCARD) == 0) {
if ((state->flags & CLEANUP_FLAG_HOLD) != 0) { if ((state->flags & CLEANUP_FLAG_HOLD) != 0) {
@@ -265,22 +272,18 @@ int cleanup_flush(CLEANUP_STATE *state)
state->errs = mail_stream_finish(state->handle, (VSTRING *) 0); state->errs = mail_stream_finish(state->handle, (VSTRING *) 0);
} else { } else {
mail_stream_cleanup(state->handle); mail_stream_cleanup(state->handle);
if ((state->flags & CLEANUP_FLAG_DISCARD) != 0)
state->errs = 0;
} }
state->handle = 0; state->handle = 0;
state->dst = 0; state->dst = 0;
/* /*
* If there was an error, remove the queue file, the optional bounce * If there was an error, or if the message must be discarded for other
* logfile with undeliverable recipients, and the optional trace file * reasons, remove the queue file and the optional trace file with DSN
* with DSN SUCCESS notifications. * SUCCESS records from virtual alias expansion.
*/ */
if (state->errs != 0 || (state->flags & CLEANUP_FLAG_DISCARD) != 0) { if (state->errs != 0 || (state->flags & CLEANUP_FLAG_DISCARD) != 0) {
if (cleanup_trace_path) if (cleanup_trace_path)
(void) REMOVE(vstring_str(cleanup_trace_path)); (void) REMOVE(vstring_str(cleanup_trace_path));
if (cleanup_bounce_path)
(void) REMOVE(vstring_str(cleanup_bounce_path));
if (REMOVE(cleanup_path)) if (REMOVE(cleanup_path))
msg_warn("remove %s: %m", cleanup_path); msg_warn("remove %s: %m", cleanup_path);
} }
@@ -292,15 +295,11 @@ int cleanup_flush(CLEANUP_STATE *state)
*/ */
trace_junk = cleanup_trace_path; trace_junk = cleanup_trace_path;
cleanup_trace_path = 0; /* don't delete upon error */ cleanup_trace_path = 0; /* don't delete upon error */
bounce_junk = cleanup_bounce_path;
cleanup_bounce_path = 0; /* don't delete upon error */
junk = cleanup_path; junk = cleanup_path;
cleanup_path = 0; /* don't delete upon error */ cleanup_path = 0; /* don't delete upon error */
if (trace_junk) if (trace_junk)
vstring_free(trace_junk); vstring_free(trace_junk);
if (bounce_junk)
vstring_free(bounce_junk);
myfree(junk); myfree(junk);
/* /*

View File

@@ -12,7 +12,8 @@
/* cleanup_bounce() updates the bounce log on request by client /* cleanup_bounce() updates the bounce log on request by client
/* programs that cannot handle such problems themselves. /* programs that cannot handle such problems themselves.
/* /*
/* Upon successful completion, all error flags are reset. /* Upon successful completion, all error flags are reset,
/* and the message is scheduled for deletion.
/* Otherwise, the CLEANUP_STAT_WRITE error flag is raised. /* Otherwise, the CLEANUP_STAT_WRITE error flag is raised.
/* /*
/* Arguments: /* Arguments:
@@ -52,7 +53,6 @@
#include <dsn_mask.h> #include <dsn_mask.h>
#include <mail_queue.h> #include <mail_queue.h>
#include <dsn_attr_map.h> #include <dsn_attr_map.h>
#include <deliver_completed.h>
/* Application-specific. */ /* Application-specific. */
@@ -65,24 +65,10 @@
static void cleanup_bounce_append(CLEANUP_STATE *state, RECIPIENT *rcpt, static void cleanup_bounce_append(CLEANUP_STATE *state, RECIPIENT *rcpt,
DSN *dsn) DSN *dsn)
{ {
const char *myname = "cleanup_bounce_append";
long last_offset;
if (cleanup_bounce_path == 0) {
cleanup_bounce_path = vstring_alloc(10);
(void) mail_queue_path(cleanup_bounce_path, MAIL_QUEUE_BOUNCE,
state->queue_id);
}
if (bounce_append(BOUNCE_FLAG_CLEAN, state->queue_id, state->time, if (bounce_append(BOUNCE_FLAG_CLEAN, state->queue_id, state->time,
rcpt, "none", dsn) != 0) { rcpt, "none", dsn) != 0) {
msg_warn("%s: bounce logfile update error", state->queue_id); msg_warn("%s: bounce logfile update error", state->queue_id);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
} else if (rcpt->offset > 0) {
if ((last_offset = vstream_ftell(state->dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path);
deliver_completed(state->dst, rcpt->offset);
if (vstream_fseek(state->dst, last_offset, SEEK_SET) < 0)
msg_fatal("%s: seek %s: %m", myname, cleanup_path);
} }
} }
@@ -108,6 +94,10 @@ int cleanup_bounce(CLEANUP_STATE *state)
int rec_type; int rec_type;
int junk; int junk;
long curr_offset; long curr_offset;
const char *encoding;
const char *dsn_envid;
int dsn_ret;
int bounce_err;
/* /*
* Parse the failure reason if one was given, otherwise use a generic * Parse the failure reason if one was given, otherwise use a generic
@@ -127,18 +117,19 @@ int cleanup_bounce(CLEANUP_STATE *state)
* Create a bounce logfile with one entry for each final recipient. * Create a bounce logfile with one entry for each final recipient.
* Degrade gracefully in case of no recipients or no queue file. * Degrade gracefully in case of no recipients or no queue file.
* *
* We're NOT going to flush the bounce file from the cleanup server; if we
* need to write trace logfile records, and the trace service fails, we
* must be able to cancel the entire cleanup request including any trace
* or bounce logfiles. The queue manager will flush the bounce (and
* trace) logfile, possibly after it has generated its own success or
* failure notification records.
*
* Victor Duchovni observes that the number of recipients in the queue file * Victor Duchovni observes that the number of recipients in the queue file
* can potentially be very large due to virtual alias expansion. This can * can potentially be very large due to virtual alias expansion. This can
* expand the recipient count by virtual_alias_expansion_limit (default: * expand the recipient count by virtual_alias_expansion_limit (default:
* 1000) times. * 1000) times.
*
* After a queue file size error, purge any unwritten data (so that
* vstream_fseek() won't fail while trying to flush it) and reset the
* stream error flags to avoid false alarms.
*/ */
if (state->errs & CLEANUP_STAT_SIZE) {
(void) vstream_fpurge(state->dst);
vstream_clearerr(state->dst);
}
if (vstream_fseek(state->dst, 0L, SEEK_SET) < 0) if (vstream_fseek(state->dst, 0L, SEEK_SET) < 0)
msg_fatal("%s: seek %s: %m", myname, cleanup_path); msg_fatal("%s: seek %s: %m", myname, cleanup_path);
@@ -206,12 +197,51 @@ int cleanup_bounce(CLEANUP_STATE *state)
/* /*
* No recipients. Yes, this can happen. * No recipients. Yes, this can happen.
*/ */
if (rcpt == 0) { if ((state->errs & CLEANUP_STAT_WRITE) == 0 && rcpt == 0) {
RECIPIENT_ASSIGN(&recipient, 0, "", 0, "", "unknown"); RECIPIENT_ASSIGN(&recipient, 0, "", 0, "", "unknown");
(void) DSN_SIMPLE(&dsn, dsn_status, dsn_text); (void) DSN_SIMPLE(&dsn, dsn_status, dsn_text);
cleanup_bounce_append(state, &recipient, &dsn); cleanup_bounce_append(state, &recipient, &dsn);
} }
vstring_free(buf); vstring_free(buf);
return (state->errs &= CLEANUP_STAT_WRITE); /*
* Flush the bounce logfile to the sender. See also qmgr_active.c.
*/
if ((state->errs & CLEANUP_STAT_WRITE) == 0) {
if ((encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) == 0)
encoding = MAIL_ATTR_ENC_NONE;
dsn_envid = state->dsn_envid ?
state->dsn_envid : "";
dsn_ret = (state->errs & (CLEANUP_STAT_CONT | CLEANUP_STAT_SIZE)) ?
DSN_RET_HDRS : state->dsn_ret;
if (state->verp_delims == 0 || var_verp_bounce_off) {
bounce_err =
bounce_flush(BOUNCE_FLAG_CLEAN,
state->queue_name, state->queue_id,
encoding, state->sender, dsn_envid,
dsn_ret);
} else {
bounce_err =
bounce_flush_verp(BOUNCE_FLAG_CLEAN,
state->queue_name, state->queue_id,
encoding, state->sender, dsn_envid,
dsn_ret, state->verp_delims);
}
if (bounce_err != 0) {
msg_warn("%s: bounce message failure", state->queue_id);
state->errs |= CLEANUP_STAT_WRITE;
}
}
/*
* Schedule this message (and trace logfile) for deletion when all is
* well. When all is not well these files would be deleted too, but the
* client would get a different completion status so we have to carefully
* maintain the bits anyway.
*/
if ((state->errs &= CLEANUP_STAT_WRITE) == 0)
state->flags |= CLEANUP_FLAG_DISCARD;
return (state->errs);
} }

View File

@@ -368,6 +368,22 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
} }
return; return;
} }
/* XXX Needed for cleanup_bounce(); sanity check usage. */
if (type == REC_TYPE_VERP) {
if (state->verp_delims == 0) {
if (state->sender == 0 || state->sender[0] == 0) {
msg_warn("%s: ignoring VERP request for null sender",
state->queue_id);
} else if (verp_delims_verify(buf) != 0) {
msg_warn("%s: ignoring bad VERP request: \"%.100s\"",
state->queue_id, buf);
} else {
state->verp_delims = mystrdup(buf);
cleanup_out(state, type, buf, len);
}
}
return;
}
if (type == REC_TYPE_ATTR) { if (type == REC_TYPE_ATTR) {
if (state->attr->used >= var_qattr_count_limit) { if (state->attr->used >= var_qattr_count_limit) {
msg_warn("%s: message rejected: attribute count exceeds limit %d", msg_warn("%s: message rejected: attribute count exceeds limit %d",

View File

@@ -251,7 +251,7 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type,
} }
} }
/* cleanup_extracted_finish - process one extracted envelope record */ /* cleanup_extracted_finish - complete the third message segment */
void cleanup_extracted_finish(CLEANUP_STATE *state) void cleanup_extracted_finish(CLEANUP_STATE *state)
{ {

View File

@@ -24,7 +24,6 @@
/* /*
/* char *cleanup_path; /* char *cleanup_path;
/* VSTRING *cleanup_trace_path; /* VSTRING *cleanup_trace_path;
/* VSTRING *cleanup_bounce_path;
/* /*
/* void cleanup_all() /* void cleanup_all()
/* /*
@@ -54,8 +53,6 @@
/* trace logfile with DSN SUCCESS notifications. This information is /* trace logfile with DSN SUCCESS notifications. This information is
/* used to remove a trace file when the mail transaction is canceled. /* used to remove a trace file when the mail transaction is canceled.
/* /*
/* cleanup_bounce_path is the same for removing a bounce logfile.
/*
/* cleanup_all() must be called in case of fatal error, in order /* cleanup_all() must be called in case of fatal error, in order
/* to remove an incomplete queue file. /* to remove an incomplete queue file.
/* /*
@@ -80,12 +77,14 @@
#include <sys_defs.h> #include <sys_defs.h>
#include <signal.h> #include <signal.h>
#include <string.h>
/* Utility library. */ /* Utility library. */
#include <msg.h> #include <msg.h>
#include <iostuff.h> #include <iostuff.h>
#include <name_mask.h> #include <name_mask.h>
#include <stringops.h>
/* Global library. */ /* Global library. */
@@ -109,7 +108,6 @@ char *cleanup_path; /* queue file name */
* logfiles that need to be cleaned up when the cleanup request is aborted. * logfiles that need to be cleaned up when the cleanup request is aborted.
*/ */
VSTRING *cleanup_trace_path; VSTRING *cleanup_trace_path;
VSTRING *cleanup_bounce_path;
/* /*
* Tunable parameters. * Tunable parameters.
@@ -143,6 +141,9 @@ int var_body_check_len; /* when to stop body scan */
char *var_send_bcc_maps; /* sender auto-bcc maps */ char *var_send_bcc_maps; /* sender auto-bcc maps */
char *var_rcpt_bcc_maps; /* recipient auto-bcc maps */ char *var_rcpt_bcc_maps; /* recipient auto-bcc maps */
char *var_remote_rwr_domain; /* header-only surrogate */ char *var_remote_rwr_domain; /* header-only surrogate */
char *var_msg_reject_chars; /* reject these characters */
char *var_msg_strip_chars; /* strip these characters */
int var_verp_bounce_off; /* don't verp the bounces */
CONFIG_INT_TABLE cleanup_int_table[] = { CONFIG_INT_TABLE cleanup_int_table[] = {
VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0, VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
@@ -156,6 +157,7 @@ CONFIG_INT_TABLE cleanup_int_table[] = {
CONFIG_BOOL_TABLE cleanup_bool_table[] = { CONFIG_BOOL_TABLE cleanup_bool_table[] = {
VAR_ENABLE_ORCPT, DEF_ENABLE_ORCPT, &var_enable_orcpt, VAR_ENABLE_ORCPT, DEF_ENABLE_ORCPT, &var_enable_orcpt,
VAR_VERP_BOUNCE_OFF, DEF_VERP_BOUNCE_OFF, &var_verp_bounce_off,
0, 0,
}; };
@@ -186,6 +188,8 @@ CONFIG_STR_TABLE cleanup_str_table[] = {
VAR_SEND_BCC_MAPS, DEF_SEND_BCC_MAPS, &var_send_bcc_maps, 0, 0, VAR_SEND_BCC_MAPS, DEF_SEND_BCC_MAPS, &var_send_bcc_maps, 0, 0,
VAR_RCPT_BCC_MAPS, DEF_RCPT_BCC_MAPS, &var_rcpt_bcc_maps, 0, 0, VAR_RCPT_BCC_MAPS, DEF_RCPT_BCC_MAPS, &var_rcpt_bcc_maps, 0, 0,
VAR_REM_RWR_DOMAIN, DEF_REM_RWR_DOMAIN, &var_remote_rwr_domain, 0, 0, VAR_REM_RWR_DOMAIN, DEF_REM_RWR_DOMAIN, &var_remote_rwr_domain, 0, 0,
VAR_MSG_REJECT_CHARS, DEF_MSG_REJECT_CHARS, &var_msg_reject_chars, 0, 0,
VAR_MSG_STRIP_CHARS, DEF_MSG_STRIP_CHARS, &var_msg_strip_chars, 0, 0,
0, 0,
}; };
@@ -209,6 +213,12 @@ int cleanup_masq_flags;
MAPS *cleanup_send_bcc_maps; MAPS *cleanup_send_bcc_maps;
MAPS *cleanup_rcpt_bcc_maps; MAPS *cleanup_rcpt_bcc_maps;
/*
* Character filters.
*/
VSTRING *cleanup_reject_chars;
VSTRING *cleanup_strip_chars;
/* /*
* Address extension propagation restrictions. * Address extension propagation restrictions.
*/ */
@@ -238,10 +248,6 @@ void cleanup_sig(int sig)
(void) REMOVE(vstring_str(cleanup_trace_path)); (void) REMOVE(vstring_str(cleanup_trace_path));
cleanup_trace_path = 0; cleanup_trace_path = 0;
} }
if (cleanup_bounce_path) {
(void) REMOVE(vstring_str(cleanup_bounce_path));
cleanup_bounce_path = 0;
}
if (cleanup_path) { if (cleanup_path) {
(void) REMOVE(cleanup_path); (void) REMOVE(cleanup_path);
cleanup_path = 0; cleanup_path = 0;
@@ -360,4 +366,17 @@ void cleanup_post_jail(char *unused_name, char **unused_argv)
*/ */
cleanup_ext_prop_mask = cleanup_ext_prop_mask =
ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension); ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
/*
* Setup the filters for characters that should be rejected, and for
* characters that should be removed.
*/
if (*var_msg_reject_chars) {
cleanup_reject_chars = vstring_alloc(strlen(var_msg_reject_chars));
unescape(cleanup_reject_chars, var_msg_reject_chars);
}
if (*var_msg_strip_chars) {
cleanup_strip_chars = vstring_alloc(strlen(var_msg_strip_chars));
unescape(cleanup_strip_chars, var_msg_strip_chars);
}
} }

View File

@@ -293,6 +293,7 @@ static void cleanup_act_log(CLEANUP_STATE *state,
#define CLEANUP_ACT_CTXT_HEADER "header" #define CLEANUP_ACT_CTXT_HEADER "header"
#define CLEANUP_ACT_CTXT_BODY "body" #define CLEANUP_ACT_CTXT_BODY "body"
#define CLEANUP_ACT_CTXT_ANY "content"
/* cleanup_act - act upon a header/body match */ /* cleanup_act - act upon a header/body match */
@@ -703,8 +704,51 @@ static void cleanup_body_callback(void *context, int type,
static void cleanup_message_headerbody(CLEANUP_STATE *state, int type, static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
const char *buf, ssize_t len) const char *buf, ssize_t len)
{ {
char *myname = "cleanup_message_headerbody"; const char *myname = "cleanup_message_headerbody";
MIME_STATE_DETAIL *detail; MIME_STATE_DETAIL *detail;
const char *cp;
char *dst;
/*
* Reject unwanted characters.
*
* XXX Possible optimization: simplify the loop when the "reject" set
* contains only one character.
*/
if ((state->flags & CLEANUP_FLAG_FILTER) && cleanup_reject_chars) {
for (cp = buf; cp < buf + len; cp++) {
if (memchr(vstring_str(cleanup_reject_chars),
*(const unsigned char *) cp,
VSTRING_LEN(cleanup_reject_chars))) {
cleanup_act(state, CLEANUP_ACT_CTXT_ANY,
buf, "REJECT disallowed character",
"character reject");
return;
}
}
}
/*
* Strip unwanted characters. Don't overwrite the input.
*
* XXX Possible optimization: simplify the loop when the "strip" set
* contains only one character.
*
* XXX Possible optimization: copy the input only if we really have to.
*/
if ((state->flags & CLEANUP_FLAG_FILTER) && cleanup_strip_chars) {
VSTRING_RESET(state->stripped_buf);
VSTRING_SPACE(state->stripped_buf, len + 1);
dst = vstring_str(state->stripped_buf);
for (cp = buf; cp < buf + len; cp++)
if (!memchr(vstring_str(cleanup_strip_chars),
*(const unsigned char *) cp,
VSTRING_LEN(cleanup_strip_chars)))
*dst++ = *cp;
*dst = 0;
buf = vstring_str(state->stripped_buf);
len = dst - buf;
}
/* /*
* Copy text record to the output. * Copy text record to the output.

View File

@@ -59,6 +59,8 @@ CLEANUP_STATE *cleanup_state_alloc(void)
state->attr_buf = vstring_alloc(10); state->attr_buf = vstring_alloc(10);
state->temp1 = vstring_alloc(10); state->temp1 = vstring_alloc(10);
state->temp2 = vstring_alloc(10); state->temp2 = vstring_alloc(10);
if (cleanup_strip_chars)
state->stripped_buf = vstring_alloc(10);
state->dst = 0; state->dst = 0;
state->handle = 0; state->handle = 0;
state->queue_name = 0; state->queue_name = 0;
@@ -94,6 +96,7 @@ CLEANUP_STATE *cleanup_state_alloc(void)
state->dsn_ret = 0; state->dsn_ret = 0;
state->dsn_notify = 0; state->dsn_notify = 0;
state->dsn_orcpt = 0; state->dsn_orcpt = 0;
state->verp_delims = 0;
return (state); return (state);
} }
@@ -104,6 +107,8 @@ void cleanup_state_free(CLEANUP_STATE *state)
vstring_free(state->attr_buf); vstring_free(state->attr_buf);
vstring_free(state->temp1); vstring_free(state->temp1);
vstring_free(state->temp2); vstring_free(state->temp2);
if (cleanup_strip_chars)
vstring_free(state->stripped_buf);
if (state->fullname) if (state->fullname)
myfree(state->fullname); myfree(state->fullname);
if (state->sender) if (state->sender)
@@ -134,5 +139,7 @@ void cleanup_state_free(CLEANUP_STATE *state)
myfree(state->dsn_envid); myfree(state->dsn_envid);
if (state->dsn_orcpt) if (state->dsn_orcpt)
myfree(state->dsn_orcpt); myfree(state->dsn_orcpt);
if (state->verp_delims)
myfree(state->verp_delims);
myfree((char *) state); myfree((char *) state);
} }

View File

@@ -24,6 +24,17 @@
/* const char *dsn_envid; /* const char *dsn_envid;
/* int dsn_ret; /* int dsn_ret;
/* /*
/* int bounce_flush_verp(flags, queue, id, encoding, sender,
/* dsn_envid, dsn_ret, verp_delims)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/* const char *dsn_envid;
/* int dsn_ret;
/* const char *verp_delims;
/*
/* int bounce_one(flags, queue, id, encoding, sender, envid, ret, /* int bounce_one(flags, queue, id, encoding, sender, envid, ret,
/* entry, recipient, relay, dsn) /* entry, recipient, relay, dsn)
/* int flags; /* int flags;
@@ -53,6 +64,10 @@
/* built with bounce_append(). The bounce logfile is removed /* built with bounce_append(). The bounce logfile is removed
/* upon successful completion. /* upon successful completion.
/* /*
/* bounce_flush_verp() is like bounce_flush(), but sends one
/* notification per recipient, with the failed recipient encoded
/* into the sender address.
/*
/* bounce_one() bounces one recipient and immediately sends a /* bounce_one() bounces one recipient and immediately sends a
/* notification to the sender. This procedure does not append /* notification to the sender. This procedure does not append
/* the recipient and dsn_text to the per-message bounce log, and /* the recipient and dsn_text to the per-message bounce log, and
@@ -101,6 +116,9 @@
/* Optional DSN return full/headers option. /* Optional DSN return full/headers option.
/* .IP dsn /* .IP dsn
/* Delivery status. See dsn(3). The specified action is ignored. /* Delivery status. See dsn(3). The specified action is ignored.
/* .IP verp_delims
/* VERP delimiter characters, used when encoding the failed
/* sender into the envelope sender address.
/* DIAGNOSTICS /* DIAGNOSTICS
/* In case of success, these functions log the action, and return a /* In case of success, these functions log the action, and return a
/* zero value. Otherwise, the functions return a non-zero result, /* zero value. Otherwise, the functions return a non-zero result,
@@ -276,6 +294,40 @@ int bounce_flush(int flags, const char *queue, const char *id,
} }
} }
/* bounce_flush_verp - verpified notification */
int bounce_flush_verp(int flags, const char *queue, const char *id,
const char *encoding, const char *sender,
const char *dsn_envid, int dsn_ret,
const char *verp_delims)
{
/*
* When we're pretending that we can't bounce, don't send a bounce
* message.
*/
if (var_soft_bounce)
return (-1);
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_VERP,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
ATTR_TYPE_NUM, MAIL_ATTR_DSN_RET, dsn_ret,
ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
ATTR_TYPE_END) == 0) {
return (0);
} else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
msg_info("%s: status=deferred (bounce failed)", id);
return (-1);
} else {
return (-1);
}
}
/* bounce_one - send notice for one recipient */ /* bounce_one - send notice for one recipient */
int bounce_one(int flags, const char *queue, const char *id, int bounce_one(int flags, const char *queue, const char *id,

View File

@@ -28,6 +28,8 @@ extern int bounce_append(int, const char *, time_t, RECIPIENT *,
const char *, DSN *); const char *, DSN *);
extern int bounce_flush(int, const char *, const char *, const char *, extern int bounce_flush(int, const char *, const char *, const char *,
const char *, const char *, int); const char *, const char *, int);
extern int bounce_flush_verp(int, const char *, const char *, const char *,
const char *, const char *, int, const char *);
extern int bounce_one(int, const char *, const char *, const char *, extern int bounce_one(int, const char *, const char *, const char *,
const char *, const char *, const char *, const char *,
int, time_t, RECIPIENT *, int, time_t, RECIPIENT *,

View File

@@ -2362,6 +2362,17 @@ extern char *var_smtp_ehlo_dis_maps;
*/ */
extern const char null_format_string[1]; extern const char null_format_string[1];
/*
* Characters to reject or strip.
*/
#define VAR_MSG_REJECT_CHARS "message_reject_characters"
#define DEF_MSG_REJECT_CHARS ""
extern char *var_msg_reject_chars;
#define VAR_MSG_STRIP_CHARS "message_strip_characters"
#define DEF_MSG_STRIP_CHARS ""
extern char *var_msg_strip_chars;
/* LICENSE /* LICENSE
/* .ad /* .ad
/* .fi /* .fi

View File

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

View File

@@ -272,6 +272,8 @@ void qmgr_active_done(QMGR_MESSAGE *message)
* *
* Bounces are sent asynchronously to avoid stalling while the cleanup * Bounces are sent asynchronously to avoid stalling while the cleanup
* daemon waits for the qmgr to accept the "new mail" trigger. * daemon waits for the qmgr to accept the "new mail" trigger.
*
* See also code in cleanup_bounce.c.
*/ */
if (stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_BOUNCE, message->queue_id), &st) == 0) { if (stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_BOUNCE, message->queue_id), &st) == 0) {
if (st.st_size == 0) { if (st.st_size == 0) {

View File

@@ -272,6 +272,8 @@ void qmgr_active_done(QMGR_MESSAGE *message)
* *
* Bounces are sent asynchronously to avoid stalling while the cleanup * Bounces are sent asynchronously to avoid stalling while the cleanup
* daemon waits for the qmgr to accept the "new mail" trigger. * daemon waits for the qmgr to accept the "new mail" trigger.
*
* See also code in cleanup_bounce.c.
*/ */
if (stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_BOUNCE, message->queue_id), &st) == 0) { if (stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_BOUNCE, message->queue_id), &st) == 0) {
if (st.st_size == 0) { if (st.st_size == 0) {

View File

@@ -250,6 +250,8 @@ int smtpd_proxy_open(SMTPD_STATE *state, const char *service,
0, 0, 0, 0,
}; };
CLEANUP_STAT_DETAIL *detail; CLEANUP_STAT_DETAIL *detail;
int (*connect_fn) (const char *, int, int);
const char *endpoint;
/* /*
* This buffer persists beyond the end of a proxy session so we can * This buffer persists beyond the end of a proxy session so we can
@@ -258,10 +260,24 @@ int smtpd_proxy_open(SMTPD_STATE *state, const char *service,
if (state->proxy_buffer == 0) if (state->proxy_buffer == 0)
state->proxy_buffer = vstring_alloc(10); state->proxy_buffer = vstring_alloc(10);
/*
* Find connection method (default inet)
*/
if (strncasecmp("unix:", service, 5) == 0) {
endpoint = service + 5;
connect_fn = unix_connect;
} else {
if (strncasecmp("inet:", service, 5) == 0)
endpoint = service + 5;
else
endpoint = service;
connect_fn = inet_connect;
}
/* /*
* Connect to proxy. * Connect to proxy.
*/ */
if ((fd = inet_connect(service, BLOCKING, timeout)) < 0) { if ((fd = connect_fn(endpoint, BLOCKING, timeout)) < 0) {
state->error_mask |= MAIL_ERROR_SOFTWARE; state->error_mask |= MAIL_ERROR_SOFTWARE;
state->err |= CLEANUP_STAT_PROXY; state->err |= CLEANUP_STAT_PROXY;
msg_warn("connect to proxy service %s: %m", service); msg_warn("connect to proxy service %s: %m", service);

View File

@@ -105,8 +105,8 @@ TLScontext_t *tls_alloc_context(int log_level, const char *peername)
TLScontext_t *TLScontext; TLScontext_t *TLScontext;
/* /*
* PORTABILITY: Do not assume that null pointers are all-zero bits. * PORTABILITY: Do not assume that null pointers are all-zero bits. Use
* Use explicit assignments to initialize pointers. * explicit assignments to initialize pointers.
* *
* See the C language FAQ item 5.17, or if you have time to burn, * See the C language FAQ item 5.17, or if you have time to burn,
* http://www.google.com/search?q=zero+bit+null+pointer * http://www.google.com/search?q=zero+bit+null+pointer
@@ -288,4 +288,11 @@ long tls_bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi,
return (ret); return (ret);
} }
#else
/*
* Broken linker workaround.
*/
int tls_dummy_for_broken_linkers;
#endif #endif

View File

@@ -59,6 +59,9 @@ int sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len)
EWOULDBLOCK, EWOULDBLOCK,
ENOBUFS, /* HPUX11 */ ENOBUFS, /* HPUX11 */
ECONNABORTED, ECONNABORTED,
#ifdef EPROTO
EPROTO, /* SunOS 5.5.1 */
#endif
0, 0,
}; };
int count; int count;
@@ -71,6 +74,10 @@ int sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len)
* hosed beyond recovery. There is no point treating this as a beneficial * hosed beyond recovery. There is no point treating this as a beneficial
* error result because the program would go into a tight loop. * error result because the program would go into a tight loop.
* *
* XXX Solaris 2.5.1 accept() returns EPROTO when a TCP client has
* disconnected in the mean time. Since there is no connection, it is
* safe to map the error code onto EAGAIN.
*
* XXX LINUX < 2.1 accept() wakes up before the three-way handshake is * XXX LINUX < 2.1 accept() wakes up before the three-way handshake is
* complete, so it can fail with ECONNRESET and other "false alarm" * complete, so it can fail with ECONNRESET and other "false alarm"
* indications. * indications.

View File

@@ -58,6 +58,9 @@
/* int vstream_fflush(stream) /* int vstream_fflush(stream)
/* VSTREAM *stream; /* VSTREAM *stream;
/* /*
/* int vstream_fpurge(stream)
/* VSTREAM *stream;
/*
/* ssize_t vstream_fread(stream, buf, len) /* ssize_t vstream_fread(stream, buf, len)
/* VSTREAM *stream; /* VSTREAM *stream;
/* char *buf; /* char *buf;
@@ -210,6 +213,12 @@
/* vstream_fflush() returns 0 in case of success, VSTREAM_EOF in /* vstream_fflush() returns 0 in case of success, VSTREAM_EOF in
/* case of problems. It is an error to flush a read-only stream. /* case of problems. It is an error to flush a read-only stream.
/* /*
/* vstream_fpurge() discards the contents of the stream buffer.
/* In the case of a double-buffered stream, it discards the
/* content of both the read and write buffers.
/* vstream_fpurge() returns 0 in case of success, VSTREAM_EOF in
/* case of problems.
/*
/* vstream_fread() and vstream_fwrite() perform unformatted I/O /* vstream_fread() and vstream_fwrite() perform unformatted I/O
/* on the named stream. The result value is the number of bytes /* on the named stream. The result value is the number of bytes
/* transferred. A short count is returned in case of end-of-file /* transferred. A short count is returned in case of end-of-file
@@ -800,6 +809,53 @@ static int vstream_buf_space(VBUF *bp, ssize_t want)
return (vstream_ferror(stream) ? VSTREAM_EOF : 0); /* mmap() may fail */ return (vstream_ferror(stream) ? VSTREAM_EOF : 0); /* mmap() may fail */
} }
/* vstream_fpurge - discard unread or unwritten content */
int vstream_fpurge(VSTREAM *stream)
{
const char *myname = "vstream_fpurge";
VBUF *bp = &stream->buf;
/*
* To discard all unread contents, position the read buffer at its end,
* so that we skip over any unread data, and so that the next read
* operation will refill the buffer.
*
* To discard all unwritten content, position the write buffer at its
* beginning, so that the next write operation clobbers any unwritten
* data.
*/
switch (bp->flags & (VSTREAM_FLAG_READ_DOUBLE | VSTREAM_FLAG_WRITE)) {
case VSTREAM_FLAG_READ_DOUBLE:
VSTREAM_BUF_AT_START(&stream->write_buf);
/* FALLTHROUGH */
case VSTREAM_FLAG_READ:
VSTREAM_BUF_AT_END(bp);
break;
case VSTREAM_FLAG_DOUBLE:
VSTREAM_BUF_AT_START(&stream->write_buf);
VSTREAM_BUF_AT_END(&stream->read_buf);
break;
case VSTREAM_FLAG_WRITE_DOUBLE:
VSTREAM_BUF_AT_END(&stream->read_buf);
/* FALLTHROUGH */
case VSTREAM_FLAG_WRITE:
VSTREAM_BUF_AT_START(bp);
break;
case VSTREAM_FLAG_READ_DOUBLE | VSTREAM_FLAG_WRITE:
case VSTREAM_FLAG_READ | VSTREAM_FLAG_WRITE:
msg_panic("%s: read/write stream", myname);
}
/*
* Invalidate the cached file seek position.
*/
bp->flags &= ~VSTREAM_FLAG_SEEK;
stream->offset = 0;
return (0);
}
/* vstream_fseek - change I/O position */ /* vstream_fseek - change I/O position */
off_t vstream_fseek(VSTREAM *stream, off_t offset, int whence) off_t vstream_fseek(VSTREAM *stream, off_t offset, int whence)

View File

@@ -75,6 +75,7 @@ extern VSTREAM *vstream_fopen(const char *, int, mode_t);
extern int vstream_fclose(VSTREAM *); extern int vstream_fclose(VSTREAM *);
extern off_t vstream_fseek(VSTREAM *, off_t, int); extern off_t vstream_fseek(VSTREAM *, off_t, int);
extern off_t vstream_ftell(VSTREAM *); extern off_t vstream_ftell(VSTREAM *);
extern int vstream_fpurge(VSTREAM *);
extern int vstream_fflush(VSTREAM *); extern int vstream_fflush(VSTREAM *);
extern int vstream_fputs(const char *, VSTREAM *); extern int vstream_fputs(const char *, VSTREAM *);
extern VSTREAM *vstream_fdopen(int, int); extern VSTREAM *vstream_fdopen(int, int);