mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-29 21:27:57 +00:00
postfix-2.0.16-20031226
This commit is contained in:
parent
468e9bae3d
commit
e14a8a626a
@ -8920,14 +8920,28 @@ Apologies for any names omitted.
|
|||||||
Cleanup: eliminated binary hashes from anvil server. Anvil
|
Cleanup: eliminated binary hashes from anvil server. Anvil
|
||||||
client information is now stored on top of its VSTREAM.
|
client information is now stored on top of its VSTREAM.
|
||||||
|
|
||||||
|
20031226
|
||||||
|
|
||||||
|
Feature: bounce_queue_lifetime parameter (default:
|
||||||
|
$maximal_queue_life_time) that bounds the time that
|
||||||
|
MAILER-DAEMON messages spend in the queue before they are
|
||||||
|
considered undeliverable.
|
||||||
|
|
||||||
|
Feature: disable "mail loops back to myself" protection
|
||||||
|
when SMTP mail is sent to a non-standard port. This makes
|
||||||
|
setting up content filters less painful.
|
||||||
|
|
||||||
|
Cleanup: disallow bare x.x.x.x numeric IP addresses in
|
||||||
|
email addresses. The form user@[x.x.x.x] is still allowed.
|
||||||
|
|
||||||
|
Cleanup: cleaned up the naming of internal symbols in the
|
||||||
|
SMTP client.
|
||||||
|
|
||||||
Open problems:
|
Open problems:
|
||||||
|
|
||||||
Low: in the SMTP client, pass the session, request and
|
Low: in the SMTP client, pass the session, request and
|
||||||
state structures as separate arguments.
|
state structures as separate arguments.
|
||||||
|
|
||||||
Low: in the SMTP client, turn off "mail loops back to
|
|
||||||
myself" detection if a non-default TCP port is specified.
|
|
||||||
|
|
||||||
High: when virtual aliasing is turned off after content
|
High: when virtual aliasing is turned off after content
|
||||||
filtering, local submissions may escape virtual aliasing.
|
filtering, local submissions may escape virtual aliasing.
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ for testing, of course.
|
|||||||
smtp inet n - n - - smtpd
|
smtp inet n - n - - smtpd
|
||||||
-o smtpd_proxy_filter=26
|
-o smtpd_proxy_filter=26
|
||||||
:26 inet n - n - - smtpd
|
:26 inet n - n - - smtpd
|
||||||
-o smtpd_authorized_xclient_hosts=127.0.0.0/8
|
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
|
||||||
-o smtpd_client_restrictions=
|
-o smtpd_client_restrictions=
|
||||||
-o smtpd_helo_restrictions=
|
-o smtpd_helo_restrictions=
|
||||||
-o smtpd_sender_restrictions=
|
-o smtpd_sender_restrictions=
|
||||||
@ -135,7 +135,7 @@ Note: do not specify spaces around the "=" or "," characters.
|
|||||||
The ":26" causes Postfix to listen on the localhost address only.
|
The ":26" causes Postfix to listen on the localhost address only.
|
||||||
DO NOT expose the secondary SMTP server to the Internet :-)
|
DO NOT expose the secondary SMTP server to the Internet :-)
|
||||||
|
|
||||||
The smtpd_authorized_xclient_hosts parameter allows the before
|
The smtpd_authorized_xforward_hosts parameter allows the before
|
||||||
filter SMTP server to forward remote SMTP client information to
|
filter SMTP server to forward remote SMTP client information to
|
||||||
the after-filter SMTP server, so that the after-filter Postfix
|
the after-filter SMTP server, so that the after-filter Postfix
|
||||||
daemons log the remote SMTP client information instead of logging
|
daemons log the remote SMTP client information instead of logging
|
||||||
|
@ -22,7 +22,7 @@ server's Received: message header.
|
|||||||
style content filter applications, the filter can be simplified if
|
style content filter applications, the filter can be simplified if
|
||||||
it can delegate decisions concerning mail relay and other access
|
it can delegate decisions concerning mail relay and other access
|
||||||
control to the MTA. This is especially useful when the filter acts
|
control to the MTA. This is especially useful when the filter acts
|
||||||
as a transparent proxy for SMTP commands. As in the first example,
|
as a transparent proxy for SMTP commands. As in the other examples,
|
||||||
this requires that the filter can override the MTA's idea of the
|
this requires that the filter can override the MTA's idea of the
|
||||||
SMTP client hostname, network address, and other information.
|
SMTP client hostname, network address, and other information.
|
||||||
|
|
||||||
@ -68,8 +68,8 @@ is not enclosed with [].
|
|||||||
|
|
||||||
The PROTO attribute specifies either SMTP or ESMTP.
|
The PROTO attribute specifies either SMTP or ESMTP.
|
||||||
|
|
||||||
The HELO attribute specifies a HELO parameter value, or the value
|
The HELO attribute specifies an SMTP HELO parameter value, or the
|
||||||
[UNAVAILABLE] when the information is unavailable.
|
value [UNAVAILABLE] when the information is unavailable.
|
||||||
|
|
||||||
Note 1: syntactically valid NAME and HELO attributes can be up to
|
Note 1: syntactically valid NAME and HELO attributes can be up to
|
||||||
255 characters long. The client must not send XCLIENT commands that
|
255 characters long. The client must not send XCLIENT commands that
|
||||||
@ -81,16 +81,15 @@ upper case, lower case or mixed case.
|
|||||||
Security
|
Security
|
||||||
========
|
========
|
||||||
|
|
||||||
The XCLIENT command changes audit trails and/or client access
|
The XCLIENT command changes audit trails and/or SMTP client access
|
||||||
permissions. Use of this command must be restricted to authorized
|
permissions. Use of this command must be restricted to authorized
|
||||||
clients.
|
SMTP clients. However, the XCLIENT command should not override its
|
||||||
|
own access control mechanism.
|
||||||
The XCLIENT should not override its own access control mechanism.
|
|
||||||
|
|
||||||
SMTP connection caching
|
SMTP connection caching
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
SMTP connection caching makes it possible to deliver multiple
|
XCLIENT attributes persist until the end of an SMTP session. If
|
||||||
messages within the same SMTP session. The XCLIENT attributes are
|
one session is used to deliver mail from different SMTP clients,
|
||||||
persistent across an SMTP session, and need to be reset as appropriate
|
the XCLIENT attributes need to be reset as appropriate in between
|
||||||
in between deliveries.
|
deliveries.
|
||||||
|
@ -12,11 +12,12 @@ remote client and/or message identifying information through the
|
|||||||
content filter to MTA2, so that the information could be logged as
|
content filter to MTA2, so that the information could be logged as
|
||||||
part of mail handling transactions.
|
part of mail handling transactions.
|
||||||
|
|
||||||
This extension is implemented as a separate command, so that it
|
This extension is implemented as a separate command, and can be
|
||||||
can be used to transmit client or message attributes incrementally.
|
used to transmit client or message attributes incrementally. It
|
||||||
It is not implemented by passing additional parameters via the MAIL
|
is not implemented by passing additional parameters via the MAIL
|
||||||
FROM command, because doing so would require extending the MAIL
|
FROM command, because doing so would require extending the MAIL
|
||||||
FROM command length limit by another 600 or more characters.
|
FROM command length limit by another 600 or more characters beyond
|
||||||
|
the space needed by other extensions such as AUTH.
|
||||||
|
|
||||||
Command syntax
|
Command syntax
|
||||||
==============
|
==============
|
||||||
|
@ -22,6 +22,17 @@ snapshot release). Patches change the patchlevel and the release
|
|||||||
date. Snapshots change only the release date, unless they include
|
date. Snapshots change only the release date, unless they include
|
||||||
the same bugfixes as a patch release.
|
the same bugfixes as a patch release.
|
||||||
|
|
||||||
|
Incompatible changes with Postfix snapshot 2.0.16-20031226
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
Postfix no longer allows mail addresses with bare numeric IP
|
||||||
|
addresses (user@1.2.3.4). The form user@[ipaddress] is still
|
||||||
|
allowed.
|
||||||
|
|
||||||
|
Bounce messages now have a separate queue life time. This is
|
||||||
|
controlled by the bounce_queue_lifetime parameter. The default is
|
||||||
|
$maximal_queue_life_time.
|
||||||
|
|
||||||
Incompatible changes with Postfix snapshot 2.0.16-20031223
|
Incompatible changes with Postfix snapshot 2.0.16-20031223
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
|
@ -46,6 +46,18 @@ maximal_backoff_time = 4000s
|
|||||||
#
|
#
|
||||||
maximal_queue_lifetime = 5d
|
maximal_queue_lifetime = 5d
|
||||||
|
|
||||||
|
# The bounce_queue_lifetime parameter specifies the maximal time
|
||||||
|
# a bounce message is queued before it is considered undeliverable.
|
||||||
|
# By default, this is the same as the queue life time for regular
|
||||||
|
# mail.
|
||||||
|
#
|
||||||
|
# Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
|
||||||
|
# The default time unit is d (days).
|
||||||
|
#
|
||||||
|
# Specify 0 when mail delivery should be tried only once.
|
||||||
|
#
|
||||||
|
bounce_queue_lifetime = $maximal_queue_lifetime
|
||||||
|
|
||||||
# The minimal_backoff_time parameter specifies the minimal time
|
# The minimal_backoff_time parameter specifies the minimal time
|
||||||
# between attempts to deliver a deferred message. This parameter
|
# between attempts to deliver a deferred message. This parameter
|
||||||
# also limits the time an unreachable destination is kept in the
|
# also limits the time an unreachable destination is kept in the
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<html> <head> </head> <body> <pre>
|
<html> <body> <pre>
|
||||||
NQMGR(8) NQMGR(8)
|
NQMGR(8) NQMGR(8)
|
||||||
|
|
||||||
<b>NAME</b>
|
<b>NAME</b>
|
||||||
@ -111,25 +111,25 @@ NQMGR(8) NQMGR(8)
|
|||||||
actions (the message is followed by the symbolic constant
|
actions (the message is followed by the symbolic constant
|
||||||
used internally by the software):
|
used internally by the software):
|
||||||
|
|
||||||
<b>D (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>DEFERRED)</b>
|
<b>D (QMGR_REQ_SCAN_DEFERRED)</b>
|
||||||
Start a deferred queue scan. If a deferred queue
|
Start a deferred queue scan. If a deferred queue
|
||||||
scan is already in progress, that scan will be
|
scan is already in progress, that scan will be
|
||||||
restarted as soon as it finishes.
|
restarted as soon as it finishes.
|
||||||
|
|
||||||
<b>I (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>INCOMING)</b>
|
<b>I (QMGR_REQ_SCAN_INCOMING)</b>
|
||||||
Start an incoming queue scan. If an incoming queue
|
Start an incoming queue scan. If an incoming queue
|
||||||
scan is already in progress, that scan will be
|
scan is already in progress, that scan will be
|
||||||
restarted as soon as it finishes.
|
restarted as soon as it finishes.
|
||||||
|
|
||||||
<b>A (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>ALL)</b>
|
<b>A (QMGR_REQ_SCAN_ALL)</b>
|
||||||
Ignore deferred queue file time stamps. The request
|
Ignore deferred queue file time stamps. The request
|
||||||
affects the next deferred queue scan.
|
affects the next deferred queue scan.
|
||||||
|
|
||||||
<b>F (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>FLUSH</b><i>_</i><b>DEAD)</b>
|
<b>F (QMGR_REQ_FLUSH_DEAD)</b>
|
||||||
Purge all information about dead transports and
|
Purge all information about dead transports and
|
||||||
destinations.
|
destinations.
|
||||||
|
|
||||||
<b>W (TRIGGER</b><i>_</i><b>REQ</b><i>_</i><b>WAKEUP)</b>
|
<b>W (TRIGGER_REQ_WAKEUP)</b>
|
||||||
Wakeup call, This is used by the master server to
|
Wakeup call, This is used by the master server to
|
||||||
instantiate servers that should not go away for-
|
instantiate servers that should not go away for-
|
||||||
ever. The action is to start an incoming queue
|
ever. The action is to start an incoming queue
|
||||||
@ -159,7 +159,7 @@ NQMGR(8) NQMGR(8)
|
|||||||
Corrupted message files are saved to the <b>corrupt</b> queue for
|
Corrupted message files are saved to the <b>corrupt</b> queue for
|
||||||
further inspection.
|
further inspection.
|
||||||
|
|
||||||
Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
|
Depending on the setting of the <b>notify_classes</b> parameter,
|
||||||
the postmaster is notified of bounces and of other trou-
|
the postmaster is notified of bounces and of other trou-
|
||||||
ble.
|
ble.
|
||||||
|
|
||||||
@ -176,54 +176,54 @@ NQMGR(8) NQMGR(8)
|
|||||||
command after a configuration change.
|
command after a configuration change.
|
||||||
|
|
||||||
<b>Miscellaneous</b>
|
<b>Miscellaneous</b>
|
||||||
<b>allow</b><i>_</i><b>min</b><i>_</i><b>user</b>
|
<b>allow_min_user</b>
|
||||||
Do not bounce recipient addresses that begin with
|
Do not bounce recipient addresses that begin with
|
||||||
'-'.
|
'-'.
|
||||||
|
|
||||||
<b>queue</b><i>_</i><b>directory</b>
|
<b>queue_directory</b>
|
||||||
Top-level directory of the Postfix queue.
|
Top-level directory of the Postfix queue.
|
||||||
|
|
||||||
<b>Active queue controls</b>
|
<b>Active queue controls</b>
|
||||||
In the text below, <i>transport</i> is the first field in a <b>mas-</b>
|
In the text below, <i>transport</i> is the first field in a <b>mas-</b>
|
||||||
<b>ter.cf</b> entry.
|
<b>ter.cf</b> entry.
|
||||||
|
|
||||||
<b>qmgr</b><i>_</i><b>clog</b><i>_</i><b>warn</b><i>_</i><b>time</b>
|
<b>qmgr_clog_warn_time</b>
|
||||||
Minimal delay between warnings that a specific des-
|
Minimal delay between warnings that a specific des-
|
||||||
tination is clogging up the active queue. Specify 0
|
tination is clogging up the active queue. Specify 0
|
||||||
to disable.
|
to disable.
|
||||||
|
|
||||||
<b>qmgr</b><i>_</i><b>message</b><i>_</i><b>active</b><i>_</i><b>limit</b>
|
<b>qmgr_message_active_limit</b>
|
||||||
Limit the number of messages in the active queue.
|
Limit the number of messages in the active queue.
|
||||||
|
|
||||||
<b>qmgr</b><i>_</i><b>message</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<b>qmgr_message_recipient_limit</b>
|
||||||
Limit the number of in-memory recipients.
|
Limit the number of in-memory recipients.
|
||||||
|
|
||||||
This parameter also limits the size of the short-
|
This parameter also limits the size of the short-
|
||||||
term, in-memory destination cache.
|
term, in-memory destination cache.
|
||||||
|
|
||||||
<b>qmgr</b><i>_</i><b>message</b><i>_</i><b>recipient</b><i>_</i><b>minimum</b>
|
<b>qmgr_message_recipient_minimum</b>
|
||||||
Per message minimum of in-memory recipients.
|
Per message minimum of in-memory recipients.
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<b>default_recipient_limit</b>
|
||||||
Default limit on the number of in-memory recipients
|
Default limit on the number of in-memory recipients
|
||||||
per transport.
|
per transport.
|
||||||
|
|
||||||
<i>transport_</i><b>recipient</b><i>_</i><b>limit</b>
|
<i>transport</i><b>_recipient_limit</b>
|
||||||
Limit on the number of in-memory recipients, for
|
Limit on the number of in-memory recipients, for
|
||||||
the named message <i>transport</i>.
|
the named message <i>transport</i>.
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>extra</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<b>default_extra_recipient_limit</b>
|
||||||
Default limit on the total number of per transport
|
Default limit on the total number of per transport
|
||||||
in-memory recipients that the preempting messages
|
in-memory recipients that the preempting messages
|
||||||
can have.
|
can have.
|
||||||
|
|
||||||
<i>transport_</i><b>extra</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<i>transport</i><b>_extra_recipient_limit</b>
|
||||||
Limit on the number of in-memory recipients which
|
Limit on the number of in-memory recipients which
|
||||||
all preempting messages delivered by the transport
|
all preempting messages delivered by the transport
|
||||||
<i>transport</i> can have.
|
<i>transport</i> can have.
|
||||||
|
|
||||||
<b>Timing controls</b>
|
<b>Timing controls</b>
|
||||||
<b>minimal</b><i>_</i><b>backoff</b><i>_</i><b>time</b>
|
<b>minimal_backoff_time</b>
|
||||||
Minimal time in seconds between delivery attempts
|
Minimal time in seconds between delivery attempts
|
||||||
of a deferred message.
|
of a deferred message.
|
||||||
|
|
||||||
@ -231,52 +231,56 @@ NQMGR(8) NQMGR(8)
|
|||||||
destination is kept in the short-term, in-memory
|
destination is kept in the short-term, in-memory
|
||||||
destination status cache.
|
destination status cache.
|
||||||
|
|
||||||
<b>maximal</b><i>_</i><b>backoff</b><i>_</i><b>time</b>
|
<b>maximal_backoff_time</b>
|
||||||
Maximal time in seconds between delivery attempts
|
Maximal time in seconds between delivery attempts
|
||||||
of a deferred message.
|
of a deferred message.
|
||||||
|
|
||||||
<b>maximal</b><i>_</i><b>queue</b><i>_</i><b>lifetime</b>
|
<b>maximal_queue_lifetime</b>
|
||||||
Maximal time in days a message is queued before it
|
Maximal time (default: in days) a regular message
|
||||||
is sent back as undeliverable.
|
is queued before it is considered undeliverable.
|
||||||
|
|
||||||
<b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
|
<b>bounce_queue_lifetime</b>
|
||||||
|
Maximal time (default: in days) a bounce message is
|
||||||
|
queued before it is considered undeliverable.
|
||||||
|
|
||||||
|
<b>queue_run_delay</b>
|
||||||
Time in seconds between deferred queue scans. Queue
|
Time in seconds between deferred queue scans. Queue
|
||||||
scans do not overlap.
|
scans do not overlap.
|
||||||
|
|
||||||
<b>transport</b><i>_</i><b>retry</b><i>_</i><b>time</b>
|
<b>transport_retry_time</b>
|
||||||
Time in seconds between attempts to contact a bro-
|
Time in seconds between attempts to contact a bro-
|
||||||
ken delivery transport.
|
ken delivery transport.
|
||||||
|
|
||||||
<b>Concurrency controls</b>
|
<b>Concurrency controls</b>
|
||||||
<b>initial</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b>
|
<b>initial_destination_concurrency</b>
|
||||||
Initial per-destination concurrency level for par-
|
Initial per-destination concurrency level for par-
|
||||||
allel delivery to the same destination.
|
allel delivery to the same destination.
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
|
<b>default_destination_concurrency_limit</b>
|
||||||
Default limit on the number of parallel deliveries
|
Default limit on the number of parallel deliveries
|
||||||
to the same destination.
|
to the same destination.
|
||||||
|
|
||||||
<i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
|
<i>transport</i><b>_destination_concurrency_limit</b>
|
||||||
Limit on the number of parallel deliveries to the
|
Limit on the number of parallel deliveries to the
|
||||||
same destination, for delivery via the named mes-
|
same destination, for delivery via the named mes-
|
||||||
sage <i>transport</i>.
|
sage <i>transport</i>.
|
||||||
|
|
||||||
<b>Recipient controls</b>
|
<b>Recipient controls</b>
|
||||||
<b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<b>default_destination_recipient_limit</b>
|
||||||
Default limit on the number of recipients per mes-
|
Default limit on the number of recipients per mes-
|
||||||
sage transfer.
|
sage transfer.
|
||||||
|
|
||||||
<i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<i>transport</i><b>_destination_recipient_limit</b>
|
||||||
Limit on the number of recipients per message
|
Limit on the number of recipients per message
|
||||||
transfer, for the named message <i>transport</i>.
|
transfer, for the named message <i>transport</i>.
|
||||||
|
|
||||||
<b>Message scheduling</b>
|
<b>Message scheduling</b>
|
||||||
<i>transport_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>cost</b> (valid range: 0,2,3...)
|
<i>transport</i><b>_delivery_slot_cost</b> (valid range: 0,2,3...)
|
||||||
This parameter basically controls how often a mes-
|
This parameter basically controls how often a mes-
|
||||||
sage delivered by <i>transport</i> can be preempted by
|
sage delivered by <i>transport</i> can be preempted by
|
||||||
another message. An internal per-message/transport
|
another message. An internal per-message/transport
|
||||||
counter is incremented by one for each <i>trans-</i>
|
counter is incremented by one for each <i>trans-</i>
|
||||||
<i>port_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>cost</b> deliveries handled by
|
<i>port</i><b>_delivery_slot_cost</b> deliveries handled by
|
||||||
<i>transport</i>. This counter represents the number of
|
<i>transport</i>. This counter represents the number of
|
||||||
"available delivery slots" for use by other mes-
|
"available delivery slots" for use by other mes-
|
||||||
sages. Current message can be preempted by another
|
sages. Current message can be preempted by another
|
||||||
@ -287,32 +291,32 @@ NQMGR(8) NQMGR(8)
|
|||||||
Value equal to 0 disables the message preemption
|
Value equal to 0 disables the message preemption
|
||||||
for <i>transport</i>.
|
for <i>transport</i>.
|
||||||
|
|
||||||
<i>transport_</i><b>minimum</b><i>_</i><b>delivery</b><i>_</i><b>slots</b>
|
<i>transport</i><b>_minimum_delivery_slots</b>
|
||||||
Message preemption is not attempted at all whenever
|
Message preemption is not attempted at all whenever
|
||||||
a message that can't ever accumulate at least
|
a message that can't ever accumulate at least
|
||||||
<i>transport_</i><b>minimum</b><i>_</i><b>delivery</b><i>_</i><b>slots</b> available delivery
|
<i>transport</i><b>_minimum_delivery_slots</b> available delivery
|
||||||
slots is being delivered by <i>transport</i>.
|
slots is being delivered by <i>transport</i>.
|
||||||
|
|
||||||
<i>transport_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>discount</b> (valid range: 0..100)
|
<i>transport</i><b>_delivery_slot_discount</b> (valid range: 0..100)
|
||||||
|
|
||||||
<i>transport_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>loan</b>
|
<i>transport</i><b>_delivery_slot_loan</b>
|
||||||
These parameters speed up the moment when a message
|
These parameters speed up the moment when a message
|
||||||
preemption can happen. Instead of waiting until
|
preemption can happen. Instead of waiting until
|
||||||
the full amount of delivery slots required is
|
the full amount of delivery slots required is
|
||||||
available, the preemption can happen when <i>trans-</i>
|
available, the preemption can happen when <i>trans-</i>
|
||||||
<i>port_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>discount</b> percent of the required
|
<i>port</i><b>_delivery_slot_discount</b> percent of the required
|
||||||
amount plus <i>transport_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>loan</b> still
|
amount plus <i>transport</i><b>_delivery_slot_loan</b> still
|
||||||
remains to be accumulated. Note that the full
|
remains to be accumulated. Note that the full
|
||||||
amount will still have to be accumulated before
|
amount will still have to be accumulated before
|
||||||
another preemption can take place later.
|
another preemption can take place later.
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>cost</b>
|
<b>default_delivery_slot_cost</b>
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>minimum</b><i>_</i><b>delivery</b><i>_</i><b>slots</b>
|
<b>default_minimum_delivery_slots</b>
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>discount</b>
|
<b>default_delivery_slot_discount</b>
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>delivery</b><i>_</i><b>slot</b><i>_</i><b>loan</b>
|
<b>default_delivery_slot_loan</b>
|
||||||
Default values for the transport specific parame-
|
Default values for the transport specific parame-
|
||||||
ters described above.
|
ters described above.
|
||||||
|
|
||||||
|
@ -84,8 +84,9 @@ POSTSUPER(1) POSTSUPER(1)
|
|||||||
|
|
||||||
Note: while mail is "on hold" it will not expire
|
Note: while mail is "on hold" it will not expire
|
||||||
when its time in the queue exceeds the <b>maxi-</b>
|
when its time in the queue exceeds the <b>maxi-</b>
|
||||||
<b>mal_queue_lifetime</b> setting. It becomes subject to
|
<b>mal_queue_lifetime</b> or <b>bounce_queue_lifetime</b> set-
|
||||||
expiration after it is released from "hold".
|
ting. It becomes subject to expiration after it is
|
||||||
|
released from "hold".
|
||||||
|
|
||||||
<b>-H</b> <i>queue</i><b>_</b><i>id</i>
|
<b>-H</b> <i>queue</i><b>_</b><i>id</i>
|
||||||
Release mail that was put "on hold". Move one mes-
|
Release mail that was put "on hold". Move one mes-
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<html> <head> </head> <body> <pre>
|
<html> <body> <pre>
|
||||||
QMGR(8) QMGR(8)
|
QMGR(8) QMGR(8)
|
||||||
|
|
||||||
<b>NAME</b>
|
<b>NAME</b>
|
||||||
@ -105,25 +105,25 @@ QMGR(8) QMGR(8)
|
|||||||
actions (the message is followed by the symbolic constant
|
actions (the message is followed by the symbolic constant
|
||||||
used internally by the software):
|
used internally by the software):
|
||||||
|
|
||||||
<b>D (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>DEFERRED)</b>
|
<b>D (QMGR_REQ_SCAN_DEFERRED)</b>
|
||||||
Start a deferred queue scan. If a deferred queue
|
Start a deferred queue scan. If a deferred queue
|
||||||
scan is already in progress, that scan will be
|
scan is already in progress, that scan will be
|
||||||
restarted as soon as it finishes.
|
restarted as soon as it finishes.
|
||||||
|
|
||||||
<b>I (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>INCOMING)</b>
|
<b>I (QMGR_REQ_SCAN_INCOMING)</b>
|
||||||
Start an incoming queue scan. If an incoming queue
|
Start an incoming queue scan. If an incoming queue
|
||||||
scan is already in progress, that scan will be
|
scan is already in progress, that scan will be
|
||||||
restarted as soon as it finishes.
|
restarted as soon as it finishes.
|
||||||
|
|
||||||
<b>A (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>ALL)</b>
|
<b>A (QMGR_REQ_SCAN_ALL)</b>
|
||||||
Ignore deferred queue file time stamps. The request
|
Ignore deferred queue file time stamps. The request
|
||||||
affects the next deferred queue scan.
|
affects the next deferred queue scan.
|
||||||
|
|
||||||
<b>F (QMGR</b><i>_</i><b>REQ</b><i>_</i><b>FLUSH</b><i>_</i><b>DEAD)</b>
|
<b>F (QMGR_REQ_FLUSH_DEAD)</b>
|
||||||
Purge all information about dead transports and
|
Purge all information about dead transports and
|
||||||
destinations.
|
destinations.
|
||||||
|
|
||||||
<b>W (TRIGGER</b><i>_</i><b>REQ</b><i>_</i><b>WAKEUP)</b>
|
<b>W (TRIGGER_REQ_WAKEUP)</b>
|
||||||
Wakeup call, This is used by the master server to
|
Wakeup call, This is used by the master server to
|
||||||
instantiate servers that should not go away for-
|
instantiate servers that should not go away for-
|
||||||
ever. The action is to start an incoming queue
|
ever. The action is to start an incoming queue
|
||||||
@ -152,7 +152,7 @@ QMGR(8) QMGR(8)
|
|||||||
Corrupted message files are saved to the <b>corrupt</b> queue for
|
Corrupted message files are saved to the <b>corrupt</b> queue for
|
||||||
further inspection.
|
further inspection.
|
||||||
|
|
||||||
Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
|
Depending on the setting of the <b>notify_classes</b> parameter,
|
||||||
the postmaster is notified of bounces and of other trou-
|
the postmaster is notified of bounces and of other trou-
|
||||||
ble.
|
ble.
|
||||||
|
|
||||||
@ -169,30 +169,30 @@ QMGR(8) QMGR(8)
|
|||||||
command after a configuration change.
|
command after a configuration change.
|
||||||
|
|
||||||
<b>Miscellaneous</b>
|
<b>Miscellaneous</b>
|
||||||
<b>allow</b><i>_</i><b>min</b><i>_</i><b>user</b>
|
<b>allow_min_user</b>
|
||||||
Do not bounce recipient addresses that begin with
|
Do not bounce recipient addresses that begin with
|
||||||
'-'.
|
'-'.
|
||||||
|
|
||||||
<b>queue</b><i>_</i><b>directory</b>
|
<b>queue_directory</b>
|
||||||
Top-level directory of the Postfix queue.
|
Top-level directory of the Postfix queue.
|
||||||
|
|
||||||
<b>Active queue controls</b>
|
<b>Active queue controls</b>
|
||||||
<b>qmgr</b><i>_</i><b>clog</b><i>_</i><b>warn</b><i>_</i><b>time</b>
|
<b>qmgr_clog_warn_time</b>
|
||||||
Minimal delay between warnings that a specific des-
|
Minimal delay between warnings that a specific des-
|
||||||
tination is clogging up the active queue. Specify 0
|
tination is clogging up the active queue. Specify 0
|
||||||
to disable.
|
to disable.
|
||||||
|
|
||||||
<b>qmgr</b><i>_</i><b>message</b><i>_</i><b>active</b><i>_</i><b>limit</b>
|
<b>qmgr_message_active_limit</b>
|
||||||
Limit the number of messages in the active queue.
|
Limit the number of messages in the active queue.
|
||||||
|
|
||||||
<b>qmgr</b><i>_</i><b>message</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<b>qmgr_message_recipient_limit</b>
|
||||||
Limit the number of in-memory recipients.
|
Limit the number of in-memory recipients.
|
||||||
|
|
||||||
This parameter also limits the size of the short-
|
This parameter also limits the size of the short-
|
||||||
term, in-memory destination cache.
|
term, in-memory destination cache.
|
||||||
|
|
||||||
<b>Timing controls</b>
|
<b>Timing controls</b>
|
||||||
<b>minimal</b><i>_</i><b>backoff</b><i>_</i><b>time</b>
|
<b>minimal_backoff_time</b>
|
||||||
Minimal time in seconds between delivery attempts
|
Minimal time in seconds between delivery attempts
|
||||||
of a deferred message.
|
of a deferred message.
|
||||||
|
|
||||||
@ -200,19 +200,23 @@ QMGR(8) QMGR(8)
|
|||||||
destination is kept in the short-term, in-memory
|
destination is kept in the short-term, in-memory
|
||||||
destination status cache.
|
destination status cache.
|
||||||
|
|
||||||
<b>maximal</b><i>_</i><b>backoff</b><i>_</i><b>time</b>
|
<b>maximal_backoff_time</b>
|
||||||
Maximal time in seconds between delivery attempts
|
Maximal time in seconds between delivery attempts
|
||||||
of a deferred message.
|
of a deferred message.
|
||||||
|
|
||||||
<b>maximal</b><i>_</i><b>queue</b><i>_</i><b>lifetime</b>
|
<b>maximal_queue_lifetime</b>
|
||||||
Maximal time in days a message is queued before it
|
Maximal time (default: in days) a regular message
|
||||||
is sent back as undeliverable.
|
is queued before it is considered undeliverable.
|
||||||
|
|
||||||
<b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
|
<b>bounce_queue_lifetime</b>
|
||||||
|
Maximal time (default: in days) a bounce message is
|
||||||
|
queued before it is considered undeliverable.
|
||||||
|
|
||||||
|
<b>queue_run_delay</b>
|
||||||
Time in seconds between deferred queue scans. Queue
|
Time in seconds between deferred queue scans. Queue
|
||||||
scans do not overlap.
|
scans do not overlap.
|
||||||
|
|
||||||
<b>transport</b><i>_</i><b>retry</b><i>_</i><b>time</b>
|
<b>transport_retry_time</b>
|
||||||
Time in seconds between attempts to contact a bro-
|
Time in seconds between attempts to contact a bro-
|
||||||
ken delivery transport.
|
ken delivery transport.
|
||||||
|
|
||||||
@ -220,7 +224,7 @@ QMGR(8) QMGR(8)
|
|||||||
In the text below, <i>transport</i> is the first field in a <b>mas-</b>
|
In the text below, <i>transport</i> is the first field in a <b>mas-</b>
|
||||||
<b>ter.cf</b> entry.
|
<b>ter.cf</b> entry.
|
||||||
|
|
||||||
<b>qmgr</b><i>_</i><b>fudge</b><i>_</i><b>factor</b> (valid range: 10..100)
|
<b>qmgr_fudge_factor</b> (valid range: 10..100)
|
||||||
The percentage of delivery resources that a busy
|
The percentage of delivery resources that a busy
|
||||||
mail system will use up for delivery of a large
|
mail system will use up for delivery of a large
|
||||||
mailing list message. With 100%, delivery of one
|
mailing list message. With 100%, delivery of one
|
||||||
@ -236,25 +240,25 @@ QMGR(8) QMGR(8)
|
|||||||
list receive that same burst of messages a whole
|
list receive that same burst of messages a whole
|
||||||
day later.
|
day later.
|
||||||
|
|
||||||
<b>initial</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b>
|
<b>initial_destination_concurrency</b>
|
||||||
Initial per-destination concurrency level for par-
|
Initial per-destination concurrency level for par-
|
||||||
allel delivery to the same destination.
|
allel delivery to the same destination.
|
||||||
|
|
||||||
<b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
|
<b>default_destination_concurrency_limit</b>
|
||||||
Default limit on the number of parallel deliveries
|
Default limit on the number of parallel deliveries
|
||||||
to the same destination.
|
to the same destination.
|
||||||
|
|
||||||
<i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
|
<i>transport</i><b>_destination_concurrency_limit</b>
|
||||||
Limit on the number of parallel deliveries to the
|
Limit on the number of parallel deliveries to the
|
||||||
same destination, for delivery via the named mes-
|
same destination, for delivery via the named mes-
|
||||||
sage <i>transport</i>.
|
sage <i>transport</i>.
|
||||||
|
|
||||||
<b>Recipient controls</b>
|
<b>Recipient controls</b>
|
||||||
<b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<b>default_destination_recipient_limit</b>
|
||||||
Default limit on the number of recipients per mes-
|
Default limit on the number of recipients per mes-
|
||||||
sage transfer.
|
sage transfer.
|
||||||
|
|
||||||
<i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
|
<i>transport</i><b>_destination_recipient_limit</b>
|
||||||
Limit on the number of recipients per message
|
Limit on the number of recipients per message
|
||||||
transfer, for the named message <i>transport</i>.
|
transfer, for the named message <i>transport</i>.
|
||||||
|
|
||||||
|
@ -307,6 +307,13 @@ immediately after the first unsuccessful delivery attempt.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
|
<dt> <b>bounce_queue_lifetime</b> (default: 2 days) <dd> How
|
||||||
|
long a bounce message stays in the queue before it is considered
|
||||||
|
undeliverable. Specify 0 for mail that should be returned
|
||||||
|
immediately after the first unsuccessful delivery attempt.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
<dt> <b>minimal_backoff_time</b> (default: 1000 seconds) <dd> The
|
<dt> <b>minimal_backoff_time</b> (default: 1000 seconds) <dd> The
|
||||||
minimal amount of time a message won't be looked at, and the minimal
|
minimal amount of time a message won't be looked at, and the minimal
|
||||||
amount of time to stay away from a "dead" destination.
|
amount of time to stay away from a "dead" destination.
|
||||||
|
@ -80,9 +80,9 @@ SMTPD(8) SMTPD(8)
|
|||||||
checking and without any state change. This list
|
checking and without any state change. This list
|
||||||
overrides built-in command definitions.
|
overrides built-in command definitions.
|
||||||
|
|
||||||
<b>Content inspection controls</b>
|
<b>Content inspection after mail is queued</b>
|
||||||
Optionally, Postfix can be configured to send new mail to
|
Postfix can be configured to send new mail to an external
|
||||||
external content filter software AFTER the mail is queued.
|
content filter AFTER the mail is queued.
|
||||||
|
|
||||||
<b>content_filter</b>
|
<b>content_filter</b>
|
||||||
The name of a mail delivery transport that filters
|
The name of a mail delivery transport that filters
|
||||||
@ -114,22 +114,22 @@ SMTPD(8) SMTPD(8)
|
|||||||
cally specified with the SMTP server <b>after</b>
|
cally specified with the SMTP server <b>after</b>
|
||||||
an external content filter.
|
an external content filter.
|
||||||
|
|
||||||
<b>Pass-through proxy</b>
|
<b>Content inspection before mail is queued</b>
|
||||||
Optionally, the Postfix SMTP server can be configured to
|
The Postfix SMTP server can be configured to forward all
|
||||||
forward all mail to a proxy server, for example a real-
|
mail to a real-time SMTP-based content filter BEFORE mail
|
||||||
time content filter, BEFORE mail is queued.
|
is queued.
|
||||||
|
|
||||||
<b>smtpd_proxy_filter</b>
|
<b>smtpd_proxy_filter</b>
|
||||||
The <i>host:port</i> of the SMTP proxy server. The <i>host</i> or
|
The <i>host:port</i> of the real-time SMTP-based content
|
||||||
<i>host:</i> portion is optional.
|
filter. The <i>host</i> or <i>host:</i> portion is optional.
|
||||||
|
|
||||||
<b>smtpd_proxy_timeout</b>
|
<b>smtpd_proxy_timeout</b>
|
||||||
Timeout for connecting to, sending to and receiving
|
Timeout for connecting to, sending to and receiving
|
||||||
from the SMTP proxy server.
|
from the real-time SMTP-based content filter.
|
||||||
|
|
||||||
<b>smtpd_proxy_ehlo</b>
|
<b>smtpd_proxy_ehlo</b>
|
||||||
The hostname to use when sending an EHLO command to
|
The hostname to use when sending an EHLO command to
|
||||||
the SMTP proxy server.
|
the real-time SMTP-based content filter.
|
||||||
|
|
||||||
<b>Authentication controls</b>
|
<b>Authentication controls</b>
|
||||||
<b>smtpd_sasl_auth_enable</b>
|
<b>smtpd_sasl_auth_enable</b>
|
||||||
|
@ -89,8 +89,8 @@ case.
|
|||||||
.sp
|
.sp
|
||||||
Note: while mail is "on hold" it will not expire when its
|
Note: while mail is "on hold" it will not expire when its
|
||||||
time in the queue exceeds the \fBmaximal_queue_lifetime\fR
|
time in the queue exceeds the \fBmaximal_queue_lifetime\fR
|
||||||
setting. It becomes subject to expiration after it is
|
or \fBbounce_queue_lifetime\fR setting. It becomes subject to
|
||||||
released from "hold".
|
expiration after it is released from "hold".
|
||||||
.IP "\fB-H \fIqueue_id\fR"
|
.IP "\fB-H \fIqueue_id\fR"
|
||||||
Release mail that was put "on hold".
|
Release mail that was put "on hold".
|
||||||
Move one message with the named queue ID from the named
|
Move one message with the named queue ID from the named
|
||||||
|
@ -217,8 +217,11 @@ is kept in the short-term, in-memory destination status cache.
|
|||||||
Maximal time in seconds between delivery attempts
|
Maximal time in seconds between delivery attempts
|
||||||
of a deferred message.
|
of a deferred message.
|
||||||
.IP \fBmaximal_queue_lifetime\fR
|
.IP \fBmaximal_queue_lifetime\fR
|
||||||
Maximal time in days a message is queued
|
Maximal time (default: in days) a regular message is queued
|
||||||
before it is sent back as undeliverable.
|
before it is considered undeliverable.
|
||||||
|
.IP \fBbounce_queue_lifetime\fR
|
||||||
|
Maximal time (default: in days) a bounce message is queued
|
||||||
|
before it is considered undeliverable.
|
||||||
.IP \fBqueue_run_delay\fR
|
.IP \fBqueue_run_delay\fR
|
||||||
Time in seconds between deferred queue scans. Queue scans do
|
Time in seconds between deferred queue scans. Queue scans do
|
||||||
not overlap.
|
not overlap.
|
||||||
|
@ -198,8 +198,11 @@ is kept in the short-term, in-memory destination status cache.
|
|||||||
Maximal time in seconds between delivery attempts
|
Maximal time in seconds between delivery attempts
|
||||||
of a deferred message.
|
of a deferred message.
|
||||||
.IP \fBmaximal_queue_lifetime\fR
|
.IP \fBmaximal_queue_lifetime\fR
|
||||||
Maximal time in days a message is queued
|
Maximal time (default: in days) a regular message is queued
|
||||||
before it is sent back as undeliverable.
|
before it is considered undeliverable.
|
||||||
|
.IP \fBbounce_queue_lifetime\fR
|
||||||
|
Maximal time (default: in days) a bounce message is queued
|
||||||
|
before it is considered undeliverable.
|
||||||
.IP \fBqueue_run_delay\fR
|
.IP \fBqueue_run_delay\fR
|
||||||
Time in seconds between deferred queue scans. Queue scans do
|
Time in seconds between deferred queue scans. Queue scans do
|
||||||
not overlap.
|
not overlap.
|
||||||
|
@ -85,9 +85,11 @@ offered by an SMTP server.
|
|||||||
List of commands that are treated as NOOP (no operation) commands,
|
List of commands that are treated as NOOP (no operation) commands,
|
||||||
without any parameter syntax checking and without any state change.
|
without any parameter syntax checking and without any state change.
|
||||||
This list overrides built-in command definitions.
|
This list overrides built-in command definitions.
|
||||||
.SH "Content inspection controls"
|
.SH "Content inspection after mail is queued"
|
||||||
Optionally, Postfix can be configured to send new mail to
|
.ad
|
||||||
external content filter software AFTER the mail is queued.
|
.fi
|
||||||
|
Postfix can be configured to send new mail to an external
|
||||||
|
content filter AFTER the mail is queued.
|
||||||
.IP \fBcontent_filter\fR
|
.IP \fBcontent_filter\fR
|
||||||
The name of a mail delivery transport that filters mail and that
|
The name of a mail delivery transport that filters mail and that
|
||||||
either bounces mail or re-injects the result back into Postfix.
|
either bounces mail or re-injects the result back into Postfix.
|
||||||
@ -110,22 +112,20 @@ content filter.
|
|||||||
Disable header/body_checks. This is typically specified with the
|
Disable header/body_checks. This is typically specified with the
|
||||||
SMTP server \fBafter\fR an external content filter.
|
SMTP server \fBafter\fR an external content filter.
|
||||||
.RE
|
.RE
|
||||||
.SH "Pass-through proxy"
|
.SH "Content inspection before mail is queued"
|
||||||
.ad
|
.ad
|
||||||
.fi
|
.fi
|
||||||
.ad
|
The Postfix SMTP server can be configured to forward all mail
|
||||||
Optionally, the Postfix SMTP server can be configured to
|
to a real-time SMTP-based content filter BEFORE mail is queued.
|
||||||
forward all mail to a proxy server, for example a real-time
|
|
||||||
content filter, BEFORE mail is queued.
|
|
||||||
.IP \fBsmtpd_proxy_filter\fR
|
.IP \fBsmtpd_proxy_filter\fR
|
||||||
The \fIhost:port\fR of the SMTP proxy server. The \fIhost\fR
|
The \fIhost:port\fR of the real-time SMTP-based content filter.
|
||||||
or \fIhost:\fR portion is optional.
|
The \fIhost\fR or \fIhost:\fR portion is optional.
|
||||||
.IP \fBsmtpd_proxy_timeout\fR
|
.IP \fBsmtpd_proxy_timeout\fR
|
||||||
Timeout for connecting to, sending to and receiving from
|
Timeout for connecting to, sending to and receiving from
|
||||||
the SMTP proxy server.
|
the real-time SMTP-based content filter.
|
||||||
.IP \fBsmtpd_proxy_ehlo\fR
|
.IP \fBsmtpd_proxy_ehlo\fR
|
||||||
The hostname to use when sending an EHLO command to the
|
The hostname to use when sending an EHLO command to the
|
||||||
SMTP proxy server.
|
real-time SMTP-based content filter.
|
||||||
.SH "Authentication controls"
|
.SH "Authentication controls"
|
||||||
.IP \fBsmtpd_sasl_auth_enable\fR
|
.IP \fBsmtpd_sasl_auth_enable\fR
|
||||||
Enable per-session authentication as per RFC 2554 (SASL).
|
Enable per-session authentication as per RFC 2554 (SASL).
|
||||||
|
@ -548,6 +548,10 @@ extern int var_max_backoff_time;
|
|||||||
#define DEF_MAX_QUEUE_TIME "5d"
|
#define DEF_MAX_QUEUE_TIME "5d"
|
||||||
extern int var_max_queue_time;
|
extern int var_max_queue_time;
|
||||||
|
|
||||||
|
#define VAR_DSN_QUEUE_TIME "bounce_queue_lifetime"
|
||||||
|
#define DEF_DSN_QUEUE_TIME "$" VAR_MAX_QUEUE_TIME
|
||||||
|
extern int var_dsn_queue_time;
|
||||||
|
|
||||||
#define VAR_DELAY_WARN_TIME "delay_warning_time"
|
#define VAR_DELAY_WARN_TIME "delay_warning_time"
|
||||||
#define DEF_DELAY_WARN_TIME "0h"
|
#define DEF_DELAY_WARN_TIME "0h"
|
||||||
extern int var_delay_warn_time;
|
extern int var_delay_warn_time;
|
||||||
@ -1760,7 +1764,7 @@ extern int var_verify_pos_try;
|
|||||||
extern int var_verify_neg_exp;
|
extern int var_verify_neg_exp;
|
||||||
|
|
||||||
#define VAR_VERIFY_NEG_TRY "address_verify_negative_refresh_time"
|
#define VAR_VERIFY_NEG_TRY "address_verify_negative_refresh_time"
|
||||||
#define DEF_VERIFY_NEG_TRY "2h"
|
#define DEF_VERIFY_NEG_TRY "3h"
|
||||||
extern int var_verify_neg_try;
|
extern int var_verify_neg_try;
|
||||||
|
|
||||||
#define VAR_VERIFY_NEG_CACHE "address_verify_negative_cache"
|
#define VAR_VERIFY_NEG_CACHE "address_verify_negative_cache"
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Patches change the patchlevel and the release date. Snapshots change the
|
* Patches change the patchlevel and the release date. Snapshots change the
|
||||||
* release date only, unless they include the same bugfix as a patch release.
|
* release date only, unless they include the same bugfix as a patch release.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20031224"
|
#define MAIL_RELEASE_DATE "20031226"
|
||||||
|
|
||||||
#define VAR_MAIL_VERSION "mail_version"
|
#define VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE
|
#define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE
|
||||||
|
@ -166,15 +166,26 @@ void resolve_clnt(const char *class, const char *addr, RESOLVE_REPLY *reply)
|
|||||||
/*
|
/*
|
||||||
* Peek at the cache.
|
* Peek at the cache.
|
||||||
*/
|
*/
|
||||||
|
#define IFSET(flag, text) ((reply->flags & (flag)) ? (text) : "")
|
||||||
|
|
||||||
if (*addr && strcmp(addr, STR(last_addr)) == 0) {
|
if (*addr && strcmp(addr, STR(last_addr)) == 0) {
|
||||||
vstring_strcpy(reply->transport, STR(last_reply.transport));
|
vstring_strcpy(reply->transport, STR(last_reply.transport));
|
||||||
vstring_strcpy(reply->nexthop, STR(last_reply.nexthop));
|
vstring_strcpy(reply->nexthop, STR(last_reply.nexthop));
|
||||||
vstring_strcpy(reply->recipient, STR(last_reply.recipient));
|
vstring_strcpy(reply->recipient, STR(last_reply.recipient));
|
||||||
reply->flags = last_reply.flags;
|
reply->flags = last_reply.flags;
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: cached: `%s' -> t=`%s' h=`%s' r=`%s'",
|
msg_info("%s: cached: `%s' -> transp=`%s' host=`%s' rcpt=`%s' flags=%s%s%s%s class=%s%s%s%s%s",
|
||||||
myname, addr, STR(reply->transport),
|
myname, addr, STR(reply->transport),
|
||||||
STR(reply->nexthop), STR(reply->recipient));
|
STR(reply->nexthop), STR(reply->recipient),
|
||||||
|
IFSET(RESOLVE_FLAG_FINAL, "final"),
|
||||||
|
IFSET(RESOLVE_FLAG_ROUTED, "routed"),
|
||||||
|
IFSET(RESOLVE_FLAG_ERROR, "error"),
|
||||||
|
IFSET(RESOLVE_FLAG_FAIL, "fail"),
|
||||||
|
IFSET(RESOLVE_CLASS_LOCAL, "local"),
|
||||||
|
IFSET(RESOLVE_CLASS_ALIAS, "alias"),
|
||||||
|
IFSET(RESOLVE_CLASS_VIRTUAL, "virtual"),
|
||||||
|
IFSET(RESOLVE_CLASS_RELAY, "relay"),
|
||||||
|
IFSET(RESOLVE_CLASS_DEFAULT, "default"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,9 +219,18 @@ void resolve_clnt(const char *class, const char *addr, RESOLVE_REPLY *reply)
|
|||||||
var_rewrite_service);
|
var_rewrite_service);
|
||||||
} else {
|
} else {
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: `%s' -> t=`%s' h=`%s' r=`%s'",
|
msg_info("%s: `%s' -> transp=`%s' host=`%s' rcpt=`%s' flags=%s%s%s%s class=%s%s%s%s%s",
|
||||||
myname, addr, STR(reply->transport),
|
myname, addr, STR(reply->transport),
|
||||||
STR(reply->nexthop), STR(reply->recipient));
|
STR(reply->nexthop), STR(reply->recipient),
|
||||||
|
IFSET(RESOLVE_FLAG_FINAL, "final"),
|
||||||
|
IFSET(RESOLVE_FLAG_ROUTED, "routed"),
|
||||||
|
IFSET(RESOLVE_FLAG_ERROR, "error"),
|
||||||
|
IFSET(RESOLVE_FLAG_FAIL, "fail"),
|
||||||
|
IFSET(RESOLVE_CLASS_LOCAL, "local"),
|
||||||
|
IFSET(RESOLVE_CLASS_ALIAS, "alias"),
|
||||||
|
IFSET(RESOLVE_CLASS_VIRTUAL, "virtual"),
|
||||||
|
IFSET(RESOLVE_CLASS_RELAY, "relay"),
|
||||||
|
IFSET(RESOLVE_CLASS_DEFAULT, "default"));
|
||||||
if (STR(reply->transport)[0] == 0)
|
if (STR(reply->transport)[0] == 0)
|
||||||
msg_warn("%s: null transport result for: <%s>", myname, addr);
|
msg_warn("%s: null transport result for: <%s>", myname, addr);
|
||||||
else if (STR(reply->recipient)[0] == 0 && *addr != 0)
|
else if (STR(reply->recipient)[0] == 0 && *addr != 0)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
SRCS = master.c master_conf.c master_ent.c master_sig.c master_avail.c \
|
SRCS = master.c master_conf.c master_ent.c master_sig.c master_avail.c \
|
||||||
master_spawn.c master_service.c master_status.o master_listen.c \
|
master_spawn.c master_service.c master_status.c master_listen.c \
|
||||||
master_proto.c single_server.c multi_server.c master_vars.c \
|
master_proto.c single_server.c multi_server.c master_vars.c \
|
||||||
master_wakeup.c master_flow.c mail_flow.c
|
master_wakeup.c master_flow.c mail_flow.c
|
||||||
OBJS = master.o master_conf.o master_ent.o master_sig.o master_avail.o \
|
OBJS = master.o master_conf.o master_ent.o master_sig.o master_avail.o \
|
||||||
|
@ -106,10 +106,6 @@ extern void master_refresh(void);
|
|||||||
/*
|
/*
|
||||||
* master_vars.c
|
* master_vars.c
|
||||||
*/
|
*/
|
||||||
extern char *var_program_dir;
|
|
||||||
extern int var_proc_limit;
|
|
||||||
extern int var_use_limit;
|
|
||||||
extern int var_idle_limit;
|
|
||||||
extern void master_vars_init(void);
|
extern void master_vars_init(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -193,8 +193,11 @@
|
|||||||
/* Maximal time in seconds between delivery attempts
|
/* Maximal time in seconds between delivery attempts
|
||||||
/* of a deferred message.
|
/* of a deferred message.
|
||||||
/* .IP \fBmaximal_queue_lifetime\fR
|
/* .IP \fBmaximal_queue_lifetime\fR
|
||||||
/* Maximal time in days a message is queued
|
/* Maximal time (default: in days) a regular message is queued
|
||||||
/* before it is sent back as undeliverable.
|
/* before it is considered undeliverable.
|
||||||
|
/* .IP \fBbounce_queue_lifetime\fR
|
||||||
|
/* Maximal time (default: in days) a bounce message is queued
|
||||||
|
/* before it is considered undeliverable.
|
||||||
/* .IP \fBqueue_run_delay\fR
|
/* .IP \fBqueue_run_delay\fR
|
||||||
/* Time in seconds between deferred queue scans. Queue scans do
|
/* Time in seconds between deferred queue scans. Queue scans do
|
||||||
/* not overlap.
|
/* not overlap.
|
||||||
@ -314,6 +317,7 @@ int var_queue_run_delay;
|
|||||||
int var_min_backoff_time;
|
int var_min_backoff_time;
|
||||||
int var_max_backoff_time;
|
int var_max_backoff_time;
|
||||||
int var_max_queue_time;
|
int var_max_queue_time;
|
||||||
|
int var_dsn_queue_time;
|
||||||
int var_qmgr_active_limit;
|
int var_qmgr_active_limit;
|
||||||
int var_qmgr_rcpt_limit;
|
int var_qmgr_rcpt_limit;
|
||||||
int var_qmgr_msg_rcpt_limit;
|
int var_qmgr_msg_rcpt_limit;
|
||||||
@ -529,6 +533,7 @@ int main(int argc, char **argv)
|
|||||||
VAR_MIN_BACKOFF_TIME, DEF_MIN_BACKOFF_TIME, &var_min_backoff_time, 1, 0,
|
VAR_MIN_BACKOFF_TIME, DEF_MIN_BACKOFF_TIME, &var_min_backoff_time, 1, 0,
|
||||||
VAR_MAX_BACKOFF_TIME, DEF_MAX_BACKOFF_TIME, &var_max_backoff_time, 1, 0,
|
VAR_MAX_BACKOFF_TIME, DEF_MAX_BACKOFF_TIME, &var_max_backoff_time, 1, 0,
|
||||||
VAR_MAX_QUEUE_TIME, DEF_MAX_QUEUE_TIME, &var_max_queue_time, 0, 8640000,
|
VAR_MAX_QUEUE_TIME, DEF_MAX_QUEUE_TIME, &var_max_queue_time, 0, 8640000,
|
||||||
|
VAR_DSN_QUEUE_TIME, DEF_DSN_QUEUE_TIME, &var_dsn_queue_time, 0, 8640000,
|
||||||
VAR_XPORT_RETRY_TIME, DEF_XPORT_RETRY_TIME, &var_transport_retry_time, 1, 0,
|
VAR_XPORT_RETRY_TIME, DEF_XPORT_RETRY_TIME, &var_transport_retry_time, 1, 0,
|
||||||
VAR_QMGR_CLOG_WARN_TIME, DEF_QMGR_CLOG_WARN_TIME, &var_qmgr_clog_warn_time, 0, 0,
|
VAR_QMGR_CLOG_WARN_TIME, DEF_QMGR_CLOG_WARN_TIME, &var_qmgr_clog_warn_time, 0, 0,
|
||||||
0,
|
0,
|
||||||
|
@ -378,7 +378,8 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
|
|||||||
* daemon waits for the qmgr to accept the "new mail" trigger.
|
* daemon waits for the qmgr to accept the "new mail" trigger.
|
||||||
*/
|
*/
|
||||||
if (message->flags) {
|
if (message->flags) {
|
||||||
if (event_time() >= message->arrival_time + var_max_queue_time) {
|
if (event_time() >= message->arrival_time +
|
||||||
|
(*message->sender ? var_max_queue_time : var_dsn_queue_time)) {
|
||||||
msg_info("%s: from=<%s>, status=expired, returned to sender",
|
msg_info("%s: from=<%s>, status=expired, returned to sender",
|
||||||
message->queue_id, message->sender);
|
message->queue_id, message->sender);
|
||||||
if (message->verp_delims == 0 || var_verp_bounce_off)
|
if (message->verp_delims == 0 || var_verp_bounce_off)
|
||||||
|
@ -83,8 +83,8 @@
|
|||||||
/* .sp
|
/* .sp
|
||||||
/* Note: while mail is "on hold" it will not expire when its
|
/* Note: while mail is "on hold" it will not expire when its
|
||||||
/* time in the queue exceeds the \fBmaximal_queue_lifetime\fR
|
/* time in the queue exceeds the \fBmaximal_queue_lifetime\fR
|
||||||
/* setting. It becomes subject to expiration after it is
|
/* or \fBbounce_queue_lifetime\fR setting. It becomes subject to
|
||||||
/* released from "hold".
|
/* expiration after it is released from "hold".
|
||||||
/* .IP "\fB-H \fIqueue_id\fR"
|
/* .IP "\fB-H \fIqueue_id\fR"
|
||||||
/* Release mail that was put "on hold".
|
/* Release mail that was put "on hold".
|
||||||
/* Move one message with the named queue ID from the named
|
/* Move one message with the named queue ID from the named
|
||||||
|
@ -174,8 +174,11 @@
|
|||||||
/* Maximal time in seconds between delivery attempts
|
/* Maximal time in seconds between delivery attempts
|
||||||
/* of a deferred message.
|
/* of a deferred message.
|
||||||
/* .IP \fBmaximal_queue_lifetime\fR
|
/* .IP \fBmaximal_queue_lifetime\fR
|
||||||
/* Maximal time in days a message is queued
|
/* Maximal time (default: in days) a regular message is queued
|
||||||
/* before it is sent back as undeliverable.
|
/* before it is considered undeliverable.
|
||||||
|
/* .IP \fBbounce_queue_lifetime\fR
|
||||||
|
/* Maximal time (default: in days) a bounce message is queued
|
||||||
|
/* before it is considered undeliverable.
|
||||||
/* .IP \fBqueue_run_delay\fR
|
/* .IP \fBqueue_run_delay\fR
|
||||||
/* Time in seconds between deferred queue scans. Queue scans do
|
/* Time in seconds between deferred queue scans. Queue scans do
|
||||||
/* not overlap.
|
/* not overlap.
|
||||||
@ -269,6 +272,7 @@ int var_queue_run_delay;
|
|||||||
int var_min_backoff_time;
|
int var_min_backoff_time;
|
||||||
int var_max_backoff_time;
|
int var_max_backoff_time;
|
||||||
int var_max_queue_time;
|
int var_max_queue_time;
|
||||||
|
int var_dsn_queue_time;
|
||||||
int var_qmgr_active_limit;
|
int var_qmgr_active_limit;
|
||||||
int var_qmgr_rcpt_limit;
|
int var_qmgr_rcpt_limit;
|
||||||
int var_init_dest_concurrency;
|
int var_init_dest_concurrency;
|
||||||
@ -481,6 +485,7 @@ int main(int argc, char **argv)
|
|||||||
VAR_MIN_BACKOFF_TIME, DEF_MIN_BACKOFF_TIME, &var_min_backoff_time, 1, 0,
|
VAR_MIN_BACKOFF_TIME, DEF_MIN_BACKOFF_TIME, &var_min_backoff_time, 1, 0,
|
||||||
VAR_MAX_BACKOFF_TIME, DEF_MAX_BACKOFF_TIME, &var_max_backoff_time, 1, 0,
|
VAR_MAX_BACKOFF_TIME, DEF_MAX_BACKOFF_TIME, &var_max_backoff_time, 1, 0,
|
||||||
VAR_MAX_QUEUE_TIME, DEF_MAX_QUEUE_TIME, &var_max_queue_time, 0, 8640000,
|
VAR_MAX_QUEUE_TIME, DEF_MAX_QUEUE_TIME, &var_max_queue_time, 0, 8640000,
|
||||||
|
VAR_DSN_QUEUE_TIME, DEF_DSN_QUEUE_TIME, &var_dsn_queue_time, 0, 8640000,
|
||||||
VAR_XPORT_RETRY_TIME, DEF_XPORT_RETRY_TIME, &var_transport_retry_time, 1, 0,
|
VAR_XPORT_RETRY_TIME, DEF_XPORT_RETRY_TIME, &var_transport_retry_time, 1, 0,
|
||||||
VAR_QMGR_CLOG_WARN_TIME, DEF_QMGR_CLOG_WARN_TIME, &var_qmgr_clog_warn_time, 0, 0,
|
VAR_QMGR_CLOG_WARN_TIME, DEF_QMGR_CLOG_WARN_TIME, &var_qmgr_clog_warn_time, 0, 0,
|
||||||
0,
|
0,
|
||||||
|
@ -378,7 +378,8 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
|
|||||||
* daemon waits for the qmgr to accept the "new mail" trigger.
|
* daemon waits for the qmgr to accept the "new mail" trigger.
|
||||||
*/
|
*/
|
||||||
if (message->flags) {
|
if (message->flags) {
|
||||||
if (event_time() >= message->arrival_time + var_max_queue_time) {
|
if (event_time() >= message->arrival_time +
|
||||||
|
(*message->sender ? var_max_queue_time : var_dsn_queue_time)) {
|
||||||
msg_info("%s: from=<%s>, status=expired, returned to sender",
|
msg_info("%s: from=<%s>, status=expired, returned to sender",
|
||||||
message->queue_id, message->sender);
|
message->queue_id, message->sender);
|
||||||
if (message->verp_delims == 0 || var_verp_bounce_off)
|
if (message->verp_delims == 0 || var_verp_bounce_off)
|
||||||
|
@ -419,8 +419,8 @@ static void smtp_service(VSTREAM *client_stream, char *unused_service, char **ar
|
|||||||
static void pre_init(char *unused_name, char **unused_argv)
|
static void pre_init(char *unused_name, char **unused_argv)
|
||||||
{
|
{
|
||||||
static NAME_MASK lookup_masks[] = {
|
static NAME_MASK lookup_masks[] = {
|
||||||
SMTP_HOST_LOOKUP_DNS, SMTP_MASK_DNS,
|
SMTP_HOST_LOOKUP_DNS, SMTP_HOST_FLAG_DNS,
|
||||||
SMTP_HOST_LOOKUP_NATIVE, SMTP_MASK_NATIVE,
|
SMTP_HOST_LOOKUP_NATIVE, SMTP_HOST_FLAG_NATIVE,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -433,7 +433,7 @@ static void pre_init(char *unused_name, char **unused_argv)
|
|||||||
* Select hostname lookup mechanisms.
|
* Select hostname lookup mechanisms.
|
||||||
*/
|
*/
|
||||||
if (var_disable_dns)
|
if (var_disable_dns)
|
||||||
smtp_host_lookup_mask = SMTP_MASK_NATIVE;
|
smtp_host_lookup_mask = SMTP_HOST_FLAG_NATIVE;
|
||||||
else
|
else
|
||||||
smtp_host_lookup_mask = name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks,
|
smtp_host_lookup_mask = name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks,
|
||||||
var_smtp_host_lookup);
|
var_smtp_host_lookup);
|
||||||
|
@ -82,20 +82,27 @@ typedef struct SMTP_STATE {
|
|||||||
#define SMTP_FEATURE_XFORWARD_PROTO (1<<9)
|
#define SMTP_FEATURE_XFORWARD_PROTO (1<<9)
|
||||||
#define SMTP_FEATURE_XFORWARD_HELO (1<<10)
|
#define SMTP_FEATURE_XFORWARD_HELO (1<<10)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Misc flags.
|
||||||
|
*/
|
||||||
|
#define SMTP_MISC_FLAG_LOOP_DETECT (1<<0)
|
||||||
|
|
||||||
|
#define SMTP_MISC_FLAG_DEFAULT SMTP_MISC_FLAG_LOOP_DETECT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* smtp.c
|
* smtp.c
|
||||||
*/
|
*/
|
||||||
extern int smtp_errno; /* XXX can we get rid of this? */
|
extern int smtp_errno; /* XXX can we get rid of this? */
|
||||||
|
|
||||||
#define SMTP_NONE 0 /* no error */
|
#define SMTP_ERR_NONE 0 /* no error */
|
||||||
#define SMTP_FAIL 1 /* permanent error */
|
#define SMTP_ERR_FAIL 1 /* permanent error */
|
||||||
#define SMTP_RETRY 2 /* temporary error */
|
#define SMTP_ERR_RETRY 2 /* temporary error */
|
||||||
#define SMTP_LOOP 3 /* MX loop */
|
#define SMTP_ERR_LOOP 3 /* mailer loop */
|
||||||
|
|
||||||
extern int smtp_host_lookup_mask; /* host lookup methods to use */
|
extern int smtp_host_lookup_mask; /* host lookup methods to use */
|
||||||
|
|
||||||
#define SMTP_MASK_DNS (1<<0)
|
#define SMTP_HOST_FLAG_DNS (1<<0)
|
||||||
#define SMTP_MASK_NATIVE (1<<1)
|
#define SMTP_HOST_FLAG_NATIVE (1<<1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* smtp_session.c
|
* smtp_session.c
|
||||||
@ -119,7 +126,7 @@ extern int smtp_connect(SMTP_STATE *);
|
|||||||
/*
|
/*
|
||||||
* smtp_proto.c
|
* smtp_proto.c
|
||||||
*/
|
*/
|
||||||
extern int smtp_helo(SMTP_STATE *);
|
extern int smtp_helo(SMTP_STATE *, int);
|
||||||
extern int smtp_xfer(SMTP_STATE *);
|
extern int smtp_xfer(SMTP_STATE *);
|
||||||
extern void smtp_quit(SMTP_STATE *);
|
extern void smtp_quit(SMTP_STATE *);
|
||||||
|
|
||||||
|
@ -6,12 +6,14 @@
|
|||||||
/* SYNOPSIS
|
/* SYNOPSIS
|
||||||
/* #include "smtp_addr.h"
|
/* #include "smtp_addr.h"
|
||||||
/*
|
/*
|
||||||
/* DNS_RR *smtp_domain_addr(name, why)
|
/* DNS_RR *smtp_domain_addr(name, misc_flags, why)
|
||||||
/* char *name;
|
/* char *name;
|
||||||
|
/* int misc_flags;
|
||||||
/* VSTRING *why;
|
/* VSTRING *why;
|
||||||
/*
|
/*
|
||||||
/* DNS_RR *smtp_host_addr(name, why)
|
/* DNS_RR *smtp_host_addr(name, misc_flags, why)
|
||||||
/* char *name;
|
/* char *name;
|
||||||
|
/* int misc_flags;
|
||||||
/* VSTRING *why;
|
/* VSTRING *why;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* This module implements Internet address lookups. By default,
|
/* This module implements Internet address lookups. By default,
|
||||||
@ -173,7 +175,7 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI
|
|||||||
/*
|
/*
|
||||||
* Use DNS lookup, but keep the option open to use native name service.
|
* Use DNS lookup, but keep the option open to use native name service.
|
||||||
*/
|
*/
|
||||||
if (smtp_host_lookup_mask & SMTP_MASK_DNS) {
|
if (smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS) {
|
||||||
switch (dns_lookup(host, T_A, RES_DEFNAMES, &addr, (VSTRING *) 0, why)) {
|
switch (dns_lookup(host, T_A, RES_DEFNAMES, &addr, (VSTRING *) 0, why)) {
|
||||||
case DNS_OK:
|
case DNS_OK:
|
||||||
for (rr = addr; rr; rr = rr->next)
|
for (rr = addr; rr; rr = rr->next)
|
||||||
@ -181,15 +183,15 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI
|
|||||||
addr_list = dns_rr_append(addr_list, addr);
|
addr_list = dns_rr_append(addr_list, addr);
|
||||||
return (addr_list);
|
return (addr_list);
|
||||||
default:
|
default:
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
return (addr_list);
|
return (addr_list);
|
||||||
case DNS_FAIL:
|
case DNS_FAIL:
|
||||||
if (smtp_errno != SMTP_RETRY)
|
if (smtp_errno != SMTP_ERR_RETRY)
|
||||||
smtp_errno = SMTP_FAIL;
|
smtp_errno = SMTP_ERR_FAIL;
|
||||||
return (addr_list);
|
return (addr_list);
|
||||||
case DNS_NOTFOUND:
|
case DNS_NOTFOUND:
|
||||||
if (smtp_errno != SMTP_RETRY)
|
if (smtp_errno != SMTP_ERR_RETRY)
|
||||||
smtp_errno = SMTP_FAIL;
|
smtp_errno = SMTP_ERR_FAIL;
|
||||||
/* maybe gethostbyname() will succeed */
|
/* maybe gethostbyname() will succeed */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -198,18 +200,19 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI
|
|||||||
/*
|
/*
|
||||||
* Use the native name service which also looks in /etc/hosts.
|
* Use the native name service which also looks in /etc/hosts.
|
||||||
*/
|
*/
|
||||||
if (smtp_host_lookup_mask & SMTP_MASK_NATIVE) {
|
if (smtp_host_lookup_mask & SMTP_HOST_FLAG_NATIVE) {
|
||||||
memset((char *) &fixed, 0, sizeof(fixed));
|
memset((char *) &fixed, 0, sizeof(fixed));
|
||||||
if ((hp = gethostbyname(host)) == 0) {
|
if ((hp = gethostbyname(host)) == 0) {
|
||||||
vstring_sprintf(why, "%s: %s", host, HSTRERROR(h_errno));
|
vstring_sprintf(why, "%s: %s", host, HSTRERROR(h_errno));
|
||||||
if (smtp_errno != SMTP_RETRY)
|
if (smtp_errno != SMTP_ERR_RETRY)
|
||||||
smtp_errno = (h_errno == TRY_AGAIN ? SMTP_RETRY : SMTP_FAIL);
|
smtp_errno =
|
||||||
|
(h_errno == TRY_AGAIN ? SMTP_ERR_RETRY : SMTP_ERR_FAIL);
|
||||||
} else if (hp->h_addrtype != AF_INET) {
|
} else if (hp->h_addrtype != AF_INET) {
|
||||||
vstring_sprintf(why, "%s: host not found", host);
|
vstring_sprintf(why, "%s: host not found", host);
|
||||||
msg_warn("%s: unknown address family %d for %s",
|
msg_warn("%s: unknown address family %d for %s",
|
||||||
myname, hp->h_addrtype, host);
|
myname, hp->h_addrtype, host);
|
||||||
if (smtp_errno != SMTP_RETRY)
|
if (smtp_errno != SMTP_ERR_RETRY)
|
||||||
smtp_errno = SMTP_FAIL;
|
smtp_errno = SMTP_ERR_FAIL;
|
||||||
} else {
|
} else {
|
||||||
while (hp->h_addr_list[0]) {
|
while (hp->h_addr_list[0]) {
|
||||||
addr_list = dns_rr_append(addr_list,
|
addr_list = dns_rr_append(addr_list,
|
||||||
@ -331,7 +334,7 @@ static int smtp_compare_pref(DNS_RR *a, DNS_RR *b)
|
|||||||
|
|
||||||
/* smtp_domain_addr - mail exchanger address lookup */
|
/* smtp_domain_addr - mail exchanger address lookup */
|
||||||
|
|
||||||
DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
|
DNS_RR *smtp_domain_addr(char *name, int misc_flags, VSTRING *why)
|
||||||
{
|
{
|
||||||
DNS_RR *mx_names;
|
DNS_RR *mx_names;
|
||||||
DNS_RR *addr_list = 0;
|
DNS_RR *addr_list = 0;
|
||||||
@ -339,7 +342,7 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
|
|||||||
unsigned best_pref;
|
unsigned best_pref;
|
||||||
unsigned best_found;
|
unsigned best_found;
|
||||||
|
|
||||||
smtp_errno = SMTP_NONE; /* Paranoia */
|
smtp_errno = SMTP_ERR_NONE; /* Paranoia */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preferences from DNS use 0..32767, fall-backs use 32768+.
|
* Preferences from DNS use 0..32767, fall-backs use 32768+.
|
||||||
@ -396,14 +399,14 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
|
|||||||
*/
|
*/
|
||||||
switch (dns_lookup(name, T_MX, 0, &mx_names, (VSTRING *) 0, why)) {
|
switch (dns_lookup(name, T_MX, 0, &mx_names, (VSTRING *) 0, why)) {
|
||||||
default:
|
default:
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
if (var_ign_mx_lookup_err)
|
if (var_ign_mx_lookup_err)
|
||||||
addr_list = smtp_host_addr(name, why);
|
addr_list = smtp_host_addr(name, misc_flags, why);
|
||||||
break;
|
break;
|
||||||
case DNS_FAIL:
|
case DNS_FAIL:
|
||||||
smtp_errno = SMTP_FAIL;
|
smtp_errno = SMTP_ERR_FAIL;
|
||||||
if (var_ign_mx_lookup_err)
|
if (var_ign_mx_lookup_err)
|
||||||
addr_list = smtp_host_addr(name, why);
|
addr_list = smtp_host_addr(name, misc_flags, why);
|
||||||
break;
|
break;
|
||||||
case DNS_OK:
|
case DNS_OK:
|
||||||
mx_names = dns_rr_sort(mx_names, smtp_compare_pref);
|
mx_names = dns_rr_sort(mx_names, smtp_compare_pref);
|
||||||
@ -412,24 +415,25 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
|
|||||||
dns_rr_free(mx_names);
|
dns_rr_free(mx_names);
|
||||||
if (addr_list == 0) {
|
if (addr_list == 0) {
|
||||||
if (var_smtp_defer_mxaddr)
|
if (var_smtp_defer_mxaddr)
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
msg_warn("no MX host for %s has a valid A record", name);
|
msg_warn("no MX host for %s has a valid A record", name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
best_found = (addr_list ? addr_list->pref : IMPOSSIBLE_PREFERENCE);
|
best_found = (addr_list ? addr_list->pref : IMPOSSIBLE_PREFERENCE);
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
smtp_print_addr(name, addr_list);
|
smtp_print_addr(name, addr_list);
|
||||||
if ((self = smtp_find_self(addr_list)) != 0) {
|
if ((misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
|
||||||
|
&& (self = smtp_find_self(addr_list)) != 0) {
|
||||||
addr_list = smtp_truncate_self(addr_list, self->pref);
|
addr_list = smtp_truncate_self(addr_list, self->pref);
|
||||||
if (addr_list == 0) {
|
if (addr_list == 0) {
|
||||||
if (best_pref != best_found) {
|
if (best_pref != best_found) {
|
||||||
vstring_sprintf(why, "unable to find primary relay for %s",
|
vstring_sprintf(why, "unable to find primary relay for %s",
|
||||||
name);
|
name);
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
} else {
|
} else {
|
||||||
vstring_sprintf(why, "mail for %s loops back to myself",
|
vstring_sprintf(why, "mail for %s loops back to myself",
|
||||||
name);
|
name);
|
||||||
smtp_errno = SMTP_LOOP;
|
smtp_errno = SMTP_ERR_LOOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,7 +443,7 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DNS_NOTFOUND:
|
case DNS_NOTFOUND:
|
||||||
addr_list = smtp_host_addr(name, why);
|
addr_list = smtp_host_addr(name, misc_flags, why);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,11 +455,11 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why)
|
|||||||
|
|
||||||
/* smtp_host_addr - direct host lookup */
|
/* smtp_host_addr - direct host lookup */
|
||||||
|
|
||||||
DNS_RR *smtp_host_addr(char *host, VSTRING *why)
|
DNS_RR *smtp_host_addr(char *host, int misc_flags, VSTRING *why)
|
||||||
{
|
{
|
||||||
DNS_RR *addr_list;
|
DNS_RR *addr_list;
|
||||||
|
|
||||||
smtp_errno = SMTP_NONE; /* Paranoia */
|
smtp_errno = SMTP_ERR_NONE; /* Paranoia */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the host is specified by numerical address, just convert the
|
* If the host is specified by numerical address, just convert the
|
||||||
@ -463,14 +467,14 @@ DNS_RR *smtp_host_addr(char *host, VSTRING *why)
|
|||||||
*/
|
*/
|
||||||
#define PREF0 0
|
#define PREF0 0
|
||||||
addr_list = smtp_addr_one((DNS_RR *) 0, host, PREF0, why);
|
addr_list = smtp_addr_one((DNS_RR *) 0, host, PREF0, why);
|
||||||
#if 0
|
if (addr_list
|
||||||
if (addr_list && smtp_find_self(addr_list) != 0) {
|
&& (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
|
||||||
|
&& smtp_find_self(addr_list) != 0) {
|
||||||
dns_rr_free(addr_list);
|
dns_rr_free(addr_list);
|
||||||
vstring_sprintf(why, "mail for %s loops back to myself", host);
|
vstring_sprintf(why, "mail for %s loops back to myself", host);
|
||||||
smtp_errno = SMTP_LOOP;
|
smtp_errno = SMTP_ERR_LOOP;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (addr_list && addr_list->next && var_smtp_rand_addr)
|
if (addr_list && addr_list->next && var_smtp_rand_addr)
|
||||||
addr_list = dns_rr_shuffle(addr_list);
|
addr_list = dns_rr_shuffle(addr_list);
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
/*
|
/*
|
||||||
* Internal interfaces.
|
* Internal interfaces.
|
||||||
*/
|
*/
|
||||||
extern DNS_RR *smtp_host_addr(char *, VSTRING *);
|
extern DNS_RR *smtp_host_addr(char *, int, VSTRING *);
|
||||||
extern DNS_RR *smtp_domain_addr(char *, VSTRING *);
|
extern DNS_RR *smtp_domain_addr(char *, int, VSTRING *);
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
/* int smtp_connect(state)
|
/* int smtp_connect(state)
|
||||||
/* SMTP_STATE *state;
|
/* SMTP_STATE *state;
|
||||||
/* DESCRIPTION
|
/* DESCRIPTION
|
||||||
/* This module implements SMTP connection management and mail
|
/* This module implements SMTP connection management and controls
|
||||||
/* delivery.
|
/* mail delivery.
|
||||||
/*
|
/*
|
||||||
/* smtp_connect() attempts to establish an SMTP session with a host
|
/* smtp_connect() attempts to establish an SMTP session with a host
|
||||||
/* that represents the destination domain, or with an optional fallback
|
/* that represents the destination domain, or with an optional fallback
|
||||||
@ -62,7 +62,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INADDR_NONE
|
#ifndef INADDR_NONE
|
||||||
#define INADDR_NONE 0xffffff
|
#define INADDR_NONE 0xffffffff
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Utility library. */
|
/* Utility library. */
|
||||||
@ -111,14 +111,14 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
|
|||||||
int ch;
|
int ch;
|
||||||
unsigned long inaddr;
|
unsigned long inaddr;
|
||||||
|
|
||||||
smtp_errno = SMTP_NONE; /* Paranoia */
|
smtp_errno = SMTP_ERR_NONE; /* Paranoia */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity checks.
|
* Sanity checks.
|
||||||
*/
|
*/
|
||||||
if (addr->data_len > sizeof(sin.sin_addr)) {
|
if (addr->data_len > sizeof(sin.sin_addr)) {
|
||||||
msg_warn("%s: skip address with length %d", myname, addr->data_len);
|
msg_warn("%s: skip address with length %d", myname, addr->data_len);
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
|
|||||||
if (conn_stat < 0) {
|
if (conn_stat < 0) {
|
||||||
vstring_sprintf(why, "connect to %s[%s]: %m",
|
vstring_sprintf(why, "connect to %s[%s]: %m",
|
||||||
addr->name, inet_ntoa(sin.sin_addr));
|
addr->name, inet_ntoa(sin.sin_addr));
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
close(sock);
|
close(sock);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
|
|||||||
if (read_wait(sock, var_smtp_helo_tmout) < 0) {
|
if (read_wait(sock, var_smtp_helo_tmout) < 0) {
|
||||||
vstring_sprintf(why, "connect to %s[%s]: read timeout",
|
vstring_sprintf(why, "connect to %s[%s]: read timeout",
|
||||||
addr->name, inet_ntoa(sin.sin_addr));
|
addr->name, inet_ntoa(sin.sin_addr));
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
close(sock);
|
close(sock);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
|
|||||||
if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
|
if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
|
||||||
vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial SMTP greeting",
|
vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial SMTP greeting",
|
||||||
addr->name, inet_ntoa(sin.sin_addr));
|
addr->name, inet_ntoa(sin.sin_addr));
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
vstream_fclose(stream);
|
vstream_fclose(stream);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
|
|||||||
if (ch == '4' && var_smtp_skip_4xx_greeting) {
|
if (ch == '4' && var_smtp_skip_4xx_greeting) {
|
||||||
vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
|
vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
|
||||||
addr->name, inet_ntoa(sin.sin_addr));
|
addr->name, inet_ntoa(sin.sin_addr));
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
vstream_fclose(stream);
|
vstream_fclose(stream);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -230,7 +230,7 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
|
|||||||
if (ch == '5' && var_smtp_skip_5xx_greeting) {
|
if (ch == '5' && var_smtp_skip_5xx_greeting) {
|
||||||
vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
|
vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
|
||||||
addr->name, inet_ntoa(sin.sin_addr));
|
addr->name, inet_ntoa(sin.sin_addr));
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
vstream_fclose(stream);
|
vstream_fclose(stream);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -290,6 +290,7 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
DNS_RR *next;
|
DNS_RR *next;
|
||||||
int addr_count;
|
int addr_count;
|
||||||
int sess_count;
|
int sess_count;
|
||||||
|
int misc_flags = SMTP_MISC_FLAG_DEFAULT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First try to deliver to the indicated destination, then try to deliver
|
* First try to deliver to the indicated destination, then try to deliver
|
||||||
@ -336,10 +337,14 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
*/
|
*/
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("connecting to %s port %d", host, ntohs(port));
|
msg_info("connecting to %s port %d", host, ntohs(port));
|
||||||
|
if (ntohs(port) != 25)
|
||||||
|
misc_flags &= ~SMTP_MISC_FLAG_LOOP_DETECT;
|
||||||
|
else
|
||||||
|
misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
|
||||||
if (var_disable_dns || *dest == '[') {
|
if (var_disable_dns || *dest == '[') {
|
||||||
addr_list = smtp_host_addr(host, why);
|
addr_list = smtp_host_addr(host, misc_flags, why);
|
||||||
} else {
|
} else {
|
||||||
addr_list = smtp_domain_addr(host, why);
|
addr_list = smtp_domain_addr(host, misc_flags, why);
|
||||||
}
|
}
|
||||||
myfree(dest_buf);
|
myfree(dest_buf);
|
||||||
|
|
||||||
@ -347,20 +352,18 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
* Don't try any backup host if mail loops to myself. That would just
|
* Don't try any backup host if mail loops to myself. That would just
|
||||||
* make the problem worse.
|
* make the problem worse.
|
||||||
*/
|
*/
|
||||||
if (addr_list == 0 && smtp_errno == SMTP_LOOP)
|
if (addr_list == 0 && smtp_errno == SMTP_ERR_LOOP)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Connect to an SMTP server. XXX Limit the number of addresses that
|
* Connect to an SMTP server.
|
||||||
* we're willing to try for a non-fallback destination.
|
|
||||||
*
|
*
|
||||||
* At the start of an SMTP session, all recipients are unmarked. In the
|
* At the start of an SMTP session, all recipients are unmarked. In the
|
||||||
* course of an SMTP session, recipients are marked as KEEP (deliver
|
* course of an SMTP session, recipients are marked as KEEP (deliver
|
||||||
* to backup mail server) or DROP (remove from recipient list). The
|
* to alternate mail server) or DROP (remove from recipient list). At
|
||||||
* marking policy is configurable with the smtp_backup_on_soft_error
|
* the end of an SMTP session, weed out the recipient list. Unmark
|
||||||
* parameter. At the end of an SMTP session, weed out the recipient
|
* any left-over recipients and try to deliver them to a backup mail
|
||||||
* list. Unmark any left-over recipients and try to deliver them to a
|
* server.
|
||||||
* backup mail server.
|
|
||||||
*/
|
*/
|
||||||
sess_count = addr_count = 0;
|
sess_count = addr_count = 0;
|
||||||
for (addr = addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
|
for (addr = addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
|
||||||
@ -373,7 +376,7 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
state->final_server = (cpp[1] == 0 && next == 0);
|
state->final_server = (cpp[1] == 0 && next == 0);
|
||||||
state->session->best = (addr->pref == addr_list->pref);
|
state->session->best = (addr->pref == addr_list->pref);
|
||||||
debug_peer_check(state->session->host, state->session->addr);
|
debug_peer_check(state->session->host, state->session->addr);
|
||||||
if (smtp_helo(state) == 0)
|
if (smtp_helo(state, misc_flags) == 0)
|
||||||
smtp_xfer(state);
|
smtp_xfer(state);
|
||||||
if (state->history != 0
|
if (state->history != 0
|
||||||
&& (state->error_mask & name_mask(VAR_NOTIFY_CLASSES,
|
&& (state->error_mask & name_mask(VAR_NOTIFY_CLASSES,
|
||||||
@ -404,8 +407,8 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
default:
|
default:
|
||||||
msg_panic("smtp_connect: bad error indication %d", smtp_errno);
|
msg_panic("smtp_connect: bad error indication %d", smtp_errno);
|
||||||
|
|
||||||
case SMTP_LOOP:
|
case SMTP_ERR_LOOP:
|
||||||
case SMTP_FAIL:
|
case SMTP_ERR_FAIL:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The fall-back destination did not resolve as expected, or it
|
* The fall-back destination did not resolve as expected, or it
|
||||||
@ -413,7 +416,7 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
*/
|
*/
|
||||||
if (sites->argc > 1 && cpp > sites->argv) {
|
if (sites->argc > 1 && cpp > sites->argv) {
|
||||||
msg_warn("%s configuration problem", VAR_FALLBACK_RELAY);
|
msg_warn("%s configuration problem", VAR_FALLBACK_RELAY);
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -422,14 +425,14 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
*/
|
*/
|
||||||
else if (strcmp(sites->argv[0], var_relayhost) == 0) {
|
else if (strcmp(sites->argv[0], var_relayhost) == 0) {
|
||||||
msg_warn("%s configuration problem", VAR_RELAYHOST);
|
msg_warn("%s configuration problem", VAR_RELAYHOST);
|
||||||
smtp_errno = SMTP_RETRY;
|
smtp_errno = SMTP_ERR_RETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mail for the next-hop destination loops back to myself. Pass
|
* Mail for the next-hop destination loops back to myself. Pass
|
||||||
* the mail to the best_mx_transport or bounce it.
|
* the mail to the best_mx_transport or bounce it.
|
||||||
*/
|
*/
|
||||||
else if (smtp_errno == SMTP_LOOP && *var_bestmx_transp) {
|
else if (smtp_errno == SMTP_ERR_LOOP && *var_bestmx_transp) {
|
||||||
state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
|
state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
|
||||||
var_bestmx_transp,
|
var_bestmx_transp,
|
||||||
request);
|
request);
|
||||||
@ -438,14 +441,14 @@ int smtp_connect(SMTP_STATE *state)
|
|||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case SMTP_RETRY:
|
case SMTP_ERR_RETRY:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We still need to bounce or defer some left-over recipients:
|
* We still need to bounce or defer some left-over recipients:
|
||||||
* either mail loops or some backup mail server was unavailable.
|
* either mail loops or some backup mail server was unavailable.
|
||||||
*/
|
*/
|
||||||
state->final_server = 1; /* XXX */
|
state->final_server = 1; /* XXX */
|
||||||
smtp_site_fail(state, smtp_errno == SMTP_RETRY ? 450 : 550,
|
smtp_site_fail(state, smtp_errno == SMTP_ERR_RETRY ? 450 : 550,
|
||||||
"%s", vstring_str(why));
|
"%s", vstring_str(why));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -167,7 +167,7 @@ char *xfer_request[SMTP_STATE_LAST] = {
|
|||||||
|
|
||||||
/* smtp_helo - perform initial handshake with SMTP server */
|
/* smtp_helo - perform initial handshake with SMTP server */
|
||||||
|
|
||||||
int smtp_helo(SMTP_STATE *state)
|
int smtp_helo(SMTP_STATE *state, int misc_flags)
|
||||||
{
|
{
|
||||||
SMTP_SESSION *session = state->session;
|
SMTP_SESSION *session = state->session;
|
||||||
DELIVER_REQUEST *request = state->request;
|
DELIVER_REQUEST *request = state->request;
|
||||||
@ -218,6 +218,7 @@ int smtp_helo(SMTP_STATE *state)
|
|||||||
(void) mystrtok(&words, "- \t\n");
|
(void) mystrtok(&words, "- \t\n");
|
||||||
for (n = 0; (word = mystrtok(&words, " \t\n")) != 0; n++) {
|
for (n = 0; (word = mystrtok(&words, " \t\n")) != 0; n++) {
|
||||||
if (n == 0 && strcasecmp(word, var_myhostname) == 0) {
|
if (n == 0 && strcasecmp(word, var_myhostname) == 0) {
|
||||||
|
if (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
|
||||||
msg_warn("host %s greeted me with my own hostname %s",
|
msg_warn("host %s greeted me with my own hostname %s",
|
||||||
session->namaddr, var_myhostname);
|
session->namaddr, var_myhostname);
|
||||||
} else if (strcasecmp(word, "ESMTP") == 0)
|
} else if (strcasecmp(word, "ESMTP") == 0)
|
||||||
@ -283,6 +284,7 @@ int smtp_helo(SMTP_STATE *state)
|
|||||||
smtp_sasl_helo_auth(state, words);
|
smtp_sasl_helo_auth(state, words);
|
||||||
#endif
|
#endif
|
||||||
else if (strcasecmp(word, var_myhostname) == 0) {
|
else if (strcasecmp(word, var_myhostname) == 0) {
|
||||||
|
if (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT) {
|
||||||
msg_warn("host %s replied to HELO/EHLO with my own hostname %s",
|
msg_warn("host %s replied to HELO/EHLO with my own hostname %s",
|
||||||
session->namaddr, var_myhostname);
|
session->namaddr, var_myhostname);
|
||||||
return (smtp_site_fail(state, session->best ? 550 : 450,
|
return (smtp_site_fail(state, session->best ? 550 : 450,
|
||||||
@ -291,6 +293,7 @@ int smtp_helo(SMTP_STATE *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("server features: 0x%x size %.0f",
|
msg_info("server features: 0x%x size %.0f",
|
||||||
state->features, (double) state->size_limit);
|
state->features, (double) state->size_limit);
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
/* .IP \(bu
|
/* .IP \(bu
|
||||||
/* In the course of a delivery attempt each recipient is
|
/* In the course of a delivery attempt each recipient is
|
||||||
/* marked either as DROP (remove from recipient list) or KEEP
|
/* marked either as DROP (remove from recipient list) or KEEP
|
||||||
/* (deliver to backup mail server).
|
/* (deliver to alternate mail server).
|
||||||
/* .IP \(bu
|
/* .IP \(bu
|
||||||
/* After a delivery attempt any recipients marked DROP are deleted
|
/* After a delivery attempt any recipients marked DROP are deleted
|
||||||
/* from the request, and the left-over recipients are unmarked.
|
/* from the request, and the left-over recipients are unmarked.
|
||||||
|
@ -71,9 +71,11 @@
|
|||||||
/* List of commands that are treated as NOOP (no operation) commands,
|
/* List of commands that are treated as NOOP (no operation) commands,
|
||||||
/* without any parameter syntax checking and without any state change.
|
/* without any parameter syntax checking and without any state change.
|
||||||
/* This list overrides built-in command definitions.
|
/* This list overrides built-in command definitions.
|
||||||
/* .SH "Content inspection controls"
|
/* .SH "Content inspection after mail is queued"
|
||||||
/* Optionally, Postfix can be configured to send new mail to
|
/* .ad
|
||||||
/* external content filter software AFTER the mail is queued.
|
/* .fi
|
||||||
|
/* Postfix can be configured to send new mail to an external
|
||||||
|
/* content filter AFTER the mail is queued.
|
||||||
/* .IP \fBcontent_filter\fR
|
/* .IP \fBcontent_filter\fR
|
||||||
/* The name of a mail delivery transport that filters mail and that
|
/* The name of a mail delivery transport that filters mail and that
|
||||||
/* either bounces mail or re-injects the result back into Postfix.
|
/* either bounces mail or re-injects the result back into Postfix.
|
||||||
@ -96,22 +98,20 @@
|
|||||||
/* Disable header/body_checks. This is typically specified with the
|
/* Disable header/body_checks. This is typically specified with the
|
||||||
/* SMTP server \fBafter\fR an external content filter.
|
/* SMTP server \fBafter\fR an external content filter.
|
||||||
/* .RE
|
/* .RE
|
||||||
/* .SH "Pass-through proxy"
|
/* .SH "Content inspection before mail is queued"
|
||||||
/* .ad
|
/* .ad
|
||||||
/* .fi
|
/* .fi
|
||||||
/* .ad
|
/* The Postfix SMTP server can be configured to forward all mail
|
||||||
/* Optionally, the Postfix SMTP server can be configured to
|
/* to a real-time SMTP-based content filter BEFORE mail is queued.
|
||||||
/* forward all mail to a proxy server, for example a real-time
|
|
||||||
/* content filter, BEFORE mail is queued.
|
|
||||||
/* .IP \fBsmtpd_proxy_filter\fR
|
/* .IP \fBsmtpd_proxy_filter\fR
|
||||||
/* The \fIhost:port\fR of the SMTP proxy server. The \fIhost\fR
|
/* The \fIhost:port\fR of the real-time SMTP-based content filter.
|
||||||
/* or \fIhost:\fR portion is optional.
|
/* The \fIhost\fR or \fIhost:\fR portion is optional.
|
||||||
/* .IP \fBsmtpd_proxy_timeout\fR
|
/* .IP \fBsmtpd_proxy_timeout\fR
|
||||||
/* Timeout for connecting to, sending to and receiving from
|
/* Timeout for connecting to, sending to and receiving from
|
||||||
/* the SMTP proxy server.
|
/* the real-time SMTP-based content filter.
|
||||||
/* .IP \fBsmtpd_proxy_ehlo\fR
|
/* .IP \fBsmtpd_proxy_ehlo\fR
|
||||||
/* The hostname to use when sending an EHLO command to the
|
/* The hostname to use when sending an EHLO command to the
|
||||||
/* SMTP proxy server.
|
/* real-time SMTP-based content filter.
|
||||||
/* .SH "Authentication controls"
|
/* .SH "Authentication controls"
|
||||||
/* .IP \fBsmtpd_sasl_auth_enable\fR
|
/* .IP \fBsmtpd_sasl_auth_enable\fR
|
||||||
/* Enable per-session authentication as per RFC 2554 (SASL).
|
/* Enable per-session authentication as per RFC 2554 (SASL).
|
||||||
@ -966,8 +966,10 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
|
|||||||
* Report trouble. Log a warning only if we are going to sleep+reject so
|
* Report trouble. Log a warning only if we are going to sleep+reject so
|
||||||
* that attackers can't flood our logfiles.
|
* that attackers can't flood our logfiles.
|
||||||
*/
|
*/
|
||||||
|
if (err == 0)
|
||||||
if ((arg->strval[0] == 0 && !allow_empty_addr)
|
if ((arg->strval[0] == 0 && !allow_empty_addr)
|
||||||
|| (strict_rfc821 && arg->strval[0] == '@')) {
|
|| (strict_rfc821 && arg->strval[0] == '@')
|
||||||
|
|| smtpd_check_addr(STR(arg->vstrval)) != 0) {
|
||||||
msg_warn("Illegal address syntax from %s in %s command: %s",
|
msg_warn("Illegal address syntax from %s in %s command: %s",
|
||||||
state->namaddr, state->where, STR(arg->vstrval));
|
state->namaddr, state->where, STR(arg->vstrval));
|
||||||
err = "501 Bad address syntax";
|
err = "501 Bad address syntax";
|
||||||
@ -1243,6 +1245,12 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
|||||||
} else if (state->cleanup == 0) {
|
} else if (state->cleanup == 0) {
|
||||||
mail_open_stream(state);
|
mail_open_stream(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Proxy the recipient. OK, so we lied. If the real-time proxy rejects
|
||||||
|
* the recipient then we can have a proxy connection without having
|
||||||
|
* accepted a recipient.
|
||||||
|
*/
|
||||||
if (state->proxy && smtpd_proxy_cmd(state, SMTPD_PROX_WANT_OK,
|
if (state->proxy && smtpd_proxy_cmd(state, SMTPD_PROX_WANT_OK,
|
||||||
"%s", STR(state->buffer)) != 0) {
|
"%s", STR(state->buffer)) != 0) {
|
||||||
smtpd_chat_reply(state, "%s", STR(state->proxy_buffer));
|
smtpd_chat_reply(state, "%s", STR(state->proxy_buffer));
|
||||||
@ -1343,9 +1351,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
|||||||
* Terminate the message envelope segment. Start the message content
|
* Terminate the message envelope segment. Start the message content
|
||||||
* segment, and prepend our own Received: header. If there is only one
|
* segment, and prepend our own Received: header. If there is only one
|
||||||
* recipient, list the recipient address.
|
* recipient, list the recipient address.
|
||||||
*
|
|
||||||
* Suppress our own Received: header in the unlikely case that we are an
|
|
||||||
* intermediate proxy.
|
|
||||||
*/
|
*/
|
||||||
if (state->cleanup) {
|
if (state->cleanup) {
|
||||||
if (state->saved_filter)
|
if (state->saved_filter)
|
||||||
@ -1356,6 +1361,11 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
|||||||
rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d", state->saved_flags);
|
rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d", state->saved_flags);
|
||||||
rec_fputs(state->cleanup, REC_TYPE_MESG, "");
|
rec_fputs(state->cleanup, REC_TYPE_MESG, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Suppress our own Received: header in the unlikely case that we are an
|
||||||
|
* intermediate proxy.
|
||||||
|
*/
|
||||||
if (!state->proxy || state->xforward.flags == 0) {
|
if (!state->proxy || state->xforward.flags == 0) {
|
||||||
out_fprintf(out_stream, REC_TYPE_NORM,
|
out_fprintf(out_stream, REC_TYPE_NORM,
|
||||||
"Received: from %s (%s [%s])",
|
"Received: from %s (%s [%s])",
|
||||||
@ -1389,7 +1399,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the message content. If the cleanup process has a problem, keep
|
* Copy the message content. If the cleanup process has a problem, keep
|
||||||
* reading until the remote stops sending, then complain. Read typed
|
* reading until the remote stops sending, then complain. Produce typed
|
||||||
* records from the SMTP stream so we can handle data that spans buffers.
|
* records from the SMTP stream so we can handle data that spans buffers.
|
||||||
*
|
*
|
||||||
* XXX Force an empty record when the queue file content begins with
|
* XXX Force an empty record when the queue file content begins with
|
||||||
|
@ -56,35 +56,39 @@ typedef struct {
|
|||||||
} SMTPD_XFORWARD_ATTR;
|
} SMTPD_XFORWARD_ATTR;
|
||||||
|
|
||||||
typedef struct SMTPD_STATE {
|
typedef struct SMTPD_STATE {
|
||||||
int err;
|
int err; /* cleanup server/queue file errors */
|
||||||
VSTREAM *client;
|
VSTREAM *client; /* SMTP client handle */
|
||||||
VSTRING *buffer;
|
VSTRING *buffer; /* SMTP client buffer */
|
||||||
time_t time;
|
time_t time; /* start of MAIL FROM transaction */
|
||||||
char *name;
|
char *name; /* client hostname */
|
||||||
char *addr;
|
char *addr; /* client host address string */
|
||||||
char *namaddr;
|
char *namaddr; /* combined name and address */
|
||||||
int peer_code; /* 2=ok, 4=soft, 5=hard */
|
int peer_code; /* 2=ok, 4=soft, 5=hard */
|
||||||
int error_count;
|
int error_count; /* reset after DOT */
|
||||||
int error_mask;
|
int error_mask; /* client errors */
|
||||||
int notify_mask;
|
int notify_mask; /* what to report to postmaster */
|
||||||
char *helo_name;
|
char *helo_name; /* client HELO/EHLO argument */
|
||||||
char *queue_id;
|
char *queue_id; /* from cleanup server/queue file */
|
||||||
VSTREAM *cleanup;
|
VSTREAM *cleanup; /* cleanup server/queue file handle */
|
||||||
MAIL_STREAM *dest;
|
MAIL_STREAM *dest; /* another server/file handle */
|
||||||
int rcpt_count;
|
int rcpt_count; /* number of accepted recipients */
|
||||||
char *access_denied;
|
char *access_denied; /* fixme */
|
||||||
ARGV *history;
|
ARGV *history; /* protocol transcript */
|
||||||
char *reason;
|
char *reason; /* cause of connection loss */
|
||||||
char *sender;
|
char *sender; /* sender address */
|
||||||
char *encoding; /* owned by mail_cmd() */
|
char *encoding; /* owned by mail_cmd() */
|
||||||
char *verp_delims; /* owned by mail_cmd() */
|
char *verp_delims; /* owned by mail_cmd() */
|
||||||
char *recipient;
|
char *recipient; /* recipient address */
|
||||||
char *etrn_name;
|
char *etrn_name; /* client ETRN argument */
|
||||||
char *protocol;
|
char *protocol; /* SMTP or ESMTP */
|
||||||
char *where;
|
char *where; /* protocol stage */
|
||||||
int recursion;
|
int recursion; /* Kellerspeicherpegelanzeiger */
|
||||||
off_t msg_size;
|
off_t msg_size; /* MAIL FROM message size */
|
||||||
int junk_cmds;
|
int junk_cmds; /* counter */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SASL specific.
|
||||||
|
*/
|
||||||
#ifdef USE_SASL_AUTH
|
#ifdef USE_SASL_AUTH
|
||||||
#if SASL_VERSION_MAJOR >= 2
|
#if SASL_VERSION_MAJOR >= 2
|
||||||
const char *sasl_mechanism_list;
|
const char *sasl_mechanism_list;
|
||||||
@ -98,6 +102,10 @@ typedef struct SMTPD_STATE {
|
|||||||
VSTRING *sasl_encoded;
|
VSTRING *sasl_encoded;
|
||||||
VSTRING *sasl_decoded;
|
VSTRING *sasl_decoded;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Specific to smtpd access checks.
|
||||||
|
*/
|
||||||
int rcptmap_checked;
|
int rcptmap_checked;
|
||||||
int warn_if_reject; /* force reject into warning */
|
int warn_if_reject; /* force reject into warning */
|
||||||
SMTPD_DEFER defer_if_reject; /* force reject into deferral */
|
SMTPD_DEFER defer_if_reject; /* force reject into deferral */
|
||||||
@ -111,13 +119,17 @@ typedef struct SMTPD_STATE {
|
|||||||
int saved_flags; /* postponed hold/discard */
|
int saved_flags; /* postponed hold/discard */
|
||||||
VSTRING *expand_buf; /* scratch space for $name expansion */
|
VSTRING *expand_buf; /* scratch space for $name expansion */
|
||||||
|
|
||||||
/* Pass-through proxy client. */
|
/*
|
||||||
|
* Pass-through proxy client.
|
||||||
|
*/
|
||||||
VSTREAM *proxy; /* proxy handle */
|
VSTREAM *proxy; /* proxy handle */
|
||||||
VSTRING *proxy_buffer; /* proxy query/reply buffer */
|
VSTRING *proxy_buffer; /* proxy query/reply buffer */
|
||||||
char *proxy_mail; /* owned by mail_cmd() */
|
char *proxy_mail; /* owned by mail_cmd() */
|
||||||
int proxy_xforward_features; /* XFORWARD proxy state */
|
int proxy_xforward_features; /* XFORWARD proxy state */
|
||||||
|
|
||||||
/* XFORWARD server state. */
|
/*
|
||||||
|
* XFORWARD server state.
|
||||||
|
*/
|
||||||
SMTPD_XFORWARD_ATTR xforward; /* up-stream logging info */
|
SMTPD_XFORWARD_ATTR xforward; /* up-stream logging info */
|
||||||
} SMTPD_STATE;
|
} SMTPD_STATE;
|
||||||
|
|
||||||
@ -221,9 +233,9 @@ extern void smtpd_peer_reset(SMTPD_STATE *state);
|
|||||||
#define FORWARD_HELO(s) FORWARD_CLIENT_ATTR((s), helo_name)
|
#define FORWARD_HELO(s) FORWARD_CLIENT_ATTR((s), helo_name)
|
||||||
#define FORWARD_IDENT(s) FORWARD_IDENT_ATTR(s)
|
#define FORWARD_IDENT(s) FORWARD_IDENT_ATTR(s)
|
||||||
|
|
||||||
extern void smtpd_xforward_init(SMTPD_STATE *state);
|
extern void smtpd_xforward_init(SMTPD_STATE *);
|
||||||
extern void smtpd_xforward_preset(SMTPD_STATE *state);
|
extern void smtpd_xforward_preset(SMTPD_STATE *);
|
||||||
extern void smtpd_xforward_reset(SMTPD_STATE *state);
|
extern void smtpd_xforward_reset(SMTPD_STATE *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transparency: before mail is queued, do we check for unknown recipients,
|
* Transparency: before mail is queued, do we check for unknown recipients,
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
/*
|
/*
|
||||||
/* void smtpd_check_init()
|
/* void smtpd_check_init()
|
||||||
/*
|
/*
|
||||||
|
/* int smtpd_check_addr(address)
|
||||||
|
/* const char *address;
|
||||||
|
/*
|
||||||
/* char *smtpd_check_client(state)
|
/* char *smtpd_check_client(state)
|
||||||
/* SMTPD_STATE *state;
|
/* SMTPD_STATE *state;
|
||||||
/*
|
/*
|
||||||
@ -39,6 +42,9 @@
|
|||||||
/* smtpd_check_init() initializes. This function should be called
|
/* smtpd_check_init() initializes. This function should be called
|
||||||
/* once during the process life time.
|
/* once during the process life time.
|
||||||
/*
|
/*
|
||||||
|
/* smtpd_check_addr() sanity checks an email address and returns
|
||||||
|
/* non-zero in case of badness.
|
||||||
|
/*
|
||||||
/* Each of the following routines scrutinizes the argument passed to
|
/* Each of the following routines scrutinizes the argument passed to
|
||||||
/* an SMTP command such as HELO, MAIL FROM, RCPT TO, or scrutinizes
|
/* an SMTP command such as HELO, MAIL FROM, RCPT TO, or scrutinizes
|
||||||
/* the initial client connection request. The administrator can
|
/* the initial client connection request. The administrator can
|
||||||
@ -3404,6 +3410,31 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
|||||||
return (status);
|
return (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* smtpd_check_addr - address sanity check */
|
||||||
|
|
||||||
|
int smtpd_check_addr(const char *addr)
|
||||||
|
{
|
||||||
|
const RESOLVE_REPLY *resolve_reply;
|
||||||
|
char *myname = "smtpd_check_addr";
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (msg_verbose)
|
||||||
|
msg_info("%s: addr=%s", myname, addr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Catch syntax errors early on if we can, but be prepared to re-compute
|
||||||
|
* the result later when the cache fills up with lots of recipients, at
|
||||||
|
* which time errors can still happen.
|
||||||
|
*/
|
||||||
|
if (addr == 0 || *addr == 0)
|
||||||
|
return (0);
|
||||||
|
resolve_reply = (const RESOLVE_REPLY *)
|
||||||
|
ctable_locate(smtpd_resolve_cache, addr);
|
||||||
|
if (resolve_reply->flags & RESOLVE_FLAG_ERROR)
|
||||||
|
return (-1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* smtpd_check_client - validate client name or address */
|
/* smtpd_check_client - validate client name or address */
|
||||||
|
|
||||||
char *smtpd_check_client(SMTPD_STATE *state)
|
char *smtpd_check_client(SMTPD_STATE *state)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* External interface.
|
* External interface.
|
||||||
*/
|
*/
|
||||||
extern void smtpd_check_init(void);
|
extern void smtpd_check_init(void);
|
||||||
|
extern int smtpd_check_addr(const char *);
|
||||||
extern char *smtpd_check_client(SMTPD_STATE *);
|
extern char *smtpd_check_client(SMTPD_STATE *);
|
||||||
extern char *smtpd_check_helo(SMTPD_STATE *, char *);
|
extern char *smtpd_check_helo(SMTPD_STATE *, char *);
|
||||||
extern char *smtpd_check_mail(SMTPD_STATE *, char *);
|
extern char *smtpd_check_mail(SMTPD_STATE *, char *);
|
||||||
|
@ -357,7 +357,8 @@ static void resolve_addr(RES_CONTEXT *rp, char *addr,
|
|||||||
tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
|
tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
|
||||||
rcpt_domain = strrchr(STR(nextrcpt), '@') + 1;
|
rcpt_domain = strrchr(STR(nextrcpt), '@') + 1;
|
||||||
if (*rcpt_domain == '[' ? !valid_hostliteral(rcpt_domain, DONT_GRIPE) :
|
if (*rcpt_domain == '[' ? !valid_hostliteral(rcpt_domain, DONT_GRIPE) :
|
||||||
!valid_hostname(rcpt_domain, DONT_GRIPE))
|
(!valid_hostname(rcpt_domain, DONT_GRIPE)
|
||||||
|
|| valid_hostaddr(rcpt_domain, DONT_GRIPE)))
|
||||||
*flags |= RESOLVE_FLAG_ERROR;
|
*flags |= RESOLVE_FLAG_ERROR;
|
||||||
tok822_free_tree(tree);
|
tok822_free_tree(tree);
|
||||||
tree = 0;
|
tree = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user