diff --git a/postfix/HISTORY b/postfix/HISTORY
index ae9005eb4..4e0cbda9e 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -15860,3 +15860,39 @@ Apologies for any names omitted.
20100707
Completed the 20100610 bugfix. File: tls/tls_misc.c.
+
+20100714
+
+ Compatibility with Postfix < 2.3: fix 20061207 was incomplete
+ (undoing the change to bounce instead of defer after
+ pipe-to-command delivery fails with a signal). Fix by Thomas
+ Arnett. File: global/pipe_command.c.
+
+20100715
+
+ Convenience: "postconf name=value ..." is now equivalent to
+ "postconf -e name=value ...". File: postconf/postconf.c.
+
+20100724
+
+ Feature: INFO header/body_checks action for non-warning
+ messages (for example, to log all Milter-inserted headers).
+ File: global/header_body_checks.c, proto/header_checks.
+
+ Cleanup: after-filter Postfix SMTP servers now log before-filter
+ queue IDs. For this, the XFORWARD protocol was extended
+ with an IDENT attribute for the before-filter queue ID.
+ This code was started in Postfix 2.1, but it was never
+ finished due to time constraints. Files: smtpd/smtpd.[hc]
+ smtpd/smtpd_proxy.c, smtpd/smtpd_sasl_proto.c,
+ *qmgr/qmgr_messsage.c, *qmgr/qmgr_deliver.c,
+ global/deliver_request.[hc], global/mail_proto.h,
+ global/deliver_pass.c, smtp/smtp_proto.c.
+
+20100727
+
+ Bugfix: the milter_header_checks parser provided only the
+ actions that change the message flow (reject, filter,
+ discard, redirect) but disabled the non-flow actions (warn,
+ replace, prepend, ignore, dunno, ok). File:
+ cleanup/cleanup_milter.c.
diff --git a/postfix/README_FILES/SQLITE_README b/postfix/README_FILES/SQLITE_README
index 9895c1f54..cdd035cbe 100644
--- a/postfix/README_FILES/SQLITE_README
+++ b/postfix/README_FILES/SQLITE_README
@@ -16,9 +16,11 @@ from:
http://www.sqlite.org/
-In order to build Postfix with sqlite map support, you will need to add -
-DHAS_SQLITE and -I for the directory containing the sqlite headers, and the
-sqlite3 library to AUXLIBS, for example:
+In order to build Postfix with sqlite map support, you will need to add to
+CCARGS the flags -DHAS_SQLITE and -I with the directory containing the sqlite
+header files, and you will need to add to AUXLIBS the directory and name of the
+sqlite3 library, plus the name of the standard POSIX thread library (pthread).
+For example:
make -f Makefile.init makefiles \
'CCARGS=-DHAS_SQLITE -I/usr/local/include' \
@@ -57,6 +59,8 @@ aliases table if you want.
CCrreeddiittss
+SQLite support was added with Postfix version 2.8.
+
* Implementation by Axel Steiner
* Documentation by Jesus Garcia Crespo
diff --git a/postfix/README_FILES/STANDARD_CONFIGURATION_README b/postfix/README_FILES/STANDARD_CONFIGURATION_README
index 39ff4f609..e347c8828 100644
--- a/postfix/README_FILES/STANDARD_CONFIGURATION_README
+++ b/postfix/README_FILES/STANDARD_CONFIGURATION_README
@@ -320,16 +320,13 @@ Translation:
Execute the command "ppoossttmmaapp //eettcc//ppoossttffiixx//vviirrttuuaall" after editing the file.
-.
-
RRuunnnniinngg PPoossttffiixx bbeehhiinndd aa ffiirreewwaallll
The simplest way to set up Postfix on a host behind a firewalled network is to
send all mail to a gateway host, and to let that mail host take care of
internal and external forwarding. Examples of that are shown in the local area
network section above. A more sophisticated approach is to send only external
-mail to the gateway host, and to send intranet mail directly. That's what
-Wietse does at work.
+mail to the gateway host, and to send intranet mail directly.
Note: this example requires Postfix version 2.0 and later. To find out what
Postfix version you have, execute the command "ppoossttccoonnff mmaaiill__vveerrssiioonn".
diff --git a/postfix/README_FILES/XFORWARD_README b/postfix/README_FILES/XFORWARD_README
index 0742dbe93..11a13cd0f 100644
--- a/postfix/README_FILES/XFORWARD_README
+++ b/postfix/README_FILES/XFORWARD_README
@@ -44,7 +44,7 @@ are in fact case insensitive.
xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value )
- attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | SOURCE )
+ attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | IDENT | SOURCE )
attribute-value = xtext
@@ -70,6 +70,11 @@ are in fact case insensitive.
when the information is unavailable. The hostname may be a non-DNS
hostname.
+ * The IDENT attribute specifies a local message identifier on the up-stream
+ host, or [UNAVAILABLE] when the information is unavailable. The down-stream
+ MTA may log this information together with its own local message identifier
+ to facilitate message tracking across MTAs.
+
* The SOURCE attribute specifies LOCAL when the message was received from a
source that is local with respect to the up-stream host (for example, the
message originated from the up-stream host itself), REMOTE for all other
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index 304f401b8..f958f082f 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -14,6 +14,29 @@ specifies the release date of a stable release or snapshot release.
If you upgrade from Postfix 2.6 or earlier, read RELEASE_NOTES-2.7
before proceeding.
+Incompatibility with snapshot 20100728
+======================================
+
+The format of the "postfix/smtpd[pid]: queueid: client=host[addr]"
+logfile record has changed. When available, the before-filter client
+information and the before-filter queue ID are now appended to the
+end of the record.
+
+Major changes with snapshot 20100728
+====================================
+
+Improved message tracking across SMTP-based content filters. The
+logging example below is from an after-filter SMTP server. Here,
+951F692462F is a before-filter queue ID, hades.porcupine.org is a
+before-filter SMTP client, while 6B4A9924782 is the after-filter
+queue ID, and localhost[127.0.0.1] is the SMTP-based content filter
+that sends mail into the after-filter SMTP server.
+
+ postfix/smtpd[4074]: 6B4A9924782:
+ client=localhost[127.0.0.1],
+ orig_queue_id=951F692462F
+ orig_client=hades.porcupine.org[168.100.189.10]
+
Incompatibility with snapshot 20100610
======================================
diff --git a/postfix/WISHLIST b/postfix/WISHLIST
index b92af354e..f7f4023a6 100644
--- a/postfix/WISHLIST
+++ b/postfix/WISHLIST
@@ -4,6 +4,17 @@ Wish list:
Update history in manpage/readme for SQLite driver.
+ header_checks(5): document synopsis and feature subsets.
+
+ Would it help if there were different cleanup_server parameter
+ names for different message paths? smtpd(8) uses the same
+ cleanup_server value for receiving remote mail and for
+ sending postmaster problem reports. Do we need separate
+ mumble_cleanup_service_name parameters for "inject", "notify"
+ and "forward" (with backwards compatinble defaults)?
+
+ IF/ENDIF support for CIDR tables.
+
Make postconf aware of magical suffixes (the ones that
combine with transport names) and show them in "postconf
-n" output. Making this work with "postconf -d" is trickier.
@@ -11,6 +22,11 @@ Wish list:
Need a regular expression table to translate address
verification responses into hard/soft/accept reply codes.
+ Is there a way to make sendmail -V work after local alias
+ expansion? Majordomo-like mailing lists would benefit from
+ this; the example in VERP_README does not work in the general
+ case.
+
When an alias is a member of an :include: list with owner-
alias, local(8) needs an option to deliver alias or alias->user
indirectly. What happens when an :include: list with owner-
diff --git a/postfix/conf/header_checks b/postfix/conf/header_checks
index 23d4972cc..f10e2dfaf 100644
--- a/postfix/conf/header_checks
+++ b/postfix/conf/header_checks
@@ -9,6 +9,13 @@
# nested_header_checks = pcre:/etc/postfix/nested_header_checks
# body_checks = pcre:/etc/postfix/body_checks
#
+# milter_header_checks = pcre:/etc/postfix/milter_header_checks
+#
+# smtp_header_checks = pcre:/etc/postfix/smtp_header_checks
+# smtp_mime_header_checks = pcre:/etc/postfix/smtp_mime_header_checks
+# smtp_nested_header_checks = pcre:/etc/postfix/smtp_nested_header_checks
+# smtp_body_checks = pcre:/etc/postfix/smtp_body_checks
+#
# postmap -q "string" pcre:/etc/postfix/filename
# postmap -q - pcre:/etc/postfix/filename In order to build Postfix with sqlite map support, you will need to add
--DHAS_SQLITE and -I for the directory containing the sqlite headers, and
-the sqlite3 library to AUXLIBS, for example: In order to build Postfix with sqlite map support, you will
+need to add to CCARGS the flags -DHAS_SQLITE and -I with the directory
+containing the sqlite header files, and you will need to add to
+AUXLIBS the directory and name of the sqlite3 library, plus the
+name of the standard POSIX thread library (pthread). For example:
+
@@ -84,6 +87,8 @@ access table, and one for an aliases table if you want.
SQLite support was added with Postfix version 2.8.
+Execute the command "postmap /etc/postfix/virtual" after -editing the file.
. +editing the file.Note: this example requires Postfix version 2.0 and later. To find out what Postfix version you have, execute the command "postconf diff --git a/postfix/html/XFORWARD_README.html b/postfix/html/XFORWARD_README.html index 64c81e244..e2eb7c850 100644 --- a/postfix/html/XFORWARD_README.html +++ b/postfix/html/XFORWARD_README.html @@ -72,7 +72,7 @@ names are shown in upper case, they are in fact case insensitive. xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value )
- attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | SOURCE ) + attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | IDENT | SOURCE )
attribute-value = xtext @@ -108,6 +108,12 @@ names are shown in upper case, they are in fact case insensitive. SMTP HELO command), or [UNAVAILABLE] when the information is unavailable. The hostname may be a non-DNS hostname.
+The IDENT attribute specifies a local message identifier + on the up-stream host, or [UNAVAILABLE] when the information + is unavailable. The down-stream MTA may log this information + together with its own local message identifier to facilitate + message tracking across MTAs.
+The SOURCE attribute specifies LOCAL when the message was received from a source that is local with respect to the up-stream host (for example, the message originated from the diff --git a/postfix/html/header_checks.5.html b/postfix/html/header_checks.5.html index 1a406ba40..9705e12c7 100644 --- a/postfix/html/header_checks.5.html +++ b/postfix/html/header_checks.5.html @@ -15,6 +15,13 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) nested_header_checks = pcre:/etc/postfix/nested_header_checks body_checks = pcre:/etc/postfix/body_checks + milter_header_checks = pcre:/etc/postfix/milter_header_checks + + smtp_header_checks = pcre:/etc/postfix/smtp_header_checks + smtp_mime_header_checks = pcre:/etc/postfix/smtp_mime_header_checks + smtp_nested_header_checks = pcre:/etc/postfix/smtp_nested_header_checks + smtp_body_checks = pcre:/etc/postfix/smtp_body_checks + postmap -q "string" pcre:/etc/postfix/filename postmap -q - pcre:/etc/postfix/filename <inputfile @@ -31,6 +38,10 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) is repeated for the next message header or message body line. + Note: message headers are examined one logical header at a + time, even when a message header spans multiple lines. + Body lines are always examined one line at a time. + For examples, see the EXAMPLES section at the end of this manual page. @@ -40,9 +51,11 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) referenced below in the README FILES section if you need more sophisticated content analysis. - Postfix supports four built-in content inspection classes: +FILTERS WHILE RECEIVING MAIL + Postfix implements the following four built-in content + inspection classes while receiving mail: - header_checks + header_checks (default: empty) These are applied to initial message headers (except for the headers that are processed with mime_header_checks). @@ -68,79 +81,99 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) the initial message headers is treated as body con- tent. - Note: message headers are examined one logical header at a - time, even when a message header spans multiple lines. - Body lines are always examined one line at a time. +FILTERS AFTER RECEIVING MAIL + Postfix supports a subset of the built-in content inspec- + tion classes after the message is received: + + milter_header_checks (default: empty) + These are applied to headers that are added with + Milter applications. + + This feature is available in Postfix 2.7 and later. + +FILTERS WHILE DELIVERING MAIL + Postfix supports all four content inspection classes while + delivering mail via SMTP. + + smtp_header_checks (default: empty) + + smtp_mime_header_checks (default: empty) + + smtp_nested_header_checks (default: empty) + + smtp_body_checks (default: empty) + These features are available in Postfix 2.5 and + later. COMPATIBILITY With Postfix version 2.2 and earlier specify "postmap -fq" to query a table that contains case sensitive patterns. By - default, regexp: and pcre: patterns are case insensitive. + default, regexp: and pcre: patterns are case insensitive. TABLE FORMAT - This document assumes that header and body_checks rules - are specified in the form of Postfix regular expression - lookup tables. Usually the best performance is obtained + This document assumes that header and body_checks rules + are specified in the form of Postfix regular expression + lookup tables. Usually the best performance is obtained with pcre (Perl Compatible Regular Expression) tables, but - the slower regexp (POSIX regular expressions) support is - more widely available. Use the command "postconf -m" to - find out what lookup table types your Postfix system sup- + the slower regexp (POSIX regular expressions) support is + more widely available. Use the command "postconf -m" to + find out what lookup table types your Postfix system sup- ports. The general format of Postfix regular expression tables is - given below. For a discussion of specific pattern or - flags syntax, see pcre_table(5) or regexp_table(5), + given below. For a discussion of specific pattern or + flags syntax, see pcre_table(5) or regexp_table(5), respectively. /pattern/flags action - When /pattern/ matches the input string, execute - the corresponding action. See below for a list of + When /pattern/ matches the input string, execute + the corresponding action. See below for a list of possible actions. !/pattern/flags action - When /pattern/ does not match the input string, + When /pattern/ does not match the input string, execute the corresponding action. if /pattern/flags endif Match the input string against the patterns between - if and endif, if and only if the same input string + if and endif, if and only if the same input string also matches /pattern/. The if..endif can nest. - Note: do not prepend whitespace to patterns inside + Note: do not prepend whitespace to patterns inside if..endif. if !/pattern/flags endif Match the input string against the patterns between - if and endif, if and only if the same input string + if and endif, if and only if the same input string does not match /pattern/. The if..endif can nest. blank lines and comments - Empty lines and whitespace-only lines are ignored, - as are lines whose first non-whitespace character + Empty lines and whitespace-only lines are ignored, + as are lines whose first non-whitespace character is a `#'. multi-line text - A pattern/action line starts with non-whitespace - text. A line that starts with whitespace continues + A pattern/action line starts with non-whitespace + text. A line that starts with whitespace continues a logical line. TABLE SEARCH ORDER - For each line of message input, the patterns are applied - in the order as specified in the table. When a pattern is - found that matches the input line, the corresponding - action is executed and then the next input line is + For each line of message input, the patterns are applied + in the order as specified in the table. When a pattern is + found that matches the input line, the corresponding + action is executed and then the next input line is inspected. TEXT SUBSTITUTION - Substitution of substrings from the matched expression - into the action string is possible using the conventional - Perl syntax ($1, $2, etc.). The macros in the result - string may need to be written as ${n} or $(n) if they + Substitution of substrings from the matched expression + into the action string is possible using the conventional + Perl syntax ($1, $2, etc.). The macros in the result + string may need to be written as ${n} or $(n) if they aren't followed by whitespace. - Note: since negated patterns (those preceded by !) return + Note: since negated patterns (those preceded by !) return a result when the expression does not match, substitutions are not available for negated patterns. @@ -149,12 +182,12 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) case for consistency with other Postfix documentation. DISCARD optional text... - Claim successful delivery and silently discard the - message. Log the optional text if specified, oth- + Claim successful delivery and silently discard the + message. Log the optional text if specified, oth- erwise log a generic message. - Note: this action disables further header or - body_checks inspection of the current message and + Note: this action disables further header or + body_checks inspection of the current message and affects all recipients. To discard only one recip- ient without discarding the entire message, use the transport(5) table to direct mail to the discard(8) @@ -162,6 +195,9 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) This feature is available in Postfix 2.0 and later. + This feature is not supported with smtp header/body + checks. + DUNNO Pretend that the input line did not match any pat- tern, and inspect the next input line. This action can be used to shorten the table search. @@ -204,31 +240,45 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) This feature is available in Postfix 2.0 and later. + This feature is not supported with smtp header/body + checks. + HOLD optional text... - Arrange for the message to be placed on the hold - queue, and inspect the next input line. The mes- - sage remains on hold until someone either deletes - it or releases it for delivery. Log the optional + Arrange for the message to be placed on the hold + queue, and inspect the next input line. The mes- + sage remains on hold until someone either deletes + it or releases it for delivery. Log the optional text if specified, otherwise log a generic message. - Mail that is placed on hold can be examined with - the postcat(1) command, and can be destroyed or + Mail that is placed on hold can be examined with + the postcat(1) command, and can be destroyed or released with the postsuper(1) command. - Note: use "postsuper -r" to release mail that was - kept on hold for a significant fraction of $maxi- + Note: use "postsuper -r" to release mail that was + kept on hold for a significant fraction of $maxi- mal_queue_lifetime or $bounce_queue_lifetime, or - longer. Use "postsuper -H" only for mail that will + longer. Use "postsuper -H" only for mail that will not expire within a few delivery attempts. - Note: this action affects all recipients of the + Note: this action affects all recipients of the message. This feature is available in Postfix 2.0 and later. + This feature is not supported with smtp header/body + checks. + IGNORE Delete the current line from the input, and inspect the next input line. + INFO optional text... + Log an "info:" record with the optional text... (or + log a generic text), and inspect the next input + line. This action is useful for routine logging or + for debugging. + + This feature is available in Postfix 2.8 and later. + PREPEND text... Prepend one line with the specified text, and inspect the next input line. @@ -254,19 +304,25 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) This feature is available in Postfix 2.1 and later. + This feature is not supported with mil- + ter_header_checks. + REDIRECT user@domain - Write a message redirection request to the queue - file, and inspect the next input line. After the + Write a message redirection request to the queue + file, and inspect the next input line. After the message is queued, it will be sent to the specified address instead of the intended recipient(s). - Note: this action overrides the FILTER action, and - affects all recipients of the message. If multiple - REDIRECT actions fire, only the last one is exe- + Note: this action overrides the FILTER action, and + affects all recipients of the message. If multiple + REDIRECT actions fire, only the last one is exe- cuted. This feature is available in Postfix 2.1 and later. + This feature is not supported with smtp header/body + checks. + REPLACE text... Replace the current line with the specified text, and inspect the next input line. @@ -302,11 +358,15 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) ning of optional text..., Postfix inserts a default enhanced status code of "5.7.1". + This feature is not supported with smtp header/body + checks. + WARN optional text... - Log a warning with the optional text... (or log a - generic message), and inspect the next input line. - This action is useful for debugging and for testing - a pattern before applying more drastic actions. + Log a "warning:" record with the optional text... + (or log a generic text), and inspect the next input + line. This action is useful for debugging and for + testing a pattern before applying more drastic + actions. BUGS Empty lines never match, because some map types mis-behave diff --git a/postfix/html/postconf.1.html b/postfix/html/postconf.1.html index f9bab489f..36f016d91 100644 --- a/postfix/html/postconf.1.html +++ b/postfix/html/postconf.1.html @@ -85,45 +85,48 @@ POSTCONF(1) POSTCONF(1) line. Use quotes in order to protect shell metacharacters and whitespace. - -h Show parameter values only, not the ``name = '' - label that normally precedes the value. + With Postfix version 2.8 and later, the -e is no + longer needed. - -l List the names of all supported mailbox locking + -h Show parameter values only, not the "name = " label + that normally precedes the value. + + -l List the names of all supported mailbox locking methods. Postfix supports the following methods: - flock A kernel-based advisory locking method for - local files only. This locking method is - available on systems with a BSD compatible + flock A kernel-based advisory locking method for + local files only. This locking method is + available on systems with a BSD compatible library. - fcntl A kernel-based advisory locking method for + fcntl A kernel-based advisory locking method for local and remote files. dotlock - An application-level locking method. An - application locks a file named filename by - creating a file named filename.lock. The - application is expected to remove its own - lock file, as well as stale lock files that + An application-level locking method. An + application locks a file named filename by + creating a file named filename.lock. The + application is expected to remove its own + lock file, as well as stale lock files that were left behind after abnormal termination. -m List the names of all supported lookup table types. - In Postfix configuration files, lookup tables are - specified as type:name, where type is one of the - types listed below. The table name syntax depends - on the lookup table type as described in the DATA- + In Postfix configuration files, lookup tables are + specified as type:name, where type is one of the + types listed below. The table name syntax depends + on the lookup table type as described in the DATA- BASE_README document. - btree A sorted, balanced tree structure. This is + btree A sorted, balanced tree structure. This is available on systems with support for Berke- ley DB databases. - cdb A read-optimized structure with no support - for incremental updates. This is available + cdb A read-optimized structure with no support + for incremental updates. This is available on systems with support for CDB databases. - cidr A table that associates values with Class- - less Inter-Domain Routing (CIDR) patterns. + cidr A table that associates values with Class- + less Inter-Domain Routing (CIDR) patterns. This is described in cidr_table(5). dbm An indexed file type based on hashing. This @@ -132,12 +135,12 @@ POSTCONF(1) POSTCONF(1) environ The UNIX process environment array. The - lookup key is the variable name. Originally - implemented for testing, someone may find + lookup key is the variable name. Originally + implemented for testing, someone may find this useful someday. hash An indexed file type based on hashing. This - is available on systems with support for + is available on systems with support for Berkeley DB databases. internal @@ -145,70 +148,70 @@ POSTCONF(1) POSTCONF(1) tent are lost when a process terminates. ldap (read-only) - Perform lookups using the LDAP protocol. + Perform lookups using the LDAP protocol. This is described in ldap_table(5). mysql (read-only) - Perform lookups using the MYSQL protocol. + Perform lookups using the MYSQL protocol. This is described in mysql_table(5). pcre (read-only) A lookup table based on Perl Compatible Reg- - ular Expressions. The file format is + ular Expressions. The file format is described in pcre_table(5). pgsql (read-only) - Perform lookups using the PostgreSQL proto- + Perform lookups using the PostgreSQL proto- col. This is described in pgsql_table(5). proxy (read-only) - A lookup table that is implemented via the - Postfix proxymap(8) service. The table name + A lookup table that is implemented via the + Postfix proxymap(8) service. The table name syntax is type:name. regexp (read-only) A lookup table based on regular expressions. - The file format is described in regexp_ta- + The file format is described in regexp_ta- ble(5). sdbm An indexed file type based on hashing. This - is available on systems with support for + is available on systems with support for SDBM databases. sqlite (read-only) - Perform lookups from SQLite database files. + Perform lookups from SQLite database files. This is described in sqlite_table(5). static (read-only) - A table that always returns its name as - lookup result. For example, static:foobar - always returns the string foobar as lookup + A table that always returns its name as + lookup result. For example, static:foobar + always returns the string foobar as lookup result. tcp (read-only) Perform lookups using a simple request-reply - protocol that is described in tcp_table(5). + protocol that is described in tcp_table(5). This feature is not included with the stable Postfix release. unix (read-only) - A limited way to query the UNIX authentica- + A limited way to query the UNIX authentica- tion database. The following tables are implemented: unix:passwd.byname - The table is the UNIX password data- - base. The key is a login name. The - result is a password file entry in + The table is the UNIX password data- + base. The key is a login name. The + result is a password file entry in passwd(5) format. unix:group.byname The table is the UNIX group database. - The key is a group name. The result - is a group file entry in group(5) + The key is a group name. The result + is a group file entry in group(5) format. - Other table types may exist depending on how Post- + Other table types may exist depending on how Post- fix was built. -n Print parameter settings that are not left at their @@ -217,29 +220,29 @@ POSTCONF(1) POSTCONF(1) -t [template_file] Display the templates for delivery status notifica- - tion (DSN) messages. To override the built-in tem- - plates, specify a template file at the end of the + tion (DSN) messages. To override the built-in tem- + plates, specify a template file at the end of the command line, or specify a template file in main.cf - with the bounce_template_file parameter. To force - selection of the built-in templates, specify an + with the bounce_template_file parameter. To force + selection of the built-in templates, specify an empty template file name (in shell language: ""). - This feature is available with Postfix 2.3 and + This feature is available with Postfix 2.3 and later. -v Enable verbose logging for debugging purposes. Mul- - tiple -v options make the software increasingly + tiple -v options make the software increasingly verbose. - -# Edit the main.cf configuration file. The file is + -# Edit the main.cf configuration file. The file is copied to a temporary file then renamed into place. - The parameters specified on the command line are + The parameters specified on the command line are commented-out, so that they revert to their default - values. Specify a list of parameter names, not - name=value pairs. There is no postconf command to + values. Specify a list of parameter names, not + name=value pairs. There is no postconf command to perform the reverse operation. - This feature is available with Postfix 2.6 and + This feature is available with Postfix 2.6 and later. DIAGNOSTICS @@ -250,18 +253,18 @@ POSTCONF(1) POSTCONF(1) Directory with Postfix configuration files. CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant + The following main.cf parameters are especially relevant to this program. - 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. 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. bounce_template_file (empty) - Pathname of a configuration file with bounce mes- + Pathname of a configuration file with bounce mes- sage templates. FILES @@ -275,7 +278,7 @@ POSTCONF(1) POSTCONF(1) DATABASE_README, Postfix lookup table overview 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/postfix-manuals.html b/postfix/html/postfix-manuals.html index fd6dca77f..560ab63c6 100644 --- a/postfix/html/postfix-manuals.html +++ b/postfix/html/postfix-manuals.html @@ -165,7 +165,7 @@ the following convention:
http://www.sqlite.org/
-In order to build Postfix with sqlite map support, you will need to add --DHAS_SQLITE and -I for the directory containing the sqlite headers, and -the sqlite3 library to AUXLIBS, for example:
+In order to build Postfix with sqlite map support, you will +need to add to CCARGS the flags -DHAS_SQLITE and -I with the directory +containing the sqlite header files, and you will need to add to +AUXLIBS the directory and name of the sqlite3 library, plus the +name of the standard POSIX thread library (pthread). For example: +
@@ -84,6 +87,8 @@ access table, and one for an aliases table if you want.Credits
+SQLite support was added with Postfix version 2.8.
+
- Implementation by Axel Steiner
diff --git a/postfix/proto/STANDARD_CONFIGURATION_README.html b/postfix/proto/STANDARD_CONFIGURATION_README.html index f5f5c9eb5..c3333d0ee 100644 --- a/postfix/proto/STANDARD_CONFIGURATION_README.html +++ b/postfix/proto/STANDARD_CONFIGURATION_README.html @@ -443,7 +443,7 @@ matches $inet_interfaces or $proxy_interfaces.Execute the command "postmap /etc/postfix/virtual" after -editing the file.
. +editing the file.Running Postfix behind a firewall
@@ -452,8 +452,7 @@ network is to send all mail to a gateway host, and to let that mail host take care of internal and external forwarding. Examples of that are shown in the local area network section above. A more sophisticated approach is to send only external -mail to the gateway host, and to send intranet mail directly. -That's what Wietse does at work. +mail to the gateway host, and to send intranet mail directly.Note: this example requires Postfix version 2.0 and later. To find out what Postfix version you have, execute the command "postconf diff --git a/postfix/proto/XFORWARD_README.html b/postfix/proto/XFORWARD_README.html index 9e17db825..6ab2a49f9 100644 --- a/postfix/proto/XFORWARD_README.html +++ b/postfix/proto/XFORWARD_README.html @@ -72,7 +72,7 @@ names are shown in upper case, they are in fact case insensitive. xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value )
- attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | SOURCE ) + attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | IDENT | SOURCE )
attribute-value = xtext @@ -108,6 +108,12 @@ names are shown in upper case, they are in fact case insensitive. SMTP HELO command), or [UNAVAILABLE] when the information is unavailable. The hostname may be a non-DNS hostname.
+The IDENT attribute specifies a local message identifier + on the up-stream host, or [UNAVAILABLE] when the information + is unavailable. The down-stream MTA may log this information + together with its own local message identifier to facilitate + message tracking across MTAs.
+The SOURCE attribute specifies LOCAL when the message was received from a source that is local with respect to the up-stream host (for example, the message originated from the diff --git a/postfix/proto/header_checks b/postfix/proto/header_checks index e01fe6219..bf1cb0007 100644 --- a/postfix/proto/header_checks +++ b/postfix/proto/header_checks @@ -10,6 +10,13 @@ # \fBnested_header_checks = pcre:/etc/postfix/nested_header_checks\fR # \fBbody_checks = pcre:/etc/postfix/body_checks\fR # .sp +# \fBmilter_header_checks = pcre:/etc/postfix/milter_header_checks\fR +# .sp +# \fBsmtp_header_checks = pcre:/etc/postfix/smtp_header_checks\fR +# \fBsmtp_mime_header_checks = pcre:/etc/postfix/smtp_mime_header_checks\fR +# \fBsmtp_nested_header_checks = pcre:/etc/postfix/smtp_nested_header_checks\fR +# \fBsmtp_body_checks = pcre:/etc/postfix/smtp_body_checks\fR +# .sp # \fBpostmap -q "\fIstring\fB" pcre:/etc/postfix/\fIfilename\fR # \fBpostmap -q - pcre:/etc/postfix/\fIfilename\fR <\fIinputfile\fR # .fi @@ -26,6 +33,10 @@ # the matching process is repeated for the next message header or # message body line. # +# Note: message headers are examined one logical header at a time, +# even when a message header spans multiple lines. Body lines are +# always examined one line at a time. +# # For examples, see the EXAMPLES section at the end of this # manual page. # @@ -33,9 +44,12 @@ # from worms or viruses; they do not decode attachments, and they do # not unzip archives. See the documents referenced below in the README # FILES section if you need more sophisticated content analysis. -# -# Postfix supports four built-in content inspection classes: -# .IP \fBheader_checks\fR +# FILTERS WHILE RECEIVING MAIL +# .ad +# .fi +# Postfix implements the following four built-in content +# inspection classes while receiving mail: +# .IP "\fBheader_checks\fR (default: empty)" # These are applied to initial message headers (except for # the headers that are processed with \fBmime_header_checks\fR). # .IP "\fBmime_header_checks\fR (default: \fB$header_checks\fR)" @@ -54,10 +68,26 @@ # .sp # With Postfix versions before 2.0, all content after the initial # message headers is treated as body content. -# .PP -# Note: message headers are examined one logical header at a time, -# even when a message header spans multiple lines. Body lines are -# always examined one line at a time. +# FILTERS AFTER RECEIVING MAIL +# .ad +# .fi +# Postfix supports a subset of the built-in content inspection +# classes after the message is received: +# .IP "\fBmilter_header_checks\fR (default: empty)" +# These are applied to headers that are added with Milter +# applications. +# .sp +# This feature is available in Postfix 2.7 and later. +# FILTERS WHILE DELIVERING MAIL +# .ad +# .fi +# Postfix supports all four content inspection classes while +# delivering mail via SMTP. +# .IP "\fBsmtp_header_checks\fR (default: empty)" +# .IP "\fBsmtp_mime_header_checks\fR (default: empty)" +# .IP "\fBsmtp_nested_header_checks\fR (default: empty)" +# .IP "\fBsmtp_body_checks\fR (default: empty)" +# These features are available in Postfix 2.5 and later. # COMPATIBILITY # .ad # .fi @@ -170,6 +200,8 @@ # use the transport(5) table to direct mail to the discard(8) service. # .sp # This feature is available in Postfix 2.0 and later. +# .sp +# This feature is not supported with smtp header/body checks. # .IP \fBDUNNO\fR # Pretend that the input line did not match any pattern, and inspect the # next input line. This action can be used to shorten the table search. @@ -209,6 +241,8 @@ # features. # .sp # This feature is available in Postfix 2.0 and later. +# .sp +# This feature is not supported with smtp header/body checks. # .IP "\fBHOLD \fIoptional text...\fR" # Arrange for the message to be placed on the \fBhold\fR queue, # and inspect the next input line. The message remains on \fBhold\fR @@ -228,9 +262,17 @@ # Note: this action affects all recipients of the message. # .sp # This feature is available in Postfix 2.0 and later. +# .sp +# This feature is not supported with smtp header/body checks. # .IP \fBIGNORE\fR # Delete the current line from the input, and inspect # the next input line. +# .IP "\fBINFO \fIoptional text...\fR +# Log an "info:" record with the \fIoptional text...\fR (or +# log a generic text), and inspect the next input line. This +# action is useful for routine logging or for debugging. +# .sp +# This feature is available in Postfix 2.8 and later. # .IP "\fBPREPEND \fItext...\fR" # Prepend one line with the specified text, and inspect the next # input line. @@ -253,6 +295,8 @@ # .RE # .IP # This feature is available in Postfix 2.1 and later. +# .sp +# This feature is not supported with milter_header_checks. # .IP "\fBREDIRECT \fIuser@domain\fR" # Write a message redirection request to the queue file, and # inspect the next input line. After the message is queued, @@ -264,6 +308,8 @@ # fire, only the last one is executed. # .sp # This feature is available in Postfix 2.1 and later. +# .sp +# This feature is not supported with smtp header/body checks. # .IP "\fBREPLACE \fItext...\fR" # Replace the current line with the specified text, and inspect the next # input line. @@ -294,9 +340,11 @@ # When no code is specified at the beginning of \fIoptional # text...\fR, Postfix inserts a default enhanced status code of # "5.7.1". +# .sp +# This feature is not supported with smtp header/body checks. # .IP "\fBWARN \fIoptional text...\fR -# Log a warning with the \fIoptional text...\fR (or log a -# generic message), and inspect the next input line. This +# Log a "warning:" record with the \fIoptional text...\fR (or +# log a generic text), and inspect the next input line. This # action is useful for debugging and for testing a pattern # before applying more drastic actions. # BUGS diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index e5175fd7c..4de1aa530 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -326,6 +326,10 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context, cleanup_act_log(state, "warning", context, buf, optional_text); return (buf); } + if (STREQUAL(value, "INFO", command_len)) { + cleanup_act_log(state, "info", context, buf, optional_text); + return (buf); + } if (STREQUAL(value, "FILTER", command_len)) { if (*optional_text == 0) { msg_warn("missing FILTER command argument in %s map", map_class); diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c index 6ecfa4c3b..05ded6167 100644 --- a/postfix/src/cleanup/cleanup_milter.c +++ b/postfix/src/cleanup/cleanup_milter.c @@ -370,8 +370,7 @@ static char *cleanup_milter_hbc_extend(void *context, const char *command, } return ((char *) buf); } - msg_warn("unknown command in %s map: %s", map_class, command); - return ((char *) buf); + return ((char *) HBC_CHECKS_STAT_UNKNOWN); } /* cleanup_milter_header_checks - inspect Milter-generated header */ diff --git a/postfix/src/global/deliver_pass.c b/postfix/src/global/deliver_pass.c index 5799597aa..0eaa45ddf 100644 --- a/postfix/src/global/deliver_pass.c +++ b/postfix/src/global/deliver_pass.c @@ -120,6 +120,7 @@ static int deliver_pass_send_request(VSTREAM *stream, DELIVER_REQUEST *request, ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, request->sasl_username, ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, request->sasl_sender, /* XXX Ditto if we want to pass TLS certificate info. */ + ATTR_TYPE_STR, MAIL_ATTR_LOG_IDENT, request->log_ident, ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, request->rewrite_context, ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, 1, ATTR_TYPE_END); diff --git a/postfix/src/global/deliver_request.c b/postfix/src/global/deliver_request.c index 060c04f90..e32e82fb9 100644 --- a/postfix/src/global/deliver_request.c +++ b/postfix/src/global/deliver_request.c @@ -28,9 +28,10 @@ /* char *sasl_method; /* char *sasl_username; /* char *sasl_sender; +/* char *log_ident; /* char *rewrite_context; -/* char *dsn_envid; -/* int dsn_ret; +/* char *dsn_envid; +/* int dsn_ret; /* .in -5 /* } DELIVER_REQUEST; /* @@ -202,6 +203,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) static VSTRING *sasl_method; static VSTRING *sasl_username; static VSTRING *sasl_sender; + static VSTRING *log_ident; static VSTRING *rewrite_context; static VSTRING *dsn_envid; static RCPT_BUF *rcpt_buf; @@ -227,6 +229,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) sasl_method = vstring_alloc(10); sasl_username = vstring_alloc(10); sasl_sender = vstring_alloc(10); + log_ident = vstring_alloc(10); rewrite_context = vstring_alloc(10); dsn_envid = vstring_alloc(10); rcpt_buf = rcpb_create(); @@ -259,9 +262,10 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, sasl_username, ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, sasl_sender, /* XXX Ditto if we want to pass TLS certificate info. */ + ATTR_TYPE_STR, MAIL_ATTR_LOG_IDENT, log_ident, ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, rewrite_context, ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, &rcpt_count, - ATTR_TYPE_END) != 21) { + ATTR_TYPE_END) != 22) { msg_warn("%s: error receiving common attributes", myname); return (-1); } @@ -286,6 +290,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) request->sasl_method = mystrdup(vstring_str(sasl_method)); request->sasl_username = mystrdup(vstring_str(sasl_username)); request->sasl_sender = mystrdup(vstring_str(sasl_sender)); + request->log_ident = mystrdup(vstring_str(log_ident)); request->rewrite_context = mystrdup(vstring_str(rewrite_context)); request->dsn_envid = mystrdup(vstring_str(dsn_envid)); request->dsn_ret = dsn_ret; @@ -322,9 +327,9 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) * queue, and releases the lock before starting deliveries from that * file. The queue manager does not lock the file again when reading more * recipients into memory. When the queue manager is restarted, the new - * process moves files from the active queue to the incoming queue to cool - * off for a while. Delivery agents should therefore never try to open a - * file that is locked by a queue manager process. + * process moves files from the active queue to the incoming queue to + * cool off for a while. Delivery agents should therefore never try to + * open a file that is locked by a queue manager process. * * Opening the queue file can fail for a variety of reasons, such as the * system running out of resources. Instead of throwing away mail, we're @@ -375,6 +380,7 @@ static DELIVER_REQUEST *deliver_request_alloc(void) request->sasl_method = 0; request->sasl_username = 0; request->sasl_sender = 0; + request->log_ident = 0; request->rewrite_context = 0; request->dsn_envid = 0; return (request); @@ -415,6 +421,8 @@ static void deliver_request_free(DELIVER_REQUEST *request) myfree(request->sasl_username); if (request->sasl_sender) myfree(request->sasl_sender); + if (request->log_ident) + myfree(request->log_ident); if (request->rewrite_context) myfree(request->rewrite_context); if (request->dsn_envid) diff --git a/postfix/src/global/deliver_request.h b/postfix/src/global/deliver_request.h index 2c74c00f7..d2ca7719d 100644 --- a/postfix/src/global/deliver_request.h +++ b/postfix/src/global/deliver_request.h @@ -48,6 +48,7 @@ typedef struct DELIVER_REQUEST { char *sasl_method; /* SASL method */ char *sasl_username; /* SASL user name */ char *sasl_sender; /* SASL sender */ + char *log_ident; /* original queue ID */ char *rewrite_context; /* address rewrite context */ char *dsn_envid; /* DSN envelope ID */ int dsn_ret; /* DSN full/header notification */ diff --git a/postfix/src/global/header_body_checks.c b/postfix/src/global/header_body_checks.c index b5f2aa12b..c6c894e4d 100644 --- a/postfix/src/global/header_body_checks.c +++ b/postfix/src/global/header_body_checks.c @@ -59,9 +59,9 @@ /* DESCRIPTION /* This module implements header_checks and body_checks. /* Actions are executed while mail is being delivered. The -/* following actions are recognized: WARN, REPLACE, PREPEND, -/* IGNORE, DUNNO, and OK. These actions are safe for use in -/* delivery agents. +/* following actions are recognized: INFO, WARN, REPLACE, +/* PREPEND, IGNORE, DUNNO, and OK. These actions are safe for +/* use in delivery agents. /* /* Other actions may be supplied via the extension mechanism /* described below. For example, actions that change the @@ -115,7 +115,7 @@ /* and the input byte offset within the current header or body /* segment. The result value is either the original line /* argument, HBC_CHECKS_STAT_IGNORE (delete the line from the -/* input stream) or HBC_CHECK_STAT_UNKNOWN (the command was +/* input stream) or HBC_CHECKS_STAT_UNKNOWN (the command was /* not recognized). Specify a null pointer to disable this /* feature. /* .RE @@ -248,6 +248,10 @@ static char *hbc_action(void *context, HBC_CALL_BACKS *cb, cb->logger(context, "warning", where, line, cmd_args); return ((char *) line); } + if (STREQUAL(cmd, "INFO", cmd_len)) { + cb->logger(context, "info", where, line, cmd_args); + return ((char *) line); + } if (STREQUAL(cmd, "REPLACE", cmd_len)) { if (*cmd_args == 0) { msg_warn("REPLACE action without text in %s map", map_class); diff --git a/postfix/src/global/mail_proto.h b/postfix/src/global/mail_proto.h index 4f92c15e5..e4cd57440 100644 --- a/postfix/src/global/mail_proto.h +++ b/postfix/src/global/mail_proto.h @@ -129,6 +129,7 @@ extern char *mail_pathname(const char *, const char *); #define MAIL_ATTR_ETRN_DOMAIN "etrn_domain" #define MAIL_ATTR_DUMMY "dummy" #define MAIL_ATTR_STRESS "stress" +#define MAIL_ATTR_LOG_IDENT "log_ident" #define MAIL_ATTR_RWR_CONTEXT "rewrite_context" #define MAIL_ATTR_RWR_LOCAL "local" diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index eb04015d0..43b745aa9 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20100707" +#define MAIL_RELEASE_DATE "20100728" #define MAIL_VERSION_NUMBER "2.8" #ifdef SNAPSHOT diff --git a/postfix/src/global/pipe_command.c b/postfix/src/global/pipe_command.c index ce3bad0a9..6cd4100ed 100644 --- a/postfix/src/global/pipe_command.c +++ b/postfix/src/global/pipe_command.c @@ -628,7 +628,7 @@ int pipe_command(VSTREAM *src, DSN_BUF *why,...) */ if (!NORMAL_EXIT_STATUS(wait_status)) { if (WIFSIGNALED(wait_status)) { - dsb_unix(why, "5.3.0", log_len ? + dsb_unix(why, "4.3.0", log_len ? log_buf : sys_exits_detail(EX_SOFTWARE)->text, "Command died with signal %d: \"%s\"%s%s", WTERMSIG(wait_status), args.command, diff --git a/postfix/src/local/forward.c b/postfix/src/local/forward.c index 74cb642b3..6ebe74f18 100644 --- a/postfix/src/local/forward.c +++ b/postfix/src/local/forward.c @@ -177,6 +177,9 @@ static FORWARD_INFO *forward_open(DELIVER_REQUEST *request, const char *sender) rec_fprintf((fp), REC_TYPE_ATTR, "%s=%s", (name), (value)); \ } while (0) + /* + * XXX encapsulate these as one object. + */ PASS_ATTR(cleanup, MAIL_ATTR_LOG_CLIENT_NAME, request->client_name); PASS_ATTR(cleanup, MAIL_ATTR_LOG_CLIENT_ADDR, request->client_addr); PASS_ATTR(cleanup, MAIL_ATTR_LOG_PROTO_NAME, request->client_proto); @@ -184,6 +187,7 @@ static FORWARD_INFO *forward_open(DELIVER_REQUEST *request, const char *sender) 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_LOG_IDENT, request->log_ident); PASS_ATTR(cleanup, MAIL_ATTR_RWR_CONTEXT, request->rewrite_context); vstring_free(buffer); diff --git a/postfix/src/milter/test-milter.c b/postfix/src/milter/test-milter.c index 69e83bc77..58e6728f5 100644 --- a/postfix/src/milter/test-milter.c +++ b/postfix/src/milter/test-milter.c @@ -209,7 +209,7 @@ static int test_reply(SMFICTX *ctx, int code) printf("test_reply %s\n", reply_code); return (reply_code[0] == '4' ? SMFIS_TEMPFAIL : SMFIS_REJECT); } else { - printf("test_reply %d\n", code); + printf("test_reply %d\n\n", code); return (code); } } diff --git a/postfix/src/oqmgr/qmgr.h b/postfix/src/oqmgr/qmgr.h index ddd4b3f36..802ce12ee 100644 --- a/postfix/src/oqmgr/qmgr.h +++ b/postfix/src/oqmgr/qmgr.h @@ -313,6 +313,7 @@ struct QMGR_MESSAGE { char *sasl_method; /* SASL method */ char *sasl_username; /* SASL user name */ char *sasl_sender; /* SASL sender */ + char *log_ident; /* up-stream queue ID */ char *rewrite_context; /* address qualification */ RECIPIENT_LIST rcpt_list; /* complete addresses */ }; diff --git a/postfix/src/oqmgr/qmgr_deliver.c b/postfix/src/oqmgr/qmgr_deliver.c index 0c8ee8013..ce81fd702 100644 --- a/postfix/src/oqmgr/qmgr_deliver.c +++ b/postfix/src/oqmgr/qmgr_deliver.c @@ -177,6 +177,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, message->sasl_username, ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, message->sasl_sender, /* XXX Ditto if we want to pass TLS certificate info. */ + ATTR_TYPE_STR, MAIL_ATTR_LOG_IDENT, message->log_ident, ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, message->rewrite_context, ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, list.len, ATTR_TYPE_END); diff --git a/postfix/src/oqmgr/qmgr_message.c b/postfix/src/oqmgr/qmgr_message.c index 3408b3f4e..a773d9981 100644 --- a/postfix/src/oqmgr/qmgr_message.c +++ b/postfix/src/oqmgr/qmgr_message.c @@ -185,6 +185,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->sasl_method = 0; message->sasl_username = 0; message->sasl_sender = 0; + message->log_ident = 0; message->rewrite_context = 0; recipient_list_init(&message->rcpt_list, RCPT_LIST_INIT_QUEUE); return (message); @@ -686,6 +687,12 @@ static int qmgr_message_read(QMGR_MESSAGE *message) else msg_warn("%s: ignoring multiple %s attribute: %s", message->queue_id, MAIL_ATTR_SASL_SENDER, value); + } else if (strcmp(name, MAIL_ATTR_LOG_IDENT) == 0) { + if (message->log_ident == 0) + message->log_ident = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_LOG_IDENT, value); } else if (strcmp(name, MAIL_ATTR_RWR_CONTEXT) == 0) { if (message->rewrite_context == 0) message->rewrite_context = mystrdup(value); @@ -776,6 +783,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->sasl_username = mystrdup(""); if (message->sasl_sender == 0) message->sasl_sender = mystrdup(""); + if (message->log_ident == 0) + message->log_ident = mystrdup(""); if (message->rewrite_context == 0) message->rewrite_context = mystrdup(MAIL_ATTR_RWR_LOCAL); /* Postfix < 2.3 compatibility. */ @@ -1287,6 +1296,8 @@ void qmgr_message_free(QMGR_MESSAGE *message) myfree(message->sasl_username); if (message->sasl_sender) myfree(message->sasl_sender); + if (message->log_ident) + myfree(message->log_ident); if (message->rewrite_context) myfree(message->rewrite_context); recipient_list_free(&message->rcpt_list); diff --git a/postfix/src/postconf/postconf.c b/postfix/src/postconf/postconf.c index a2c5ce772..3abfc56bf 100644 --- a/postfix/src/postconf/postconf.c +++ b/postfix/src/postconf/postconf.c @@ -73,8 +73,11 @@ /* to a temporary file then renamed into place. Parameters and /* values are specified on the command line. Use quotes in order /* to protect shell metacharacters and whitespace. +/* +/* With Postfix version 2.8 and later, the \fB-e\fR is no +/* longer needed. /* .IP \fB-h\fR -/* Show parameter values only, not the ``name = '' label +/* Show parameter values only, not the "\fIname = " label /* that normally precedes the value. /* .IP \fB-l\fR /* List the names of all supported mailbox locking methods. @@ -389,7 +392,8 @@ static const CONFIG_STR_FN_TABLE str_fn_table_2[] = { /* * XXX Global so that call-backs can see it. */ -static int cmd_mode = SHOW_NAME; +#define DEF_MODE SHOW_NAME +static int cmd_mode = DEF_MODE; /* check_myhostname - lookup hostname and validate */ @@ -1202,6 +1206,9 @@ int main(int argc, char **argv) */ else if (cmd_mode & (EDIT_MAIN | COMMENT_OUT)) { edit_parameters(cmd_mode, argc - optind, argv + optind); + } else if (cmd_mode == DEF_MODE + && argv[optind] && strchr(argv[optind], '=')) { + edit_parameters(cmd_mode | EDIT_MAIN, argc - optind, argv + optind); } /* diff --git a/postfix/src/postfix/postfix.c b/postfix/src/postfix/postfix.c index 1a2df97d9..b2ed31094 100644 --- a/postfix/src/postfix/postfix.c +++ b/postfix/src/postfix/postfix.c @@ -245,7 +245,7 @@ /* pcre_table(5), Associate PCRE pattern with value /* pgsql_table(5), Postfix PostgreSQL client /* regexp_table(5), Associate POSIX regexp pattern with value -/* slite_table(5), Postfix SQLite database driver +/* sqlite_table(5), Postfix SQLite database driver /* tcp_table(5), Postfix client-server table lookup /* /* Daemon processes: diff --git a/postfix/src/qmgr/qmgr.h b/postfix/src/qmgr/qmgr.h index 52f0327e3..6737e42c0 100644 --- a/postfix/src/qmgr/qmgr.h +++ b/postfix/src/qmgr/qmgr.h @@ -358,6 +358,7 @@ struct QMGR_MESSAGE { char *sasl_method; /* SASL method */ char *sasl_username; /* SASL user name */ char *sasl_sender; /* SASL sender */ + char *log_ident; /* up-stream queue ID */ char *rewrite_context; /* address qualification */ RECIPIENT_LIST rcpt_list; /* complete addresses */ int rcpt_count; /* used recipient slots */ diff --git a/postfix/src/qmgr/qmgr_deliver.c b/postfix/src/qmgr/qmgr_deliver.c index 0e037e385..2fbb0493e 100644 --- a/postfix/src/qmgr/qmgr_deliver.c +++ b/postfix/src/qmgr/qmgr_deliver.c @@ -182,6 +182,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, message->sasl_username, ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, message->sasl_sender, /* XXX Ditto if we want to pass TLS certificate info. */ + ATTR_TYPE_STR, MAIL_ATTR_LOG_IDENT, message->log_ident, ATTR_TYPE_STR, MAIL_ATTR_RWR_CONTEXT, message->rewrite_context, ATTR_TYPE_INT, MAIL_ATTR_RCPT_COUNT, list.len, ATTR_TYPE_END); diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index c65728387..576fb2d6f 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -196,6 +196,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->sasl_method = 0; message->sasl_username = 0; message->sasl_sender = 0; + message->log_ident = 0; message->rewrite_context = 0; recipient_list_init(&message->rcpt_list, RCPT_LIST_INIT_QUEUE); message->rcpt_count = 0; @@ -727,6 +728,12 @@ static int qmgr_message_read(QMGR_MESSAGE *message) else msg_warn("%s: ignoring multiple %s attribute: %s", message->queue_id, MAIL_ATTR_SASL_SENDER, value); + } else if (strcmp(name, MAIL_ATTR_LOG_IDENT) == 0) { + if (message->log_ident == 0) + message->log_ident = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_LOG_IDENT, value); } else if (strcmp(name, MAIL_ATTR_RWR_CONTEXT) == 0) { if (message->rewrite_context == 0) message->rewrite_context = mystrdup(value); @@ -824,6 +831,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->sasl_username = mystrdup(""); if (message->sasl_sender == 0) message->sasl_sender = mystrdup(""); + if (message->log_ident == 0) + message->log_ident = mystrdup(""); if (message->rewrite_context == 0) message->rewrite_context = mystrdup(MAIL_ATTR_RWR_LOCAL); /* Postfix < 2.3 compatibility. */ @@ -1408,6 +1417,8 @@ void qmgr_message_free(QMGR_MESSAGE *message) myfree(message->sasl_username); if (message->sasl_sender) myfree(message->sasl_sender); + if (message->log_ident) + myfree(message->log_ident); if (message->rewrite_context) myfree(message->rewrite_context); recipient_list_free(&message->rcpt_list); diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h index c8a4dd3d1..5174fe38d 100644 --- a/postfix/src/smtp/smtp.h +++ b/postfix/src/smtp/smtp.h @@ -121,6 +121,7 @@ typedef struct SMTP_STATE { #define SMTP_FEATURE_PIX_DELAY_DOTCRLF (1<<17) /* PIX smtp fixup mode */ #define SMTP_FEATURE_XFORWARD_PORT (1<<18) #define SMTP_FEATURE_EARLY_TLS_MAIL_REPLY (1<<19) /* CVE-2009-3555 */ +#define SMTP_FEATURE_XFORWARD_IDENT (1<<20) /* * Features that passivate under the endpoint. diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index 20e020492..f4e0d946b 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -270,6 +270,7 @@ int smtp_helo(SMTP_STATE *state) XFORWARD_PORT, SMTP_FEATURE_XFORWARD_PORT, XFORWARD_PROTO, SMTP_FEATURE_XFORWARD_PROTO, XFORWARD_HELO, SMTP_FEATURE_XFORWARD_HELO, + XFORWARD_IDENT, SMTP_FEATURE_XFORWARD_IDENT, XFORWARD_DOMAIN, SMTP_FEATURE_XFORWARD_DOMAIN, 0, 0, }; @@ -1220,6 +1221,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state, #define CAN_FORWARD_CLIENT_PORT _ATTR_AVAIL_AND_KNOWN_ #define CAN_FORWARD_PROTO_NAME _ATTR_AVAIL_AND_KNOWN_ #define CAN_FORWARD_HELO_NAME DEL_REQ_ATTR_AVAIL +#define CAN_FORWARD_IDENT_NAME DEL_REQ_ATTR_AVAIL #define CAN_FORWARD_RWR_CONTEXT DEL_REQ_ATTR_AVAIL #endif @@ -1258,6 +1260,11 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state, vstring_strcat(next_command, " " XFORWARD_HELO "="); xtext_quote_append(next_command, request->client_helo, ""); } + if ((session->features & SMTP_FEATURE_XFORWARD_IDENT) + && CAN_FORWARD_IDENT_NAME(request->log_ident)) { + vstring_strcat(next_command, " " XFORWARD_IDENT "="); + xtext_quote_append(next_command, request->log_ident, ""); + } if ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN) && CAN_FORWARD_RWR_CONTEXT(request->rewrite_context)) { vstring_strcat(next_command, " " XFORWARD_DOMAIN "="); @@ -2008,6 +2015,8 @@ int smtp_xfer(SMTP_STATE *state) && CAN_FORWARD_PROTO_NAME(request->client_proto)) || ((session->features & SMTP_FEATURE_XFORWARD_HELO) && CAN_FORWARD_HELO_NAME(request->client_helo)) + || ((session->features & SMTP_FEATURE_XFORWARD_IDENT) + && CAN_FORWARD_IDENT_NAME(request->log_ident)) || ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN) && CAN_FORWARD_RWR_CONTEXT(request->rewrite_context))); if (send_name_addr) diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 91612d8d0..8637926c6 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -583,7 +583,7 @@ /* .IP "\fBsmtpd_recipient_limit (1000)\fR" /* The maximal number of recipients that the Postfix SMTP server /* accepts per message delivery request. -/* .IP "\fBsmtpd_timeout (normal: 300s, stress: 10s)\fR" +/* .IP "\fBsmtpd_timeout (normal: 300s, overload: 10s)\fR" /* The time limit for sending a Postfix SMTP server response and for /* receiving a remote SMTP client request. /* .IP "\fBsmtpd_history_flush_threshold (100)\fR" @@ -613,8 +613,8 @@ /* to send to this service per time unit, regardless of whether or not /* Postfix actually accepts those recipients. /* .IP "\fBsmtpd_client_event_limit_exceptions ($mynetworks)\fR" -/* Clients that are excluded from connection count, connection rate, -/* or SMTP request rate restrictions. +/* Clients that are excluded from smtpd_client_*_count/rate_limit +/* restrictions. /* .PP /* Available in Postfix version 2.3 and later: /* .IP "\fBsmtpd_client_new_tls_session_rate_limit (0)\fR" @@ -637,10 +637,10 @@ /* The number of errors a remote SMTP client is allowed to make without /* delivering mail before the Postfix SMTP server slows down all its /* responses. -/* .IP "\fBsmtpd_hard_error_limit (normal: 20, stress: 1)\fR" +/* .IP "\fBsmtpd_hard_error_limit (normal: 20, overload: 1)\fR" /* The maximal number of errors a remote SMTP client is allowed to /* make without delivering mail. -/* .IP "\fBsmtpd_junk_command_limit (normal: 100, stress: 1)\fR" +/* .IP "\fBsmtpd_junk_command_limit (normal: 100, overload: 1)\fR" /* The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote /* SMTP client can send before the Postfix SMTP server starts to /* increment the error counter with each junk command. @@ -744,7 +744,7 @@ /* See the file ADDRESS_VERIFICATION_README for information /* about how to configure and operate the Postfix sender/recipient /* address verification service. -/* .IP "\fBaddress_verify_poll_count (${stress?1}${stress:3})\fR" +/* .IP "\fBaddress_verify_poll_count (normal: 3, overload: 1)\fR" /* How many times to query the \fBverify\fR(8) service for the completion /* of an address verification request in progress. /* .IP "\fBaddress_verify_poll_delay (3s)\fR" @@ -1662,7 +1662,8 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) ENQUEUE_FIX_REPLY(state, reply_buf, XFORWARD_CMD " " XFORWARD_NAME " " XFORWARD_ADDR " " XFORWARD_PROTO " " XFORWARD_HELO - " " XFORWARD_DOMAIN " " XFORWARD_PORT); + " " XFORWARD_DOMAIN " " XFORWARD_PORT + " " XFORWARD_IDENT); if ((discard_mask & EHLO_MASK_ENHANCEDSTATUSCODES) == 0) ENQUEUE_FIX_REPLY(state, reply_buf, "ENHANCEDSTATUSCODES"); if ((discard_mask & EHLO_MASK_8BITMIME) == 0) @@ -1786,6 +1787,9 @@ static int mail_open_stream(SMTPD_STATE *state) REC_TYPE_TIME_ARG(state->arrival_time)); if (*var_filter_xport) rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport); + if (FORWARD_IDENT(state)) + rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s", + MAIL_ATTR_LOG_IDENT, FORWARD_IDENT(state)); rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_RWR_CONTEXT, FORWARD_DOMAIN(state)); #ifdef USE_SASL_AUTH @@ -1903,8 +1907,22 @@ static int mail_open_stream(SMTPD_STATE *state) smtpd_sasl_mail_log(state); else #endif - msg_info("%s: client=%s", state->queue_id ? - state->queue_id : "NOQUEUE", FORWARD_NAMADDR(state)); + + /* + * See also: smtpd_sasl_proto.c, for a longer client= logfile record. + */ +#define PRINT_OR_NULL(cond, str) \ + ((cond) ? (str) : "") +#define PRINT2_OR_NULL(cond, name, value) \ + PRINT_OR_NULL((cond), (name)), PRINT_OR_NULL((cond), (value)) + + msg_info("%s: client=%s%s%s%s%s", + (state->queue_id ? state->queue_id : "NOQUEUE"), + state->namaddr, + PRINT2_OR_NULL(HAVE_FORWARDED_IDENT(state), + ", orig_queue_id=", FORWARD_IDENT(state)), + PRINT2_OR_NULL(HAVE_FORWARDED_CLIENT_ATTR(state), + ", orig_client=", FORWARD_NAMADDR(state))); return (0); } @@ -3645,6 +3663,7 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) XFORWARD_PORT, SMTPD_STATE_XFORWARD_PORT, XFORWARD_PROTO, SMTPD_STATE_XFORWARD_PROTO, XFORWARD_HELO, SMTPD_STATE_XFORWARD_HELO, + XFORWARD_IDENT, SMTPD_STATE_XFORWARD_IDENT, XFORWARD_DOMAIN, SMTPD_STATE_XFORWARD_DOMAIN, 0, 0, }; @@ -3813,6 +3832,20 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) UPDATE_STR(state->xforward.protocol, attr_value); break; + /* + * IDENT=local message identifier on the up-stream MTA. Censor + * special characters that could mess up logging or macro + * expansions. + */ + case SMTPD_STATE_XFORWARD_IDENT: + if (STREQ(attr_value, XFORWARD_UNAVAILABLE)) { + attr_value = CLIENT_IDENT_UNKNOWN; + } else { + neuter(attr_value, NEUTER_CHARACTERS, '?'); + } + UPDATE_STR(state->xforward.ident, attr_value); + break; + /* * DOMAIN=local or remote. */ diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 8900dce15..931dcbcfd 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -60,7 +60,7 @@ typedef struct { char *rfc_addr; /* address for RFC 2821 */ char *protocol; /* email protocol */ char *helo_name; /* helo/ehlo parameter */ - char *ident; /* message identifier */ + char *ident; /* local message identifier */ char *domain; /* rewrite context */ } SMTPD_XFORWARD_ATTR; @@ -190,7 +190,7 @@ typedef struct { #define SMTPD_STATE_XFORWARD_PROTO (1<<3) /* protocol received */ #define SMTPD_STATE_XFORWARD_HELO (1<<4) /* client helo received */ #define SMTPD_STATE_XFORWARD_IDENT (1<<5) /* message identifier */ -#define SMTPD_STATE_XFORWARD_DOMAIN (1<<6) /* message identifier */ +#define SMTPD_STATE_XFORWARD_DOMAIN (1<<6) /* address context */ #define SMTPD_STATE_XFORWARD_PORT (1<<7) /* client port received */ #define SMTPD_STATE_XFORWARD_CLIENT_MASK \ @@ -314,8 +314,11 @@ extern void smtpd_peer_reset(SMTPD_STATE *state); * Don't mix information from the current SMTP session with forwarded * information from an up-stream session. */ +#define HAVE_FORWARDED_CLIENT_ATTR(s) \ + ((s)->xforward.flags & SMTPD_STATE_XFORWARD_CLIENT_MASK) + #define FORWARD_CLIENT_ATTR(s, a) \ - (((s)->xforward.flags & SMTPD_STATE_XFORWARD_CLIENT_MASK) ? \ + (HAVE_FORWARDED_CLIENT_ATTR(s) ? \ (s)->xforward.a : (s)->a) #define FORWARD_ADDR(s) FORWARD_CLIENT_ATTR((s), rfc_addr) @@ -325,10 +328,19 @@ extern void smtpd_peer_reset(SMTPD_STATE *state); #define FORWARD_HELO(s) FORWARD_CLIENT_ATTR((s), helo_name) #define FORWARD_PORT(s) FORWARD_CLIENT_ATTR((s), port) -#define FORWARD_IDENT(s) \ - (((s)->xforward.flags & SMTPD_STATE_XFORWARD_IDENT) ? \ - (s)->queue_id : (s)->ident) + /* + * Mixing is not a problem with forwarded local message identifiers. + */ +#define HAVE_FORWARDED_IDENT(s) \ + ((s)->xforward.ident != 0) +#define FORWARD_IDENT(s) \ + (HAVE_FORWARDED_IDENT(s) ? \ + (s)->xforward.ident : (s)->queue_id) + + /* + * Mixing is not a problem with forwarded address rewriting contexts. + */ #define FORWARD_DOMAIN(s) \ (((s)->xforward.flags & SMTPD_STATE_XFORWARD_DOMAIN) ? \ (s)->xforward.domain : (s)->rewrite_context) diff --git a/postfix/src/smtpd/smtpd_proxy.c b/postfix/src/smtpd/smtpd_proxy.c index 0968f5b5b..deb752108 100644 --- a/postfix/src/smtpd/smtpd_proxy.c +++ b/postfix/src/smtpd/smtpd_proxy.c @@ -325,6 +325,7 @@ static int smtpd_proxy_connect(SMTPD_STATE *state) XFORWARD_PORT, SMTPD_PROXY_XFORWARD_PORT, XFORWARD_PROTO, SMTPD_PROXY_XFORWARD_PROTO, XFORWARD_HELO, SMTPD_PROXY_XFORWARD_HELO, + XFORWARD_IDENT, SMTPD_PROXY_XFORWARD_IDENT, XFORWARD_DOMAIN, SMTPD_PROXY_XFORWARD_DOMAIN, 0, 0, }; @@ -426,6 +427,10 @@ static int smtpd_proxy_connect(SMTPD_STATE *state) && smtpd_proxy_xforward_send(state, buf, XFORWARD_HELO, IS_AVAIL_CLIENT_HELO(FORWARD_HELO(state)), FORWARD_HELO(state))) + || ((server_xforward_features & SMTPD_PROXY_XFORWARD_IDENT) + && smtpd_proxy_xforward_send(state, buf, XFORWARD_IDENT, + IS_AVAIL_CLIENT_IDENT(FORWARD_IDENT(state)), + FORWARD_IDENT(state))) || ((server_xforward_features & SMTPD_PROXY_XFORWARD_PROTO) && smtpd_proxy_xforward_send(state, buf, XFORWARD_PROTO, IS_AVAIL_CLIENT_PROTO(FORWARD_PROTO(state)), diff --git a/postfix/src/smtpd/smtpd_sasl_proto.c b/postfix/src/smtpd/smtpd_sasl_proto.c index 89064feb0..9fcdc1ed0 100644 --- a/postfix/src/smtpd/smtpd_sasl_proto.c +++ b/postfix/src/smtpd/smtpd_sasl_proto.c @@ -234,16 +234,28 @@ char *smtpd_sasl_mail_opt(SMTPD_STATE *state, const char *addr) void smtpd_sasl_mail_log(SMTPD_STATE *state) { -#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3)) - msg_info("%s: client=%s%s%s%s%s%s%s", - state->queue_id ? state->queue_id : "NOQUEUE", FORWARD_NAMADDR(state), - IFELSE(state->sasl_method, ", sasl_method=", ""), - IFELSE(state->sasl_method, state->sasl_method, ""), - IFELSE(state->sasl_username, ", sasl_username=", ""), - IFELSE(state->sasl_username, state->sasl_username, ""), - IFELSE(state->sasl_sender, ", sasl_sender=", ""), - IFELSE(state->sasl_sender, state->sasl_sender, "")); + /* + * See also: smtpd.c, for a shorter client= logfile record. + */ +#define PRINT_OR_NULL(cond, str) \ + ((cond) ? (str) : "") +#define PRINT2_OR_NULL(cond, name, value) \ + PRINT_OR_NULL((cond), (name)), PRINT_OR_NULL((cond), (value)) + + msg_info("%s: client=%s%s%s%s%s%s%s%s%s%s%s", + (state->queue_id ? state->queue_id : "NOQUEUE"), + state->namaddr, + PRINT2_OR_NULL(state->sasl_method, + ", sasl_method=", state->sasl_method), + PRINT2_OR_NULL(state->sasl_username, + ", sasl_username=", state->sasl_username), + PRINT2_OR_NULL(state->sasl_sender, + ", sasl_sender=", state->sasl_sender), + PRINT2_OR_NULL(HAVE_FORWARDED_IDENT(state), + ", orig_queue_id=", FORWARD_IDENT(state)), + PRINT2_OR_NULL(HAVE_FORWARDED_CLIENT_ATTR(state), + ", orig_client=", FORWARD_NAMADDR(state))); } /* smtpd_sasl_mail_reset - SASL-specific MAIL FROM cleanup */