avoiding code tries a little harder when it encounters a
race condition. File: util/safe_open.c.
-20030623
-
- Non-prod operator precedence bug with detecting end of
- DATA. Matthias Andree. File: smtpd/smtpd.c.
-
20030624
Bugfix: reject_unverified_address() set the defer_if_reject
Feature: TCP lookup table support, finally finished. Files:
proto/tcp_table, proto/dict_tcp.[hc].
-20030703
+20030705
- Non-prod: the SMTPD proxy client lost the reply to ".".
- Amazing.
+ Feature: new receive_override_options parameter controls
+ what happens before or after an external content filter:
+ rejecting unknown recipients, canonical and virtual address
+ mapping, address masquerading, automatic BCC recipients
+ and header/body checks. This is more convenient than having
+ to specify two different cleanup services in the master.cf
+ file.
Open problems:
Introduction
============
-This is a very first implementation of Postfix content filtering.
-A Postfix content filter receives unfiltered mail from Postfix and
-does one of the following:
+Normally, Postfix receives mail, stores it in the mail queue and
+then delivers it. With the external content filter described here,
+mail is filtered AFTER it is queued. This gives you maximal control
+over how many filtering processes you are willing to run in parallel.
-- re-injects the mail back into Postfix, perhaps after changing content
-- rejects the mail (by sending a suitable status code back to
- Postfix) so that it is returned to sender.
-- sends the mail somewhere else
+[This is not to be confused with the approach that is described in
+the SMTPD_PROXY_README document, where SMTP mail is filtered BEFORE
+it is queued]
+
+An external content filter receives unfiltered mail from Postfix
+and does one of the following:
+
+1 - Re-inject the mail back into Postfix, perhaps after changing
+ content.
+
+2 - Reject the mail (by sending a suitable status code back to
+ Postfix) so that it is returned to sender.
+
+3 - Send the mail somewhere else.
This document describes two approaches to content filtering: simple
and advanced. Both filter all the mail by default.
At the end are examples that show how to filter only mail from
-users, about using different filters for different domains that
-you provide MX service for, and about selective filtering on the
-basis of message envelope and/or header/body patterns.
+users, how to use different filters for different domains that you
+provide MX service for, and how to set up selective filtering on
+the basis of message envelope and/or header/body patterns.
Simple content filtering example
================================
software that can receive and deliver mail via SMTP.
Some Anti-virus software is built to receive and deliver mail via
-SMTP and is ready to use as an advanced Postfix content filter.
+SMTP and is ready to use as an advanced external content filter.
For non-SMTP capable content filtering software, Bennett Todd's
SMTP proxy implements a nice PERL/SMTP content filtering framework.
See: http://bent.latency.net/smtpprox/
: :
.................
-To enable content filtering in this manner, specify in main.cf a
-new parameter:
+To enable content filtering in this manner, specify in main.cf:
/etc/postfix/main.cf:
content_filter = scan:localhost:10025
+ receive_override_options = no_address_mappings
+
+The first line causes Postfix to add one extra content filtering
+record to each incoming mail message, with content scan:localhost:10025.
+The content filtering records are added by the smtpd, pickup and
+qmqpd servers.
-This causes Postfix to add one extra content filtering record to
-each incoming mail message, with content scan:localhost:10025.
-The content filtering records are added by the smtpd and pickup
-servers.
+The second line disables address mapping before the content filter,
+so that the content filter sees the original mail addresses instead
+of the result of virtual alias expansion, canonical mapping, address
+masquerading, etc.
When a queue file has content filtering information, the queue
manager will deliver the mail to the specified content filter
/etc/postfix/master.cf:
localhost:10026 inet n - n - 10 smtpd
-o content_filter=
- -o local_recipient_maps=
- -o relay_recipient_maps=
+ -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o myhostname=localhost.domain.tld
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-Warning for Postfix version 2 users: in this SMTP server after the
-content filter, do not override main.cf settings for virtual_alias_maps
-or virtual_alias_domains. That would cause mail to be rejected with
-"User unknown".
+Note: do not use spaces around the "=" or "," characters.
This SMTP server has the same process limit as the "filter" master.cf
entry.
-The "-o content_filter=" requests no content filtering for incoming
-mail.
+The "-o content_filter=" overrides main.cf and requests no content
+filtering for incoming mail. This is required or else mail will
+stay in the content filtering loop.
-The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
-unnecessary table lookups.
+The "-o receive_override_options" line overrides main.cf and turns
+off table lookups that were already done before the content filter:
+attempts to find out if a recipient is unknown, and header/body
+checks that can suck up lots of CPU cycles. These override options
+are either implemented by the SMTP server itself, or they are passed
+on to the cleanup server.
-The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
-<servername> greeted me with my own hostname") if your content
-filter is based on a proxy that simply relays SMTP commands.
+The "-o myhostname=localhost.domain.tld" overrides main.cf and
+avoids false alarms ("host <servername> greeted me with my own
+hostname") if your content filter is based on a proxy that simply
+relays SMTP commands.
The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
-turn off UCE controls that would only waste time here.
-
-Squeezing out more performance
-==============================
-
-Many refinements are possible, such as running a specially-configured
-smtp delivery agent for feeding mail into the content filter, and
-turning off address rewriting before content filtering.
-
-As the example below shows, things quickly become very complex,
-because a lot of main.cf like information gets listed in the
-master.cf file. This makes the system hard to understand.
-
-Even worse, details change as Postfix evolves and different
-configuration parameters are implemented by different programs.
-
-If you need to squeeze out more performance, it is probably simpler
-to run multiple Postfix instances, one before and one after the
-content filter. That way, each instance can have simple main.cf
-and master.cf files, each instance can have its own mail queue,
-and the system will be easier to understand.
-
-As before, we will set up a content filtering program that receives
-SMTP mail via localhost port 10025, and that submits SMTP mail back
-into Postfix via localhost port 10026.
-
- .......................................
- : Postfix :
- ----->smtpd \ :
- : -pre-cleanup-\ /local---->
- ---->pickup / -queue- :
- : -cleanup-/ | \smtp----->
- : bounces/ ^ v :
- : and locally | v :
- : forwarded smtpd scan :
- : messages 10026 | :
- ...........................|...........
- ^ |
- | v
- ....|.............
- : | 10025 :
- : filter :
- : :
- ..................
-
-To enable content filtering in this manner, specify in main.cf a
-new parameter:
-
-/etc/postfix/main.cf:
- content_filter = scan:localhost:10025
-
-/etc/postfix/master.cf:
-#
-# These are the usual input "smtpd" and local "pickup" servers already
-# present in master.cf. We add an option to select a non-default
-# cleanup service (defined further below).
-#
-smtp inet n - n - - smtpd
- -o cleanup_service_name=pre-cleanup
-pickup fifo n - n 60 1 pickup
- -o cleanup_service_name=pre-cleanup
-#
-# ------------------------------------------------------------------
-#
-# This is the cleanup daemon that handles messages in front of
-# the content filter. It does header_checks and body_checks (if
-# any), but does no virtual alias or canonical address mapping,
-# so that mail passes through your content filter with the original
-# recipient addresses mostly intact.
-#
-# Virtual alias or canonical address mapping happens in the second
-# cleanup phase after the content filter. This gives the content_filter
-# access to *largely* unmodified addresses for maximum flexibility.
-#
-# Some sites may specifically want to perform canonical or virtual
-# address mapping in front of the content_filter. In that case you
-# still have to enable address rewriting in the after-filter cleanup
-# instance, in order to correctly process forwarded mail or bounced
-# mail.
-#
-pre-cleanup unix n - n - 0 cleanup
- -o canonical_maps=
- -o sender_canonical_maps=
- -o recipient_canonical_maps=
- -o masquerade_domains=
- -o virtual_alias_maps=
-#
-# ------------------------------------------------------------------
-#
-# This is the delivery agent that injects mail into the content
-# filter. It is tuned for low concurrency, because most content
-# filters burn CPU and use lots of memory. The process limit of 10
-# re-enforces the effect of $default_destination_concurrency_limit.
-# Even without an explicit process limit, the concurrency is bounded
-# because all messages heading into the content filter have the same
-# destination.
-#
-scan unix - - n - 10 smtp
-#
-# ------------------------------------------------------------------
-#
-# This is the SMTP listener that receives filtered messages from
-# the content filter. It *MUST* clear the content_filter
-# parameter to avoid loops, and use a different hostname to avoid
-# triggering the Postfix SMTP loop detection code.
-#
-# This "smtpd" uses the normal cleanup service which is also used
-# for bounces and for internally forwarded mail.
-#
-# The parameters from mynetworks onward disable all access
-# control other than insisting on connections from one of the IP
-# addresses of the host. This is typically overkill, but can
-# reduce resource usage, if the default restrictions use lots of
-# tables.
-#
-localhost:10026 inet n - n - - smtpd
- -o content_filter=
- -o myhostname=localhost.domain.tld
- -o local_recipient_maps=
- -o relay_recipient_maps=
- -o mynetworks=127.0.0.0/8
- -o mynetworks_style=host
- -o smtpd_restriction_classes=
- -o smtpd_client_restrictions=
- -o smtpd_helo_restrictions=
- -o smtpd_sender_restrictions=
- -o smtpd_recipient_restrictions=permit_mynetworks,reject
-#
-# Do not override main.cf settings here for virtual_alias_maps or
-# virtual_mailbox_maps. This causes mail to be rejected with "User
-# unknown in virtual (alias|mailbox) recipient table".
-#
-# ------------------------------------------------------------------
-#
-# This is the normal cleanup daemon for use after content filtering.
-# No header or body checks, because those have already been taken
-# care of by the pre-cleanup service before the content filter.
-#
-# The normal cleanup instance does all the virtual alias and canonical
-# address mapping that was disabled in the pre-cleanup instance before
-# the content filter. This rewriting must be done even when you didn't
-# disable address rewriting in the pre-cleanup instance, in order to
-# correctly process bounces and locally forwarded mail.
-#
-cleanup unix n - n - 0 cleanup
- -o header_checks=
- -o mime_header_checks=
- -o nested_header_checks=
- -o body_checks=
-#
-# ------------------------------------------------------------------
-#
-# The normal "smtp" delivery agent for contrast with "scan".
-#
-smtp unix - - n - - smtp
-
-The above example causes Postfix to add one content filtering record
-to each incoming mail message, with content scan:localhost:10025.
-You can use the same syntax as in the right-hand side of a Postfix
-transport table. The content filtering records are added by the
-smtpd and pickup servers.
-
-The "scan" transport is a dedicated instance of the "smtp" delivery
-agent for injecting messages into the SMTP content filter. Using
-a dedicated "smtp" transport allows one to tune it for the specific
-task of delivering mail to a local content filter (low latency,
-low concurrency, throughput dependent on predictably low latency).
-
-See the previous example for setting up the content filter with
-the Postfix spawn service; you can of course use any server that
-can be run stand-alone outside the Postfix environment.
+override main.cf and turn off UCE controls that would only waste
+time here.
Filtering mail from outside users only
======================================
# SMTP service for external users, with content filtering.
1.2.3.5:smtp inet n - n - - smtpd
- -o content_filter=foo:bar
+ -o content_filter=foo:bar
+ -o receive_override_options=no_address_mappings
+
+After this, you can follow the same procedure as outlined in the
+"advanced" content filtering example above, except that you do not
+need to specify "content_filter" or "receive_override_options" in
+the main.cf file.
Getting really nasty
====================
Purpose of the SMTPD pass-through proxy feature
===============================================
-The Postfix SMTP server can be configured to forward all mail to
-a proxy server, for example, a real-time SPAM filter. The proxy is
-supposed to send the mail into another Postfix SMTP server process
-for normal delivery.
+Normally, Postfix receives mail, stores it in the mail queue and
+then delivers it. The Postfix SMTP server can be configured to
+forward all incoming mail to an SMTP proxy server (for example, a
+real-time SPAM filter) that inspects all mail BEFORE it is stored
+in the Postfix mail queue.
-The proxy server receives only the commands that the Postfix SMTP
-server has approved. The proxy server should accept the same MAIL
-FROM and RCPT TO command syntax as Postfix, but does not need to
-support ESMTP command pipelining.
+[This is not to be confused with the approach described in the
+FILTER_README document, where all mail is inspected AFTER it is
+stored in the Postfix mail queue]
-This feature is meant to be used as follows:
-
- Internet -> smtpd -> proxy -> smtpd -> cleanup -> queue
- Postfix Postfix Postfix Postfix
+The SMTP proxy server receives unfiltered mail from Postfix and
+does one of the following:
-For reference, this is the normal path from network to mail queue:
+1 - Re-inject the mail back into Postfix, perhaps after changing
+ content.
- Internet -> smtpd -> cleanup -> queue
- Postfix Postfix Postfix
+2 - Reject the mail (by sending a suitable status code back to
+ Postfix) so that it is returned to sender.
+3 - Send the mail somewhere else.
Limitations
===========
into Postfix via an alternative Postfix SMTP server that always
turns on content filtering.
+How the Postfix talks to the SMTP proxy
+=======================================
+
+When Postfix talks to the SMTP proxy server it generates its own
+EHLO, DATA and QUIT commands, and forwards unmodified copies of
+the MAIL FROM and RCPT TO commands that the Postfix SMTP server
+has approved. All commands are sent without using ESMTP command
+pipelining. The SMTP proxy server must accept the same MAIL FROM
+and RCPT TO command syntax as the Postfix SMTP server.
+
+This feature is meant to be used as follows:
+ / smtp
+ Internet -> smtpd -> proxy -> smtpd -> cleanup -> queue -> local
+ Postfix Postfix \ virtual etc.
+
+For reference, this is the normal path through Postfix:
+
+ / smtp
+ Internet -> smtpd -> cleanup -> queue -> local
+ Postfix \ virtual etc.
+
+For comparison, this is the FILTER_README approach with an SMTP-based
+content filter:
+ / smtp
+ Internet -> smtpd -> cleanup -> queue -> local
+ Postfix ^ v \ virtual etc.
+ smtpd smtp
+ Postfix Postfix
+ \ /
+ filter <-
Configuration parameters
========================
/etc/postfix/master.cf
smtp inet n - n - - smtpd
- -o smtpd_proxy_filter=26
+ -o smtpd_proxy_filter=26
:26 inet n - n - - smtpd
+ -o receive_override_options=no_unknown_recipient_checks
+
+Note: do not specify spaces around the "=" or "," characters.
The ":26" causes Postfix to listen on the localhost address only.
+DO NOT expose the secondary SMTP server to the Internet :-)
The result is as follows:
Internet -> smtpd on port 25 -> smtpd on port 26 -> cleanup -> queue
This configuration is sufficient for stress testing.
+
+Other suggestions for test configurations: use the Postfix smtp-sink
+command as the proxy, or something as basic as netcat.
date. Snapshots change only the release date, unless they include
the same bugfixes as a patch release.
+Major changes with Postfix snapshot 2.0.13-20030705
+===================================================
+
+New receive_override_options parameter that eliminates the need
+for different cleanup service instances before and after an external
+content filter. One parameter controls what happens before or after
+the content filter: rejecting unknown recipients, canonical mapping,
+virtual alias expansion, masquerading, automatic BCC recipients
+and header/body checks. See sample-filter.cf for details.
+
Incompatible changes with Postfix snapshot 2.0.13-20030704
==========================================================
# A network address is a sequence of one or more
# octets separated by ".".
#
-# NOTE: use the cidr lookup table type if to specify
+# NOTE: use the cidr lookup table type to specify
# network/netmask patterns. See cidr_table(5) for
# details.
#
#
# By default, only the first 50 kbytes of a message body segment are
# inspected with body_checks patterns.
-#
+#
body_checks_max_size = 51200
+
+# The receive_override_options parameter controls what input processing
+# happens before or after an external content filter.
+#
+# Specify zero or more of the following options. The options override
+# main.cf settings and are either implemented by the SMTP server, by
+# the QMQP server, or by the pickup server, or they are passed on to
+# the cleanup server.
+#
+# When the receive_override_options setting BEFORE the content filter
+# is specified in the main.cf file, specify the "AFTER content filter"
+# receive_override_options setting in master.cf (or vice versa).
+#
+# - no_unknown_recipient_checks: Do not try to reject unknown
+# recipients (SMTP server only). This is typically specified AFTER
+# an external content filter.
+#
+# - no_address_mappings: Disable canonical address mapping, virtual
+# alias map expansion, address masquerading, and automatic BCC
+# recipients. This is typically specified BEFORE an external content
+# filter.
+#
+# - no_header_body_checks: Disable header/body_checks. This is
+# typically specified AFTER an external content filter.
+#
+# receive_override_options = no_unknown_recipient_checks, no_header_body_checks
+# receive_override_options = no_address_mappings
+receive_override_options =
# By default, this feature is disabled.
#
# Specify the types and names of databases to use. After change,
-# run "postmap /etc/postfix/relocated", then "postfix reload".
+# run "postmap /etc/postfix/recipient_bcc".
#
# NOTE: if mail to the BCC address bounces it will be returned to
# the sender.
# By default, this feature is disabled.
#
# Specify the types and names of databases to use. After change,
-# run "postmap /etc/postfix/relocated", then "postfix reload".
+# run "postmap /etc/postfix/sender_bcc".
#
# NOTE: if mail to the BCC address bounces it will be returned to
# the sender.
A network address is a sequence of one or more
octets separated by ".".
- NOTE: use the <b>cidr</b> lookup table type if to specify
+ NOTE: use the <b>cidr</b> lookup table type to specify
network/netmask patterns. See <a href="cidr_table.5.html">cidr_table(5)</a> for
details.
reports are sent to the <a href="bounce.8.html"><b>bounce</b>(8)</a> or <a href="defer.8.html"><b>defer</b>(8)</a> daemon as
appropriate.
-<b>SYSTEM-WIDE</b> <b>AND</b> <b>USER-LEVEL</b> <b>ALIASING</b>
+<b>SYSTEM-WIDE AND USER-LEVEL ALIASING</b>
The system administrator can set up one or more system-
wide <b>sendmail</b>-style alias databases. Users can have <b>send-</b>
<b>mail</b>-style ~/.<b>forward</b> files. Mail for <i>name</i> is delivered
<b>cate</b><i>_</i><b>filter</b><i>_</i><b>limit</b> configuration parameter limits the num-
ber of remembered recipients.
-<b>MAIL</b> <b>FORWARDING</b>
+<b>MAIL FORWARDING</b>
For the sake of reliability, forwarded mail is re-submit-
ted as a new message, so that each recipient has a sepa-
rate on-file delivery status record.
already listed in a <b>Delivered-To:</b> header, the message is
bounced.
-<b>MAILBOX</b> <b>DELIVERY</b>
+<b>MAILBOX DELIVERY</b>
The default per-user mailbox is a file in the UNIX mail
spool directory (<b>/var/mail/</b><i>user</i> or <b>/var/spool/mail/</b><i>user</i>);
the location can be specified with the <b>mail</b><i>_</i><b>spool</b><i>_</i><b>direc-</b>
UNIX passwd database.
In the case of UNIX-style mailbox delivery, the <b>local</b> dae-
- mon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" envelope header to
+ mon prepends a "<b>From</b> <i>sender time_stamp</i>" envelope header to
each message, prepends an <b>X-Original-To:</b> header with the
recipient address as given to Postfix, prepends an
optional <b>Delivered-To:</b> header with the envelope recipient
the recipient address as given to Postfix, and prepends a
<b>Return-Path:</b> header with the envelope sender address.
-<b>EXTERNAL</b> <b>COMMAND</b> <b>DELIVERY</b>
+<b>EXTERNAL COMMAND DELIVERY</b>
The <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b> configuration parameter
restricts delivery to external commands. The default set-
- ting (<b>alias,</b> <b>forward</b>) forbids command destinations in
+ ting (<b>alias, forward</b>) forbids command destinations in
<b>:include:</b> files.
The command is executed directly where possible. Assis-
The current working directory is the mail queue directory.
- The <b>local</b> daemon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" enve-
+ The <b>local</b> daemon prepends a "<b>From</b> <i>sender time_stamp</i>" enve-
lope header to each message, prepends an <b>X-Original-To:</b>
header with the recipient address as given to Postfix,
prepends an optional <b>Delivered-To:</b> header with the recipi-
ent envelope address, prepends a <b>Return-Path:</b> header with
the sender envelope address, and appends no empty line.
-<b>EXTERNAL</b> <b>FILE</b> <b>DELIVERY</b>
+<b>EXTERNAL FILE DELIVERY</b>
The delivery format depends on the destination filename
syntax. The default is to use UNIX-style mailbox format.
Specify a name ending in <b>/</b> for <b>qmail</b>-compatible <b>maildir</b>
<b>forward</b>) forbids file destinations in <b>:include:</b> files.
In the case of UNIX-style mailbox delivery, the <b>local</b> dae-
- mon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" envelope header to
+ mon prepends a "<b>From</b> <i>sender time_stamp</i>" envelope header to
each message, prepends an <b>X-Original-To:</b> header with the
recipient address as given to Postfix, prepends an
optional <b>Delivered-To:</b> header with the recipient envelope
the recipient address as given to Postfix. The envelope
sender address is available in the <b>Return-Path:</b> header.
-<b>ADDRESS</b> <b>EXTENSION</b>
+<b>ADDRESS EXTENSION</b>
The optional <b>recipient</b><i>_</i><b>delimiter</b> configuration parameter
specifies how to separate address extensions from local
recipient names.
- For example, with "<b>recipient</b><i>_</i><b>delimiter</b> <b>=</b> <b>+</b>", mail for
+ For example, with "<b>recipient</b><i>_</i><b>delimiter = +</b>", mail for
<i>name</i>+<i>foo</i> is delivered to the alias <i>name</i>+<i>foo</i> or to the
alias <i>name</i>, to the destinations listed in ~<i>name</i>/.<b>for-</b>
<b>ward</b>+<i>foo</i> or in ~<i>name</i>/.<b>forward</b>, to the mailbox owned by the
In all cases the <b>local</b> daemon prepends an optional `<b>Deliv-</b>
<b>ered-To:</b> <i>name</i>+<i>foo</i>' header line.
-<b>DELIVERY</b> <b>RIGHTS</b>
+<b>DELIVERY RIGHTS</b>
Deliveries to external files and external commands are
made with the rights of the receiving user on whose behalf
the delivery is made. In the absence of a user context,
detected early. The resulting mail forwarding loop is
broken by the use of the <b>Delivered-To:</b> message header.
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
The following <b>main.cf</b> parameters are especially relevant
to this program. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ details and for default values. Use the <b>postfix reload</b>
command after a configuration change.
<b>Miscellaneous</b>
<b>prepend</b><i>_</i><b>delivered</b><i>_</i><b>header</b>
Prepend an optional <b>Delivered-To:</b> header upon
external forwarding, delivery to command or file.
- Specify zero or more of: <b>command,</b> <b>file,</b> <b>forward</b>.
+ Specify zero or more of: <b>command, file, forward</b>.
Turning off <b>Delivered-To:</b> when forwarding mail is
not recommended.
sible by the recipient before attempting delivery.
Defer delivery otherwise.
-<b>Mailbox</b> <b>delivery</b>
+<b>Mailbox delivery</b>
<b>fallback</b><i>_</i><b>transport</b>
Message transport for recipients that are not found
in the UNIX passwd database. This parameter over-
Note: you must update the <b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> set-
ting in the <b>main.cf</b> file, otherwise the Postfix
SMTP server will reject mail for non-UNIX accounts
- with "<b>User</b> <b>unknown</b> <b>in</b> <b>local</b> <b>recipient</b> <b>table</b>".
+ with "<b>User unknown in local recipient table</b>".
<b>home</b><i>_</i><b>mailbox</b>
Pathname of a mailbox relative to a user's home
users. The <i>address</i> is subjected to <i>$name</i> expan-
sion.
- Note: you must specify "<b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> <b>=</b>"
+ Note: you must specify "<b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps =</b>"
(i.e. empty) in the <b>main.cf</b> file, otherwise the
Postfix SMTP server will reject mail for non-UNIX
- accounts with "<b>User</b> <b>unknown</b> <b>in</b> <b>local</b> <b>recipient</b>
+ accounts with "<b>User unknown in local recipient</b>
<b>table</b>".
<b>mail</b><i>_</i><b>spool</b><i>_</i><b>directory</b>
non-UNIX accounts then you must update the
<b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> setting in the <b>main.cf</b> file,
otherwise the Postfix SMTP server will reject mail
- for non-UNIX accounts with "<b>User</b> <b>unknown</b> <b>in</b> <b>local</b>
- <b>recipient</b> <b>table</b>".
+ for non-UNIX accounts with "<b>User unknown in local</b>
+ <b>recipient table</b>".
-<b>Locking</b> <b>controls</b>
+<b>Locking controls</b>
<b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
Limit the number of attempts to acquire an exclu-
sive lock on a mailbox or external file.
What file locking method(s) to use when delivering
to a UNIX-style mailbox. The default setting is
system dependent. For a list of available file
- locking methods, use the <b>postconf</b> <b>-l</b> command.
+ locking methods, use the <b>postconf -l</b> command.
-<b>Resource</b> <b>controls</b>
+<b>Resource controls</b>
<b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>
Limit the amount of time for delivery to external
command.
that is written to upon delivery). Set to zero to
disable the limit.
-<b>Security</b> <b>controls</b>
+<b>Security controls</b>
<b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>
Restrict the usage of mail delivery to external
command. Specify zero or more of: <b>alias</b>, <b>forward</b>,
The <i>maildir</i> structure appears in the <b>qmail</b> system by
Daniel Bernstein.
-<b>SEE</b> <b>ALSO</b>
+<b>SEE ALSO</b>
<a href="aliases.5.html">aliases(5)</a> format of alias database
<a href="bounce.8.html">bounce(8)</a> non-delivery status reports
<a href="postalias.1.html">postalias(1)</a> create/update alias database
already complex <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon would have to deal with
unfiltered user data.
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
The following <b>main.cf</b> parameters are especially relevant
to this program. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ details and for default values. Use the <b>postfix reload</b>
command after a configuration change.
-<b>Content</b> <b>inspection</b> <b>controls</b>
+<b>Content inspection controls</b>
<b>content</b><i>_</i><b>filter</b>
The name of a mail delivery transport that filters
mail and that either bounces mail or re-injects the
same syntax as the right-hand side of a Postfix
transport table.
+ <b>receive</b><i>_</i><b>override</b><i>_</i><b>options</b>
+ The following options override <b>main.cf</b> settings.
+ The options are passed on to the downstream cleanup
+ server.
+
+ <b>no</b><i>_</i><b>address</b><i>_</i><b>mappings</b>
+ Disable canonical address mapping, virtual
+ alias map expansion, address masquerading,
+ and automatic BCC recipients. Specify this
+ if address mapping etc. are to be done <b>after</b>
+ an external content filter.
+
+ <b>no</b><i>_</i><b>header</b><i>_</i><b>body</b><i>_</i><b>checks</b>
+ Disable header/body_checks. Specify this if
+ header/body_checks are to be done <b>after</b> an
+ external content filter.
+
<b>Miscellaneous</b>
<b>queue</b><i>_</i><b>directory</b>
Top-level directory of the Postfix queue.
-<b>SEE</b> <b>ALSO</b>
+<b>SEE ALSO</b>
<a href="cleanup.8.html">cleanup(8)</a> message canonicalization
<a href="master.8.html">master(8)</a> process manager
<a href="sendmail.1.html">sendmail(1)</a>, postdrop(8) mail posting agent
directory instead of the default configuration
directory.
- <b>-q</b> Search the Postfix queue for <i>files</i>. By default,
- file names are taken literally.
+ <b>-q</b> Search the Postfix queue for the named <i>files</i>
+ instead of taking the names literally.
<b>-v</b> Enable verbose logging for debugging purposes. Mul-
tiple <b>-v</b> options make the software increasingly
<b>MAIL</b><i>_</i><b>CONFIG</b>
Directory with Postfix configuration files.
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
See the Postfix <b>main.cf</b> file for syntax details and for
- default values. Use the <b>postfix</b> <b>reload</b> command after a
+ default values. Use the <b>postfix reload</b> command after a
configuration change.
<b>queue</b><i>_</i><b>directory</b>
Postfix replies immediately and closes the connection. It
is left up to the client to handle the situation.
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
The following <b>main.cf</b> parameters are especially relevant
to this program. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ details and for default values. Use the <b>postfix reload</b>
command after a configuration change.
<b>Miscellaneous</b>
reject responses. This can be useful for testing
purposes.
-<b>Content</b> <b>inspection</b> <b>controls</b>
+<b>Content inspection controls</b>
<b>content</b><i>_</i><b>filter</b>
The name of a mail delivery transport that filters
mail and that either bounces mail or re-injects the
same syntax as the right-hand side of a Postfix
transport table.
-<b>Resource</b> <b>controls</b>
+ <b>receive</b><i>_</i><b>override</b><i>_</i><b>options</b>
+ The following options override <b>main.cf</b> settings.
+ The options are passed on to the downstream cleanup
+ server.
+
+ <b>no</b><i>_</i><b>address</b><i>_</i><b>mappings</b>
+ Disable canonical address mapping, virtual
+ alias map expansion, address masquerading,
+ and automatic BCC recipients. Specify this
+ if address mapping etc. are to be done <b>after</b>
+ an external content filter.
+
+ <b>no</b><i>_</i><b>header</b><i>_</i><b>body</b><i>_</i><b>checks</b>
+ Disable header/body_checks. Specify this if
+ header/body_checks are to be done <b>after</b> an
+ external content filter.
+
+<b>Resource controls</b>
<b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
Limit the amount of memory in bytes used for the
handling of partial input lines, and the length of
Time to wait in seconds before informing the client
of a problem. This slows down run-away errors.
-<b>SEE</b> <b>ALSO</b>
+<b>SEE ALSO</b>
<a href="http://cr.yp.to/proto/qmqp.html">http://cr.yp.to/proto/qmqp.html</a>, QMQP protocol
<a href="cleanup.8.html">cleanup(8)</a> message canonicalization
<a href="master.8.html">master(8)</a> process manager
same syntax as the right-hand side of a Postfix
transport table.
+ <b>receive</b><i>_</i><b>override</b><i>_</i><b>options</b>
+ The following options override <b>main.cf</b> settings.
+ The options are either implemented by the SMTP
+ server or are passed on to the downstream cleanup
+ server.
+
+ <b>no</b><i>_</i><b>unknown</b><i>_</i><b>recipient</b><i>_</i><b>checks</b>
+ Do not try to reject unknown recipients.
+ This is typically specified with the SMTP
+ server <b>after</b> an external content filter.
+
+ <b>no</b><i>_</i><b>address</b><i>_</i><b>mappings</b>
+ Disable canonical address mapping, virtual
+ alias map expansion, address masquerading,
+ and automatic BCC recipients. This is typi-
+ cally specified with the SMTP server <b>before</b>
+ an external content filter.
+
+ <b>no</b><i>_</i><b>header</b><i>_</i><b>body</b><i>_</i><b>checks</b>
+ Disable header/body_checks. This is typi-
+ cally specified with the SMTP server <b>after</b>
+ an external content filter.
+
<b>Authentication controls</b>
<b>enable</b><i>_</i><b>sasl</b><i>_</i><b>authentication</b>
- Enable per-session authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
- (SASL). This functionality is available only when
+ Enable per-session authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
+ (SASL). This functionality is available only when
explicitly selected at program build time and
explicitly enabled at runtime.
Disallow anonymous logins.
<b>smtpd</b><i>_</i><b>sender</b><i>_</i><b>login</b><i>_</i><b>maps</b>
- Maps that specify the SASL login name that owns a
- MAIL FROM sender address. Used by the
+ Maps that specify the SASL login name that owns a
+ MAIL FROM sender address. Used by the
<b>reject</b><i>_</i><b>sender</b><i>_</i><b>login</b><i>_</i><b>mismatch</b> sender anti-spoofing
restriction.
<b>Pass-through proxy</b>
- Optionally, the Postfix SMTP server can be configured to
- forward all mail to a proxy server, for example a real-
- time content filter. This proxy server should support the
- same MAIL FROM and RCPT TO command syntax as Postfix, but
+ Optionally, the Postfix SMTP server can be configured to
+ forward all mail to a proxy server, for example a real-
+ time content filter. This proxy server should support the
+ same MAIL FROM and RCPT TO command syntax as Postfix, but
does not need to support ESMTP command pipelining.
<b>smtpd</b><i>_</i><b>proxy</b><i>_</i><b>filter</b>
that are authorized to use the XVERP extension.
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
- Increment in verbose logging level when a remote
+ Increment in verbose logging level when a remote
host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
parameter.
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
- List of domain or network patterns. When a remote
- host matches a pattern, increase the verbose log-
- ging level by the amount specified in the
+ List of domain or network patterns. When a remote
+ host matches a pattern, increase the verbose log-
+ ging level by the amount specified in the
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
<b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>
The default VERP delimiter characters that are used
- when the XVERP command is specified without
+ when the XVERP command is specified without
explicit delimiters.
<b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
- Recipient of protocol/policy/resource/software
+ Recipient of protocol/policy/resource/software
error notices.
<b>hopcount</b><i>_</i><b>limit</b>
<b>notify</b><i>_</i><b>classes</b>
List of error classes. Of special interest are:
- <b>policy</b> When a client violates any policy, mail a
+ <b>policy</b> When a client violates any policy, mail a
transcript of the entire SMTP session to the
postmaster.
<b>protocol</b>
- When a client violates the SMTP protocol or
+ When a client violates the SMTP protocol or
issues an unimplemented command, mail a
transcript of the entire SMTP session to the
postmaster.
<b>smtpd</b><i>_</i><b>banner</b>
- Text that follows the <b>220</b> status code in the SMTP
+ Text that follows the <b>220</b> status code in the SMTP
greeting banner.
<b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
expansion of rbl template responses and other text.
<b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
- Restrict the number of recipients that the SMTP
+ Restrict the number of recipients that the SMTP
server accepts per message delivery.
<b>smtpd</b><i>_</i><b>timeout</b>
- Limit the time to send a server response and to
+ Limit the time to send a server response and to
receive a client request.
<b>soft</b><i>_</i><b>bounce</b>
- Change hard (5xx) reject responses into soft (4xx)
- reject responses. This can be useful for testing
+ Change hard (5xx) reject responses into soft (4xx)
+ reject responses. This can be useful for testing
purposes.
<b>verp</b><i>_</i><b>delimiter</b><i>_</i><b>filter</b>
- The characters that Postfix accepts as VERP delim-
+ The characters that Postfix accepts as VERP delim-
iter characters.
<b>Known versus unknown recipients</b>
<b>show</b><i>_</i><b>user</b><i>_</i><b>unknown</b><i>_</i><b>table</b><i>_</i><b>name</b>
- Whether or not to reveal the table name in the
- "User unknown" responses. The extra detail makes
- trouble shooting easier but also reveals informa-
+ Whether or not to reveal the table name in the
+ "User unknown" responses. The extra detail makes
+ trouble shooting easier but also reveals informa-
tion that is nobody elses business.
<b>unknown</b><i>_</i><b>local</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
- ent whose domain matches <b>$mydestination</b> or
+ ent whose domain matches <b>$mydestination</b> or
<b>$inet</b><i>_</i><b>interfaces</b>, while <b>$local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> is
- non-empty and does not list the recipient address
+ non-empty and does not list the recipient address
or address local-part.
<b>unknown</b><i>_</i><b>relay</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
ent whose domain matches <b>$relay</b><i>_</i><b>domains</b>, while
- <b>$relay</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> is non-empty and does not
+ <b>$relay</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> is non-empty and does not
list the recipient address.
<b>unknown</b><i>_</i><b>virtual</b><i>_</i><b>alias</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
- ent whose domain matches <b>$virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>,
- while the recipient is not listed in <b>$vir-</b>
+ ent whose domain matches <b>$virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>,
+ while the recipient is not listed in <b>$vir-</b>
<b>tual</b><i>_</i><b>alias</b><i>_</i><b>maps</b>.
<b>unknown</b><i>_</i><b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
- ent whose domain matches <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>,
+ ent whose domain matches <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>,
while the recipient is not listed in <b>$virtual</b><i>_</i><b>mail-</b>
<b>box</b><i>_</i><b>maps</b>.
<b>Resource controls</b>
<b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
- Limit the amount of memory in bytes used for the
+ Limit the amount of memory in bytes used for the
handling of partial input lines.
<b>message</b><i>_</i><b>size</b><i>_</i><b>limit</b>
ing on-disk storage for envelope information.
<b>queue</b><i>_</i><b>minfree</b>
- Minimal amount of free space in bytes in the queue
- file system for the SMTP server to accept any mail
+ Minimal amount of free space in bytes in the queue
+ file system for the SMTP server to accept any mail
at all.
<b>smtpd</b><i>_</i><b>history</b><i>_</i><b>flush</b><i>_</i><b>threshold</b>
<b>smtpd</b><i>_</i><b>soft</b><i>_</i><b>error</b><i>_</i><b>limit</b>
When an SMTP client has made this number of errors,
- wait <i>error_count</i> seconds before responding to any
+ wait <i>error_count</i> seconds before responding to any
client request.
<b>smtpd</b><i>_</i><b>hard</b><i>_</i><b>error</b><i>_</i><b>limit</b>
- Disconnect after a client has made this number of
+ Disconnect after a client has made this number of
errors.
<b>smtpd</b><i>_</i><b>junk</b><i>_</i><b>command</b><i>_</i><b>limit</b>
Limit the number of times a client can issue a junk
- command such as NOOP, VRFY, ETRN or RSET in one
- SMTP session before it is penalized with tarpit
+ command such as NOOP, VRFY, ETRN or RSET in one
+ SMTP session before it is penalized with tarpit
delays.
<b>UCE control restrictions</b>
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b>
- List of Postfix features that use <i>domain.tld</i> pat-
- terns to match <i>sub.domain.tld</i> (as opposed to
+ List of Postfix features that use <i>domain.tld</i> pat-
+ terns to match <i>sub.domain.tld</i> (as opposed to
requiring <i>.domain.tld</i> patterns).
<b>smtpd</b><i>_</i><b>client</b><i>_</i><b>restrictions</b>
tem.
<b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>required</b>
- Require that clients introduce themselves at the
+ Require that clients introduce themselves at the
beginning of an SMTP session.
<b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>restrictions</b>
- Restrict what client hostnames are allowed in <b>HELO</b>
+ Restrict what client hostnames are allowed in <b>HELO</b>
and <b>EHLO</b> commands.
<b>smtpd</b><i>_</i><b>sender</b><i>_</i><b>restrictions</b>
- Restrict what sender addresses are allowed in <b>MAIL</b>
+ Restrict what sender addresses are allowed in <b>MAIL</b>
<b>FROM</b> commands.
<b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
- Restrict what recipient addresses are allowed in
+ Restrict what recipient addresses are allowed in
<b>RCPT TO</b> commands.
<b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
mands, and what clients may issue <b>ETRN</b> commands.
<b>smtpd</b><i>_</i><b>data</b><i>_</i><b>restrictions</b>
- Restrictions on the <b>DATA</b> command. Currently, the
- only restriction that makes sense here is
+ Restrictions on the <b>DATA</b> command. Currently, the
+ only restriction that makes sense here is
<b>reject</b><i>_</i><b>unauth</b><i>_</i><b>pipelining</b>.
<b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
- Allow untrusted clients to specify addresses with
- sender-specified routing. Enabling this opens up
- nasty relay loopholes involving trusted backup MX
+ Allow untrusted clients to specify addresses with
+ sender-specified routing. Enabling this opens up
+ nasty relay loopholes involving trusted backup MX
hosts.
<b>smtpd</b><i>_</i><b>restriction</b><i>_</i><b>classes</b>
- Declares the name of zero or more parameters that
- contain a list of UCE restrictions. The names of
- these parameters can then be used instead of the
+ Declares the name of zero or more parameters that
+ contain a list of UCE restrictions. The names of
+ these parameters can then be used instead of the
restriction lists that they represent.
<b>smtpd</b><i>_</i><b>null</b><i>_</i><b>access</b><i>_</i><b>lookup</b><i>_</i><b>key</b>
- The lookup key to be used in SMTPD access tables
- instead of the null sender address. A null sender
+ The lookup key to be used in SMTPD access tables
+ instead of the null sender address. A null sender
address cannot be looked up.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b> (deprecated)
- List of DNS domains that publish the addresses of
+ List of DNS domains that publish the addresses of
blacklisted hosts. This is used with the deprecated
<b>reject</b><i>_</i><b>maps</b><i>_</i><b>rbl</b> restriction.
<b>permit</b><i>_</i><b>mx</b><i>_</i><b>backup</b><i>_</i><b>networks</b>
- Only domains whose primary MX hosts match the
- listed networks are eligible for the <b>per-</b>
+ Only domains whose primary MX hosts match the
+ listed networks are eligible for the <b>per-</b>
<b>mit</b><i>_</i><b>mx</b><i>_</i><b>backup</b> feature.
<b>relay</b><i>_</i><b>domains</b>
- Restrict what domains this mail system will relay
- mail to. The domains are routed to the delivery
+ Restrict what domains this mail system will relay
+ mail to. The domains are routed to the delivery
agent specified with the <b>relay</b><i>_</i><b>transport</b> setting.
<b>Sender/recipient address verification</b>
Address verification is implemented by sending probe email
- messages that are not actually delivered, and is enabled
- via the reject_unverified_{sender,recipient} access
- restriction. The status of verification probes is main-
+ messages that are not actually delivered, and is enabled
+ via the reject_unverified_{sender,recipient} access
+ restriction. The status of verification probes is main-
tained by the address verification service.
<b>address</b><i>_</i><b>verify</b><i>_</i><b>poll</b><i>_</i><b>count</b>
- How many times to query the address verification
- service for completion of an address verification
- request. Specify 1 to implement a simple form of
- greylisting, that is, always defer the request for
+ How many times to query the address verification
+ service for completion of an address verification
+ request. Specify 1 to implement a simple form of
+ greylisting, that is, always defer the request for
a new sender or recipient address.
<b>address</b><i>_</i><b>verify</b><i>_</i><b>poll</b><i>_</i><b>delay</b>
- Time to wait after querying the address verifica-
+ Time to wait after querying the address verifica-
tion service for completion of an address verifica-
tion request.
<b>UCE control responses</b>
<b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Response code when a client violates an access
+ Response code when a client violates an access
database restriction.
<b>default</b><i>_</i><b>rbl</b><i>_</i><b>reply</b>
Default template reply when a request is RBL black-
- listed. This template is used by the <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b>
- and <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
+ listed. This template is used by the <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b>
+ and <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
<b>rbl</b><i>_</i><b>reply</b><i>_</i><b>maps</b> and <b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>.
<b>defer</b><i>_</i><b>code</b>
- Response code when a client request is rejected by
+ Response code when a client request is rejected by
the <b>defer</b> restriction.
<b>invalid</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Response code when a client violates the
+ Response code when a client violates the
<b>reject</b><i>_</i><b>invalid</b><i>_</i><b>hostname</b> restriction.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Response code when a request is RBL blacklisted.
<b>multi</b><i>_</i><b>recipient</b><i>_</i><b>bounce</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Response code when a multi-recipient bounce is
+ Response code when a multi-recipient bounce is
blocked.
<b>rbl</b><i>_</i><b>reply</b><i>_</i><b>maps</b>
- Table with template responses for RBL blacklisted
- requests, indexed by RBL domain name. These tem-
+ Table with template responses for RBL blacklisted
+ requests, indexed by RBL domain name. These tem-
plates are used by the <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b> and
- <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
+ <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
<b>default</b><i>_</i><b>rbl</b><i>_</i><b>reply</b> and <b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>.
<b>reject</b><i>_</i><b>code</b>
- Response code when the client matches a <b>reject</b>
+ Response code when the client matches a <b>reject</b>
restriction.
<b>relay</b><i>_</i><b>domains</b><i>_</i><b>reject</b><i>_</i><b>code</b>
mail relay policy.
<b>unknown</b><i>_</i><b>address</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Response code when a client violates the
+ Response code when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
<b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
tion.
<b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Response code when a client violates the
+ Response code when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
<b>unverified</b><i>_</i><b>sender</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Response code when a sender address is known to be
+ Response code when a sender address is known to be
undeliverable.
<b>unverified</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Response code when a recipient address is known to
+ Response code when a recipient address is known to
be undeliverable.
<b>SEE ALSO</b>
<a href="verify.8.html">verify(8)</a> address verification service
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
The \fBmain.cf\fR configuration file is in the named directory
instead of the default configuration directory.
.IP \fB-q\fR
-Search the Postfix queue for \fIfiles\fR. By default,
-file names are taken literally.
+Search the Postfix queue for the named \fIfiles\fR instead
+of taking the names literally.
.IP \fB-v\fR
Enable verbose logging for debugging purposes. Multiple \fB-v\fR
options make the software increasingly verbose.
Matches any host address in the specified network. A network
address is a sequence of one or more octets separated by ".".
-NOTE: use the \fBcidr\fR lookup table type if to specify
+NOTE: use the \fBcidr\fR lookup table type to specify
network/netmask patterns. See cidr_table(5) for details.
.SH ACTIONS
.na
either bounces mail or re-injects the result back into Postfix.
This parameter uses the same syntax as the right-hand side of
a Postfix transport table.
+.IP \fBreceive_override_options\fB
+The following options override \fBmain.cf\fR settings.
+The options are passed on to the downstream cleanup server.
+.RS
+.IP \fBno_address_mappings\fR
+Disable canonical address mapping, virtual alias map expansion,
+address masquerading, and automatic BCC recipients. Specify this
+if address mapping etc. are to be done \fBafter\fR an external
+content filter.
+.IP \fBno_header_body_checks\fR
+Disable header/body_checks. Specify this if header/body_checks
+are to be done \fBafter\fR an external content filter.
+.RE
.SH Miscellaneous
.ad
.fi
either bounces mail or re-injects the result back into Postfix.
This parameter uses the same syntax as the right-hand side of
a Postfix transport table.
+.IP \fBreceive_override_options\fB
+The following options override \fBmain.cf\fR settings.
+The options are passed on to the downstream cleanup server.
+.RS
+.IP \fBno_address_mappings\fR
+Disable canonical address mapping, virtual alias map expansion,
+address masquerading, and automatic BCC recipients. Specify this
+if address mapping etc. are to be done \fBafter\fR an external
+content filter.
+.IP \fBno_header_body_checks\fR
+Disable header/body_checks. Specify this if header/body_checks
+are to be done \fBafter\fR an external content filter.
+.RE
.SH "Resource controls"
.ad
.fi
either bounces mail or re-injects the result back into Postfix.
This parameter uses the same syntax as the right-hand side of
a Postfix transport table.
+.IP \fBreceive_override_options\fB
+The following options override \fBmain.cf\fR settings.
+The options are either implemented by the SMTP server or
+are passed on to the downstream cleanup server.
+.RS
+.IP \fBno_unknown_recipient_checks\fR
+Do not try to reject unknown recipients. This is typically specified
+with the SMTP server \fBafter\fR an external content filter.
+.IP \fBno_address_mappings\fR
+Disable canonical address mapping, virtual alias map expansion,
+address masquerading, and automatic BCC recipients. This is
+typically specified with the SMTP server \fBbefore\fR an external
+content filter.
+.IP \fBno_header_body_checks\fR
+Disable header/body_checks. This is typically specified with the
+SMTP server \fBafter\fR an external content filter.
+.RE
.SH "Authentication controls"
.IP \fBenable_sasl_authentication\fR
Enable per-session authentication as per RFC 2554 (SASL).
# Matches any host address in the specified network. A network
# address is a sequence of one or more octets separated by ".".
#
-# NOTE: use the \fBcidr\fR lookup table type if to specify
+# NOTE: use the \fBcidr\fR lookup table type to specify
# network/netmask patterns. See cidr_table(5) for details.
# ACTIONS
# .ad
encoding, BOUNCE_MSG_FAIL);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define BOUNCE_HEADERS 1
#define BOUNCE_ALL 0
postmaster = var_2bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
/*
*/
else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
/*
postmaster = var_bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
if (bounce_header(bounce, bounce_info, postmaster) == 0
&& bounce_diagnostic_log(bounce, bounce_info) == 0
encoding, BOUNCE_MSG_FAIL);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define BOUNCE_HEADERS 1
#define BOUNCE_ALL 0
verp_sender(verp_buf, verp_delims, recipient,
bounce_info->log_handle->recipient);
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, STR(verp_buf),
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
/*
postmaster = var_bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
if (bounce_header(bounce, bounce_info, postmaster) == 0
&& bounce_recipient_log(bounce, bounce_info) == 0
dsn_action, why);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define BOUNCE_HEADERS 1
#define BOUNCE_ALL 0
} else {
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_2bounce_rcpt,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
/*
*/
else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, orig_sender,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
/*
*/
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_bounce_rcpt,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
if (bounce_header(bounce, bounce_info, var_bounce_rcpt) == 0
&& bounce_recipient_log(bounce, bounce_info) == 0
encoding, BOUNCE_MSG_STATUS);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define BOUNCE_ALL 0
* per-recipient status, and a copy of the original message.
*/
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
if (bounce_header(bounce, bounce_info, recipient) == 0
&& bounce_boilerplate(bounce, bounce_info) == 0
encoding, BOUNCE_MSG_WARN);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define BOUNCE_HEADERS 1
postmaster = var_delay_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
/*
*/
else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
/*
postmaster = var_delay_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS)) != 0) {
if (bounce_header(bounce, bounce_info, postmaster) == 0
&& bounce_diagnostic_log(bounce, bounce_info) == 0
cleanup_out_recipient.o: ../../include/mail_params.h
cleanup_out_recipient.o: ../../include/rec_type.h
cleanup_out_recipient.o: ../../include/ext_prop.h
+cleanup_out_recipient.o: ../../include/cleanup_user.h
cleanup_out_recipient.o: cleanup.h
cleanup_out_recipient.o: ../../include/vstring.h
cleanup_out_recipient.o: ../../include/vbuf.h
if (strcasecmp(STR(clean_addr), STR(state->temp1)) == 0)
vstring_strcpy(clean_addr, "");
}
- if (cleanup_send_canon_maps)
- cleanup_map11_internal(state, clean_addr, cleanup_send_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_comm_canon_maps)
- cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_masq_domains
- && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_FROM))
- cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+ if (state->flags & CLEANUP_FLAG_MAP_OK) {
+ if (cleanup_send_canon_maps)
+ cleanup_map11_internal(state, clean_addr, cleanup_send_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_comm_canon_maps)
+ cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_masq_domains
+ && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_FROM))
+ cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+ }
CLEANUP_OUT_BUF(state, REC_TYPE_FROM, clean_addr);
if (state->sender == 0)
state->sender = mystrdup(STR(clean_addr));
const char *bcc;
cleanup_rewrite_internal(clean_addr, *buf ? buf : var_empty_addr);
- if (cleanup_rcpt_canon_maps)
- cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_comm_canon_maps)
- cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_masq_domains
- && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
- cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+ if (state->flags & CLEANUP_FLAG_MAP_OK) {
+ if (cleanup_rcpt_canon_maps)
+ cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_comm_canon_maps)
+ cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_masq_domains
+ && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
+ cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+ }
cleanup_out_recipient(state, state->orig_rcpt, STR(clean_addr));
if (state->recip == 0)
state->recip = mystrdup(STR(clean_addr));
VSTRING *clean_addr = vstring_alloc(100);
cleanup_rewrite_internal(clean_addr, bcc);
- if (cleanup_rcpt_canon_maps)
- cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_comm_canon_maps)
- cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_masq_domains
- && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
- cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+ if (state->flags & CLEANUP_FLAG_MAP_OK) {
+ if (cleanup_rcpt_canon_maps)
+ cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_comm_canon_maps)
+ cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_masq_domains
+ && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
+ cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+ }
cleanup_out_recipient(state, STR(clean_addr), STR(clean_addr));
vstring_free(clean_addr);
}
/* Enable header/body filtering. This should be enabled only with mail
/* that enters Postfix, not with locally forwarded mail or with bounce
/* messages.
+/* .IP CLEANUP_FLAG_MAP_OK
+/* Enable canonical and virtual mapping, and address masquerading.
/* .PP
+/* For convenience the CLEANUP_FLAG_MASK_EXTERNAL macro specifies
+/* the options that are normally needed for mail that enters
+/* Postfix from outside, and CLEANUP_FLAG_MASK_INTERNAL specifies
+/* the options that are normally needed for internally generated or
+/* forwarded mail.
+/*
/* CLEANUP_RECORD() is a macro that processes one message record,
/* that copies the result to the queue file, and that maintains a
/* little state machine. The last record in a valid message has type
/*
* Control how unmatched extensions are propagated.
*/
- cleanup_ext_prop_mask = ext_prop_mask(var_prop_extension);
+ cleanup_ext_prop_mask =
+ ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
}
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
cleanup_rewrite_tree(*tpp);
- if (cleanup_send_canon_maps)
- cleanup_map11_tree(state, *tpp, cleanup_send_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_comm_canon_maps)
- cleanup_map11_tree(state, *tpp, cleanup_comm_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_masq_domains
- && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_FROM))
- cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
+ if (state->flags & CLEANUP_FLAG_MAP_OK) {
+ if (cleanup_send_canon_maps)
+ cleanup_map11_tree(state, *tpp, cleanup_send_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_comm_canon_maps)
+ cleanup_map11_tree(state, *tpp, cleanup_comm_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_masq_domains
+ && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_FROM))
+ cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
+ }
if (hdr_opts->type == HDR_FROM && state->from == 0)
state->from = cleanup_extract_internal(header_buf, *tpp);
if (hdr_opts->type == HDR_RESENT_FROM && state->resent_from == 0)
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
cleanup_rewrite_tree(*tpp);
- if (cleanup_rcpt_canon_maps)
- cleanup_map11_tree(state, *tpp, cleanup_rcpt_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
- if (cleanup_comm_canon_maps)
- cleanup_map11_tree(state, *tpp, cleanup_comm_canon_maps,
- cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-
- if (cleanup_masq_domains
- && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_RCPT))
- cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
+ if (state->flags & CLEANUP_FLAG_MAP_OK) {
+ if (cleanup_rcpt_canon_maps)
+ cleanup_map11_tree(state, *tpp, cleanup_rcpt_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+ if (cleanup_comm_canon_maps)
+ cleanup_map11_tree(state, *tpp, cleanup_comm_canon_maps,
+ cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+
+ if (cleanup_masq_domains
+ && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_RCPT))
+ cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
+ }
}
vstring_sprintf(header_buf, "%s: ", hdr_opts->name);
tok822_externalize(header_buf, tree, TOK822_STR_HEAD);
#include <mail_params.h>
#include <rec_type.h>
#include <ext_prop.h>
+#include <cleanup_user.h>
/* Application-specific. */
* onto the same mailbox. The recipient will use our original recipient
* message header to figure things out.
*/
- if (cleanup_virt_alias_maps == 0) {
+ if ((state->flags & CLEANUP_FLAG_MAP_OK) == 0
+ || cleanup_virt_alias_maps == 0) {
if (been_here(state->dups, "%s\n%s", orcpt, recip) == 0) {
cleanup_out_string(state, REC_TYPE_ORCP, orcpt);
cleanup_out_string(state, REC_TYPE_RCPT, recip);
flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
verp_sender.c match_parent_style.c mime_state.c header_token.c \
strip_addr.c virtual8_maps.c hold_message.c verify_clnt.c \
- trace.c log_adhoc.c verify.c dict_proxy.c mail_dict.c
+ trace.c log_adhoc.c verify.c dict_proxy.c mail_dict.c input_transp.c
OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
debug_peer.o debug_process.o defer.o deliver_completed.o \
deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
verp_sender.o match_parent_style.o mime_state.o header_token.o \
strip_addr.o virtual8_maps.o hold_message.o verify_clnt.o \
- trace.o log_adhoc.o verify.o dict_proxy.o mail_dict.o
+ trace.o log_adhoc.o verify.o dict_proxy.o mail_dict.o input_transp.o
HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
match_parent_style.h quote_flags.h mime_state.h header_token.h \
lex_822.h strip_addr.h virtual8_maps.h hold_message.h verify_clnt.h \
- trace.h log_adhoc.h verify.h dict_proxy.h mail_dict.h qmgr_user.h
+ trace.h log_adhoc.h verify.h dict_proxy.h mail_dict.h qmgr_user.h \
+ input_transp.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
hold_message.o: ../../include/vstream.h
hold_message.o: mail_params.h
hold_message.o: hold_message.h
+input_transp.o: input_transp.c
+input_transp.o: ../../include/sys_defs.h
+input_transp.o: ../../include/name_mask.h
+input_transp.o: mail_params.h
+input_transp.o: input_transp.h
is_header.o: is_header.c
is_header.o: ../../include/sys_defs.h
is_header.o: is_header.h
#define CLEANUP_FLAG_HOLD (1<<2) /* Place message on hold */
#define CLEANUP_FLAG_DISCARD (1<<3) /* Discard message silently */
#define CLEANUP_FLAG_BCC_OK (1<<4) /* Ok to add auto-BCC addresses */
+#define CLEANUP_FLAG_MAP_OK (1<<5) /* Ok to map addresses */
+
+ /*
+ * These are normally set when receiving mail from outside.
+ */
+#define CLEANUP_FLAG_MASK_EXTERNAL \
+ (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_BCC_OK | CLEANUP_FLAG_MAP_OK)
+
+ /*
+ * These are normally set when generating notices or when forwarding mail
+ * internally.
+ */
+#define CLEANUP_FLAG_MASK_INTERNAL CLEANUP_FLAG_MAP_OK
/*
* These are set on the fly while processing SMTP envelopes or message
* Sanity checks.
*/
if (dict_flags & DICT_FLAG_NO_PROXY)
- msg_fatal("%s: proxy map must not be used with this map type", map);
+ msg_fatal("%s: %s map is not allowed for security sensitive data",
+ map, DICT_TYPE_PROXY);
if (open_flags != O_RDONLY)
- msg_fatal("%s: proxy map open requires O_RDONLY access mode", map);
+ msg_fatal("%s: %s map open requires O_RDONLY access mode",
+ map, DICT_TYPE_PROXY);
/*
* Local initialization.
/* SYNOPSIS
/* #include <exp_prop.h>
/*
-/* int ext_prop_mask(pattern)
+/* int ext_prop_mask(param_name, pattern)
+/* const char *param_name;
/* const char *pattern;
/* DESCRIPTION
/* This module controld address extension propagation.
/* computes the corresponding mask. The following names are
/* recognized in \fBpattern\fR, with the corresponding bit mask
/* given in parentheses:
-/* .IP "canonical (EXP_PROP_CANONICAL)"
+/* .IP "canonical (EXT_PROP_CANONICAL)"
/* Propagate unmatched address extensions to the right-hand side
/* of canonical table entries (not: regular expressions).
-/* .IP "virtual (EXP_PROP_VIRTUAL)
+/* .IP "virtual (EXT_PROP_VIRTUAL)
/* Propagate unmatched address extensions to the right-hand side
/* of virtual table entries (not: regular expressions).
-/* .IP "alias (EXP_PROP_ALIAS)
+/* .IP "alias (EXT_PROP_ALIAS)
/* Propagate unmatched address extensions to the right-hand side
/* of alias database entries.
-/* .IP "forward (EXP_PROP_FORWARD)"
+/* .IP "forward (EXT_PROP_FORWARD)"
/* Propagate unmatched address extensions to the right-hand side
/* of .forward file entries.
-/* .IP "include (EXP_PROP_INCLUDE)"
+/* .IP "include (EXT_PROP_INCLUDE)"
/* Propagate unmatched address extensions to the right-hand side
/* of :include: file entries.
/* DIAGNOSTICS
/* ext_prop_mask - compute extension propagation mask */
-int ext_prop_mask(const char *pattern)
+int ext_prop_mask(const char *param_name, const char *pattern)
{
static NAME_MASK table[] = {
"canonical", EXT_PROP_CANONICAL,
0,
};
- return (name_mask(VAR_PROP_EXTENSION, table, pattern));
+ return (name_mask(param_name, table, pattern));
}
#define EXT_PROP_FORWARD (1<<3)
#define EXT_PROP_INCLUDE (1<<4)
-extern int ext_prop_mask(const char *);
+extern int ext_prop_mask(const char *, const char *);
/* LICENSE
/* .ad
--- /dev/null
+/*++
+/* NAME
+/* input_transp 3
+/* SUMMARY
+/* receive transparency control
+/* SYNOPSIS
+/* #include <input_transp.h>
+/*
+/* int input_transp_mask(param_name, pattern)
+/* const char *param_name;
+/* const char *pattern;
+/* DESCRIPTION
+/* This module controls how much processing happens before mail is
+/* written to the Postfix queue. Each transparency option is either
+/* implemented by a client of the cleanup service, or is passed
+/* along in a client request to the cleanup service.
+/*
+/* input_transp_mask() takes a comma-separated list of names and
+/* computes the corresponding mask. The following names are
+/* recognized in \fBpattern\fR, with the corresponding bit mask
+/* given in parentheses:
+/* .IP "no_unknown_recipient_checks (INPUT_TRANSP_UNKNOWN_RCPT)"
+/* Do not try to reject unknown recipients.
+/* .IP "no_address_mapping (INPUT_TRANSP_ADDRESS_MAPPING)
+/* Disable canonical address mapping, virtual alias map expansion,
+/* address masquerading, and automatic BCC recipients.
+/* .IP "no_header_body_checkss (INPUT_TRANSP_HEADER_BODY)
+/* Disable header/body_checks.
+/* DIAGNOSTICS
+/* Panic: inappropriate use.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <name_mask.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <input_transp.h>
+
+/* input_transp_mask - compute mail receive transparency mask */
+
+int input_transp_mask(const char *param_name, const char *pattern)
+{
+ static NAME_MASK table[] = {
+ "no_unknown_recipient_checks", INPUT_TRANSP_UNKNOWN_RCPT,
+ "no_address_mappings", INPUT_TRANSP_ADDRESS_MAPPING,
+ "no_header_body_checks", INPUT_TRANSP_HEADER_BODY,
+ 0,
+ };
+
+ return (name_mask(param_name, table, pattern));
+}
--- /dev/null
+#ifndef _EXT_PROP_INCLUDED_
+#define _EXT_PROP_INCLUDED_
+
+/*++
+/* NAME
+/* ext_prop 3h
+/* SUMMARY
+/* address extension propagation control
+/* SYNOPSIS
+/* #include <ext_prop.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External interface.
+ */
+#define INPUT_TRANSP_UNKNOWN_RCPT (1<<0)
+#define INPUT_TRANSP_ADDRESS_MAPPING (1<<1)
+#define INPUT_TRANSP_HEADER_BODY (1<<2)
+
+extern int input_transp_mask(const char *, const char *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
#define DEF_SMTPD_PROXY_TMOUT "100s"
extern int var_smtpd_proxy_tmout;
+ /*
+ * Transparency options for mail input interfaces and for the cleanup server
+ * behind them. These should turn off stuff we don't want to happen, because
+ * the default is to do a lot of things.
+ */
+#define VAR_INPUT_TRANSP "receive_override_options"
+#define DEF_INPUT_TRANSP ""
+extern char *var_smtpd_input_transp;
+
/* LICENSE
/* .ad
/* .fi
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
-#define MAIL_RELEASE_DATE "20030704"
+#define MAIL_RELEASE_DATE "20030705"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "2.0.13-" MAIL_RELEASE_DATE
* mail bounce wars. Always prepend one space to message content that we
* generate from untrusted data.
*/
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define LENGTH 78
#define INDENT 4
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS);
if (notice == 0) {
msg_warn("postmaster notify: %m");
info->cleanup = cleanup;
info->queue_id = mystrdup(vstring_str(buffer));
info->posting_time = time((time_t *) 0);
+
+#define FORWARD_CLEANUP_FLAGS (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_MASK_INTERNAL)
+
attr_print(cleanup, ATTR_FLAG_NONE,
- ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, CLEANUP_FLAG_BOUNCE,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, FORWARD_CLEANUP_FLAGS,
ATTR_TYPE_END);
/*
var_allow_files);
local_cmd_deliver_mask = name_mask(VAR_ALLOW_COMMANDS, command_mask,
var_allow_commands);
- local_ext_prop_mask = ext_prop_mask(var_prop_extension);
+ local_ext_prop_mask =
+ ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
local_deliver_hdr_mask = name_mask(VAR_DELIVER_HDR, deliver_mask,
var_deliver_hdr);
local_mbox_lock_mask = mbox_lock_mask(var_mailbox_lock);
pickup.o: ../../include/record.h
pickup.o: ../../include/rec_type.h
pickup.o: ../../include/lex_822.h
+pickup.o: ../../include/input_transp.h
pickup.o: ../../include/mail_server.h
/* either bounces mail or re-injects the result back into Postfix.
/* This parameter uses the same syntax as the right-hand side of
/* a Postfix transport table.
+/* .IP \fBreceive_override_options\fB
+/* The following options override \fBmain.cf\fR settings.
+/* The options are passed on to the downstream cleanup server.
+/* .RS
+/* .IP \fBno_address_mappings\fR
+/* Disable canonical address mapping, virtual alias map expansion,
+/* address masquerading, and automatic BCC recipients. Specify this
+/* if address mapping etc. are to be done \fBafter\fR an external
+/* content filter.
+/* .IP \fBno_header_body_checks\fR
+/* Disable header/body_checks. Specify this if header/body_checks
+/* are to be done \fBafter\fR an external content filter.
+/* .RE
/* .SH Miscellaneous
/* .ad
/* .fi
#include <record.h>
#include <rec_type.h>
#include <lex_822.h>
+#include <input_transp.h>
/* Single-threaded server skeleton. */
/* Application-specific. */
char *var_filter_xport;
+char *var_input_transp;
/*
* Structure to bundle a bunch of information about a queue file.
#define REMOVE_MESSAGE_FILE 1
#define KEEP_MESSAGE_FILE 2
+ /*
+ * Transparency: before mail is queued, do we allow address mapping,
+ * automatic bcc, header/body checks?
+ */
+int pickup_input_transp_mask;
+
/* file_read_error - handle error while reading queue file */
static int file_read_error(PICKUP_INFO *info, int type)
int status;
VSTREAM *qfile;
VSTREAM *cleanup;
+ int cleanup_flags;
/*
* Open the submitted file. If we cannot open it, and we're not having a
* easier to implement the many possible error exits without forgetting
* to close files, or to release memory.
*/
-#define PICKUP_CLEANUP_FLAGS \
- (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_FILTER | CLEANUP_FLAG_BCC_OK)
+ cleanup_flags = (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_MASK_EXTERNAL);
+ if (pickup_input_transp_mask & INPUT_TRANSP_ADDRESS_MAPPING)
+ cleanup_flags &= ~(CLEANUP_FLAG_BCC_OK | CLEANUP_FLAG_MAP_OK);
+ if (pickup_input_transp_mask & INPUT_TRANSP_HEADER_BODY)
+ cleanup_flags &= ~CLEANUP_FLAG_FILTER;
cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, buf,
ATTR_TYPE_END) != 1
|| attr_print(cleanup, ATTR_FLAG_NONE,
- ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, PICKUP_CLEANUP_FLAGS,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, cleanup_flags,
ATTR_TYPE_END) != 0) {
status = KEEP_MESSAGE_FILE;
} else {
} while (file_count);
}
-/* drop_privileges - drop privileges */
+/* post_jail_init - drop privileges */
-static void drop_privileges(char *unused_name, char **unused_argv)
+static void post_jail_init(char *unused_name, char **unused_argv)
{
/*
*/
if (getuid() != var_owner_uid)
set_ugid(var_owner_uid, var_owner_gid);
+
+ /*
+ * Initialize the receive transparency options: do we want unknown
+ * recipient checks, do we want address mapping.
+ */
+ pickup_input_transp_mask =
+ input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
}
/* main - pass control to the multi-threaded server skeleton */
{
static CONFIG_STR_TABLE str_table[] = {
VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
+ VAR_INPUT_TRANSP, DEF_INPUT_TRANSP, &var_input_transp, 0, 0,
0,
};
*/
trigger_server_main(argc, argv, pickup_service,
MAIL_SERVER_STR_TABLE, str_table,
- MAIL_SERVER_POST_INIT, drop_privileges,
+ MAIL_SERVER_POST_INIT, post_jail_init,
MAIL_SERVER_SOLITARY,
0);
}
/* The \fBmain.cf\fR configuration file is in the named directory
/* instead of the default configuration directory.
/* .IP \fB-q\fR
-/* Search the Postfix queue for \fIfiles\fR. By default,
-/* file names are taken literally.
+/* Search the Postfix queue for the named \fIfiles\fR instead
+/* of taking the names literally.
/* .IP \fB-v\fR
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
/* options make the software increasingly verbose.
/* .IP \fBhopcount_limit\fR
/* Limit the number of \fBReceived:\fR message headers.
/* .IP \fBqmqpd_authorized_clients\fR
-/* A list of domain or network patterns that specifies what
+/* A list of domain or network patterns that specifies what
/* clients are allowed to use the service.
/* .IP \fBqmqpd_timeout\fR
/* Limit the time to send a server response and to receive a client
/* either bounces mail or re-injects the result back into Postfix.
/* This parameter uses the same syntax as the right-hand side of
/* a Postfix transport table.
+/* .IP \fBreceive_override_options\fB
+/* The following options override \fBmain.cf\fR settings.
+/* The options are passed on to the downstream cleanup server.
+/* .RS
+/* .IP \fBno_address_mappings\fR
+/* Disable canonical address mapping, virtual alias map expansion,
+/* address masquerading, and automatic BCC recipients. Specify this
+/* if address mapping etc. are to be done \fBafter\fR an external
+/* content filter.
+/* .IP \fBno_header_body_checks\fR
+/* Disable header/body_checks. Specify this if header/body_checks
+/* are to be done \fBafter\fR an external content filter.
+/* .RE
/* .SH "Resource controls"
/* .ad
/* .fi
#include <match_parent_style.h>
#include <lex_822.h>
#include <verp_sender.h>
+#include <input_transp.h>
/* Single-threaded server skeleton. */
int var_qmqpd_err_sleep;
char *var_filter_xport;
char *var_qmqpd_clients;
+char *var_input_transp;
/*
* Silly little macros.
*/
static NAMADR_LIST *qmqpd_clients;
+ /*
+ * Transparency: before mail is queued, do we allow address mapping,
+ * automatic bcc, header/body checks?
+ */
+int qmqpd_input_transp_mask;
+
/* qmqpd_open_file - open a queue file */
static void qmqpd_open_file(QMQPD_STATE *state)
{
+ int cleanup_flags;
/*
* Connect to the cleanup server. Log client name/address with queue ID.
*/
-#define QMQPD_CLEANUP_FLAGS (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_BCC_OK)
+ cleanup_flags = CLEANUP_FLAG_MASK_EXTERNAL;
+ if (qmqpd_input_transp_mask & INPUT_TRANSP_ADDRESS_MAPPING)
+ cleanup_flags &= ~(CLEANUP_FLAG_BCC_OK | CLEANUP_FLAG_MAP_OK);
+ if (qmqpd_input_transp_mask & INPUT_TRANSP_HEADER_BODY)
+ cleanup_flags &= ~CLEANUP_FLAG_FILTER;
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC, var_cleanup_service);
if (state->dest == 0
|| attr_print(state->dest->stream, ATTR_FLAG_NONE,
- ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, QMQPD_CLEANUP_FLAGS,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, cleanup_flags,
ATTR_TYPE_END) != 0)
msg_fatal("unable to connect to the %s %s service",
MAIL_CLASS_PUBLIC, var_cleanup_service);
static void pre_accept(char *unused_name, char **unused_argv)
{
const char *table;
-
+
if ((table = dict_changed_name()) != 0) {
msg_info("table %s has changed -- restarting", table);
exit(0);
var_qmqpd_clients);
}
+/* post_jail_init - post-jail initialization */
+
+static void post_jail_init(char *unused_name, char **unused_argv)
+{
+
+ /*
+ * Initialize the receive transparency options: do we want unknown
+ * recipient checks, do we want address mapping.
+ */
+ qmqpd_input_transp_mask =
+ input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
+}
+
/* main - the main program */
int main(int argc, char **argv)
static CONFIG_STR_TABLE str_table[] = {
VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
VAR_QMQPD_CLIENTS, DEF_QMQPD_CLIENTS, &var_qmqpd_clients, 0, 0,
+ VAR_INPUT_TRANSP, DEF_INPUT_TRANSP, &var_input_transp, 0, 0,
0,
};
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_PRE_INIT, pre_jail_init,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
+ MAIL_SERVER_POST_INIT, post_jail_init,
0);
}
* mail bounce wars. Always prepend one space to message content that we
* generate from untrusted data.
*/
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define LENGTH 78
#define INDENT 4
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS);
if (notice == 0) {
msg_warn("postmaster notify: %m");
smtpd.o: ../../include/quote_flags.h
smtpd.o: ../../include/lex_822.h
smtpd.o: ../../include/namadr_list.h
+smtpd.o: ../../include/input_transp.h
smtpd.o: ../../include/mail_server.h
smtpd.o: smtpd_token.h
smtpd.o: smtpd.h
smtpd_check.o: ../../include/verify_clnt.h
smtpd_check.o: ../../include/deliver_request.h
smtpd_check.o: ../../include/recipient_list.h
+smtpd_check.o: ../../include/input_transp.h
smtpd_check.o: smtpd.h
smtpd_check.o: ../../include/mail_stream.h
smtpd_check.o: smtpd_sasl_glue.h
/* either bounces mail or re-injects the result back into Postfix.
/* This parameter uses the same syntax as the right-hand side of
/* a Postfix transport table.
+/* .IP \fBreceive_override_options\fB
+/* The following options override \fBmain.cf\fR settings.
+/* The options are either implemented by the SMTP server or
+/* are passed on to the downstream cleanup server.
+/* .RS
+/* .IP \fBno_unknown_recipient_checks\fR
+/* Do not try to reject unknown recipients. This is typically specified
+/* with the SMTP server \fBafter\fR an external content filter.
+/* .IP \fBno_address_mappings\fR
+/* Disable canonical address mapping, virtual alias map expansion,
+/* address masquerading, and automatic BCC recipients. This is
+/* typically specified with the SMTP server \fBbefore\fR an external
+/* content filter.
+/* .IP \fBno_header_body_checks\fR
+/* Disable header/body_checks. This is typically specified with the
+/* SMTP server \fBafter\fR an external content filter.
+/* .RE
/* .SH "Authentication controls"
/* .IP \fBenable_sasl_authentication\fR
/* Enable per-session authentication as per RFC 2554 (SASL).
#include <quote_822_local.h>
#include <lex_822.h>
#include <namadr_list.h>
+#include <input_transp.h>
/* Single-threaded server skeleton. */
int var_show_unk_rcpt_table;
int var_verify_poll_count;
int var_verify_poll_delay;
-
char *var_smtpd_proxy_filt;
int var_smtpd_proxy_tmout;
char *var_smtpd_proxy_ehlo;
+char *var_input_transp;
/*
* Silly little macros.
static NAMADR_LIST *verp_clients;
+ /*
+ * Other application-specific globals.
+ */
+int smtpd_input_transp_mask;
+
/*
* Forward declarations.
*/
const char *encoding, const char *verp_delims)
{
char *postdrop_command;
+ int cleanup_flags;
/*
* XXX 2821: An SMTP server is not allowed to "clean up" mail except in
* If running from the master or from inetd, connect to the cleanup
* service.
*/
-#define SMTPD_CLEANUP_FLAGS (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_BCC_OK)
+ cleanup_flags = CLEANUP_FLAG_MASK_EXTERNAL;
+ if (smtpd_input_transp_mask & INPUT_TRANSP_ADDRESS_MAPPING)
+ cleanup_flags &= ~(CLEANUP_FLAG_BCC_OK | CLEANUP_FLAG_MAP_OK);
+ if (smtpd_input_transp_mask & INPUT_TRANSP_HEADER_BODY)
+ cleanup_flags &= ~CLEANUP_FLAG_FILTER;
if (SMTPD_STAND_ALONE(state) == 0) {
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC,
var_cleanup_service);
if (state->dest == 0
|| attr_print(state->dest->stream, ATTR_FLAG_NONE,
- ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, SMTPD_CLEANUP_FLAGS,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, cleanup_flags,
ATTR_TYPE_END) != 0)
msg_fatal("unable to connect to the %s %s service",
MAIL_CLASS_PUBLIC, var_cleanup_service);
state->discard = 0;
/*
- * Try to be nice. Don't bother when we lost the connection.
+ * Try to be nice. Don't bother when we lost the connection. Don't bother
+ * waiting for a reply, it just increases latency.
*/
if (state->proxy) {
- (void) smtpd_proxy_cmd(state, SMTPD_PROX_WANT_ANY, "QUIT");
+ (void) smtpd_proxy_cmd(state, SMTPD_PROX_WANT_NONE, "QUIT");
smtpd_proxy_close(state);
}
}
}
if (cmdp->flags & SMTPD_CMD_FLAG_FORBIDDEN) {
msg_warn("%s sent non-SMTP command: %.100s",
- state->namaddr, vstring_str(state->buffer));
+ state->namaddr, vstring_str(state->buffer));
smtpd_chat_reply(state, "221 Error: I can break rules, too. Goodbye.");
break;
}
#endif
}
+/* post_jail_init - post-jail initialization */
+
+static void post_jail_init(char *unused_name, char **unused_argv)
+{
+
+ /*
+ * Initialize the receive transparency options: do we want unknown
+ * recipient checks, address mapping, header_body_checks?.
+ */
+ smtpd_input_transp_mask =
+ input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
+}
+
/* main - the main program */
int main(int argc, char **argv)
VAR_VERP_CLIENTS, DEF_VERP_CLIENTS, &var_verp_clients, 0, 0,
VAR_SMTPD_PROXY_FILT, DEF_SMTPD_PROXY_FILT, &var_smtpd_proxy_filt, 0, 0,
VAR_SMTPD_PROXY_EHLO, DEF_SMTPD_PROXY_EHLO, &var_smtpd_proxy_ehlo, 0, 0,
+ VAR_INPUT_TRANSP, DEF_INPUT_TRANSP, &var_input_transp, 0, 0,
0,
};
static CONFIG_RAW_TABLE raw_table[] = {
MAIL_SERVER_TIME_TABLE, time_table,
MAIL_SERVER_PRE_INIT, pre_jail_init,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
+ MAIL_SERVER_POST_INIT, post_jail_init,
0);
}
void smtpd_peer_init(SMTPD_STATE *state);
void smtpd_peer_reset(SMTPD_STATE *state);
+ /*
+ * Transparency: before mail is queued, do we check for unknown recipients,
+ * do we allow address mapping, automatic bcc, header/body checks?
+ */
+int smtpd_input_transp_mask;
+
/* LICENSE
/* .ad
/* .fi
* mail bounce wars. Always prepend one space to message content that we
* generate from untrusted data.
*/
-#define NULL_CLEANUP_FLAGS 0
#define NULL_TRACE_FLAGS 0
#define LENGTH 78
#define INDENT 4
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
NULL_TRACE_FLAGS);
if (notice == 0) {
msg_warn("postmaster notify: %m");
#include <mail_proto.h>
#include <mail_addr.h>
#include <verify_clnt.h>
+#include <input_transp.h>
/* Application-specific. */
* Duplicate suppression. There's an implicit check_recipient_maps
* restriction at the end of all recipient restrictions.
*/
+ if (smtpd_input_transp_mask & INPUT_TRANSP_UNKNOWN_RCPT)
+ return (0);
if (state->rcptmap_checked == 1)
return (0);
state->rcptmap_checked = 1;
/* .in +4
/* /* other fields... */
/* VSTREAM *proxy; /* connection to SMTP proxy */
-/* VSTRING *proxy_reply; /* last SMTP proxy response */
+/* VSTRING *proxy_buffer; /* last SMTP proxy response */
/* /* other fields... */
/* .in -4
/* } SMTPD_STATE;
/* MAIL FROM command, and receives the reply. A non-zero result means
/* trouble: either the proxy is unavailable, or it did not send the
/* expected reply.
-/* All results are reported via the state->proxy_reply field in a form
+/* All results are reported via the state->proxy_buffer field in a form
/* that can be sent to the SMTP client. In case of error, the
/* state->error_mask and state->err fields are updated.
-/* A state->proxy_reply field is created automatically; this field
+/* A state->proxy_buffer field is created automatically; this field
/* persists beyond the end of a proxy session.
/*
/* smtpd_proxy_cmd() formats and sends the specified command to the
/* proxy server, and receives the proxy server reply. A non-zero result
/* means trouble: either the proxy is unavailable, or it did not send the
/* expected reply.
-/* All results are reported via the state->proxy_reply field in a form
+/* All results are reported via the state->proxy_buffer field in a form
/* that can be sent to the SMTP client. In case of error, the
/* state->error_mask and state->err fields are updated.
/*
/* Expected proxy server reply status code range. A warning is logged
/* when an unexpected reply is received. Specify one of the following:
/* .RS
-/* .IP SMTPD_PROX_WANT_ANY
-/* The caller has no expectation. Do not warn for unexpected replies.
/* .IP SMTPD_PROX_WANT_OK
/* The caller expects a reply in the 200 range.
/* .IP SMTPD_PROX_WANT_MORE
/* The caller expects a reply in the 300 range.
+/* .IP SMTPD_PROX_WANT_ANY
+/* The caller has no expectation. Do not warn for unexpected replies.
+/* .IP SMTPD_PROX_WANT_NONE
+/* Do not bother waiting for a reply.
/* .RE
/* .IP format
/* A format string.
* Get server greeting banner.
*
* If this fails then we have a problem because the proxy should always
- * accept our connection.
+ * accept our connection. Make up our own response instead of passing
+ * back the greeting banner: the client expects a MAIL FROM reply.
*/
if (smtpd_proxy_cmd(state, SMTPD_PROX_WANT_OK, SMTPD_PROXY_CONNECT) != 0) {
vstring_sprintf(state->proxy_buffer,
}
/*
- * Send our own EHLO command.
- *
- * If this fails then we have a problem because the proxy should always
- * accept our EHLO command.
+ * Send our own EHLO command. If this fails then we have a problem
+ * because the proxy should always accept our EHLO command. Make up our
+ * own response instead of passing back the EHLO reply: the client
+ * expects a MAIL FROM reply.
*/
if (smtpd_proxy_cmd(state, SMTPD_PROX_WANT_OK, "EHLO %s", ehlo_name) != 0) {
vstring_sprintf(state->proxy_buffer,
return (0);
}
-/* smtpd_proxy_comms_error - report proxy communication error */
+/* smtpd_proxy_rdwr_error - report proxy communication error */
-static int smtpd_proxy_comms_error(VSTREAM *stream, int err)
+static int smtpd_proxy_rdwr_error(VSTREAM *stream, int err)
{
switch (err) {
case SMTP_ERR_EOF:
msg_warn("timeout talking to proxy %s", VSTREAM_PATH(stream));
return (err);
default:
- msg_panic("smtpd_proxy_comms_error: unknown proxy %s stream error %d",
+ msg_panic("smtpd_proxy_rdwr_error: unknown proxy %s stream error %d",
VSTREAM_PATH(stream), err);
}
}
|| vstream_ferror(state->proxy)
|| vstream_feof(state->proxy)
|| ((err = vstream_setjmp(state->proxy) != 0)
- && smtpd_proxy_comms_error(state->proxy, err))) {
+ && smtpd_proxy_rdwr_error(state->proxy, err))) {
state->error_mask |= MAIL_ERROR_SOFTWARE;
state->err |= CLEANUP_STAT_PROXY;
vstring_sprintf(state->proxy_buffer,
state->proxy);
}
+ /*
+ * Early return if we don't want to wait for a server reply (such as
+ * after sending QUIT.
+ */
+ if (expect == SMTPD_PROX_WANT_NONE)
+ return (0);
+
/*
* Censor out non-printable characters in server responses and keep the
* last line of multi-line responses.
* Log a warning in case the proxy does not send the expected response.
* Silently accept any response when the client expressed no expectation.
*/
- if (expect != SMTPD_PROX_WANT_ANY
- && expect != (STR(state->proxy_buffer)[0] - '0')) {
+ if (expect != SMTPD_PROX_WANT_ANY && expect != *STR(state->proxy_buffer)) {
va_start(ap, fmt);
smtpd_proxy_cmd_error(state, fmt, ap);
va_end(ap);
|| vstream_feof(stream))
return (REC_TYPE_ERROR);
if ((err = vstream_setjmp(stream)) != 0)
- return (smtpd_proxy_comms_error(stream, err), REC_TYPE_ERROR);
+ return (smtpd_proxy_rdwr_error(stream, err), REC_TYPE_ERROR);
/*
* Send one content record. Errors and results must be as with rec_put().
|| vstream_feof(stream))
return (REC_TYPE_ERROR);
if ((err = vstream_setjmp(stream)) != 0)
- return (smtpd_proxy_comms_error(stream, err), REC_TYPE_ERROR);
+ return (smtpd_proxy_rdwr_error(stream, err), REC_TYPE_ERROR);
/*
* Send one content record. Errors and results must be as with
/*
* Application-specific.
*/
-#define SMTPD_PROX_WANT_ANY 0
-#define SMTPD_PROX_WANT_OK 2
-#define SMTPD_PROX_WANT_MORE 3
+#define SMTPD_PROX_WANT_NONE '\0' /* Do not receive reply */
+#define SMTPD_PROX_WANT_ANY '0' /* Expect any reply */
+#define SMTPD_PROX_WANT_OK '2' /* Expect 2XX reply */
+#define SMTPD_PROX_WANT_MORE '3' /* Expect 3XX reply */
extern int smtpd_proxy_open(SMTPD_STATE *, const char *, int, const char *, const char *);
extern int smtpd_proxy_cmd(SMTPD_STATE *, int, const char *,...);
(addr_status == DEL_RCPT_STAT_OK && updated + var_verify_pos_try < now)
#define NEGATIVE_REFRESH_NEEDED(addr_status, updated) \
(addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now)
-#define NULL_CLEANUP_FLAGS 0
if (now - probed > PROBE_TTL
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
STR(addr), addr_status, now, updated);
post_mail_fopen_async(strcmp(var_verify_sender, "<>") == 0 ?
"" : var_verify_sender, STR(addr),
- NULL_CLEANUP_FLAGS,
+ CLEANUP_FLAG_MASK_INTERNAL,
DEL_REQ_FLAG_VERIFY,
verify_post_mail_action,
(void *) 0);