From: Wietse Venema Date: Thu, 18 Nov 2004 05:00:00 +0000 (-0500) Subject: postfix-2.2-20041118 X-Git-Tag: v2.2.0-RC1~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c2a5cbdc7fcae4f587b2a2a9ad46a4538f6fea1a;p=thirdparty%2Fpostfix.git postfix-2.2-20041118 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 190e4536e..3217de6ca 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -9823,6 +9823,63 @@ Apologies for any names omitted. 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 diff --git a/postfix/README_FILES/SMTPD_ACCESS_README b/postfix/README_FILES/SMTPD_ACCESS_README index 3e442b0c6..dac578645 100644 --- a/postfix/README_FILES/SMTPD_ACCESS_README +++ b/postfix/README_FILES/SMTPD_ACCESS_README @@ -136,21 +136,23 @@ The table below summarizes the purpose of each SMTP access restriction list. 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. - _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - |RReessttrriiccttiioonn lliisstt nnaammee |SSttaattuuss |EEffffeecctt ooff RREEJJEECCTT oorr DDEEFFEERR rreessuulltt| - |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | - |smtpd_client_restrictions |Optional|Reject all client commands | - |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | - |smtpd_helo_restrictions |Optional|Reject HELO/EHLO information | - |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | - |smtpd_sender_restrictions |Optional|Reject MAIL FROM information | - |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | - |smtpd_recipient_restrictions|Required|Reject RCPT TO information | - |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | - |smtpd_data_restrictions |Optional|Reject DATA command | - |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | - |smtpd_etrn_restrictions |Optional|Reject ETRN command | - |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + |RReessttrriiccttiioonn lliisstt nnaammee |SSttaattuuss |EEffffeecctt ooff RREEJJEECCTT oorr DDEEFFEERR rreessuulltt| + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |smtpd_client_restrictions |Optional|Reject all client commands | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |smtpd_helo_restrictions |Optional|Reject HELO/EHLO information | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |smtpd_sender_restrictions |Optional|Reject MAIL FROM information | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |smtpd_recipient_restrictions |Required|Reject RCPT TO information | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |smtpd_data_restrictions |Optional|Reject DATA command | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |smtpd_end_of_data_restrictions|Optional|Reject END-OF-DATA command | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | + |smtpd_etrn_restrictions |Optional|Reject ETRN command | + |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | DDeellaayyeedd eevvaalluuaattiioonn ooff SSMMTTPP aacccceessss rreessttrriiccttiioonn lliissttss @@ -165,9 +167,9 @@ Current Postfix versions postpone the evaluation of client, 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. 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 diff --git a/postfix/README_FILES/SMTPD_POLICY_README b/postfix/README_FILES/SMTPD_POLICY_README index b485acf95..34ef8ba2c 100644 --- a/postfix/README_FILES/SMTPD_POLICY_README +++ b/postfix/README_FILES/SMTPD_POLICY_README @@ -75,13 +75,18 @@ Notes: * 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. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 98c353b44..784c0de8a 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -7,6 +7,21 @@ snapshot release). Patches are issued for the official release 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 ======================================================= diff --git a/postfix/html/SMTPD_ACCESS_README.html b/postfix/html/SMTPD_ACCESS_README.html index 3435f7ef2..a91bec999 100644 --- a/postfix/html/SMTPD_ACCESS_README.html +++ b/postfix/html/SMTPD_ACCESS_README.html @@ -216,6 +216,9 @@ Reject MAIL FROM information smtpd_data_restrictions Optional Reject DATA command + smtpd_end_of_data_restrictions Optional +Reject END-OF-DATA command + smtpd_etrn_restrictions Optional Reject ETRN command @@ -238,7 +241,8 @@ and so on. This approach turned out to be difficult to use.

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.

