Compatibility: "session cache" renamed to "connection cache"
to avoid confusion with the TLS session cache.
+20041102
+
+ Feature: smtpd_end_of_data_restrictions allow you to specify
+ restrictions at the end of the SMTP DATA command. The syntax
+ is identical to that of the smtpd_data_restrictions feature.
+ This introduces a new END-OF-DATA protocol state for the
+ external policy server. Files: proto/SMTPD_POLICY_README.html,
+ proto/SMTPD_ACCESS_README.html, smtpd/smtpd_check.c.
+
+20041111
+
+ Cleanup: terminate the dict_eval() result buffer for verbose
+ logging. Victor Duchovni, Morgan Stanley. File: util/dict.c.
+
+20041112
+
+ Cleanup: be more careful when saving and restoring resolver(3)
+ options to avoid problems with an HP-UX security patch
+ (change introduced 20031215). File: dns/dns_lookup.c.
+
+20041115
+
+ Bugfix: the test for "no debugger_command" was wrong.
+ Leandro Santi. File: global/debugger_command.c.
+
+20040117
+
+ Robustness: the master-child protocol now includes a process
+ generation number besides the child process ID. The process
+ generation number is incremented by one each time the master
+ creates a child process. Child-to-master status updates
+ with the wrong generation number are ignored, instead of
+ triggering a consistency error in the master server. Files:
+ master/*server.c, master/master_status.c, master/master_spawn.c.
+
+20041118
+
+ Bugfix: the "local_header_rewrite_clients" feature (20041023)
+ did not recognize "bare" lookup tables as documented. Victor
+ Duchovni, Morgan Stanley. File: smtpd/smtpd_check.c.
+
+ Bugfix: the "local_header_rewrite_clients" feature (20041023)
+ was broken because the local delivery agent passed on a
+ bogus attribute value when forwarding internally generated
+ mail, causing the mail to be rejected by the cleanup server.
+ File: local/dotforward.c.
+
+ Bugfix: the "local_header_rewrite_clients" feature (20041023)
+ was broken because the pickup server always overwrote origin
+ information. Files: pickup/pickup.c, cleanup/cleanup_state.c,
+ *qmgr/qmgr_message.c.
+
+ Workaround: enable the "can't write before sending a file
+ descriptor" workaround for Solaris. Problem reported by
+ Victor Duchovni for Solaris 2.5.1, but we play safe and
+ enable it unconditionally.
+
Open problems:
Low: reject HELO with any domain name or IP address that
All lists use the exact same syntax; they differ only in the time of evaluation
and in the effect of a REJECT or DEFER result.
- _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b
- |R\bRe\bes\bst\btr\bri\bic\bct\bti\bio\bon\bn l\bli\bis\bst\bt n\bna\bam\bme\be |S\bSt\bta\bat\btu\bus\bs |E\bEf\bff\bfe\bec\bct\bt o\bof\bf R\bRE\bEJ\bJE\bEC\bCT\bT o\bor\br D\bDE\bEF\bFE\bER\bR r\bre\bes\bsu\bul\blt\bt|
- |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |smtpd_client_restrictions |Optional|Reject all client commands |
- |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |smtpd_helo_restrictions |Optional|Reject HELO/EHLO information |
- |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |smtpd_sender_restrictions |Optional|Reject MAIL FROM information |
- |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |smtpd_recipient_restrictions|Required|Reject RCPT TO information |
- |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |smtpd_data_restrictions |Optional|Reject DATA command |
- |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |smtpd_etrn_restrictions |Optional|Reject ETRN command |
- |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b
+ |R\bRe\bes\bst\btr\bri\bic\bct\bti\bio\bon\bn l\bli\bis\bst\bt n\bna\bam\bme\be |S\bSt\bta\bat\btu\bus\bs |E\bEf\bff\bfe\bec\bct\bt o\bof\bf R\bRE\bEJ\bJE\bEC\bCT\bT o\bor\br D\bDE\bEF\bFE\bER\bR r\bre\bes\bsu\bul\blt\bt|
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |smtpd_client_restrictions |Optional|Reject all client commands |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |smtpd_helo_restrictions |Optional|Reject HELO/EHLO information |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |smtpd_sender_restrictions |Optional|Reject MAIL FROM information |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |smtpd_recipient_restrictions |Required|Reject RCPT TO information |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |smtpd_data_restrictions |Optional|Reject DATA command |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |smtpd_end_of_data_restrictions|Optional|Reject END-OF-DATA command |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |smtpd_etrn_restrictions |Optional|Reject ETRN command |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
D\bDe\bel\bla\bay\bye\bed\bd e\bev\bva\bal\blu\bua\bat\bti\bio\bon\bn o\bof\bf S\bSM\bMT\bTP\bP a\bac\bcc\bce\bes\bss\bs r\bre\bes\bst\btr\bri\bic\bct\bti\bio\bon\bn l\bli\bis\bst\bts\bs
restriction lists until the RCPT TO or ETRN command. This behavior is
controlled by the smtpd_delay_reject parameter. Restriction lists are still
evaluated in the proper order of (client, helo, etrn) or (client, helo, sender,
-recipient, data) restrictions. When a restriction list (example: client)
-evaluates to REJECT or DEFER the other restriction lists (example: helo,
-sender, etc.) are skipped.
+recipient, data, or end-of-data) restrictions. When a restriction list
+(example: client) evaluates to REJECT or DEFER the other restriction lists
+(example: helo, sender, etc.) are skipped.
Around the time that smtpd_delay_reject was introduced, Postfix was also
changed to support mixed restriction lists that combine information about the
* The "instance" attribute value can be used to correlate different requests
regarding the same message delivery.
+ * The "size" attribute value specifies the message size that the client
+ specified in the MAIL FROM command (zero if none was specified). With
+ Postfix 2.2 and later, it specifies the actual message size when the client
+ sends the END-OF-DATA command.
+
The following is specific to SMTPD delegated policy requests:
* Protocol names are ESMTP or SMTP.
- * Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, DATA, VRFY or ETRN;
- these are the SMTP protocol states where the Postfix SMTP server makes an
- OK/REJECT/HOLD/etc. decision.
+ * Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, DATA, END-OF-DATA,
+ VRFY or ETRN; these are the SMTP protocol states where the Postfix SMTP
+ server makes an OK/REJECT/HOLD/etc. decision.
* The SASL attributes are sent only when SASL support is built into Postfix.
and change the patchlevel and the release date. Patches are never
issued for snapshot releases.
+Incompatible changes with snapshot Postfix-2.2-20041118
+=======================================================
+
+You must restart Postfix, because the master-child protocol has
+changed. Postfix will log warnings about partial status updates
+if you forget to restart the master.
+
+Major changes with snapshot Postfix-2.2-20041118
+================================================
+
+New "smtpd_end_of_data_restrictions" feature that is invoked after
+the client terminates the SMTP DATA command. The syntax is the same
+as with "smtpd_data_restrictions", but the message size is the
+actual byte count of the message content.
+
Incompatible changes with snapshot Postfix-2.2-20041030
=======================================================
<tr> <td> <a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a> </td> <td> Optional </td> <td>
Reject DATA command </td> </tr>
+<tr> <td> <a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a> </td> <td> Optional </td> <td>
+Reject END-OF-DATA command </td> </tr>
+
<tr> <td> <a href="postconf.5.html#smtpd_etrn_restrictions">smtpd_etrn_restrictions</a> </td> <td> Optional </td> <td>
Reject ETRN command </td> </tr>
helo and sender restriction lists until the RCPT TO or ETRN command.
This behavior is controlled by the <a href="postconf.5.html#smtpd_delay_reject">smtpd_delay_reject</a> parameter.
Restriction lists are still evaluated in the proper order of (client,
-helo, etrn) or (client, helo, sender, recipient, data) restrictions.
+helo, etrn) or (client, helo, sender, recipient, data, or end-of-data)
+restrictions.
When a restriction list (example: client) evaluates to REJECT or
DEFER the other restriction lists (example: helo, sender, etc.)
are skipped. </p>
<li> <p> The "instance" attribute value can be used to correlate
different requests regarding the same message delivery. </p>
+ <li> <p> The "size" attribute value specifies the message size
+ that the client specified in the MAIL FROM command (zero if
+ none was specified). With Postfix 2.2 and later, it specifies
+ the actual message size when the client sends the END-OF-DATA
+ command.
+ </p>
+
</ul>
<p> The following is specific to SMTPD delegated policy requests:
<li> <p> Protocol names are ESMTP or SMTP. </p>
<li> <p> Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT,
- DATA, VRFY or ETRN; these are the SMTP protocol states where
+ DATA, END-OF-DATA, VRFY or ETRN; these are the SMTP protocol
+ states where
the Postfix SMTP server makes an OK/REJECT/HOLD/etc. decision.
</p>
<html>
-<!-- TODO: all man pages of commands and daemons -->
-
<head>
<title>Postfix Documentation</title>
whether it is listed on the server, and regardless of the certifying
authority. </dd>
-<dt><b> <a name="check_address_map">check_address_map</a> <i><a
-href="DATABASE_README.html">type:table</a></i> </b></dt>
+<dt><b> <a name="check_address_map">check_address_map</a> <i><a href="DATABASE_README.html">type:table</a></i> </b></dt>
-<dt><b> <i><a href="DATABASE_README.html">type:table</a></i>
-</b></dt>
+<dt><b> <i><a href="DATABASE_README.html">type:table</a></i> </b></dt>
<dd> Append the domain name in $<a href="postconf.5.html#myorigin">myorigin</a> or $<a href="postconf.5.html#mydomain">mydomain</a> when the
client IP address matches the specified lookup table. The lookup
and the message has multiple envelope recipients. Although this
usage is technically allowed, it seems to have no legitimate
application. <br> NOTE: this restriction can only work reliably
-when used in <a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a>, because the total number of
+when used in <a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a> or
+<a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a>, because the total number of
recipients is not known at an earlier stage of the SMTP conversation.
Use at the RCPT stage will only reject the second etc. recipient.
<br>
</p>
+</DD>
+
+<DT><b><a name="smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a>
+(default: empty)</b></DT><DD>
+
+<p> Optional access restrictions that the Postfix SMTP server
+applies in the context of the SMTP END-OF-DATA command. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p> See <a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a> for syntax details. </p>
+
+
</DD>
<DT><b><a name="smtpd_error_sleep_time">smtpd_error_sleep_time</a>
<a href="trivial-rewrite.8.html">trivial-rewrite(8)</a>, address routing
<a href="bounce.8.html">bounce(8)</a>, delivery status reports
<a href="postconf.5.html">postconf(5)</a>, configuration parameters
+ <a href="master.5.html">master(5)</a>, generic daemon options
<a href="master.8.html">master(8)</a>, process manager
syslogd(8) system logging
fails due to a recoverable error condition, the SMTP
client will try to deliver the mail to an alternate host.
- After a successful mail transaction, a session may be
+ After a successful mail transaction, a connection may be
saved to the <a href="scache.8.html"><b>scache(8)</a></b> connection cache server, so that it
may be used by any SMTP client for a subsequent transac-
tion.
SMTP connection caching assumes that SASL credentials are
valid for all destinations that map onto the same IP
- address and TCP port, and for all sender and recipient
- addresses.
+ address and TCP port.
<b>CONFIGURATION PARAMETERS</b>
Changes to <b>main.cf</b> are picked up automatically, as <a href="smtp.8.html">smtp(8)</a>
- processes run for only a limited amount of time. Use the
+ processes run for only a limited amount of time. Use the
command "<b>postfix reload</b>" to speed up a change.
- The text below provides only a parameter summary. See
+ The text below provides only a parameter summary. See
<a href="postconf.5.html">postconf(5)</a> for more details including examples.
<b>COMPATIBILITY CONTROLS</b>
Never send EHLO at the start of an SMTP session.
<b><a href="postconf.5.html#smtp_defer_if_no_mx_address_found">smtp_defer_if_no_mx_address_found</a> (no)</b>
- Defer mail delivery when no MX record resolves to
+ Defer mail delivery when no MX record resolves to
an IP address.
<b><a href="postconf.5.html#smtp_line_length_limit">smtp_line_length_limit</a> (990)</b>
that Postfix will send via SMTP.
<b><a href="postconf.5.html#smtp_pix_workaround_delay_time">smtp_pix_workaround_delay_time</a> (10s)</b>
- How long the Postfix SMTP client pauses before
+ How long the Postfix SMTP client pauses before
sending ".<CR><LF>" in order to work around the PIX
firewall "<CR><LF>.<CR><LF>" bug.
<b><a href="postconf.5.html#smtp_pix_workaround_threshold_time">smtp_pix_workaround_threshold_time</a> (500s)</b>
- How long a message must be queued before the PIX
- firewall "<CR><LF>.<CR><LF>" bug workaround is
+ How long a message must be queued before the PIX
+ firewall "<CR><LF>.<CR><LF>" bug workaround is
turned on.
<b><a href="postconf.5.html#smtp_quote_rfc821_envelope">smtp_quote_rfc821_envelope</a> (yes)</b>
- Quote addresses in SMTP MAIL FROM and RCPT TO com-
+ Quote addresses in SMTP MAIL FROM and RCPT TO com-
mands as required by <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a>.
<b><a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a> (yes)</b>
(go away, do not try again later).
<b><a href="postconf.5.html#smtp_skip_quit_response">smtp_skip_quit_response</a> (yes)</b>
- Do not wait for the response to the SMTP QUIT com-
+ Do not wait for the response to the SMTP QUIT com-
mand.
Available in Postfix version 2.0 and earlier:
Available in Postfix version 2.0 and later:
<b><a href="postconf.5.html#disable_mime_output_conversion">disable_mime_output_conversion</a> (no)</b>
- Disable the conversion of 8BITMIME format to 7BIT
+ Disable the conversion of 8BITMIME format to 7BIT
format.
<b><a href="postconf.5.html#mime_boundary_length_limit">mime_boundary_length_limit</a> (2048)</b>
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtp_send_xforward_command">smtp_send_xforward_command</a> (no)</b>
- Send the non-standard XFORWARD command when the
- Postfix SMTP server EHLO response announces XFOR-
+ Send the non-standard XFORWARD command when the
+ Postfix SMTP server EHLO response announces XFOR-
WARD support.
<b>SASL AUTHENTICATION CONTROLS</b>
<b><a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> (no)</b>
- Enable SASL authentication in the Postfix SMTP
+ Enable SASL authentication in the Postfix SMTP
client.
<b><a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> (empty)</b>
- Optional SMTP client lookup tables with one user-
- name:password entry per remote hostname or domain.
+ Optional SMTP client lookup tables with one user-
+ name:password entry per remote hostname or domain.
<b><a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
- What authentication mechanisms the Postfix SMTP
+ What authentication mechanisms the Postfix SMTP
client is allowed to use.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> (empty)</b>
- If non-empty, filters the SMTP server's list of
+ If non-empty, filters the SMTP server's list of
offered SASL mechanisms.
<b>RESOURCE AND RATE CONTROLS</b>
<b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a> ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destina</a>-</b>
<b><a href="postconf.5.html#default_destination_concurrency_limit">tion_concurrency_limit</a>)</b>
- The maximal number of parallel deliveries to the
- same destination via the smtp message delivery
+ The maximal number of parallel deliveries to the
+ same destination via the smtp message delivery
transport.
<b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destina</a>-</b>
<b><a href="postconf.5.html#default_destination_recipient_limit">tion_recipient_limit</a>)</b>
- The maximal number of recipients per delivery via
+ The maximal number of recipients per delivery via
the smtp message delivery transport.
<b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
- The SMTP client time limit for completing a TCP
+ The SMTP client time limit for completing a TCP
connection, or zero (use the operating system
built-in time limit).
<b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
- The SMTP client time limit for sending the HELO or
- EHLO command, and for receiving the initial server
+ The SMTP client time limit for sending the HELO or
+ EHLO command, and for receiving the initial server
response.
<b><a href="postconf.5.html#smtp_xforward_timeout">smtp_xforward_timeout</a> (300s)</b>
command, and for receiving the server response.
<b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
- The SMTP client time limit for sending the MAIL
- FROM command, and for receiving the server
+ The SMTP client time limit for sending the MAIL
+ FROM command, and for receiving the server
response.
<b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
- The SMTP client time limit for sending the SMTP
- RCPT TO command, and for receiving the server
+ The SMTP client time limit for sending the SMTP
+ RCPT TO command, and for receiving the server
response.
<b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
- The SMTP client time limit for sending the SMTP
- DATA command, and for receiving the server
+ The SMTP client time limit for sending the SMTP
+ DATA command, and for receiving the server
response.
<b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
- The SMTP client time limit for sending the SMTP
+ The SMTP client time limit for sending the SMTP
message content.
<b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
- The SMTP client time limit for sending the SMTP
+ The SMTP client time limit for sending the SMTP
".", and for receiving the server response.
<b><a href="postconf.5.html#smtp_quit_timeout">smtp_quit_timeout</a> (300s)</b>
- The SMTP client time limit for sending the QUIT
+ The SMTP client time limit for sending the QUIT
command, and for receiving the server response.
Available in Postfix version 2.1 and later:
lookups, or zero (no limit).
<b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
- The maximal number of SMTP sessions per delivery
- request before giving up or delivering to a fall-
+ The maximal number of SMTP sessions per delivery
+ request before giving up or delivering to a fall-
back relay host, or zero (no limit).
<b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
- The SMTP client time limit for sending the RSET
+ The SMTP client time limit for sending the RSET
command, and for receiving the server response.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
- Permanently enable SMTP connection caching for the
+ Permanently enable SMTP connection caching for the
specified destinations.
<b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
- Temporarily enable SMTP connection caching while a
+ Temporarily enable SMTP connection caching while a
destination has a high volume of mail in the active
queue.
<b><a href="postconf.5.html#smtp_connection_cache_reuse_limit">smtp_connection_cache_reuse_limit</a> (10)</b>
When SMTP connection caching is enabled, the number
- of times that an SMTP session is reused before it
+ of times that an SMTP session is reused before it
is closed.
<b><a href="postconf.5.html#smtp_connection_cache_time_limit">smtp_connection_cache_time_limit</a> (2s)</b>
When SMTP connection caching is enabled, the amount
- of time that an unused SMTP client socket is kept
+ of time that an unused SMTP client socket is kept
open before it is closed.
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
- The increment in verbose logging level when a
- remote client or server matches a pattern in the
+ The increment in verbose logging level when a
+ remote client or server matches a pattern in the
<a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
<b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
- Optional list of remote client or server hostname
- or network address patterns that cause the verbose
- logging level to increase by the amount specified
+ Optional list of remote client or server hostname
+ or network address patterns that cause the verbose
+ logging level to increase by the amount specified
in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
<b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications about
- mail delivery problems that are caused by policy,
+ The recipient of postmaster notifications about
+ mail delivery problems that are caused by policy,
resource, software or protocol errors.
<b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
- The list of error classes that are reported to the
+ The list of error classes that are reported to the
postmaster.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
- Where the Postfix SMTP client should deliver mail
+ Where the Postfix SMTP client should deliver mail
when it detects a "mail loops back to myself" error
condition.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix main.cf and
+ The default location of the Postfix main.cf and
master.cf configuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to
- handle a request before it is terminated by a
+ How much time a Postfix daemon process may take to
+ handle a request before it is terminated by a
built-in watchdog timer.
<b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
- Disable DNS lookups in the Postfix SMTP and LMTP
+ Disable DNS lookups in the Postfix SMTP and LMTP
clients.
<b><a href="postconf.5.html#fallback_relay">fallback_relay</a> (empty)</b>
- Optional list of relay hosts for SMTP destinations
+ Optional list of relay hosts for SMTP destinations
that can't be found or that are unreachable.
<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
over an internal communication channel.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
- The maximum amount of time that an idle Postfix
- daemon process waits for the next service request
+ The maximum amount of time that an idle Postfix
+ daemon process waits for the next service request
before exiting.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
- The maximal number of connection requests before a
+ The maximal number of connection requests before a
Postfix daemon process terminates.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
- The process ID of a Postfix command or daemon pro-
+ The process ID of a Postfix command or daemon pro-
cess.
<b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
The network interface addresses that this mail sys-
- tem receives mail on by way of a proxy or network
+ tem receives mail on by way of a proxy or network
address translation unit.
<b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
client should bind to when making a connection.
<b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
- The hostname to send in the SMTP EHLO or HELO com-
+ The hostname to send in the SMTP EHLO or HELO com-
mand.
<b><a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a> (dns)</b>
- What mechanisms when the SMTP client uses to look
+ What mechanisms when the SMTP client uses to look
up a host's IP address.
<b><a href="postconf.5.html#smtp_randomize_addresses">smtp_randomize_addresses</a> (yes)</b>
- Randomize the order of equal-preference MX host
+ Randomize the order of equal-preference MX host
addresses.
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
- The mail system name that is prepended to the pro-
+ The mail system name that is prepended to the pro-
cess name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
<a href="bounce.8.html">bounce(8)</a>, delivery status reports
<a href="scache.8.html">scache(8)</a>, connection cache server
<a href="postconf.5.html">postconf(5)</a>, configuration parameters
+ <a href="master.5.html">master(5)</a>, generic daemon options
<a href="master.8.html">master(8)</a>, process manager
syslogd(8), system logging
<a href="SASL_README.html">SASL_README</a>, Postfix SASL howto
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
explicit <a href="postconf.5.html#reject_unlisted_recipient">reject_unlisted_recipient</a> access restric-
tion is specified.
+ Available in Postfix version 2.2 and later:
+
+ <b><a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a> (empty)</b>
+ Optional access restrictions that the Postfix SMTP
+ server applies in the context of the SMTP END-OF-
+ DATA command.
+
<b>SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS</b>
Postfix version 2.1 introduces sender and recipient
address verification. This feature is implemented by
<a href="trivial-rewrite.8.html">trivial-rewrite(8)</a>, address resolver
<a href="verify.8.html">verify(8)</a>, address verification service
<a href="postconf.5.html">postconf(5)</a>, configuration parameters
+ <a href="master.5.html">master(5)</a>, generic daemon options
<a href="master.8.html">master(8)</a>, process manager
syslogd(8), system logging
5.[0-4]) CCARGS="$CCARGS -DMISSING_USLEEP";;
*) CCARGS="$CCARGS -DHAS_POSIX_REGEXP";;
esac
+ CCARGS="$CCARGS -DCANT_WRITE_BEFORE_SENDING_FD"
# Solaris 9 added closefrom()
case $RELEASE in
5.9*|5.[1-9][0-9]*) CCARGS="$CCARGS -DHAS_CLOSEFROM";;
client TLS certificate is successfully verified, regardless of
whether it is listed on the server, and regardless of the certifying
authority.
-.IP "\fB check_address_map \fI<a
-href="DATABASE_README.html">type:table\fR \fR"
-.IP "\fB \fItype:table\fR
-\fR"
+.IP "\fB check_address_map \fItype:table\fR \fR"
+.IP "\fB \fItype:table\fR \fR"
Append the domain name in $myorigin or $mydomain when the
client IP address matches the specified lookup table. The lookup
result is ignored, and no subnet lookup is done. This is suitable
application.
.br
NOTE: this restriction can only work reliably
-when used in smtpd_data_restrictions, because the total number of
+when used in smtpd_data_restrictions or
+smtpd_end_of_data_restrictions, because the total number of
recipients is not known at an earlier stage of the SMTP conversation.
Use at the RCPT stage will only reject the second etc. recipient.
.br
recipient address information when rejecting a client name/address
or sender address, so that it is possible to find out whose mail
is being rejected.
+.SH smtpd_end_of_data_restrictions (default: empty)
+Optional access restrictions that the Postfix SMTP server
+applies in the context of the SMTP END-OF-DATA command.
+.PP
+This feature is available in Postfix 2.2 and later.
+.PP
+See smtpd_data_restrictions for syntax details.
.SH smtpd_error_sleep_time (default: 1s)
With Postfix 2.1 and later: the SMTP server response delay after
a client has made more than $smtpd_soft_error_limit errors, and
trivial-rewrite(8), address routing
bounce(8), delivery status reports
postconf(5), configuration parameters
+master(5), generic daemon options
master(8), process manager
syslogd(8) system logging
.SH "README FILES"
to a recoverable error condition, the SMTP client will try to
deliver the mail to an alternate host.
-After a successful mail transaction, a session may be saved
+After a successful mail transaction, a connection may be saved
to the \fBscache(8)\fR connection cache server, so that it
may be used by any SMTP client for a subsequent transaction.
exist without closing the session, which defeats the purpose.
SMTP connection caching assumes that SASL credentials are valid for
-all destinations that map onto the same IP address and TCP port,
-and for all sender and recipient addresses.
+all destinations that map onto the same IP address and TCP port.
.SH "CONFIGURATION PARAMETERS"
.na
.nf
bounce(8), delivery status reports
scache(8), connection cache server
postconf(5), configuration parameters
+master(5), generic daemon options
master(8), process manager
syslogd(8), system logging
.SH "README FILES"
Request that the Postfix SMTP server rejects mail for unknown
recipient addresses, even when no explicit reject_unlisted_recipient
access restriction is specified.
+.PP
+Available in Postfix version 2.2 and later:
+.IP "\fBsmtpd_end_of_data_restrictions (empty)\fR"
+Optional access restrictions that the Postfix SMTP server
+applies in the context of the SMTP END-OF-DATA command.
.SH "SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS"
.na
.nf
trivial-rewrite(8), address resolver
verify(8), address verification service
postconf(5), configuration parameters
+master(5), generic daemon options
master(8), process manager
syslogd(8), system logging
.SH "README FILES"
s;\bsmtpd_client_restrictions\b;<a href="postconf.5.html#smtpd_client_restrictions">$&</a>;g;
s;\bsmtpd_data_restrictions\b;<a href="postconf.5.html#smtpd_data_restrictions">$&</a>;g;
s;\bsmtpd_delay_reject\b;<a href="postconf.5.html#smtpd_delay_reject">$&</a>;g;
+ s;\bsmtpd_end_of_data_restrictions\b;<a href="postconf.5.html#smtpd_end_of_data_restrictions">$&</a>;g;
s;\bsmtpd_error_sleep_time\b;<a href="postconf.5.html#smtpd_error_sleep_time">$&</a>;g;
s;\bsmtpd_etrn_restrictions\b;<a href="postconf.5.html#smtpd_etrn_restrictions">$&</a>;g;
s;\bsmtpd_expansion_filter\b;<a href="postconf.5.html#smtpd_expansion_filter">$&</a>;g;
<tr> <td> smtpd_data_restrictions </td> <td> Optional </td> <td>
Reject DATA command </td> </tr>
+<tr> <td> smtpd_end_of_data_restrictions </td> <td> Optional </td> <td>
+Reject END-OF-DATA command </td> </tr>
+
<tr> <td> smtpd_etrn_restrictions </td> <td> Optional </td> <td>
Reject ETRN command </td> </tr>
helo and sender restriction lists until the RCPT TO or ETRN command.
This behavior is controlled by the smtpd_delay_reject parameter.
Restriction lists are still evaluated in the proper order of (client,
-helo, etrn) or (client, helo, sender, recipient, data) restrictions.
+helo, etrn) or (client, helo, sender, recipient, data, or end-of-data)
+restrictions.
When a restriction list (example: client) evaluates to REJECT or
DEFER the other restriction lists (example: helo, sender, etc.)
are skipped. </p>
<li> <p> The "instance" attribute value can be used to correlate
different requests regarding the same message delivery. </p>
+ <li> <p> The "size" attribute value specifies the message size
+ that the client specified in the MAIL FROM command (zero if
+ none was specified). With Postfix 2.2 and later, it specifies
+ the actual message size when the client sends the END-OF-DATA
+ command.
+ </p>
+
</ul>
<p> The following is specific to SMTPD delegated policy requests:
<li> <p> Protocol names are ESMTP or SMTP. </p>
<li> <p> Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT,
- DATA, VRFY or ETRN; these are the SMTP protocol states where
+ DATA, END-OF-DATA, VRFY or ETRN; these are the SMTP protocol
+ states where
the Postfix SMTP server makes an OK/REJECT/HOLD/etc. decision.
</p>
and the message has multiple envelope recipients. Although this
usage is technically allowed, it seems to have no legitimate
application. <br> NOTE: this restriction can only work reliably
-when used in smtpd_data_restrictions, because the total number of
+when used in smtpd_data_restrictions or
+smtpd_end_of_data_restrictions, because the total number of
recipients is not known at an earlier stage of the SMTP conversation.
Use at the RCPT stage will only reject the second etc. recipient.
<br>
smtpd_data_restrictions = reject_multi_recipient_bounce
</pre>
+%PARAM smtpd_end_of_data_restrictions
+
+<p> Optional access restrictions that the Postfix SMTP server
+applies in the context of the SMTP END-OF-DATA command. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p> See smtpd_data_restrictions for syntax details. </p>
+
%PARAM smtpd_delay_reject yes
<p>
whether it is listed on the server, and regardless of the certifying
authority. </dd>
-<dt><b> <a name="check_address_map">check_address_map</a> <i><a
-href="DATABASE_README.html">type:table</a></i> </b></dt>
+<dt><b> <a name="check_address_map">check_address_map</a> <i><a href="DATABASE_README.html">type:table</a></i> </b></dt>
-<dt><b> <i><a href="DATABASE_README.html">type:table</a></i>
-</b></dt>
+<dt><b> <i><a href="DATABASE_README.html">type:table</a></i> </b></dt>
<dd> Append the domain name in $myorigin or $mydomain when the
client IP address matches the specified lookup table. The lookup
myfree(sbuf);
return;
}
+ /* Zero-length values are place holders for unavailable values. */
+ if (*attr_value == 0) {
+ msg_warn("%s: spurious null attribute value for \"%s\" -- ignored",
+ state->queue_id, attr_name);
+ myfree(sbuf);
+ return;
+ }
if (strcmp(attr_name, MAIL_ATTR_RWR_CONTEXT) == 0) {
/* Choose header rewriting context. See also cleanup_addr.c. */
if (STREQ(attr_value, MAIL_ATTR_RWR_LOCAL)) {
state->hdr_rewrite_context = MAIL_ATTR_RWR_LOCAL;
} else if (STREQ(attr_value, MAIL_ATTR_RWR_REMOTE)) {
- state->hdr_rewrite_context =
- (*var_remote_rwr_domain ? MAIL_ATTR_RWR_REMOTE : 0);
+ state->hdr_rewrite_context =
+ (*var_remote_rwr_domain ? MAIL_ATTR_RWR_REMOTE : 0);
} else {
- msg_warn("%s: message rejected: bad rewriting context: %.100s",
- state->queue_id, attr_value);
- state->errs |= CLEANUP_STAT_BAD;
- return;
+ msg_warn("%s: message rejected: bad rewriting context: %.100s",
+ state->queue_id, attr_value);
+ state->errs |= CLEANUP_STAT_BAD;
+ return;
}
}
nvtable_update(state->attr, attr_name, attr_value);
state->rcpt_count = 0;
state->reason = 0;
state->attr = nvtable_create(10);
+ nvtable_update(state->attr, MAIL_ATTR_ORIGIN, MAIL_ATTR_ORG_LOCAL);
state->mime_state = 0;
state->mime_errs = 0;
state->hdr_rewrite_context = MAIL_ATTR_RWR_LOCAL;
{
HEADER *reply_header;
int len;
- unsigned long saved_options = _res.options;
+ unsigned long saved_options;
/*
* Initialize the name service.
if ((flags & USER_FLAGS) != flags)
msg_panic("dns_query: bad flags: %d", flags);
- _res.options &= ~(USER_FLAGS);
+ saved_options = (_res.options & USER_FLAGS);
+ _res.options &= ~saved_options;
_res.options |= flags;
/*
* only if the name server told us so.
*/
len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
- _res.options = saved_options;
+ _res.options &= ~flags;
+ _res.options |= saved_options;
if (len < 0) {
if (why)
vstring_sprintf(why, "Host or domain name not found. "
* Expand $debugger_command then run it.
*/
command = mail_conf_lookup_eval(VAR_DEBUG_COMMAND);
- if (*command == 0)
+ if (command == 0 || *command == 0)
msg_fatal("no %s variable set up", VAR_DEBUG_COMMAND);
msg_info("running: %s", command);
system(command);
#define DEF_DATA_CHECKS ""
extern char *var_data_checks;
+#define VAR_EOD_CHECKS "smtpd_end_of_data_restrictions"
+#define DEF_EOD_CHECKS ""
+extern char *var_eod_checks;
+
#define VAR_REST_CLASSES "smtpd_restriction_classes"
#define DEF_REST_CLASSES ""
extern char *var_rest_classes;
* Patches change the patchlevel and the release date. Snapshots change the
* release date only.
*/
-#define MAIL_RELEASE_DATE "20041030"
+#define MAIL_RELEASE_DATE "20041118"
#define MAIL_VERSION_NUMBER "2.2"
#define VAR_MAIL_VERSION "mail_version"
* designated sender: mailing list owner, posting user, whatever.
*/
rec_fprintf(cleanup, REC_TYPE_TIME, "%ld", (long) info->posting_time);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_CLIENT_NAME, request->client_name);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_CLIENT_ADDR, request->client_addr);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_PROTO_NAME, request->client_proto);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_HELO_NAME, request->client_helo);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_SASL_METHOD, request->sasl_method);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_SASL_USERNAME, request->sasl_username);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_SASL_SENDER, request->sasl_sender);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_RWR_CONTEXT, request->rewrite_context);
rec_fputs(cleanup, REC_TYPE_FROM, sender);
+ /*
+ * Zero-length attribute values are place holders for unavailable
+ * attribute values. See qmgr_message.c. They are not meant to be
+ * propagated to queue files.
+ */
+#define PASS_ATTR(fp, name, value) do { \
+ if ((value) && *(value)) \
+ rec_fprintf((fp), REC_TYPE_ATTR, "%s=%s", (name), (value)); \
+ } while (0)
+
+ PASS_ATTR(cleanup, MAIL_ATTR_CLIENT_NAME, request->client_name);
+ PASS_ATTR(cleanup, MAIL_ATTR_CLIENT_ADDR, request->client_addr);
+ PASS_ATTR(cleanup, MAIL_ATTR_PROTO_NAME, request->client_proto);
+ PASS_ATTR(cleanup, MAIL_ATTR_HELO_NAME, request->client_helo);
+ PASS_ATTR(cleanup, MAIL_ATTR_SASL_METHOD, request->sasl_method);
+ PASS_ATTR(cleanup, MAIL_ATTR_SASL_USERNAME, request->sasl_username);
+ PASS_ATTR(cleanup, MAIL_ATTR_SASL_SENDER, request->sasl_sender);
+ PASS_ATTR(cleanup, MAIL_ATTR_RWR_CONTEXT, request->rewrite_context);
+
vstring_free(buffer);
return (info);
}
typedef struct MASTER_PROC {
MASTER_PID pid; /* child process id */
+ unsigned gen; /* child generation number */
int avail; /* availability */
MASTER_SERV *serv; /* parent linkage */
int use_count; /* number of service requests */
/* SYNOPSIS
/* #include <master_proto.h>
/*
-/* int master_notify(pid, status)
+/* int master_notify(pid, generation, status)
/* int pid;
+/* unsigned generation;
/* int status;
/* DESCRIPTION
/* The master process provides a standard environment for its
#include "master_proto.h"
-int master_notify(int pid, int status)
+int master_notify(int pid, unsigned generation, int status)
{
char *myname = "master_notify";
MASTER_STATUS stat;
* bad status code will only have amusement value.
*/
stat.pid = pid;
+ stat.gen = generation;
stat.avail = status;
if (write(MASTER_STATUS_FD, (char *) &stat, sizeof(stat)) != sizeof(stat)) {
*/
typedef struct MASTER_STATUS {
int pid; /* process ID */
+ unsigned gen; /* child generation number */
int avail; /* availability */
} MASTER_STATUS;
+#define MASTER_GEN_NAME "GENERATION" /* passed via environment */
+
#define MASTER_STAT_TAKEN 0 /* this one is occupied */
#define MASTER_STAT_AVAIL 1 /* this process is idle */
-extern int master_notify(int, int); /* encapsulate status msg */
+extern int master_notify(int, unsigned, int); /* encapsulate status msg */
/*
* File descriptors inherited from the master process. The flow control pipe
#include <syslog.h> /* closelog() */
#include <signal.h>
#include <stdarg.h>
+#include <syslog.h>
/* Utility libraries. */
#include <binhash.h>
#include <mymalloc.h>
#include <events.h>
+#include <vstring.h>
#include <argv.h>
-#include <syslog.h>
/* Application-specific. */
MASTER_PROC *proc;
MASTER_PID pid;
int n;
+ static unsigned master_generation = 0;
+ static VSTRING *env_gen = 0;
if (master_child_table == 0)
master_child_table = binhash_create(0);
+ if (env_gen == 0)
+ env_gen = vstring_alloc(100);
/*
* Sanity checks. The master_avail module is supposed to know what it is
* Create a child process and connect parent and child via the status
* pipe.
*/
+ master_generation += 1;
switch (pid = fork()) {
/*
myname, serv->listen_fd[n]);
(void) close(serv->listen_fd[n]);
}
+ vstring_sprintf(env_gen, "%s=%o", MASTER_GEN_NAME, master_generation);
+ if (putenv(vstring_str(env_gen)) < 0)
+ msg_fatal("%s: putenv: %m", myname);
+
execvp(serv->path, serv->args->argv);
msg_fatal("%s: exec %s: %m", myname, serv->path);
exit(1);
proc = (MASTER_PROC *) mymalloc(sizeof(MASTER_PROC));
proc->serv = serv;
proc->pid = pid;
+ proc->gen = master_generation;
proc->use_count = 0;
proc->avail = 0;
binhash_enter(master_child_table, (char *) &pid,
/* NOTREACHED */
default:
- msg_warn("%s: partial status (%d bytes)", myname, n);
+ msg_warn("service %s: child (pid %d) sent partial status update (%d bytes)",
+ serv->name, stat.pid, n);
return;
case sizeof(stat):
pid = stat.pid;
if (msg_verbose)
- msg_info("%s: pid %d avail %d", myname, stat.pid, stat.avail);
+ msg_info("%s: pid %d gen %u avail %d",
+ myname, stat.pid, stat.gen, stat.avail);
}
/*
msg_info("%s: process id not found: %d", myname, stat.pid);
return;
}
+ if (proc->gen != stat.gen) {
+ msg_info("ignoring status update from child pid %d generation %u",
+ pid, stat.gen);
+ return;
+ }
if (proc->serv != serv)
msg_panic("%s: pointer corruption: %p != %p",
myname, (void *) proc->serv, (void *) serv);
#include <signal.h>
#include <syslog.h>
#include <stdlib.h>
+#include <limits.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
static void (*multi_server_pre_accept) (char *, char **);
static VSTREAM *multi_server_lock;
static int multi_server_in_flow_delay;
+static unsigned multi_server_generation;
static void (*multi_server_pre_disconn) (VSTREAM *, char *, char **);
/* multi_server_exit - normal termination */
* Do not bother the application when the client disconnected.
*/
if (peekfd(vstream_fileno(stream)) > 0) {
- if (master_notify(var_pid, MASTER_STAT_TAKEN) < 0)
+ if (master_notify(var_pid, multi_server_generation, MASTER_STAT_TAKEN) < 0)
multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
multi_server_service(stream, multi_server_name, multi_server_argv);
- if (master_notify(var_pid, MASTER_STAT_AVAIL) < 0)
+ if (master_notify(var_pid, multi_server_generation, MASTER_STAT_AVAIL) < 0)
multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
} else {
multi_server_disconnect(stream);
int zerolimit = 0;
WATCHDOG *watchdog;
char *oval;
+ char *generation;
/*
* Process environment options as early as we can.
msg_fatal("unsupported transport type: %s", transport);
}
+ /*
+ * Retrieve process generation from environment.
+ */
+ if ((generation = getenv(MASTER_GEN_NAME)) != 0) {
+ if (!alldig(generation))
+ msg_fatal("bad generation: %s", generation);
+ multi_server_generation = strtoul(generation, (char **) 0, 8);
+ }
+
/*
* Optionally start the debugger on ourself.
*/
#include <signal.h>
#include <syslog.h>
#include <stdlib.h>
+#include <limits.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
static void (*single_server_pre_accept) (char *, char **);
static VSTREAM *single_server_lock;
static int single_server_in_flow_delay;
+static unsigned single_server_generation;
/* single_server_exit - normal termination */
vstream_control(stream, VSTREAM_CTL_PATH, tmp, VSTREAM_CTL_END);
myfree(tmp);
timed_ipc_setup(stream);
- if (master_notify(var_pid, MASTER_STAT_TAKEN) < 0)
+ if (master_notify(var_pid, single_server_generation, MASTER_STAT_TAKEN) < 0)
single_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
if (single_server_in_flow_delay && mail_flow_get(1) < 0)
doze(var_in_flow_delay * 1000000);
single_server_service(stream, single_server_name, single_server_argv);
(void) vstream_fclose(stream);
- if (master_notify(var_pid, MASTER_STAT_AVAIL) < 0)
+ if (master_notify(var_pid, single_server_generation, MASTER_STAT_AVAIL) < 0)
single_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
if (msg_verbose)
msg_info("connection closed");
int zerolimit = 0;
WATCHDOG *watchdog;
char *oval;
+ char *generation;
/*
* Process environment options as early as we can.
msg_fatal("unsupported transport type: %s", transport);
}
+ /*
+ * Retrieve process generation from environment.
+ */
+ if ((generation = getenv(MASTER_GEN_NAME)) != 0) {
+ if (!alldig(generation))
+ msg_fatal("bad generation: %s", generation);
+ single_server_generation = strtoul(generation, (char **) 0, 8);
+ }
+
/*
* Optionally start the debugger on ourself.
*/
#include <signal.h>
#include <syslog.h>
#include <stdlib.h>
+#include <limits.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
static void (*trigger_server_pre_accept) (char *, char **);
static VSTREAM *trigger_server_lock;
static int trigger_server_in_flow_delay;
+static unsigned trigger_server_generation;
/* trigger_server_exit - normal termination */
/*
* Commit suicide when the master process disconnected from us.
*/
- if (master_notify(var_pid, MASTER_STAT_TAKEN) < 0)
+ if (master_notify(var_pid, trigger_server_generation, MASTER_STAT_TAKEN) < 0)
trigger_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
if (trigger_server_in_flow_delay && mail_flow_get(1) < 0)
doze(var_in_flow_delay * 1000000);
if ((len = read(fd, buf, sizeof(buf))) >= 0)
trigger_server_service(buf, len, trigger_server_name,
trigger_server_argv);
- if (master_notify(var_pid, MASTER_STAT_AVAIL) < 0)
+ if (master_notify(var_pid, trigger_server_generation, MASTER_STAT_AVAIL) < 0)
trigger_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
if (var_idle_limit > 0)
event_request_timer(trigger_server_timeout, (char *) 0, var_idle_limit);
int zerolimit = 0;
WATCHDOG *watchdog;
char *oval;
+ char *generation;
/*
* Process environment options as early as we can.
msg_fatal("unsupported transport type: %s", transport);
}
+ /*
+ * Retrieve process generation from environment.
+ */
+ if ((generation = getenv(MASTER_GEN_NAME)) != 0) {
+ if (!alldig(generation))
+ msg_fatal("bad generation: %s", generation);
+ trigger_server_generation = strtoul(generation, (char **) 0, 8);
+ }
+
/*
* Optionally start the debugger on ourself.
*/
if (message->sasl_sender == 0)
message->sasl_sender = mystrdup("");
if (message->rewrite_context == 0)
- message->rewrite_context = mystrdup("");
+ message->rewrite_context = mystrdup(MAIL_ATTR_RWR_LOCAL);
/*
* Clean up.
if (*var_filter_xport)
rec_fprintf(cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
- /*
- * Origin is local.
- */
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_ORIGIN, MAIL_ATTR_ORG_LOCAL);
- rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_RWR_CONTEXT, MAIL_ATTR_RWR_LOCAL);
-
/*
* Copy the message envelope segment. Allow only those records that we
* expect to see in the envelope section. The envelope segment must
/* trivial-rewrite(8), address routing
/* bounce(8), delivery status reports
/* postconf(5), configuration parameters
+/* master(5), generic daemon options
/* master(8), process manager
/* syslogd(8) system logging
/* README FILES
if (message->sasl_sender == 0)
message->sasl_sender = mystrdup("");
if (message->rewrite_context == 0)
- message->rewrite_context = mystrdup("");
+ message->rewrite_context = mystrdup(MAIL_ATTR_RWR_LOCAL);
/*
* Clean up.
/* bounce(8), delivery status reports
/* scache(8), connection cache server
/* postconf(5), configuration parameters
+/* master(5), generic daemon options
/* master(8), process manager
/* syslogd(8), system logging
/* README FILES
/* Request that the Postfix SMTP server rejects mail for unknown
/* recipient addresses, even when no explicit reject_unlisted_recipient
/* access restriction is specified.
+/* .PP
+/* Available in Postfix version 2.2 and later:
+/* .IP "\fBsmtpd_end_of_data_restrictions (empty)\fR"
+/* Optional access restrictions that the Postfix SMTP server
+/* applies in the context of the SMTP END-OF-DATA command.
/* SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS
/* .ad
/* .fi
/* trivial-rewrite(8), address resolver
/* verify(8), address verification service
/* postconf(5), configuration parameters
+/* master(5), generic daemon options
/* master(8), process manager
/* syslogd(8), system logging
/* README FILES
char *var_rcpt_checks;
char *var_etrn_checks;
char *var_data_checks;
+char *var_eod_checks;
int var_unk_client_code;
int var_bad_name_code;
int var_unk_name_code;
static void mail_reset(SMTPD_STATE *state)
{
state->msg_size = 0;
+ state->act_size = 0;
/*
* Unceremoniously close the pipe to the cleanup service. The cleanup
if (prev_rec_type != REC_TYPE_CONT && *start == '.'
&& (state->proxy == 0 ? (++start, --len) == 0 : len == 1))
break;
+ state->act_size += len + 2;
if (state->err == CLEANUP_STAT_OK
&& out_record(out_stream, curr_rec_type, start, len) < 0)
state->err = out_error;
}
+ state->where = SMTPD_AFTER_DOT;
+ if (SMTPD_STAND_ALONE(state) == 0 && (err = smtpd_check_eod(state)) != 0) {
+ smtpd_chat_reply(state, "%s", err);
+ if (state->proxy) {
+ smtpd_proxy_close(state);
+ } else {
+ mail_stream_cleanup(state->dest);
+ state->dest = 0;
+ state->cleanup = 0;
+ }
+ return (-1);
+ }
/*
* Send the end of DATA and finish the proxy connection. Set the
smtpd_chat_reply(state, "451 Error: internal error %d", state->err);
}
- /*
- * Disconnect after transmission must not be treated as "lost connection
- * after DATA".
- */
- state->where = SMTPD_AFTER_DOT;
-
/*
* Cleanup. The client may send another MAIL command.
*/
VAR_RCPT_CHECKS, DEF_RCPT_CHECKS, &var_rcpt_checks, 0, 0,
VAR_ETRN_CHECKS, DEF_ETRN_CHECKS, &var_etrn_checks, 0, 0,
VAR_DATA_CHECKS, DEF_DATA_CHECKS, &var_data_checks, 0, 0,
+ VAR_EOD_CHECKS, DEF_EOD_CHECKS, &var_eod_checks, 0, 0,
VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0,
VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0,
VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
char *where; /* protocol stage */
int recursion; /* Kellerspeicherpegelanzeiger */
off_t msg_size; /* MAIL FROM message size */
+ off_t act_size; /* END-OF-DATA message size */
int junk_cmds; /* counter */
int rcpt_overshoot; /* counter */
char *rewrite_context; /* address rewriting context */
/*
/* char *smtpd_check_data(state)
/* SMTPD_STATE *state;
+/*
+/* char *smtpd_check_eod(state)
+/* SMTPD_STATE *state;
/* DESCRIPTION
/* This module implements additional checks on SMTP client requests.
/* A client request is validated in the context of the session state.
/* smtpd_check_data() enforces generic restrictions after the
/* client has sent the DATA command.
/*
+/* smtpd_check_eod() enforces generic restrictions after the
+/* client has sent the END-OF-DATA command.
+/*
/* Arguments:
/* .IP name
/* The client hostname, or \fIunknown\fR.
static ARGV *rcpt_restrctions;
static ARGV *etrn_restrctions;
static ARGV *data_restrctions;
+static ARGV *eod_restrictions;
static HTABLE *smtpd_rest_classes;
static HTABLE *policy_clnt_table;
#define SMTPD_NAME_RECIPIENT "Recipient address"
#define SMTPD_NAME_ETRN "Etrn command"
#define SMTPD_NAME_DATA "Data command"
+#define SMTPD_NAME_EOD "End-of-data"
/*
* YASLM.
var_etrn_checks);
data_restrctions = smtpd_check_parse(SMTPD_CHECK_PARSE_ALL,
var_data_checks);
+ eod_restrictions = smtpd_check_parse(SMTPD_CHECK_PARSE_ALL,
+ var_eod_checks);
/*
* Parse the pre-defined restriction classes.
ATTR_TYPE_STR, MAIL_ATTR_INSTANCE,
STR(state->instance),
ATTR_TYPE_LONG, MAIL_ATTR_SIZE,
- (unsigned long) state->msg_size,
+ (unsigned long) (state->act_size > 0 ?
+ state->act_size : state->msg_size),
#ifdef USE_SASL_AUTH
ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD,
var_smtpd_sasl_enable && state->sasl_method ?
int status;
char **cpp;
DICT *dict;
+ char *name;
/*
* We don't use generic_checks() because it produces results that aren't
if (msg_verbose)
msg_info("%s: trying: %s", myname, *cpp);
status = SMTPD_CHECK_DUNNO;
- if (strcasecmp(*cpp, PERMIT_MYNETWORKS) == 0) {
+ if (strchr(name = *cpp, ':') != 0) {
+ name = CHECK_ADDR_MAP;
+ cpp -= 1;
+ }
+ if (strcasecmp(name, PERMIT_MYNETWORKS) == 0) {
status = permit_mynetworks(state);
- } else if (is_map_command(state, *cpp, CHECK_ADDR_MAP, &cpp)) {
- if ((dict = dict_handle(*cpp)) == 0)
- msg_panic("%s: dictionary not found: %s", myname, *cpp);
+ } else if (is_map_command(state, name, CHECK_ADDR_MAP, &cpp)) {
+ if ((dict = dict_handle(name)) == 0)
+ msg_panic("%s: dictionary not found: %s", myname, name);
if (dict_get(dict, state->addr) != 0)
status = SMTPD_CHECK_OK;
- } else if (strcasecmp(*cpp, PERMIT_SASL_AUTH) == 0) {
+ } else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) {
#ifdef USE_SASL_AUTH
status = permit_sasl_auth(state, SMTPD_CHECK_OK,
SMTPD_CHECK_DUNNO);
#else
status = SMTPD_CHECK_DUNNO;
#endif
-#ifdef USE_SSL
- } else if (strcasecmp(*cpp, PERMIT_TLS_ALL_CLIENTCERTS) == 0) {
+#ifdef USE_TLS
+ } else if (strcasecmp(name, PERMIT_TLS_ALL_CLIENTCERTS) == 0) {
status = permit_tls_clientcerts(state, 1);
- } else if (strcasecmp(*cpp, PERMIT_TLS_CLIENTCERTS) == 0) {
+ } else if (strcasecmp(name, PERMIT_TLS_CLIENTCERTS) == 0) {
status = permit_tls_clientcerts(state, 0);
#endif
} else {
msg_warn("parameter %s: invalid request: %s",
- VAR_LOC_RWR_CLIENTS, *cpp);
+ VAR_LOC_RWR_CLIENTS, name);
continue;
}
if (status == SMTPD_CHECK_OK) {
return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
}
+/* smtpd_check_eod - check end-of-data command */
+
+char *smtpd_check_eod(SMTPD_STATE *state)
+{
+ int status;
+ char *NOCLOBBER saved_recipient;
+
+ /*
+ * Minor kluge so that we can delegate work to the generic routine. We
+ * provide no recipient information in the case of multiple recipients,
+ * This restriction applies to all recipients alike, and logging only one
+ * of them would be misleading.
+ */
+ if (state->rcpt_count > 1) {
+ saved_recipient = state->recipient;
+ state->recipient = 0;
+ }
+
+ /*
+ * Reset the defer_if_permit flag. This is necessary when some recipients
+ * were accepted but the last one was rejected.
+ */
+ state->defer_if_permit.active = 0;
+
+ /*
+ * Apply restrictions in the order as specified.
+ *
+ * XXX We cannot specify a default target for a bare access map.
+ */
+ SMTPD_CHECK_RESET();
+ status = setjmp(smtpd_check_buf);
+ if (status == 0 && eod_restrictions->argc)
+ status = generic_checks(state, eod_restrictions,
+ "END-OF-DATA", SMTPD_NAME_EOD, NO_DEF_ACL);
+
+ /*
+ * Force permission into deferral when some earlier temporary error may
+ * have prevented us from rejecting mail, and report the earlier problem.
+ */
+ if (status != SMTPD_CHECK_REJECT && state->defer_if_permit.active)
+ status = smtpd_check_reject(state, state->defer_if_permit.class,
+ "%s", STR(state->defer_if_permit.reason));
+
+ if (state->rcpt_count > 1)
+ state->recipient = saved_recipient;
+
+ return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
+}
+
#ifdef TEST
/*
extern char *smtpd_check_rcpt(SMTPD_STATE *, char *);
extern char *smtpd_check_etrn(SMTPD_STATE *, char *);
extern char *smtpd_check_data(SMTPD_STATE *);
+extern char *smtpd_check_eod(SMTPD_STATE *);
extern char *smtpd_check_policy(SMTPD_STATE *, char *);
/* LICENSE
state->where = SMTPD_AFTER_CONNECT;
state->recursion = 0;
state->msg_size = 0;
+ state->act_size = 0;
state->junk_cmds = 0;
state->rcpt_overshoot = 0;
state->defer_if_permit_client = 0;
*/
if (buf == 0)
buf = vstring_alloc(10);
- if (loop++ == 0)
+ if (loop++ == 0) {
VSTRING_RESET(buf);
+ VSTRING_TERMINATE(buf);
+ }
ctxt.buf = buf;
ctxt.recursive = recursive;
ctxt.dict_name = dict_name;