diff --git a/postfix/html/SMTPD_POLICY_README.html b/postfix/html/SMTPD_POLICY_README.html index 5f6903478..3ee862527 100644 --- a/postfix/html/SMTPD_POLICY_README.html +++ b/postfix/html/SMTPD_POLICY_README.html @@ -114,6 +114,13 @@ size=12345
  • 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: @@ -124,7 +131,8 @@ size=12345

  • 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 + 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.

    diff --git a/postfix/html/index.html b/postfix/html/index.html index 3eb80bf48..d371c2c78 100644 --- a/postfix/html/index.html +++ b/postfix/html/index.html @@ -3,8 +3,6 @@ - - Postfix Documentation diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 66599d4fa..e058eaf80 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -3110,11 +3110,9 @@ client TLS certificate is successfully verified, regardless of whether it is listed on the server, and regardless of the certifying authority. -
    check_address_map type:table
    +
    check_address_map type:table
    -
    type:table -
    +
    type:table
    Append the domain name in $myorigin or $mydomain when the client IP address matches the specified lookup table. The lookup @@ -6532,7 +6530,8 @@ a restriction list, to make the default policy explicit.
    and the message has multiple envelope recipients. Although this usage is technically allowed, it seems to have no legitimate application.
    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.
    @@ -6667,6 +6666,19 @@ is being rejected.

    + + +
    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.

    + +

    This feature is available in Postfix 2.2 and later.

    + +

    See smtpd_data_restrictions for syntax details.

    + +
    smtpd_error_sleep_time diff --git a/postfix/html/qmgr.8.html b/postfix/html/qmgr.8.html index fe9050aa7..91c289655 100644 --- a/postfix/html/qmgr.8.html +++ b/postfix/html/qmgr.8.html @@ -366,6 +366,7 @@ QMGR(8) QMGR(8) 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 diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index ed49cc183..28fc4b42b 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -34,7 +34,7 @@ SMTP(8) SMTP(8) 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 scache(8) connection cache server, so that it may be used by any SMTP client for a subsequent transac- tion. @@ -78,15 +78,14 @@ SMTP(8) SMTP(8) 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. CONFIGURATION PARAMETERS Changes to main.cf are picked up automatically, as smtp(8) - processes run for only a limited amount of time. Use the + processes run for only a limited amount of time. Use the command "postfix reload" to speed up a change. - The text below provides only a parameter summary. See + The text below provides only a parameter summary. See postconf(5) for more details including examples. COMPATIBILITY CONTROLS @@ -100,7 +99,7 @@ SMTP(8) SMTP(8) Never send EHLO at the start of an SMTP session. smtp_defer_if_no_mx_address_found (no) - Defer mail delivery when no MX record resolves to + Defer mail delivery when no MX record resolves to an IP address. smtp_line_length_limit (990) @@ -108,17 +107,17 @@ SMTP(8) SMTP(8) that Postfix will send via SMTP. smtp_pix_workaround_delay_time (10s) - 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. smtp_pix_workaround_threshold_time (500s) - 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. smtp_quote_rfc821_envelope (yes) - Quote addresses in SMTP MAIL FROM and RCPT TO com- + Quote addresses in SMTP MAIL FROM and RCPT TO com- mands as required by RFC 821. smtp_skip_5xx_greeting (yes) @@ -126,7 +125,7 @@ SMTP(8) SMTP(8) (go away, do not try again later). smtp_skip_quit_response (yes) - 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: @@ -139,7 +138,7 @@ SMTP(8) SMTP(8) Available in Postfix version 2.0 and later: disable_mime_output_conversion (no) - Disable the conversion of 8BITMIME format to 7BIT + Disable the conversion of 8BITMIME format to 7BIT format. mime_boundary_length_limit (2048) @@ -154,49 +153,49 @@ SMTP(8) SMTP(8) Available in Postfix version 2.1 and later: smtp_send_xforward_command (no) - 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. SASL AUTHENTICATION CONTROLS smtp_sasl_auth_enable (no) - Enable SASL authentication in the Postfix SMTP + Enable SASL authentication in the Postfix SMTP client. smtp_sasl_password_maps (empty) - 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. smtp_sasl_security_options (noplaintext, noanonymous) - 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: smtp_sasl_mechanism_filter (empty) - If non-empty, filters the SMTP server's list of + If non-empty, filters the SMTP server's list of offered SASL mechanisms. RESOURCE AND RATE CONTROLS smtp_destination_concurrency_limit ($default_destina- tion_concurrency_limit) - 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. smtp_destination_recipient_limit ($default_destina- tion_recipient_limit) - The maximal number of recipients per delivery via + The maximal number of recipients per delivery via the smtp message delivery transport. smtp_connect_timeout (30s) - 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). smtp_helo_timeout (300s) - 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. smtp_xforward_timeout (300s) @@ -204,30 +203,30 @@ SMTP(8) SMTP(8) command, and for receiving the server response. smtp_mail_timeout (300s) - 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. smtp_rcpt_timeout (300s) - 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. smtp_data_init_timeout (120s) - 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. smtp_data_xfer_timeout (180s) - The SMTP client time limit for sending the SMTP + The SMTP client time limit for sending the SMTP message content. smtp_data_done_timeout (600s) - The SMTP client time limit for sending the SMTP + The SMTP client time limit for sending the SMTP ".", and for receiving the server response. smtp_quit_timeout (300s) - 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: @@ -238,77 +237,77 @@ SMTP(8) SMTP(8) lookups, or zero (no limit). smtp_mx_session_limit (2) - 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). smtp_rset_timeout (20s) - 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: smtp_connection_cache_destinations (empty) - Permanently enable SMTP connection caching for the + Permanently enable SMTP connection caching for the specified destinations. smtp_connection_cache_on_demand (yes) - 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. smtp_connection_cache_reuse_limit (10) 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. smtp_connection_cache_time_limit (2s) 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. TROUBLE SHOOTING CONTROLS debug_peer_level (2) - 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 debug_peer_list parameter. debug_peer_list (empty) - 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 $debug_peer_level. error_notice_recipient (postmaster) - 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. notify_classes (resource, software) - The list of error classes that are reported to the + The list of error classes that are reported to the postmaster. MISCELLANEOUS CONTROLS best_mx_transport (empty) - 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. config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and + The default location of the Postfix main.cf and master.cf configuration files. daemon_timeout (18000s) - 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. disable_dns_lookups (no) - Disable DNS lookups in the Postfix SMTP and LMTP + Disable DNS lookups in the Postfix SMTP and LMTP clients. fallback_relay (empty) - 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. inet_interfaces (all) @@ -320,25 +319,25 @@ SMTP(8) SMTP(8) over an internal communication channel. max_idle (100s) - 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. max_use (100) - The maximal number of connection requests before a + The maximal number of connection requests before a Postfix daemon process terminates. process_id (read-only) - The process ID of a Postfix command or daemon pro- + The process ID of a Postfix command or daemon pro- cess. process_name (read-only) - The process name of a Postfix command or daemon + The process name of a Postfix command or daemon process. proxy_interfaces (empty) 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. smtp_bind_address (empty) @@ -346,22 +345,22 @@ SMTP(8) SMTP(8) client should bind to when making a connection. smtp_helo_name ($myhostname) - The hostname to send in the SMTP EHLO or HELO com- + The hostname to send in the SMTP EHLO or HELO com- mand. smtp_host_lookup (dns) - What mechanisms when the SMTP client uses to look + What mechanisms when the SMTP client uses to look up a host's IP address. smtp_randomize_addresses (yes) - Randomize the order of equal-preference MX host + Randomize the order of equal-preference MX host addresses. syslog_facility (mail) The syslog facility of Postfix logging. syslog_name (postfix) - 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". @@ -370,6 +369,7 @@ SMTP(8) SMTP(8) 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 @@ -377,7 +377,7 @@ SMTP(8) SMTP(8) SASL_README, Postfix SASL howto LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index 4fc7cd37b..047ff5faf 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -582,6 +582,13 @@ SMTPD(8) SMTPD(8) explicit reject_unlisted_recipient access restric- tion is specified. + Available in Postfix version 2.2 and later: + + smtpd_end_of_data_restrictions (empty) + 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 Postfix version 2.1 introduces sender and recipient address verification. This feature is implemented by @@ -779,6 +786,7 @@ SMTPD(8) SMTPD(8) 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 diff --git a/postfix/makedefs b/postfix/makedefs index 7fb2a0a9f..3065eab80 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -136,6 +136,7 @@ case "$SYSTEM.$RELEASE" in 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";; diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index c19b82f59..90ffcaadb 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -1585,10 +1585,8 @@ Append the domain name in $myorigin or $mydomain when the 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 \fItype: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 @@ -3530,7 +3528,8 @@ 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 @@ -3625,6 +3624,13 @@ The default setting has one major benefit: it allows Postfix to log 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 diff --git a/postfix/man/man8/qmgr.8 b/postfix/man/man8/qmgr.8 index b90e2ad98..561674af9 100644 --- a/postfix/man/man8/qmgr.8 +++ b/postfix/man/man8/qmgr.8 @@ -326,6 +326,7 @@ records, so that "smtpd" becomes, for example, "postfix/smtpd". 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" diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index c5be8ab70..83bb849e1 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -32,7 +32,7 @@ When a server is not reachable, or when mail delivery 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 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. @@ -79,8 +79,7 @@ support for TLS object passivation and re-activation does not 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 @@ -308,6 +307,7 @@ qmgr(8), queue manager 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" diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index 01709f279..954ac2d95 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -487,6 +487,11 @@ access restriction is specified. 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 @@ -633,6 +638,7 @@ cleanup(8), message canonicalization 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" diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 612a7a600..662883cd6 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -366,6 +366,7 @@ while (<>) { s;\bsmtpd_client_restrictions\b;$&;g; s;\bsmtpd_data_restrictions\b;$&;g; s;\bsmtpd_delay_reject\b;$&;g; + s;\bsmtpd_end_of_data_restrictions\b;$&;g; s;\bsmtpd_error_sleep_time\b;$&;g; s;\bsmtpd_etrn_restrictions\b;$&;g; s;\bsmtpd_expansion_filter\b;$&;g; diff --git a/postfix/proto/SMTPD_ACCESS_README.html b/postfix/proto/SMTPD_ACCESS_README.html index 70dbcf8b2..e271afebd 100644 --- a/postfix/proto/SMTPD_ACCESS_README.html +++ b/postfix/proto/SMTPD_ACCESS_README.html @@ -216,6 +216,9 @@ Reject MAIL FROM information smtpd_data_restrictions Optional Reject DATA command + smtpd_end_of_data_restrictions Optional +Reject END-OF-DATA command + smtpd_etrn_restrictions Optional Reject ETRN command @@ -238,7 +241,8 @@ and so on. This approach turned out to be difficult to use.

    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.

    diff --git a/postfix/proto/SMTPD_POLICY_README.html b/postfix/proto/SMTPD_POLICY_README.html index d406984d2..65ab323fa 100644 --- a/postfix/proto/SMTPD_POLICY_README.html +++ b/postfix/proto/SMTPD_POLICY_README.html @@ -114,6 +114,13 @@ size=12345
  • 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: @@ -124,7 +131,8 @@ size=12345

  • 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 + 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.

    diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index d08cad61d..f462ac8b1 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -4208,7 +4208,8 @@ a restriction list, to make the default policy explicit. and the message has multiple envelope recipients. Although this usage is technically allowed, it seems to have no legitimate application.
    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.
    @@ -6666,6 +6667,15 @@ smtpd_data_restrictions = reject_unauth_pipelining smtpd_data_restrictions = reject_multi_recipient_bounce +%PARAM smtpd_end_of_data_restrictions + +

    Optional access restrictions that the Postfix SMTP server +applies in the context of the SMTP END-OF-DATA command.

    + +

    This feature is available in Postfix 2.2 and later.

    + +

    See smtpd_data_restrictions for syntax details.

    + %PARAM smtpd_delay_reject yes

    @@ -7280,11 +7290,9 @@ client TLS certificate is successfully verified, regardless of whether it is listed on the server, and regardless of the certifying authority. -

    check_address_map type:table
    +
    check_address_map type:table
    -
    type:table -
    +
    type:table
    Append the domain name in $myorigin or $mydomain when the client IP address matches the specified lookup table. The lookup diff --git a/postfix/src/cleanup/cleanup_envelope.c b/postfix/src/cleanup/cleanup_envelope.c index a2063f984..e4b31661c 100644 --- a/postfix/src/cleanup/cleanup_envelope.c +++ b/postfix/src/cleanup/cleanup_envelope.c @@ -280,18 +280,25 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, 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); diff --git a/postfix/src/cleanup/cleanup_state.c b/postfix/src/cleanup/cleanup_state.c index 3c761a572..cd36bc8b4 100644 --- a/postfix/src/cleanup/cleanup_state.c +++ b/postfix/src/cleanup/cleanup_state.c @@ -83,6 +83,7 @@ CLEANUP_STATE *cleanup_state_alloc(void) 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; diff --git a/postfix/src/dns/dns_lookup.c b/postfix/src/dns/dns_lookup.c index 7fd1528f5..03b4aaf5f 100644 --- a/postfix/src/dns/dns_lookup.c +++ b/postfix/src/dns/dns_lookup.c @@ -141,7 +141,7 @@ static int dns_query(const char *name, int type, int flags, { HEADER *reply_header; int len; - unsigned long saved_options = _res.options; + unsigned long saved_options; /* * Initialize the name service. @@ -160,7 +160,8 @@ static int dns_query(const char *name, int type, int flags, 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; /* @@ -168,7 +169,8 @@ static int dns_query(const char *name, int type, int 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. " diff --git a/postfix/src/global/debug_process.c b/postfix/src/global/debug_process.c index d04567863..504cbd109 100644 --- a/postfix/src/global/debug_process.c +++ b/postfix/src/global/debug_process.c @@ -55,7 +55,7 @@ void debug_process(void) * 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); diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index bc2e4e6a7..197893f2f 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1332,6 +1332,10 @@ extern char *var_etrn_checks; #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; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 791c85f61..1aaa94894 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * 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" diff --git a/postfix/src/local/forward.c b/postfix/src/local/forward.c index 81fab30b6..8c89aede7 100644 --- a/postfix/src/local/forward.c +++ b/postfix/src/local/forward.c @@ -152,24 +152,27 @@ static FORWARD_INFO *forward_open(DELIVER_REQUEST *request, char *sender) * 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); } diff --git a/postfix/src/master/master.h b/postfix/src/master/master.h index 3cc481207..95b5e491b 100644 --- a/postfix/src/master/master.h +++ b/postfix/src/master/master.h @@ -77,6 +77,7 @@ typedef int MASTER_PID; /* pid is key into binhash table */ 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 */ diff --git a/postfix/src/master/master_proto.c b/postfix/src/master/master_proto.c index 00e9c19dd..d1247479b 100644 --- a/postfix/src/master/master_proto.c +++ b/postfix/src/master/master_proto.c @@ -6,8 +6,9 @@ /* SYNOPSIS /* #include /* -/* 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 @@ -61,7 +62,7 @@ #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; @@ -73,6 +74,7 @@ int master_notify(int pid, int status) * 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)) { diff --git a/postfix/src/master/master_proto.h b/postfix/src/master/master_proto.h index 36c30f8d5..fc48fa092 100644 --- a/postfix/src/master/master_proto.h +++ b/postfix/src/master/master_proto.h @@ -23,13 +23,16 @@ */ 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 diff --git a/postfix/src/master/master_spawn.c b/postfix/src/master/master_spawn.c index 2eaf7bf96..1f112bc62 100644 --- a/postfix/src/master/master_spawn.c +++ b/postfix/src/master/master_spawn.c @@ -59,6 +59,7 @@ #include /* closelog() */ #include #include +#include /* Utility libraries. */ @@ -66,8 +67,8 @@ #include #include #include +#include #include -#include /* Application-specific. */ @@ -136,9 +137,13 @@ void master_spawn(MASTER_SERV *serv) 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 @@ -155,6 +160,7 @@ void master_spawn(MASTER_SERV *serv) * Create a child process and connect parent and child via the status * pipe. */ + master_generation += 1; switch (pid = fork()) { /* @@ -207,6 +213,10 @@ void master_spawn(MASTER_SERV *serv) 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); @@ -224,6 +234,7 @@ void master_spawn(MASTER_SERV *serv) 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, diff --git a/postfix/src/master/master_status.c b/postfix/src/master/master_status.c index de0cc4d28..dabde1f9d 100644 --- a/postfix/src/master/master_status.c +++ b/postfix/src/master/master_status.c @@ -89,13 +89,15 @@ static void master_status_event(int event, char *context) /* 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); } /* @@ -111,6 +113,11 @@ static void master_status_event(int event, char *context) 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); diff --git a/postfix/src/master/multi_server.c b/postfix/src/master/multi_server.c index 396c0aebc..f6f873f3c 100644 --- a/postfix/src/master/multi_server.c +++ b/postfix/src/master/multi_server.c @@ -144,6 +144,7 @@ #include #include #include +#include #include #include #include @@ -205,6 +206,7 @@ static void (*multi_server_onexit) (char *, char **); 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 */ @@ -263,10 +265,10 @@ static void multi_server_execute(int unused_event, char *context) * 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); @@ -406,6 +408,7 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...) int zerolimit = 0; WATCHDOG *watchdog; char *oval; + char *generation; /* * Process environment options as early as we can. @@ -597,6 +600,15 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...) 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. */ diff --git a/postfix/src/master/single_server.c b/postfix/src/master/single_server.c index c2feb94a6..11c045317 100644 --- a/postfix/src/master/single_server.c +++ b/postfix/src/master/single_server.c @@ -134,6 +134,7 @@ #include #include #include +#include #include #include #include @@ -193,6 +194,7 @@ static void (*single_server_onexit) (char *, char **); 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 */ @@ -243,13 +245,13 @@ static void single_server_wakeup(int fd) 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"); @@ -352,6 +354,7 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...) int zerolimit = 0; WATCHDOG *watchdog; char *oval; + char *generation; /* * Process environment options as early as we can. @@ -540,6 +543,15 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...) 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. */ diff --git a/postfix/src/master/trigger_server.c b/postfix/src/master/trigger_server.c index e7640ed2f..3681fbd74 100644 --- a/postfix/src/master/trigger_server.c +++ b/postfix/src/master/trigger_server.c @@ -142,6 +142,7 @@ #include #include #include +#include #include #include #include @@ -200,6 +201,7 @@ static void (*trigger_server_onexit) (char *, char **); 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 */ @@ -238,14 +240,14 @@ static void trigger_server_wakeup(int fd) /* * 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); @@ -348,6 +350,7 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,.. int zerolimit = 0; WATCHDOG *watchdog; char *oval; + char *generation; /* * Process environment options as early as we can. @@ -550,6 +553,15 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,.. 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. */ diff --git a/postfix/src/oqmgr/qmgr_message.c b/postfix/src/oqmgr/qmgr_message.c index 090b0f24f..17bee1f43 100644 --- a/postfix/src/oqmgr/qmgr_message.c +++ b/postfix/src/oqmgr/qmgr_message.c @@ -638,7 +638,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) 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. diff --git a/postfix/src/pickup/pickup.c b/postfix/src/pickup/pickup.c index a8ddf94a6..84c8e4cc2 100644 --- a/postfix/src/pickup/pickup.c +++ b/postfix/src/pickup/pickup.c @@ -288,14 +288,6 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup, 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 diff --git a/postfix/src/qmgr/qmgr.c b/postfix/src/qmgr/qmgr.c index 49c8bfd79..4444cc58e 100644 --- a/postfix/src/qmgr/qmgr.c +++ b/postfix/src/qmgr/qmgr.c @@ -284,6 +284,7 @@ /* 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 diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 17d2f2de2..0c6ba062c 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -673,7 +673,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) 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. diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index 63a878a1a..0ecc7140e 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -275,6 +275,7 @@ /* 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 diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index ce1410fef..444d7f8bf 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -445,6 +445,11 @@ /* 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 @@ -583,6 +588,7 @@ /* 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 @@ -715,6 +721,7 @@ char *var_mail_checks; 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; @@ -1388,6 +1395,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) 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 @@ -1758,10 +1766,23 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) 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 @@ -1846,12 +1867,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) 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. */ @@ -2884,6 +2899,7 @@ int main(int argc, char **argv) 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, diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 232c3a02a..442bbc1c7 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -86,6 +86,7 @@ typedef struct SMTPD_STATE { 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 */ diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index f8e04a768..5966ebcee 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -36,6 +36,9 @@ /* /* 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. @@ -114,6 +117,9 @@ /* 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. @@ -292,6 +298,7 @@ static ARGV *mail_restrctions; 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; @@ -324,6 +331,7 @@ static int check_rcpt_maps(SMTPD_STATE *, const char *, const char *); #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. @@ -651,6 +659,8 @@ void smtpd_check_init(void) 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. @@ -2898,7 +2908,8 @@ static int check_policy_service(SMTPD_STATE *state, const char *server, 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 ? @@ -3395,6 +3406,7 @@ void smtpd_check_rewrite(SMTPD_STATE *state) int status; char **cpp; DICT *dict; + char *name; /* * We don't use generic_checks() because it produces results that aren't @@ -3404,29 +3416,33 @@ void smtpd_check_rewrite(SMTPD_STATE *state) 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) { @@ -4002,6 +4018,55 @@ char *smtpd_check_data(SMTPD_STATE *state) 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 /* diff --git a/postfix/src/smtpd/smtpd_check.h b/postfix/src/smtpd/smtpd_check.h index 8d706bb9a..6850db737 100644 --- a/postfix/src/smtpd/smtpd_check.h +++ b/postfix/src/smtpd/smtpd_check.h @@ -22,6 +22,7 @@ extern char *smtpd_check_size(SMTPD_STATE *, off_t); 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 diff --git a/postfix/src/smtpd/smtpd_state.c b/postfix/src/smtpd/smtpd_state.c index 759f5ebfd..e51739f85 100644 --- a/postfix/src/smtpd/smtpd_state.c +++ b/postfix/src/smtpd/smtpd_state.c @@ -95,6 +95,7 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream, 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; diff --git a/postfix/src/util/dict.c b/postfix/src/util/dict.c index 51c63cde6..91b3a57b5 100644 --- a/postfix/src/util/dict.c +++ b/postfix/src/util/dict.c @@ -473,8 +473,10 @@ const char *dict_eval(const char *dict_name, const char *value, int recursive) */ 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;