]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.7-20090606
authorWietse Venema <wietse@porcupine.org>
Sat, 6 Jun 2009 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:35:31 +0000 (06:35 +0000)
81 files changed:
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/conf/postmulti-script
postfix/html/cleanup.8.html
postfix/html/postconf.5.html
postfix/makedefs
postfix/man/man5/postconf.5
postfix/man/man8/cleanup.8
postfix/mantools/postlink
postfix/proto/postconf.proto
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup.c
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_envelope.c
postfix/src/cleanup/cleanup_extracted.c
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/cleanup/cleanup_milter.in14a [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in14b [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in14c [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in14d [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in14e [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in14f [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in14g [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in15a [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in15b [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in15c [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in15d [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in15e [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in15f [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.in15g [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14a1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14a2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14b1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14b2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14c1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14c2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14d1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14d2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14e1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14e2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14f1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14f2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14g1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref14g2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15a1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15a2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15b1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15b2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15c1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15c2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15d1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15d2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15e1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15e2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15f1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15f2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15g1 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.ref15g2 [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg14a [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg14b [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg14c [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg14d [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg14e [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg14f [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg14g [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg15a [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg15b [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg15c [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg15d [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg15e [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg15f [new file with mode: 0644]
postfix/src/cleanup/cleanup_milter.reg15g [new file with mode: 0644]
postfix/src/cleanup/cleanup_state.c
postfix/src/cleanup/test-queue-file14 [new file with mode: 0644]
postfix/src/cleanup/test-queue-file15 [new file with mode: 0644]
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/postconf/Makefile.in
postfix/src/util/unix_send_fd.c

index 693173fe0e3f0bffe613fc0d96f88a7ef6505f53..fbb21dce70c0c3405770319fe38df715e56195e4 100644 (file)
@@ -15278,3 +15278,26 @@ Apologies for any names omitted.
        does not like the workaround. We now default back to the
        non-workaround code and turn on the workaround dynamically.
        Files: util/unix_send_fd.c, unix_recv_fd.c, unix_pass_fd_fix.c.
+
+20090605
+
+       Portability: modern kernels below ancient user-land. File:
+       makedefs.
+
+20090606
+
+       Feature: post-Milter header checks, with all actions except
+       PREPEND. To enable, specify for example "milter_header_checks
+       = pcre:/path/to/file".  Files: cleanup/cleanup_init.c,
+       cleanup/cleanup_milter.c, cleanup/cleanup_extracted.c,
+       cleanup/cleanup_state.c.
+
+       Bugfix: non-portable command pathname in postmulti-script.
+
+       Safety: "postmulti -e destroy" no longer attempts to remove
+       files that are created AFTER "postmulti -e create". Rationale:
+       by design, postfix queue/data directories are not trusted;
+       actions within those directory trees must not affect files
+       outside those those trees (e.g. by symlink race attacks).
+       We don't want to be nailed with a bunch of CVEs for unsafe
+       pathname handling.  File: conf/postmulti-script.
index 68fe1e2e657a908e89f830c3f32c7a294561d2d2..e10c3a338953c216939482e8c6d61566da39f5e1 100644 (file)
@@ -13,3 +13,21 @@ specifies the release date of a stable release or snapshot release.
 
 If you upgrade from Postfix 2.5 or earlier, read RELEASE_NOTES-2.6
 before proceeding.
+
+Incompatibility with snapshot 20090606
+======================================
+
+The "postmulti -e destroy" command no longer attempts to remove
+files that are created AFTER "postmulti -e create".  It still works
+as expected immediately after creating an instance by mistake.
+Trying to automatically remove other files is too risky because
+Postfix-owned directories are not trusted.
+
+Major changes with snapshot 20090606
+====================================
+
+Support for header checks on headers that are generated by Milter
+applications. This can be used, for example, to direct mail flow
+based on headers that indicate spam levels. See postconf(5) for
+"milter_header_checks. All header_checks features are implemented
+except PREPEND.
index b3e7caf4aad367ce4c37bdf646f640db49a66a86..f5a351f3d5061574c52cb170d078f32baa36f53a 100644 (file)
@@ -2,9 +2,11 @@ Wish list:
 
        Remove this file from the stable release.
 
-       Apply header_checks and body_checks when Milters add or
-       modify the message content. Use case: Milters that add
-       spamminess headers.
+       Fix the header_body_checks API, so that the name of the map
+       class (e.g. milter_header_checks) is available for logging.
+
+       Fix the mime_state and header_body_checks APIs, so that
+       they use VSTRINGs. This simplifies REPLACE actions.
 
        Update FILTER_README for multi-instance support, and rename
        the old document to FILTER_LEGACY_README.
index 3f1333be39d811d7c364196d0ccd8f0f022cafab..13fffe7fb22ecf95df3b25cad0e431e70cd74458 100644 (file)
@@ -27,6 +27,13 @@ umask 022
 #  multi_instance_group                - New value for target instance
 #  multi_instance_name         - New value for target instance
 
+# For security reasons we don't take pathnames from the file system
+# when destroying instances.  Instead we use known-to-be-safe names
+# and nothing with a / because that could be subject to races.
+QUEUE_DIRECTORIES="active bounce corrupt defer deferred flush hold incoming \
+maildrop pid private public saved trace"
+#DEBUG=echo
+
 : ${MAIL_CONFIG:?"do not invoke this command directly"}
 : ${command_directory:?"do not invoke this command directly"}
 : ${daemon_directory:?"do not invoke this command directly"}
@@ -36,6 +43,7 @@ usage() { echo "$0: Error: Usage: $USAGE" >&2; exit 1; }
 
 TAG="$MAIL_LOGTAG/postmulti-script"
 fatal() { postlog -p fatal -t "$TAG" "$1"; exit 1; }
+WARN="postlog -p warn -t $TAG"
 
 # args: add|del $dir
 #
@@ -236,57 +244,44 @@ destroy)
     postfix -c "$config_directory" status >/dev/null 2>&1 &&
        fatal "Instance '$config_directory' is not stopped"
 
-    # XXX: Internal "postfix /some/cmd" interface via /bin/env for execvp().
-    #
-    for q in maildrop incoming active deferred hold
-    do
-       postfix -c "$config_directory" /bin/env \
-           find "$q" ! -name "$q" ! -name "?" -perm 0700 -print |
-           grep "^" >/dev/null &&
-           fatal "Instance '$config_directory' $q queue is not empty"
-    done
-
     # Update multi_instance directories
     # and also (just in case) drop from alternate_config_directories
     #
-    update_cfdirs del $config_directory || exit 1
-
-    # Change default personalities:
-    MAIL_CONFIG="$config_directory"; export MAIL_CONFIG
-
-    # Full steam ahead, instance will be at least partly destroyed!
+    $DEBUG update_cfdirs del $config_directory || exit 1
 
-    # Try to remove data_directory, but not sub-directories.
-    # Note: care with "$TAG" insertion into sh -c 'script'.
+    # "postmulti -e destroy" will remove an entire instance only
+    # when invoked immediately after "postmulti -e create". Trying
+    # to remove more files is too dangerous.
     #
-    postfix /bin/sh -c \
-       'cd $data_directory; rm -f -- *; cd ..; rmdir $data_directory; \
-         PATH=$command_directory:$PATH; export PATH; \
-        test -d $data_directory && \
-            postlog -p warn -t "'"$TAG"'" \
-               "$data_directory partly removed" 2>&1' 2>/dev/null
-
-    # Remove Postfix-owned files in the queue directory.
-    # Remove all files in the "pid" sub-directory.
-    # Remove empty directories.
-    # Note: care with "$TAG" insertion into sh -c 'script'.
-    postfix /bin/sh -c \
-       'find . -user $mail_owner ! -type d -exec rm -f -- "{}" ";"; \
-        find . -depth -user $mail_owner -type d -exec rmdir -- "{}" ";"; \
-        rm -f -- pid/*; rmdir *; cd ..; rmdir $queue_directory; \
-         PATH=$command_directory:$PATH; export PATH; \
-        test -d $queue_directory && \
-            postlog -p warn -t "'"$TAG"'" \
-               "$queue_directory partly removed" 2>&1' 2>/dev/null
+    # By design, postfix-owned directory trees are not trusted, and
+    # any action within those directory trees must not affect files
+    # outside those trees (e.g. via symlink race attacks).
+    #
+    # XXX: Internal "postfix /some/cmd" interface.
+    #
+    postfix -c "$config_directory" /bin/sh -c "
+    for q in $QUEUE_DIRECTORIES
+    do
+       $DEBUG rmdir -- \$q || 
+           $WARN `pwd`/\$q: please verify contents and remove by hand
+    done
+    "
+
+    postfix -c "$config_directory" /bin/sh -c "
+    for dir in \$data_directory \$queue_directory
+    do
+       $DEBUG rmdir -- \$dir || 
+           $WARN \$dir: please verify contents and remove by hand
+    done
+    "
 
     # In the configuration directory remove just the main.cf and master.cf
     # files.
-    rm -f -- "$MAIL_CONFIG/master.cf" "$MAIL_CONFIG/main.cf" 2>/dev/null
-    rmdir -- "$MAIL_CONFIG" 2>/dev/null
-    test -d "$MAIL_CONFIG" && \
-        postlog -p warn -t "$TAG" \
-           "$MAIL_CONFIG partly removed" 2>&1
+    $DEBUG rm -f -- "$config_directory/master.cf" "$config_directory/main.cf" 2>/dev/null
+    $DEBUG rmdir -- "$config_directory" ||
+       $WARN $config_directory: please verify contents and remove by hand
     ;;
+
 enable)
     postconf -c "$config_directory" -e \
        "multi_instance_enable = yes" || exit 1;;
index 9c6196aff0232747ade0cb7c55ea250ce7030cf2..61952c1f39aaca40ec5da1b31f6a1aadfdc90973 100644 (file)
@@ -224,6 +224,13 @@ CLEANUP(8)                                                          CLEANUP(8)
               The  macros  that  are sent to Milter (mail filter)
               applications after the end of the message header.
 
+       Available in Postfix version 2.5 and later:
+
+       <b><a href="postconf.5.html#milter_header_checks">milter_header_checks</a> (empty)</b>
+              Optional lookup tables for  content  inspection  of
+              primary message headers that are produced by Milter
+              applications.
+
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
 
index f351fdd763be63f86f87b79f9cf0c1b114a24a10..85d6e2a4ace64fab467b0b66334248ff66545284 100644 (file)
@@ -5689,6 +5689,33 @@ of available macro names and their meanings.  </p>
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="milter_header_checks">milter_header_checks</a>
+(default: empty)</b></DT><DD>
+
+<p>
+Optional lookup tables for content inspection of primary
+message headers that are produced by Milter applications.
+See the <a href="header_checks.5.html">header_checks(5)</a> manual page for usage.
+</p>
+
+<p> The following example sends mail that is marked as SPAM to a
+spam sanization machine. Note that matches are case-insensitive by
+default. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+    <a href="postconf.5.html#milter_header_checks">milter_header_checks</a> = <a href="pcre_table.5.html">pcre</a>:/etc/postfix/<a href="postconf.5.html#milter_header_checks">milter_header_checks</a>
+</pre>
+<pre>
+/etc/postfix/<a href="postconf.5.html#milter_header_checks">milter_header_checks</a>:
+    /^X-SPAM-FLAG:\s+YES]/ FILTER mysmtp:sanitizer.example.com:25
+</pre>
+</blockquote>
+
+
 </DD>
 
 <DT><b><a name="milter_helo_macros">milter_helo_macros</a>
index ee464361053d9559eefda88cd94e7990d293c273..071a30ef073d2a0ad1f747d93544ba9447c5c6c1 100644 (file)
@@ -298,7 +298,15 @@ case "$SYSTEM.$RELEASE" in
                case "$RELEASE" in
                2.[0-5].*) CCARGS="$CCARGS -DNO_EPOLL";;
                    # Workaround for retarded libc 
-                   2.6.*) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
+                   2.6.*)
+                      if [ `expr "X$CCARGS" : "X.*-DNO_EPOLL"` -gt 0 ]
+                       then
+                           :
+                       elif [ ! -e /usr/include/sys/epoll.h ]
+                       then
+                           echo CCARGS="$CCARGS -DNO_EPOLL"
+                       else
+                          trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
                           cat >makedefs.test.c <<'EOF'
 #include <sys/types.h>
 #include <sys/epoll.h>
@@ -320,7 +328,8 @@ EOF
                           ${CC-gcc} -o makedefs.test makedefs.test.c || exit 1
                           ./makedefs.test 2>/dev/null ||
                                CCARGS="$CCARGS -DNO_EPOLL"
-                          rm -f makedefs.test makedefs.test.[co];;
+                          rm -f makedefs.test makedefs.test.[co]
+                      fi;;
                esac
                ;;
      GNU.0*|GNU/kFreeBSD.[567]*)
index 48a38dcfe658e311632eb32e813041857101a5bb..5ab7bbdcf54f0f991df217781e4e6167346e92e9 100644 (file)
@@ -3158,6 +3158,33 @@ after the end of the message header. See MILTER_README for a list
 of available macro names and their meanings.
 .PP
 This feature is available in Postfix 2.5 and later.
+.SH milter_header_checks (default: empty)
+Optional lookup tables for content inspection of primary
+message headers that are produced by Milter applications.
+See the \fBheader_checks\fR(5) manual page for usage.
+.PP
+The following example sends mail that is marked as SPAM to a
+spam sanization machine. Note that matches are case-insensitive by
+default.
+.sp
+.in +4
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+    milter_header_checks = pcre:/etc/postfix/milter_header_checks
+.fi
+.ad
+.ft R
+.nf
+.na
+.ft C
+/etc/postfix/milter_header_checks:
+    /^X-SPAM-FLAG:\es+YES]/ FILTER mysmtp:sanitizer.example.com:25
+.fi
+.ad
+.ft R
+.in -4
 .SH milter_helo_macros (default: see "postconf -d" output)
 The macros that are sent to Milter (mail filter) applications
 after the SMTP HELO or EHLO command. See
index de5f912f0898a789c173f8929af71cfb5b1c7041..5bba18db9c8c1415c126a3d040b8cad05e22d157 100644 (file)
@@ -190,6 +190,11 @@ Available in Postfix version 2.5 and later:
 .IP "\fBmilter_end_of_header_macros (see 'postconf -d' output)\fR"
 The macros that are sent to Milter (mail filter) applications
 after the end of the message header.
+.PP
+Available in Postfix version 2.5 and later:
+.IP "\fBmilter_header_checks (empty)\fR"
+Optional lookup tables for content inspection of primary
+message headers that are produced by Milter applications.
 .SH "MIME PROCESSING CONTROLS"
 .na
 .nf
index 7d4d59e5255ef268e0ede5ec1f01d9ec2ea008a5..31fa892cb7876e3ed9dfaa7684e6c167d2063ed0 100755 (executable)
@@ -868,6 +868,7 @@ while (<>) {
     s;\bmilter_unknown_command_macros\b;<a href="postconf.5.html#milter_unknown_command_macros">$&</a>;g;
     s;\bmilter_end_of_data_macros\b;<a href="postconf.5.html#milter_end_of_data_macros">$&</a>;g;
     s;\bmilter_end_of_header_macros\b;<a href="postconf.5.html#milter_end_of_header_macros">$&</a>;g;
+    s;\bmilter_header_checks\b;<a href="postconf.5.html#milter_header_checks">$&</a>;g;
 
     # Multi-instance support
     s;\bmulti_instance_directo[-</bB>]*\n*[ <bB>]*ries\b;<a href="postconf.5.html#multi_instance_directories">$&</a>;g;
index 6fd144ef23cc58bbf5a089da047b83350dae8ded..1a08bda44f0f0ae49f64931f2a4714598d9fe31c 100644 (file)
@@ -12300,3 +12300,25 @@ parameter. See there for details. </p>
 
 <p> This feature is available in Postfix 2.5 and later. </p>
 
+%PARAM milter_header_checks
+
+<p>
+Optional lookup tables for content inspection of primary 
+message headers that are produced by Milter applications.
+See the header_checks(5) manual page for usage.
+</p>
+
+<p> The following example sends mail that is marked as SPAM to a
+spam sanization machine. Note that matches are case-insensitive by
+default. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    milter_header_checks = pcre:/etc/postfix/milter_header_checks
+</pre>
+<pre>
+/etc/postfix/milter_header_checks:
+    /^X-SPAM-FLAG:\s+YES]/ FILTER mysmtp:sanitizer.example.com:25
+</pre>
+</blockquote> 
index 161ebf2dd0c9e8257304dde7ed3e2fb57cc25605..f59f9bb408f47be8f22bd3c43d8b403debf098e2 100644 (file)
@@ -76,7 +76,11 @@ milter_tests: cleanup_milter_test bug_tests \
        cleanup_milter_test10b cleanup_milter_test10c cleanup_milter_test10d \
        cleanup_milter_test10e cleanup_milter_test11 cleanup_milter_test12 \
        cleanup_milter_test13a cleanup_milter_test13b cleanup_milter_test13c \
-       cleanup_milter_test13d
+       cleanup_milter_test13d \
+       cleanup_milter_test14a cleanup_milter_test14b cleanup_milter_test14c \
+       cleanup_milter_test14d cleanup_milter_test14e \
+       cleanup_milter_test15a cleanup_milter_test15b cleanup_milter_test15c \
+       cleanup_milter_test15d cleanup_milter_test15e
 
 root_tests:
 
@@ -334,6 +338,106 @@ cleanup_milter_test13d: cleanup_milter test-queue-file13d cleanup_milter.in13d \
        diff cleanup_milter.ref13d cleanup_milter.tmp
        rm -f test-queue-file13d.tmp cleanup_milter.tmp
 
+cleanup_milter_test14a: cleanup_milter test-queue-file14 cleanup_milter.in14a \
+       cleanup_milter.ref14a1 ../postcat/postcat cleanup_milter.ref14a2
+       cp test-queue-file14 test-queue-file14a.tmp
+       chmod u+w test-queue-file14a.tmp
+       ./cleanup_milter <cleanup_milter.in14a 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref14a1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file14a.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref14a2 cleanup_milter.tmp2
+       rm -f test-queue-file14a.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test14b: cleanup_milter test-queue-file14 cleanup_milter.in14b \
+       cleanup_milter.ref14b1 ../postcat/postcat cleanup_milter.ref14b2
+       cp test-queue-file14 test-queue-file14b.tmp
+       chmod u+w test-queue-file14b.tmp
+       ./cleanup_milter <cleanup_milter.in14b 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref14b1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file14b.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref14b2 cleanup_milter.tmp2
+       rm -f test-queue-file14b.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test14c: cleanup_milter test-queue-file14 cleanup_milter.in14c \
+       cleanup_milter.ref14c1 ../postcat/postcat cleanup_milter.ref14c2
+       cp test-queue-file14 test-queue-file14c.tmp
+       chmod u+w test-queue-file14c.tmp
+       ./cleanup_milter <cleanup_milter.in14c 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref14c1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file14c.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref14c2 cleanup_milter.tmp2
+       rm -f test-queue-file14c.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test14d: cleanup_milter test-queue-file14 cleanup_milter.in14d \
+       cleanup_milter.ref14d1 ../postcat/postcat cleanup_milter.ref14d2
+       cp test-queue-file14 test-queue-file14d.tmp
+       chmod u+w test-queue-file14d.tmp
+       ./cleanup_milter <cleanup_milter.in14d 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref14d1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file14d.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref14d2 cleanup_milter.tmp2
+       rm -f test-queue-file14d.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test14e: cleanup_milter test-queue-file14 cleanup_milter.in14e \
+       cleanup_milter.ref14e1 ../postcat/postcat cleanup_milter.ref14e2
+       cp test-queue-file14 test-queue-file14e.tmp
+       chmod u+w test-queue-file14e.tmp
+       ./cleanup_milter <cleanup_milter.in14e 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref14e1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file14e.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref14e2 cleanup_milter.tmp2
+       rm -f test-queue-file14e.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test15a: cleanup_milter test-queue-file15 cleanup_milter.in15a \
+       cleanup_milter.ref15a1 ../postcat/postcat cleanup_milter.ref15a2
+       cp test-queue-file15 test-queue-file15a.tmp
+       chmod u+w test-queue-file15a.tmp
+       ./cleanup_milter <cleanup_milter.in15a 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref15a1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file15a.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref15a2 cleanup_milter.tmp2
+       rm -f test-queue-file15a.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test15b: cleanup_milter test-queue-file15 cleanup_milter.in15b \
+       cleanup_milter.ref15b1 ../postcat/postcat cleanup_milter.ref15b2
+       cp test-queue-file15 test-queue-file15b.tmp
+       chmod u+w test-queue-file15b.tmp
+       ./cleanup_milter <cleanup_milter.in15b 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref15b1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file15b.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref15b2 cleanup_milter.tmp2
+       rm -f test-queue-file15b.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test15c: cleanup_milter test-queue-file15 cleanup_milter.in15c \
+       cleanup_milter.ref15c1 ../postcat/postcat cleanup_milter.ref15c2
+       cp test-queue-file15 test-queue-file15c.tmp
+       chmod u+w test-queue-file15c.tmp
+       ./cleanup_milter <cleanup_milter.in15c 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref15c1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file15c.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref15c2 cleanup_milter.tmp2
+       rm -f test-queue-file15c.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test15d: cleanup_milter test-queue-file15 cleanup_milter.in15d \
+       cleanup_milter.ref15d1 ../postcat/postcat cleanup_milter.ref15d2
+       cp test-queue-file15 test-queue-file15d.tmp
+       chmod u+w test-queue-file15d.tmp
+       ./cleanup_milter <cleanup_milter.in15d 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref15d1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file15d.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref15d2 cleanup_milter.tmp2
+       rm -f test-queue-file15d.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
+cleanup_milter_test15e: cleanup_milter test-queue-file15 cleanup_milter.in15e \
+       cleanup_milter.ref15e1 ../postcat/postcat cleanup_milter.ref15e2
+       cp test-queue-file15 test-queue-file15e.tmp
+       chmod u+w test-queue-file15e.tmp
+       ./cleanup_milter <cleanup_milter.in15e 2>cleanup_milter.tmp1
+       diff cleanup_milter.ref15e1 cleanup_milter.tmp1
+       ../postcat/postcat -ov test-queue-file15e.tmp 2>/dev/null >cleanup_milter.tmp2
+       diff cleanup_milter.ref15e2 cleanup_milter.tmp2
+       rm -f test-queue-file15e.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
+
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -349,6 +453,7 @@ cleanup.o: ../../include/attr.h
 cleanup.o: ../../include/been_here.h
 cleanup.o: ../../include/cleanup_user.h
 cleanup.o: ../../include/dict.h
+cleanup.o: ../../include/header_body_checks.h
 cleanup.o: ../../include/header_opts.h
 cleanup.o: ../../include/htable.h
 cleanup.o: ../../include/iostuff.h
@@ -385,6 +490,7 @@ cleanup_addr.o: ../../include/cleanup_user.h
 cleanup_addr.o: ../../include/dict.h
 cleanup_addr.o: ../../include/dsn_mask.h
 cleanup_addr.o: ../../include/ext_prop.h
+cleanup_addr.o: ../../include/header_body_checks.h
 cleanup_addr.o: ../../include/header_opts.h
 cleanup_addr.o: ../../include/htable.h
 cleanup_addr.o: ../../include/iostuff.h
@@ -422,6 +528,7 @@ cleanup_api.o: ../../include/deliver_request.h
 cleanup_api.o: ../../include/dict.h
 cleanup_api.o: ../../include/dsn.h
 cleanup_api.o: ../../include/dsn_buf.h
+cleanup_api.o: ../../include/header_body_checks.h
 cleanup_api.o: ../../include/header_opts.h
 cleanup_api.o: ../../include/htable.h
 cleanup_api.o: ../../include/iostuff.h
@@ -456,6 +563,7 @@ cleanup_body_edit.o: ../../include/attr.h
 cleanup_body_edit.o: ../../include/been_here.h
 cleanup_body_edit.o: ../../include/cleanup_user.h
 cleanup_body_edit.o: ../../include/dict.h
+cleanup_body_edit.o: ../../include/header_body_checks.h
 cleanup_body_edit.o: ../../include/header_opts.h
 cleanup_body_edit.o: ../../include/htable.h
 cleanup_body_edit.o: ../../include/mail_conf.h
@@ -490,6 +598,7 @@ cleanup_bounce.o: ../../include/dsn.h
 cleanup_bounce.o: ../../include/dsn_buf.h
 cleanup_bounce.o: ../../include/dsn_mask.h
 cleanup_bounce.o: ../../include/dsn_util.h
+cleanup_bounce.o: ../../include/header_body_checks.h
 cleanup_bounce.o: ../../include/header_opts.h
 cleanup_bounce.o: ../../include/htable.h
 cleanup_bounce.o: ../../include/iostuff.h
@@ -527,6 +636,7 @@ cleanup_envelope.o: ../../include/been_here.h
 cleanup_envelope.o: ../../include/cleanup_user.h
 cleanup_envelope.o: ../../include/dict.h
 cleanup_envelope.o: ../../include/dsn_mask.h
+cleanup_envelope.o: ../../include/header_body_checks.h
 cleanup_envelope.o: ../../include/header_opts.h
 cleanup_envelope.o: ../../include/htable.h
 cleanup_envelope.o: ../../include/iostuff.h
@@ -545,6 +655,7 @@ cleanup_envelope.o: ../../include/nvtable.h
 cleanup_envelope.o: ../../include/qmgr_user.h
 cleanup_envelope.o: ../../include/rec_attr_map.h
 cleanup_envelope.o: ../../include/rec_type.h
+cleanup_envelope.o: ../../include/recipient_list.h
 cleanup_envelope.o: ../../include/record.h
 cleanup_envelope.o: ../../include/resolve_clnt.h
 cleanup_envelope.o: ../../include/string_list.h
@@ -563,6 +674,7 @@ cleanup_extracted.o: ../../include/been_here.h
 cleanup_extracted.o: ../../include/cleanup_user.h
 cleanup_extracted.o: ../../include/dict.h
 cleanup_extracted.o: ../../include/dsn_mask.h
+cleanup_extracted.o: ../../include/header_body_checks.h
 cleanup_extracted.o: ../../include/header_opts.h
 cleanup_extracted.o: ../../include/htable.h
 cleanup_extracted.o: ../../include/iostuff.h
@@ -597,6 +709,7 @@ cleanup_final.o: ../../include/attr.h
 cleanup_final.o: ../../include/been_here.h
 cleanup_final.o: ../../include/cleanup_user.h
 cleanup_final.o: ../../include/dict.h
+cleanup_final.o: ../../include/header_body_checks.h
 cleanup_final.o: ../../include/header_opts.h
 cleanup_final.o: ../../include/htable.h
 cleanup_final.o: ../../include/mail_conf.h
@@ -626,6 +739,7 @@ cleanup_init.o: ../../include/cleanup_user.h
 cleanup_init.o: ../../include/dict.h
 cleanup_init.o: ../../include/ext_prop.h
 cleanup_init.o: ../../include/flush_clnt.h
+cleanup_init.o: ../../include/header_body_checks.h
 cleanup_init.o: ../../include/header_opts.h
 cleanup_init.o: ../../include/htable.h
 cleanup_init.o: ../../include/iostuff.h
@@ -658,6 +772,7 @@ cleanup_map11.o: ../../include/attr.h
 cleanup_map11.o: ../../include/been_here.h
 cleanup_map11.o: ../../include/cleanup_user.h
 cleanup_map11.o: ../../include/dict.h
+cleanup_map11.o: ../../include/header_body_checks.h
 cleanup_map11.o: ../../include/header_opts.h
 cleanup_map11.o: ../../include/htable.h
 cleanup_map11.o: ../../include/mail_addr_map.h
@@ -687,6 +802,7 @@ cleanup_map1n.o: ../../include/attr.h
 cleanup_map1n.o: ../../include/been_here.h
 cleanup_map1n.o: ../../include/cleanup_user.h
 cleanup_map1n.o: ../../include/dict.h
+cleanup_map1n.o: ../../include/header_body_checks.h
 cleanup_map1n.o: ../../include/header_opts.h
 cleanup_map1n.o: ../../include/htable.h
 cleanup_map1n.o: ../../include/mail_addr_map.h
@@ -717,6 +833,7 @@ cleanup_masquerade.o: ../../include/attr.h
 cleanup_masquerade.o: ../../include/been_here.h
 cleanup_masquerade.o: ../../include/cleanup_user.h
 cleanup_masquerade.o: ../../include/dict.h
+cleanup_masquerade.o: ../../include/header_body_checks.h
 cleanup_masquerade.o: ../../include/header_opts.h
 cleanup_masquerade.o: ../../include/htable.h
 cleanup_masquerade.o: ../../include/mail_conf.h
@@ -750,6 +867,7 @@ cleanup_message.o: ../../include/conv_time.h
 cleanup_message.o: ../../include/dict.h
 cleanup_message.o: ../../include/dsn_util.h
 cleanup_message.o: ../../include/ext_prop.h
+cleanup_message.o: ../../include/header_body_checks.h
 cleanup_message.o: ../../include/header_opts.h
 cleanup_message.o: ../../include/htable.h
 cleanup_message.o: ../../include/iostuff.h
@@ -790,6 +908,8 @@ cleanup_milter.o: ../../include/been_here.h
 cleanup_milter.o: ../../include/cleanup_user.h
 cleanup_milter.o: ../../include/dict.h
 cleanup_milter.o: ../../include/dsn_mask.h
+cleanup_milter.o: ../../include/dsn_util.h
+cleanup_milter.o: ../../include/header_body_checks.h
 cleanup_milter.o: ../../include/header_opts.h
 cleanup_milter.o: ../../include/htable.h
 cleanup_milter.o: ../../include/iostuff.h
@@ -828,6 +948,7 @@ cleanup_out.o: ../../include/attr.h
 cleanup_out.o: ../../include/been_here.h
 cleanup_out.o: ../../include/cleanup_user.h
 cleanup_out.o: ../../include/dict.h
+cleanup_out.o: ../../include/header_body_checks.h
 cleanup_out.o: ../../include/header_opts.h
 cleanup_out.o: ../../include/htable.h
 cleanup_out.o: ../../include/lex_822.h
@@ -865,6 +986,7 @@ cleanup_out_recipient.o: ../../include/dsn.h
 cleanup_out_recipient.o: ../../include/dsn_buf.h
 cleanup_out_recipient.o: ../../include/dsn_mask.h
 cleanup_out_recipient.o: ../../include/ext_prop.h
+cleanup_out_recipient.o: ../../include/header_body_checks.h
 cleanup_out_recipient.o: ../../include/header_opts.h
 cleanup_out_recipient.o: ../../include/htable.h
 cleanup_out_recipient.o: ../../include/iostuff.h
@@ -899,6 +1021,7 @@ cleanup_region.o: ../../include/attr.h
 cleanup_region.o: ../../include/been_here.h
 cleanup_region.o: ../../include/cleanup_user.h
 cleanup_region.o: ../../include/dict.h
+cleanup_region.o: ../../include/header_body_checks.h
 cleanup_region.o: ../../include/header_opts.h
 cleanup_region.o: ../../include/htable.h
 cleanup_region.o: ../../include/mail_conf.h
@@ -925,6 +1048,7 @@ cleanup_rewrite.o: ../../include/attr.h
 cleanup_rewrite.o: ../../include/been_here.h
 cleanup_rewrite.o: ../../include/cleanup_user.h
 cleanup_rewrite.o: ../../include/dict.h
+cleanup_rewrite.o: ../../include/header_body_checks.h
 cleanup_rewrite.o: ../../include/header_opts.h
 cleanup_rewrite.o: ../../include/htable.h
 cleanup_rewrite.o: ../../include/iostuff.h
@@ -956,6 +1080,7 @@ cleanup_state.o: ../../include/attr.h
 cleanup_state.o: ../../include/been_here.h
 cleanup_state.o: ../../include/cleanup_user.h
 cleanup_state.o: ../../include/dict.h
+cleanup_state.o: ../../include/header_body_checks.h
 cleanup_state.o: ../../include/header_opts.h
 cleanup_state.o: ../../include/htable.h
 cleanup_state.o: ../../include/iostuff.h
index 36f4f7948a4b1260654530ae79f80b5933caed44..2caa775dcb17f5a8969891af0d105bbda9d17912 100644 (file)
 /* .IP "\fBmilter_end_of_header_macros (see 'postconf -d' output)\fR"
 /*     The macros that are sent to Milter (mail filter) applications
 /*     after the end of the message header.
+/* .PP
+/*     Available in Postfix version 2.5 and later:
+/* .IP "\fBmilter_header_checks (empty)\fR"
+/*     Optional lookup tables for content inspection of primary
+/*     message headers that are produced by Milter applications.
 /* MIME PROCESSING CONTROLS
 /* .ad
 /* .fi
index d8bfe08f82e3a513b8a9bd2d39badd5ddb72034a..b21b6fc028e237bd80fedebb47899d6d15ef218e 100644 (file)
@@ -32,6 +32,7 @@
 #include <mime_state.h>
 #include <string_list.h>
 #include <cleanup_user.h>
+#include <header_body_checks.h>
 
  /*
   * Milter library.
@@ -78,6 +79,8 @@ typedef struct CLEANUP_STATE {
     off_t   append_rcpt_pt_target;     /* target of above record */
     off_t   append_hdr_pt_offset;      /* append header here */
     off_t   append_hdr_pt_target;      /* target of above record */
+    off_t   append_meta_pt_offset;     /* append meta record here */
+    off_t   append_meta_pt_target;     /* target of above record */
     ssize_t rcpt_count;                        /* recipient count */
     char   *reason;                    /* failure reason */
     char   *smtp_reply;                        /* failure reason, SMTP-style */
@@ -108,6 +111,8 @@ typedef struct CLEANUP_STATE {
     VSTRING *milter_ext_from;          /* externalized sender */
     VSTRING *milter_ext_rcpt;          /* externalized recipient */
     VSTRING *milter_err_text;          /* milter call-back reply */
+    HBC_CHECKS *milter_hbc_checks;     /* Milter header checks */
+    VSTRING *milter_hbc_reply;         /* Milter header checks reply */
 
     /*
      * Support for Milter body replacement requests.
index 2253fa17ae4853d58a3fd1dd114318fbbc5e37aa..1f5aa51f11d27080f7fe6a3e4d2ee530de3322fb 100644 (file)
@@ -385,7 +385,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
        cleanup_addr_sender(state, buf);
        if (state->milters || cleanup_milters) {
            /* Make room to replace sender. */
-           rec_pad(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_PAYL_SIZE);
+           if ((len = strlen(state->sender)) < REC_TYPE_PTR_PAYL_SIZE)
+               rec_pad(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_PAYL_SIZE - len);
            /* Remember the after-sender record offset. */
            if ((state->sender_pt_target = vstream_ftell(state->dst)) < 0)
                msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
index cf66c5dde45a4fde7a9bf1c16313339a6c6ae68a..81bca08580bca8a1a784813e16cb423577677898 100644 (file)
@@ -188,6 +188,14 @@ void    cleanup_extracted_process(CLEANUP_STATE *state, int type,
            cleanup_out_format(state, REC_TYPE_ATTR, "%s=%s",
                               MAIL_ATTR_ENCODING, encoding);
        state->flags |= CLEANUP_FLAG_INRCPT;
+       /* Make room to append more meta records. */
+       if (state->milters || cleanup_milters) {
+           if ((state->append_meta_pt_offset = vstream_ftell(state->dst)) < 0)
+               msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
+           cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, 0L);
+           if ((state->append_meta_pt_target = vstream_ftell(state->dst)) < 0)
+               msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
+       }
     }
 
     /*
index 67a27a8d96197fcd67a0938ade6e0088a72d91e4..bc4eb9ffda1af45c61abaf9f91ce04d284d358c3 100644 (file)
@@ -161,6 +161,7 @@ char   *var_milt_eoh_macros;                /* end-of-header macros */
 char   *var_milt_eod_macros;           /* end-of-data macros */
 char   *var_milt_unk_macros;           /* unknown command macros */
 char   *var_cleanup_milters;           /* non-SMTP mail */
+char   *var_milt_head_checks;          /* post-Milter header checks */
 int     var_auto_8bit_enc_hdr;         /* auto-detect 8bit encoding header */
 int     var_always_add_hdrs;           /* always add missing headers */
 
@@ -227,6 +228,7 @@ CONFIG_STR_TABLE cleanup_str_table[] = {
     VAR_MILT_EOD_MACROS, DEF_MILT_EOD_MACROS, &var_milt_eod_macros, 0, 0,
     VAR_MILT_UNK_MACROS, DEF_MILT_UNK_MACROS, &var_milt_unk_macros, 0, 0,
     VAR_CLEANUP_MILTERS, DEF_CLEANUP_MILTERS, &var_cleanup_milters, 0, 0,
+    VAR_MILT_HEAD_CHECKS, DEF_MILT_HEAD_CHECKS, &var_milt_head_checks, 0, 0,
     0,
 };
 
index fdab9f5cc15f254eaafd872284a58f3d8bf2a283..b42367a113ae5e7af08f709b3cd7355867d8579a 100644 (file)
 #include <lex_822.h>
 #include <is_header.h>
 #include <quote_821_local.h>
+#include <dsn_util.h>
 
 /* Application-specific. */
 
 #define STR(x)         vstring_str(x)
 #define LEN(x)         VSTRING_LEN(x)
 
+/* cleanup_milter_hbc_log - log post-milter header/body_checks action */
+
+static void cleanup_milter_hbc_log(void *context, const char *action,
+                                       const char *where, const char *line,
+                                          const char *optional_text)
+{
+    const CLEANUP_STATE *state = (CLEANUP_STATE *) context;
+    const char *attr;
+
+    vstring_sprintf(state->temp1, "%s: milter-%s-%s: %s %.60s from %s[%s];",
+                   state->queue_id, where, action, where, line,
+                   state->client_name, state->client_addr);
+    if (state->sender)
+       vstring_sprintf_append(state->temp1, " from=<%s>", state->sender);
+    if (state->recip)
+       vstring_sprintf_append(state->temp1, " to=<%s>", state->recip);
+    if ((attr = nvtable_find(state->attr, MAIL_ATTR_LOG_PROTO_NAME)) != 0)
+       vstring_sprintf_append(state->temp1, " proto=%s", attr);
+    if ((attr = nvtable_find(state->attr, MAIL_ATTR_LOG_HELO_NAME)) != 0)
+       vstring_sprintf_append(state->temp1, " helo=<%s>", attr);
+    if (optional_text)
+       vstring_sprintf_append(state->temp1, ": %s", optional_text);
+    msg_info("%s", vstring_str(state->temp1));
+}
+
+/* cleanup_milter_header_prepend - prepend header to milter-generated header */
+
+static void cleanup_milter_header_prepend(void *context, int rec_type,
+                                const char *buf, ssize_t len, off_t offset)
+{
+    msg_warn("the milter_header/body_checks prepend action is not implemented");
+}
+
+/* cleanup_milter_hbc_extend - additional header/body_checks actions */
+
+static char *cleanup_milter_hbc_extend(void *context, const char *command,
+                                    int cmd_len, const char *optional_text,
+                                        const char *where, const char *buf,
+                                              ssize_t buf_len, off_t offset)
+{
+    CLEANUP_STATE *state = (CLEANUP_STATE *) context;
+    const char *map_class = VAR_MILT_HEAD_CHECKS;      /* XXX */
+
+#define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0)
+
+    /*
+     * We log all header/body-checks actions here, because we know the
+     * details of the message content that triggered the action. We also
+     * report detail-free milter-reply values to the caller through the
+     * milter_hbc_reply state member, so that up-stream code can stop sending
+     * requests after e.g., reject or discard.
+     * 
+     * As enforced elsewhere, this code is not called when (state->flags &
+     * CLEANUP_FLAG_FILTER_ALL) == 0.
+     */
+    if (STREQUAL(command, "REJECT", cmd_len)) {
+       const CLEANUP_STAT_DETAIL *detail;
+
+       if (state->reason)
+           myfree(state->reason);
+       detail = cleanup_stat_detail(CLEANUP_STAT_CONT);
+       if (*optional_text) {
+           state->reason = dsn_prepend(detail->dsn, optional_text);
+           if (*state->reason != '4' && *state->reason != '5') {
+               msg_warn("bad DSN action in %s -- need 4.x.x or 5.x.x",
+                        optional_text);
+               *state->reason = '4';
+           }
+       } else {
+           state->reason = dsn_prepend(detail->dsn, detail->text);
+       }
+       state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
+       cleanup_milter_hbc_log((void *) state, "reject", where, buf, state->reason);
+       vstring_sprintf(state->milter_hbc_reply, "%d %s", detail->smtp, state->reason);
+       STR(state->milter_hbc_reply)[0] = *state->reason;
+       return ((char *) buf);
+    }
+    if (STREQUAL(command, "FILTER", cmd_len)) {
+       if (*optional_text == 0) {
+           msg_warn("missing FILTER command argument in %s map", map_class);
+       } else if (strchr(optional_text, ':') == 0) {
+           msg_warn("bad FILTER command %s in %s -- "
+                    "need transport:destination",
+                    optional_text, map_class);
+       } else {
+           if (state->filter)
+               myfree(state->filter);
+           state->filter = mystrdup(optional_text);
+           cleanup_milter_hbc_log((void *) state, "filter", where, buf,
+                                  optional_text);
+       }
+       return ((char *) buf);
+    }
+    if (STREQUAL(command, "DISCARD", cmd_len)) {
+       cleanup_milter_hbc_log((void *) state, "discard", where, buf, optional_text);
+       vstring_strcpy(state->milter_hbc_reply, "D");
+       state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
+       return ((char *) buf);
+    }
+    if (STREQUAL(command, "HOLD", cmd_len)) {
+       if ((state->flags & CLEANUP_FLAG_HOLD) == 0) {
+           cleanup_milter_hbc_log((void *) state, "hold", where, buf, optional_text);
+           vstring_strcpy(state->milter_hbc_reply, "H");
+       }
+       return ((char *) buf);
+    }
+    if (STREQUAL(command, "REDIRECT", cmd_len)) {
+       if (strchr(optional_text, '@') == 0) {
+           msg_warn("bad REDIRECT target \"%s\" in %s map -- "
+                    "need user@domain",
+                    optional_text, map_class);
+       } else {
+           if (state->redirect)
+               myfree(state->redirect);
+           state->redirect = mystrdup(optional_text);
+           cleanup_milter_hbc_log((void *) state, "redirect", where, buf,
+                                  optional_text);
+           state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
+       }
+       return ((char *) buf);
+    }
+    msg_warn("unknown command in %s map: %s", map_class, command);
+    return ((char *) buf);
+}
+
+/* cleanup_milter_header_checks - inspect Milter-generated header */
+
+static int cleanup_milter_header_checks(CLEANUP_STATE *state, VSTRING *buf)
+{
+    char   *ret;
+
+    /*
+     * Milter application "add/insert/replace header" requests happen at the
+     * end-of-message stage, therefore all the header operations are relative
+     * to the primary message header.
+     */
+    ret = hbc_header_checks((void *) state, state->milter_hbc_checks,
+                           MIME_HDR_PRIMARY, (HEADER_OPTS *) 0,
+                           buf, (off_t) 0);
+    if (ret == 0) {
+       return (0);
+    } else {
+       if (ret != STR(buf)) {
+           vstring_strcpy(buf, ret);
+           myfree(ret);
+       }
+       return (1);
+    }
+}
+
+/* cleanup_milter_hbc_add_meta - add REDIRECT or FILTER meta records */
+
+static void cleanup_milter_hbc_add_meta(CLEANUP_STATE *state)
+{
+    const char *myname = "cleanup_milter_hbc_add_meta";
+    off_t   reverse_ptr_offset;
+    off_t   new_meta_offset;
+
+    /*
+     * Note: this code runs while the Milter infrastructure is being torn
+     * down. For this reason we handle all I/O errors here on the spot
+     * instead of reporting them back through the Milter infrastructure.
+     */
+
+    /*
+     * Sanity check.
+     */
+    if (state->append_meta_pt_offset < 0)
+       msg_panic("%s: no meta append pointer location", myname);
+    if (state->append_meta_pt_target < 0)
+       msg_panic("%s: no meta append pointer target", myname);
+
+    /*
+     * Allocate space after the end of the queue file, and write the meta
+     * record(s), followed by a reverse pointer record that points to the
+     * target of the old "meta record append" pointer record. This reverse
+     * pointer record becomes the new "meta record append" pointer record.
+     * Although the new "meta record append" pointer record will never be
+     * used we update it here to make the code more similar to other code
+     * that inserts/appends content, so that common code can be factored out
+     * later.
+     */
+    if ((new_meta_offset = vstream_fseek(state->dst, (off_t) 0, SEEK_END)) < 0) {
+       msg_warn("%s: seek file %s: %m", myname, cleanup_path);
+       state->errs |= CLEANUP_STAT_WRITE;
+       return;
+    }
+    if (state->filter != 0)
+       cleanup_out_string(state, REC_TYPE_FILT, state->filter);
+    if (state->redirect != 0)
+       cleanup_out_string(state, REC_TYPE_RDR, state->redirect);
+    if ((reverse_ptr_offset = vstream_ftell(state->dst)) < 0) {
+       msg_warn("%s: vstream_ftell file %s: %m", myname, cleanup_path);
+       state->errs |= CLEANUP_STAT_WRITE;
+       return;
+    }
+    cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
+                      (long) state->append_meta_pt_target);
+
+    /*
+     * Pointer flipping: update the old "meta record append" pointer record
+     * value with the location of the new meta record.
+     */
+    if (vstream_fseek(state->dst, state->append_meta_pt_offset, SEEK_SET) < 0) {
+       msg_warn("%s: seek file %s: %m", myname, cleanup_path);
+       state->errs |= CLEANUP_STAT_WRITE;
+       return;
+    }
+    cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
+                      (long) new_meta_offset);
+
+    /*
+     * Update the in-memory "meta append" pointer record location with the
+     * location of the reverse pointer record that follows the new meta
+     * record. The target of the "meta append" pointer record does not
+     * change; it's always the record that follows the dummy pointer record
+     * that was written while Postfix received the message.
+     */
+    state->append_meta_pt_offset = reverse_ptr_offset;
+}
+
+/* cleanup_milter_header_checks_init - initialize post-Milter header checks */
+
+static void cleanup_milter_header_checks_init(CLEANUP_STATE *state)
+{
+#define NO_NESTED_HDR_NAME     ""
+#define NO_NESTED_HDR_VALUE    ""
+#define NO_MIME_HDR_NAME       ""
+#define NO_MIME_HDR_VALUE      ""
+
+    static /* XXX not const */ HBC_CALL_BACKS call_backs = {
+       cleanup_milter_hbc_log,
+       cleanup_milter_header_prepend,
+       cleanup_milter_hbc_extend,
+    };
+
+    state->milter_hbc_checks =
+       hbc_header_checks_create(VAR_MILT_HEAD_CHECKS, var_milt_head_checks,
+                                NO_MIME_HDR_NAME, NO_MIME_HDR_VALUE,
+                                NO_NESTED_HDR_NAME, NO_NESTED_HDR_VALUE,
+                                &call_backs);
+    state->milter_hbc_reply = vstring_alloc(100);
+    if (state->filter)
+       myfree(state->filter);
+    state->filter = 0;
+    if (state->redirect)
+       myfree(state->redirect);
+    state->redirect = 0;
+}
+
+/* cleanup_milter_hbc_finish - finalize post-Milter header checks */
+
+static void cleanup_milter_hbc_finish(CLEANUP_STATE *state)
+{
+    if (state->milter_hbc_checks)
+       hbc_header_checks_free(state->milter_hbc_checks);
+    state->milter_hbc_checks = 0;
+    if (state->milter_hbc_reply)
+       vstring_free(state->milter_hbc_reply);
+    state->milter_hbc_reply = 0;
+    if (CLEANUP_OUT_OK(state) && (state->filter || state->redirect))
+       cleanup_milter_hbc_add_meta(state);
+}
+
  /*
   * Milter replies.
   */
@@ -305,6 +570,19 @@ static const char *cleanup_add_header(void *context, const char *name,
     if (state->append_hdr_pt_target < 0)
        msg_panic("%s: no header append pointer target", myname);
 
+    /*
+     * Return early when Milter header checks request that this header record
+     * be dropped.
+     */
+    buf = vstring_alloc(100);
+    vstring_sprintf(buf, "%s:%s%s", name, space, value);
+    if (state->milter_hbc_checks
+       && (state->flags & CLEANUP_FLAG_FILTER_ALL)
+       && cleanup_milter_header_checks(state, buf) == 0) {
+       vstring_free(buf);
+       return (0);
+    }
+
     /*
      * Allocate space after the end of the queue file, and write the header
      * record(s), followed by a reverse pointer record that points to the
@@ -313,10 +591,9 @@ static const char *cleanup_add_header(void *context, const char *name,
      */
     if ((new_hdr_offset = vstream_fseek(state->dst, (off_t) 0, SEEK_END)) < 0) {
        msg_warn("%s: seek file %s: %m", myname, cleanup_path);
+       vstring_free(buf);
        return (cleanup_milter_error(state, errno));
     }
-    buf = vstring_alloc(100);
-    vstring_sprintf(buf, "%s:%s%s", name, space, value);
     cleanup_out_header(state, buf);            /* Includes padding */
     vstring_free(buf);
     if ((reverse_ptr_offset = vstream_ftell(state->dst)) < 0) {
@@ -355,7 +632,13 @@ static const char *cleanup_add_header(void *context, const char *name,
     /*
      * In case of error while doing record output.
      */
-    return (CLEANUP_OUT_OK(state) ? 0 : cleanup_milter_error(state, 0));
+    return (CLEANUP_OUT_OK(state) == 0 ? cleanup_milter_error(state, 0) :
+           state->milter_hbc_reply && LEN(state->milter_hbc_reply) ?
+           STR(state->milter_hbc_reply) : 0);
+
+    /*
+     * Note: state->append_meta_pt_target never changes.
+     */
 }
 
 /* cleanup_find_header_start - find specific header instance */
@@ -671,6 +954,16 @@ static const char *cleanup_patch_header(CLEANUP_STATE *state,
      * record. It is ignored when the to-be-saved record is a pointer record.
      */
 
+    /*
+     * Return early when Milter header checks request that this header record
+     * be dropped.
+     */
+    vstring_sprintf(buf, "%s:%s%s", new_hdr_name, hdr_space, new_hdr_value);
+    if (state->milter_hbc_checks
+       && (state->flags & CLEANUP_FLAG_FILTER_ALL)
+       && cleanup_milter_header_checks(state, buf) == 0)
+       CLEANUP_PATCH_HEADER_RETURN(0);
+
     /*
      * Write the new header to a new location after the end of the queue
      * file.
@@ -679,7 +972,6 @@ static const char *cleanup_patch_header(CLEANUP_STATE *state,
        msg_warn("%s: seek file %s: %m", myname, cleanup_path);
        CLEANUP_PATCH_HEADER_RETURN(cleanup_milter_error(state, errno));
     }
-    vstring_sprintf(buf, "%s:%s%s", new_hdr_name, hdr_space, new_hdr_value);
     cleanup_out_header(state, buf);            /* Includes padding */
     if (msg_verbose > 1)
        msg_info("%s: %ld: write %.*s", myname, (long) new_hdr_offset,
@@ -734,8 +1026,10 @@ static const char *cleanup_patch_header(CLEANUP_STATE *state,
     /*
      * In case of error while doing record output.
      */
-    CLEANUP_PATCH_HEADER_RETURN(CLEANUP_OUT_OK(state) ? 0 :
-                               cleanup_milter_error(state, 0));
+    CLEANUP_PATCH_HEADER_RETURN(
+              CLEANUP_OUT_OK(state) == 0 ? cleanup_milter_error(state, 0) :
+                  state->milter_hbc_reply && LEN(state->milter_hbc_reply) ?
+                               STR(state->milter_hbc_reply) : 0);
 
     /*
      * Note: state->append_hdr_pt_target never changes.
@@ -1553,6 +1847,13 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
     default:
        msg_panic("%s: unexpected mail filter reply: %s", myname, resp);
     }
+
+    /*
+     * Don't log milter_header/body checks actions again.
+     */
+    if (state->milter_hbc_reply && strcmp(resp, STR(state->milter_hbc_reply)) == 0)
+       return (ret);
+
     vstring_sprintf(state->temp1, "%s: %s: %s from %s[%s]: %s;",
                    state->queue_id, action, event, state->client_name,
                    state->client_addr, text);
@@ -1618,6 +1919,12 @@ void    cleanup_milter_inspect(CLEANUP_STATE *state, MILTERS *milters)
     if (state->client_name == 0)
        cleanup_milter_client_init(state);
 
+    /*
+     * Prologue: prepare for Milter header/body checks.
+     */
+    if (*var_milt_head_checks)
+       cleanup_milter_header_checks_init(state);
+
     /*
      * Process mail filter replies. The reply format is verified by the mail
      * filter library.
@@ -1625,6 +1932,13 @@ void    cleanup_milter_inspect(CLEANUP_STATE *state, MILTERS *milters)
     if ((resp = milter_message(milters, state->handle->stream,
                               state->data_offset)) != 0)
        cleanup_milter_apply(state, "END-OF-MESSAGE", resp);
+
+    /*
+     * Epilogue: finalize Milter header/body checks.
+     */
+    if (*var_milt_head_checks)
+       cleanup_milter_hbc_finish(state);
+
     if (msg_verbose)
        msg_info("leave %s", myname);
 }
@@ -1779,6 +2093,7 @@ MAPS   *cleanup_virt_alias_maps;
 char   *var_milt_daemon_name = "host.example.com";
 char   *var_milt_v = DEF_MILT_V;
 MILTERS *cleanup_milters = (MILTERS *) ((char *) sizeof(*cleanup_milters));
+char   *var_milt_head_checks = "";
 
 /* Dummies to satisfy unused external references. */
 
@@ -1898,6 +2213,15 @@ static void open_queue_file(CLEANUP_STATE *state, const char *path)
                        if ((state->append_rcpt_pt_target =
                             vstream_ftell(state->dst)) < 0)
                            msg_fatal("file %s: vstream_ftell: %m", cleanup_path);
+                   } else if (curr_offset > state->xtra_offset
+                              && state->append_meta_pt_offset < 0) {
+                       state->append_meta_pt_offset = curr_offset;
+                       if (atol(STR(buf)) != 0)
+                           msg_fatal("file %s: bad dummy meta PTR record: %s",
+                                     cleanup_path, STR(buf));
+                       if ((state->append_meta_pt_target =
+                            vstream_ftell(state->dst)) < 0)
+                           msg_fatal("file %s: vstream_ftell: %m", cleanup_path);
                    }
                } else {
                    if (state->append_hdr_pt_offset < 0) {
@@ -1912,7 +2236,9 @@ static void open_queue_file(CLEANUP_STATE *state, const char *path)
                }
            }
            if (state->append_rcpt_pt_offset > 0
-               && state->append_hdr_pt_offset > 0)
+               && state->append_hdr_pt_offset > 0
+               && (rec_type == REC_TYPE_END
+                   || state->append_meta_pt_offset > 0))
                break;
        }
        if (msg_verbose) {
@@ -1944,6 +2270,11 @@ int     main(int unused_argc, char **argv)
     CLEANUP_STATE *state = cleanup_state_alloc((VSTREAM *) 0);
 
     state->queue_id = mystrdup("NOQUEUE");
+    state->sender = mystrdup("sender");
+    state->recip = mystrdup("recipient");
+    state->client_name = "client_name";
+    state->client_addr = "client_addr";
+    state->flags |= CLEANUP_FLAG_FILTER_ALL;
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
     var_line_limit = DEF_LINE_LIMIT;
@@ -1952,6 +2283,7 @@ int     main(int unused_argc, char **argv)
     for (;;) {
        ARGV   *argv;
        ssize_t index;
+       const char *resp = 0;
 
        if (istty) {
            vstream_printf("- ");
@@ -1995,13 +2327,15 @@ int     main(int unused_argc, char **argv)
        } else if (state->dst == 0) {
            msg_warn("no open queue file");
        } else if (strcmp(argv->argv[0], "close") == 0) {
+           if (*var_milt_head_checks)
+               cleanup_milter_hbc_finish(state);
            close_queue_file(state);
        } else if (strcmp(argv->argv[0], "add_header") == 0) {
            if (argv->argc < 2) {
                msg_warn("bad add_header argument count: %d", argv->argc);
            } else {
                flatten_args(arg_buf, argv->argv + 2);
-               cleanup_add_header(state, argv->argv[1], " ", STR(arg_buf));
+               resp = cleanup_add_header(state, argv->argv[1], " ", STR(arg_buf));
            }
        } else if (strcmp(argv->argv[0], "ins_header") == 0) {
            if (argv->argc < 3) {
@@ -2010,7 +2344,7 @@ int     main(int unused_argc, char **argv)
                msg_warn("bad ins_header index value");
            } else {
                flatten_args(arg_buf, argv->argv + 3);
-               cleanup_ins_header(state, index, argv->argv[2], " ", STR(arg_buf));
+               resp = cleanup_ins_header(state, index, argv->argv[2], " ", STR(arg_buf));
            }
        } else if (strcmp(argv->argv[0], "upd_header") == 0) {
            if (argv->argc < 3) {
@@ -2019,7 +2353,7 @@ int     main(int unused_argc, char **argv)
                msg_warn("bad upd_header index value");
            } else {
                flatten_args(arg_buf, argv->argv + 3);
-               cleanup_upd_header(state, index, argv->argv[2], " ", STR(arg_buf));
+               resp = cleanup_upd_header(state, index, argv->argv[2], " ", STR(arg_buf));
            }
        } else if (strcmp(argv->argv[0], "del_header") == 0) {
            if (argv->argc != 3) {
@@ -2072,13 +2406,30 @@ int     main(int unused_argc, char **argv)
                    vstream_fclose(fp);
                }
            }
+       } else if (strcmp(argv->argv[0], "header_checks") == 0) {
+           if (argv->argc != 2) {
+               msg_warn("bad header_checks argument count: %d", argv->argc);
+           } else if (*var_milt_head_checks) {
+               msg_warn("can't change header checks");
+           } else {
+               var_milt_head_checks = mystrdup(argv->argv[1]);
+               cleanup_milter_header_checks_init(state);
+           }
        } else {
            msg_warn("bad command: %s", argv->argv[0]);
        }
        argv_free(argv);
+       if (resp)
+           cleanup_milter_apply(state, "END-OF-MESSAGE", resp);
     }
     vstring_free(inbuf);
     vstring_free(arg_buf);
+    if (state->append_meta_pt_offset >= 0) {
+       if (state->flags)
+           msg_info("flags = %s", cleanup_strflags(state->flags));
+       if (state->errs)
+           msg_info("errs = %s", cleanup_strerror(state->errs));
+    }
     cleanup_state_free(state);
 
     return (0);
diff --git a/postfix/src/cleanup/cleanup_milter.in14a b/postfix/src/cleanup/cleanup_milter.in14a
new file mode 100644 (file)
index 0000000..6fc21f5
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file14a.tmp
+
+header_checks regexp:cleanup_milter.reg14a
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in14b b/postfix/src/cleanup/cleanup_milter.in14b
new file mode 100644 (file)
index 0000000..539112c
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file14b.tmp
+
+header_checks regexp:cleanup_milter.reg14b
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in14c b/postfix/src/cleanup/cleanup_milter.in14c
new file mode 100644 (file)
index 0000000..0a247b2
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file14c.tmp
+
+header_checks regexp:cleanup_milter.reg14c
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in14d b/postfix/src/cleanup/cleanup_milter.in14d
new file mode 100644 (file)
index 0000000..13aa2ef
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file14d.tmp
+
+header_checks regexp:cleanup_milter.reg14d
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in14e b/postfix/src/cleanup/cleanup_milter.in14e
new file mode 100644 (file)
index 0000000..f54ccd0
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file14e.tmp
+
+header_checks regexp:cleanup_milter.reg14e
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in14f b/postfix/src/cleanup/cleanup_milter.in14f
new file mode 100644 (file)
index 0000000..68124a7
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file14f.tmp
+
+header_checks regexp:cleanup_milter.reg14f
+ins_header 2 X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in14g b/postfix/src/cleanup/cleanup_milter.in14g
new file mode 100644 (file)
index 0000000..ebd866f
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file14g.tmp
+
+header_checks regexp:cleanup_milter.reg14g
+upd_header 1 X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in15a b/postfix/src/cleanup/cleanup_milter.in15a
new file mode 100644 (file)
index 0000000..8c2be9e
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file15a.tmp
+
+header_checks regexp:cleanup_milter.reg15a
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in15b b/postfix/src/cleanup/cleanup_milter.in15b
new file mode 100644 (file)
index 0000000..fb209ad
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file15b.tmp
+
+header_checks regexp:cleanup_milter.reg15b
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in15c b/postfix/src/cleanup/cleanup_milter.in15c
new file mode 100644 (file)
index 0000000..3b3ef36
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file15c.tmp
+
+header_checks regexp:cleanup_milter.reg15c
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in15d b/postfix/src/cleanup/cleanup_milter.in15d
new file mode 100644 (file)
index 0000000..a00b143
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file15d.tmp
+
+header_checks regexp:cleanup_milter.reg15d
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in15e b/postfix/src/cleanup/cleanup_milter.in15e
new file mode 100644 (file)
index 0000000..1c26f59
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file15e.tmp
+
+header_checks regexp:cleanup_milter.reg15e
+add_header X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in15f b/postfix/src/cleanup/cleanup_milter.in15f
new file mode 100644 (file)
index 0000000..8dc6a26
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file15f.tmp
+
+header_checks regexp:cleanup_milter.reg15f
+ins_header 2 X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in15g b/postfix/src/cleanup/cleanup_milter.in15g
new file mode 100644 (file)
index 0000000..0e90d9f
--- /dev/null
@@ -0,0 +1,7 @@
+#verbose on
+open test-queue-file15g.tmp
+
+header_checks regexp:cleanup_milter.reg15g
+ins_header 2 X-SPAM-FLAG YES
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.ref14a1 b/postfix/src/cleanup/cleanup_milter.ref14a1
new file mode 100644 (file)
index 0000000..9006f9a
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-reject: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 5.7.1 message content rejected
+./cleanup_milter: errs = message content rejected
diff --git a/postfix/src/cleanup/cleanup_milter.ref14a2 b/postfix/src/cleanup/cleanup_milter.ref14a2
new file mode 100644 (file)
index 0000000..cb690d8
--- /dev/null
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file14a.tmp ***
+        0 message_size:             365             256               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:05:19 2009
+      100 create_time: Fri Jun  5 14:05:19 2009
+      124 named_attribute: rewrite_context=local
+      147 sender_fullname: Wietse Venema
+      162 sender: wietse@ahost.example.com
+      188 pointer_record:             0
+      203 original_recipient: wietse
+      211 recipient: wietse@ahost.example.com
+      237 pointer_record:               0
+      254 *** MESSAGE CONTENTS test-queue-file14a.tmp ***
+      256 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      316 regular_text:        id DA4892510C1; Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      372 regular_text: To: wietse@ahost.example.com
+      402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
+      462 regular_text: Date: Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      555 pointer_record:             642
+      642 regular_text: X-SPAM-FLAG: YES
+      660 pointer_record:             572
+      572 regular_text: 
+      574 regular_text: Fri Jun  5 14:05:19 EDT 2009
+      604 pointer_record:               0
+      621 *** HEADER EXTRACTED test-queue-file14a.tmp ***
+      623 pointer_record:               0
+      640 *** MESSAGE FILE END test-queue-file14a.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref14b1 b/postfix/src/cleanup/cleanup_milter.ref14b1
new file mode 100644 (file)
index 0000000..5608b81
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-filter: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: transport:nexthop:port
+./cleanup_milter: flags = enable_header_body_filter enable_milters
diff --git a/postfix/src/cleanup/cleanup_milter.ref14b2 b/postfix/src/cleanup/cleanup_milter.ref14b2
new file mode 100644 (file)
index 0000000..209bf2b
--- /dev/null
@@ -0,0 +1,29 @@
+*** ENVELOPE RECORDS test-queue-file14b.tmp ***
+        0 message_size:             365             256               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:05:19 2009
+      100 create_time: Fri Jun  5 14:05:19 2009
+      124 named_attribute: rewrite_context=local
+      147 sender_fullname: Wietse Venema
+      162 sender: wietse@ahost.example.com
+      188 pointer_record:             0
+      203 original_recipient: wietse
+      211 recipient: wietse@ahost.example.com
+      237 pointer_record:               0
+      254 *** MESSAGE CONTENTS test-queue-file14b.tmp ***
+      256 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      316 regular_text:        id DA4892510C1; Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      372 regular_text: To: wietse@ahost.example.com
+      402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
+      462 regular_text: Date: Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      555 pointer_record:             642
+      642 regular_text: X-SPAM-FLAG: YES
+      660 pointer_record:             572
+      572 regular_text: 
+      574 regular_text: Fri Jun  5 14:05:19 EDT 2009
+      604 pointer_record:               0
+      621 *** HEADER EXTRACTED test-queue-file14b.tmp ***
+      623 pointer_record:             677
+      677 content_filter: transport:nexthop:port
+      701 pointer_record:             640
+      640 *** MESSAGE FILE END test-queue-file14b.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref14c1 b/postfix/src/cleanup/cleanup_milter.ref14c1
new file mode 100644 (file)
index 0000000..26b8ffd
--- /dev/null
@@ -0,0 +1 @@
+./cleanup_milter: NOQUEUE: milter-header-redirect: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: foo@examle.com
diff --git a/postfix/src/cleanup/cleanup_milter.ref14c2 b/postfix/src/cleanup/cleanup_milter.ref14c2
new file mode 100644 (file)
index 0000000..8d2be31
--- /dev/null
@@ -0,0 +1,29 @@
+*** ENVELOPE RECORDS test-queue-file14c.tmp ***
+        0 message_size:             365             256               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:05:19 2009
+      100 create_time: Fri Jun  5 14:05:19 2009
+      124 named_attribute: rewrite_context=local
+      147 sender_fullname: Wietse Venema
+      162 sender: wietse@ahost.example.com
+      188 pointer_record:             0
+      203 original_recipient: wietse
+      211 recipient: wietse@ahost.example.com
+      237 pointer_record:               0
+      254 *** MESSAGE CONTENTS test-queue-file14c.tmp ***
+      256 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      316 regular_text:        id DA4892510C1; Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      372 regular_text: To: wietse@ahost.example.com
+      402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
+      462 regular_text: Date: Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      555 pointer_record:             642
+      642 regular_text: X-SPAM-FLAG: YES
+      660 pointer_record:             572
+      572 regular_text: 
+      574 regular_text: Fri Jun  5 14:05:19 EDT 2009
+      604 pointer_record:               0
+      621 *** HEADER EXTRACTED test-queue-file14c.tmp ***
+      623 pointer_record:             677
+      677 redirect_to: foo@examle.com
+      693 pointer_record:             640
+      640 *** MESSAGE FILE END test-queue-file14c.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref14d1 b/postfix/src/cleanup/cleanup_milter.ref14d1
new file mode 100644 (file)
index 0000000..2cea8d2
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-discard: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 
+./cleanup_milter: flags = discard_message
diff --git a/postfix/src/cleanup/cleanup_milter.ref14d2 b/postfix/src/cleanup/cleanup_milter.ref14d2
new file mode 100644 (file)
index 0000000..b544187
--- /dev/null
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file14d.tmp ***
+        0 message_size:             365             256               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:05:19 2009
+      100 create_time: Fri Jun  5 14:05:19 2009
+      124 named_attribute: rewrite_context=local
+      147 sender_fullname: Wietse Venema
+      162 sender: wietse@ahost.example.com
+      188 pointer_record:             0
+      203 original_recipient: wietse
+      211 recipient: wietse@ahost.example.com
+      237 pointer_record:               0
+      254 *** MESSAGE CONTENTS test-queue-file14d.tmp ***
+      256 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      316 regular_text:        id DA4892510C1; Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      372 regular_text: To: wietse@ahost.example.com
+      402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
+      462 regular_text: Date: Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      555 pointer_record:             642
+      642 regular_text: X-SPAM-FLAG: YES
+      660 pointer_record:             572
+      572 regular_text: 
+      574 regular_text: Fri Jun  5 14:05:19 EDT 2009
+      604 pointer_record:               0
+      621 *** HEADER EXTRACTED test-queue-file14d.tmp ***
+      623 pointer_record:               0
+      640 *** MESSAGE FILE END test-queue-file14d.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref14e1 b/postfix/src/cleanup/cleanup_milter.ref14e1
new file mode 100644 (file)
index 0000000..d08c06f
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-hold: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 
+./cleanup_milter: flags = enable_header_body_filter hold_message enable_milters
diff --git a/postfix/src/cleanup/cleanup_milter.ref14e2 b/postfix/src/cleanup/cleanup_milter.ref14e2
new file mode 100644 (file)
index 0000000..e6e5cc0
--- /dev/null
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file14e.tmp ***
+        0 message_size:             365             256               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:05:19 2009
+      100 create_time: Fri Jun  5 14:05:19 2009
+      124 named_attribute: rewrite_context=local
+      147 sender_fullname: Wietse Venema
+      162 sender: wietse@ahost.example.com
+      188 pointer_record:             0
+      203 original_recipient: wietse
+      211 recipient: wietse@ahost.example.com
+      237 pointer_record:               0
+      254 *** MESSAGE CONTENTS test-queue-file14e.tmp ***
+      256 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      316 regular_text:        id DA4892510C1; Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      372 regular_text: To: wietse@ahost.example.com
+      402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
+      462 regular_text: Date: Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      555 pointer_record:             642
+      642 regular_text: X-SPAM-FLAG: YES
+      660 pointer_record:             572
+      572 regular_text: 
+      574 regular_text: Fri Jun  5 14:05:19 EDT 2009
+      604 pointer_record:               0
+      621 *** HEADER EXTRACTED test-queue-file14e.tmp ***
+      623 pointer_record:               0
+      640 *** MESSAGE FILE END test-queue-file14e.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref14f1 b/postfix/src/cleanup/cleanup_milter.ref14f1
new file mode 100644 (file)
index 0000000..9006f9a
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-reject: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 5.7.1 message content rejected
+./cleanup_milter: errs = message content rejected
diff --git a/postfix/src/cleanup/cleanup_milter.ref14f2 b/postfix/src/cleanup/cleanup_milter.ref14f2
new file mode 100644 (file)
index 0000000..3fdbf23
--- /dev/null
@@ -0,0 +1,28 @@
+*** ENVELOPE RECORDS test-queue-file14f.tmp ***
+        0 message_size:             365             256               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:05:19 2009
+      100 create_time: Fri Jun  5 14:05:19 2009
+      124 named_attribute: rewrite_context=local
+      147 sender_fullname: Wietse Venema
+      162 sender: wietse@ahost.example.com
+      188 pointer_record:             0
+      203 original_recipient: wietse
+      211 recipient: wietse@ahost.example.com
+      237 pointer_record:               0
+      254 *** MESSAGE CONTENTS test-queue-file14f.tmp ***
+      256 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      316 regular_text:        id DA4892510C1; Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      372 pointer_record:             642
+      642 regular_text: X-SPAM-FLAG: YES
+      660 regular_text: To: wietse@ahost.example.com
+      690 pointer_record:             402
+      402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
+      462 regular_text: Date: Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      555 pointer_record:               0
+      572 regular_text: 
+      574 regular_text: Fri Jun  5 14:05:19 EDT 2009
+      604 pointer_record:               0
+      621 *** HEADER EXTRACTED test-queue-file14f.tmp ***
+      623 pointer_record:               0
+      640 *** MESSAGE FILE END test-queue-file14f.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref14g1 b/postfix/src/cleanup/cleanup_milter.ref14g1
new file mode 100644 (file)
index 0000000..9006f9a
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-reject: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 5.7.1 message content rejected
+./cleanup_milter: errs = message content rejected
diff --git a/postfix/src/cleanup/cleanup_milter.ref14g2 b/postfix/src/cleanup/cleanup_milter.ref14g2
new file mode 100644 (file)
index 0000000..1ee50e4
--- /dev/null
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file14g.tmp ***
+        0 message_size:             365             256               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:05:19 2009
+      100 create_time: Fri Jun  5 14:05:19 2009
+      124 named_attribute: rewrite_context=local
+      147 sender_fullname: Wietse Venema
+      162 sender: wietse@ahost.example.com
+      188 pointer_record:             0
+      203 original_recipient: wietse
+      211 recipient: wietse@ahost.example.com
+      237 pointer_record:               0
+      254 *** MESSAGE CONTENTS test-queue-file14g.tmp ***
+      256 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      316 regular_text:        id DA4892510C1; Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      372 regular_text: To: wietse@ahost.example.com
+      402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
+      462 regular_text: Date: Fri,  5 Jun 2009 14:05:19 -0400 (EDT)
+      507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      555 pointer_record:             642
+      642 regular_text: X-SPAM-FLAG: YES
+      660 pointer_record:             572
+      572 regular_text: 
+      574 regular_text: Fri Jun  5 14:05:19 EDT 2009
+      604 pointer_record:               0
+      621 *** HEADER EXTRACTED test-queue-file14g.tmp ***
+      623 pointer_record:               0
+      640 *** MESSAGE FILE END test-queue-file14g.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref15a1 b/postfix/src/cleanup/cleanup_milter.ref15a1
new file mode 100644 (file)
index 0000000..9006f9a
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-reject: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 5.7.1 message content rejected
+./cleanup_milter: errs = message content rejected
diff --git a/postfix/src/cleanup/cleanup_milter.ref15a2 b/postfix/src/cleanup/cleanup_milter.ref15a2
new file mode 100644 (file)
index 0000000..56c5d3e
--- /dev/null
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file15a.tmp ***
+        0 message_size:             365             221               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:06:34 2009
+       99 create_time: Fri Jun  5 14:06:34 2009
+      123 named_attribute: rewrite_context=local
+      146 sender_fullname: Wietse Venema
+      161 sender: wietse@ahost.example.com
+      187 pointer_record:             0
+      202 pointer_record:               0
+      219 *** MESSAGE CONTENTS test-queue-file15a.tmp ***
+      221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      281 regular_text:        id 06F8B2510C2; Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      337 regular_text: To: wietse@ahost.example.com
+      367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
+      427 regular_text: Date: Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      520 pointer_record:             641
+      641 regular_text: X-SPAM-FLAG: YES
+      659 pointer_record:             537
+      537 regular_text: 
+      539 regular_text: Fri Jun  5 14:06:34 EDT 2009
+      569 pointer_record:               0
+      586 *** HEADER EXTRACTED test-queue-file15a.tmp ***
+      588 pointer_record:               0
+      605 original_recipient: wietse
+      613 recipient: wietse@ahost.example.com
+      639 *** MESSAGE FILE END test-queue-file15a.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref15b1 b/postfix/src/cleanup/cleanup_milter.ref15b1
new file mode 100644 (file)
index 0000000..5608b81
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-filter: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: transport:nexthop:port
+./cleanup_milter: flags = enable_header_body_filter enable_milters
diff --git a/postfix/src/cleanup/cleanup_milter.ref15b2 b/postfix/src/cleanup/cleanup_milter.ref15b2
new file mode 100644 (file)
index 0000000..c38c0a3
--- /dev/null
@@ -0,0 +1,29 @@
+*** ENVELOPE RECORDS test-queue-file15b.tmp ***
+        0 message_size:             365             221               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:06:34 2009
+       99 create_time: Fri Jun  5 14:06:34 2009
+      123 named_attribute: rewrite_context=local
+      146 sender_fullname: Wietse Venema
+      161 sender: wietse@ahost.example.com
+      187 pointer_record:             0
+      202 pointer_record:               0
+      219 *** MESSAGE CONTENTS test-queue-file15b.tmp ***
+      221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      281 regular_text:        id 06F8B2510C2; Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      337 regular_text: To: wietse@ahost.example.com
+      367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
+      427 regular_text: Date: Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      520 pointer_record:             641
+      641 regular_text: X-SPAM-FLAG: YES
+      659 pointer_record:             537
+      537 regular_text: 
+      539 regular_text: Fri Jun  5 14:06:34 EDT 2009
+      569 pointer_record:               0
+      586 *** HEADER EXTRACTED test-queue-file15b.tmp ***
+      588 pointer_record:             676
+      676 content_filter: transport:nexthop:port
+      700 pointer_record:             605
+      605 original_recipient: wietse
+      613 recipient: wietse@ahost.example.com
+      639 *** MESSAGE FILE END test-queue-file15b.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref15c1 b/postfix/src/cleanup/cleanup_milter.ref15c1
new file mode 100644 (file)
index 0000000..26b8ffd
--- /dev/null
@@ -0,0 +1 @@
+./cleanup_milter: NOQUEUE: milter-header-redirect: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: foo@examle.com
diff --git a/postfix/src/cleanup/cleanup_milter.ref15c2 b/postfix/src/cleanup/cleanup_milter.ref15c2
new file mode 100644 (file)
index 0000000..7725f48
--- /dev/null
@@ -0,0 +1,29 @@
+*** ENVELOPE RECORDS test-queue-file15c.tmp ***
+        0 message_size:             365             221               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:06:34 2009
+       99 create_time: Fri Jun  5 14:06:34 2009
+      123 named_attribute: rewrite_context=local
+      146 sender_fullname: Wietse Venema
+      161 sender: wietse@ahost.example.com
+      187 pointer_record:             0
+      202 pointer_record:               0
+      219 *** MESSAGE CONTENTS test-queue-file15c.tmp ***
+      221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      281 regular_text:        id 06F8B2510C2; Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      337 regular_text: To: wietse@ahost.example.com
+      367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
+      427 regular_text: Date: Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      520 pointer_record:             641
+      641 regular_text: X-SPAM-FLAG: YES
+      659 pointer_record:             537
+      537 regular_text: 
+      539 regular_text: Fri Jun  5 14:06:34 EDT 2009
+      569 pointer_record:               0
+      586 *** HEADER EXTRACTED test-queue-file15c.tmp ***
+      588 pointer_record:             676
+      676 redirect_to: foo@examle.com
+      692 pointer_record:             605
+      605 original_recipient: wietse
+      613 recipient: wietse@ahost.example.com
+      639 *** MESSAGE FILE END test-queue-file15c.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref15d1 b/postfix/src/cleanup/cleanup_milter.ref15d1
new file mode 100644 (file)
index 0000000..2cea8d2
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-discard: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 
+./cleanup_milter: flags = discard_message
diff --git a/postfix/src/cleanup/cleanup_milter.ref15d2 b/postfix/src/cleanup/cleanup_milter.ref15d2
new file mode 100644 (file)
index 0000000..773fd40
--- /dev/null
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file15d.tmp ***
+        0 message_size:             365             221               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:06:34 2009
+       99 create_time: Fri Jun  5 14:06:34 2009
+      123 named_attribute: rewrite_context=local
+      146 sender_fullname: Wietse Venema
+      161 sender: wietse@ahost.example.com
+      187 pointer_record:             0
+      202 pointer_record:               0
+      219 *** MESSAGE CONTENTS test-queue-file15d.tmp ***
+      221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      281 regular_text:        id 06F8B2510C2; Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      337 regular_text: To: wietse@ahost.example.com
+      367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
+      427 regular_text: Date: Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      520 pointer_record:             641
+      641 regular_text: X-SPAM-FLAG: YES
+      659 pointer_record:             537
+      537 regular_text: 
+      539 regular_text: Fri Jun  5 14:06:34 EDT 2009
+      569 pointer_record:               0
+      586 *** HEADER EXTRACTED test-queue-file15d.tmp ***
+      588 pointer_record:               0
+      605 original_recipient: wietse
+      613 recipient: wietse@ahost.example.com
+      639 *** MESSAGE FILE END test-queue-file15d.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref15e1 b/postfix/src/cleanup/cleanup_milter.ref15e1
new file mode 100644 (file)
index 0000000..d08c06f
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-hold: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 
+./cleanup_milter: flags = enable_header_body_filter hold_message enable_milters
diff --git a/postfix/src/cleanup/cleanup_milter.ref15e2 b/postfix/src/cleanup/cleanup_milter.ref15e2
new file mode 100644 (file)
index 0000000..13f9cb4
--- /dev/null
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file15e.tmp ***
+        0 message_size:             365             221               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:06:34 2009
+       99 create_time: Fri Jun  5 14:06:34 2009
+      123 named_attribute: rewrite_context=local
+      146 sender_fullname: Wietse Venema
+      161 sender: wietse@ahost.example.com
+      187 pointer_record:             0
+      202 pointer_record:               0
+      219 *** MESSAGE CONTENTS test-queue-file15e.tmp ***
+      221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      281 regular_text:        id 06F8B2510C2; Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      337 regular_text: To: wietse@ahost.example.com
+      367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
+      427 regular_text: Date: Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      520 pointer_record:             641
+      641 regular_text: X-SPAM-FLAG: YES
+      659 pointer_record:             537
+      537 regular_text: 
+      539 regular_text: Fri Jun  5 14:06:34 EDT 2009
+      569 pointer_record:               0
+      586 *** HEADER EXTRACTED test-queue-file15e.tmp ***
+      588 pointer_record:               0
+      605 original_recipient: wietse
+      613 recipient: wietse@ahost.example.com
+      639 *** MESSAGE FILE END test-queue-file15e.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref15f1 b/postfix/src/cleanup/cleanup_milter.ref15f1
new file mode 100644 (file)
index 0000000..b9d6021
--- /dev/null
@@ -0,0 +1 @@
+./cleanup_milter: NOQUEUE: milter-header-redirect: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: x@y.z
diff --git a/postfix/src/cleanup/cleanup_milter.ref15f2 b/postfix/src/cleanup/cleanup_milter.ref15f2
new file mode 100644 (file)
index 0000000..45dca53
--- /dev/null
@@ -0,0 +1,30 @@
+*** ENVELOPE RECORDS test-queue-file15f.tmp ***
+        0 message_size:             365             221               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:06:34 2009
+       99 create_time: Fri Jun  5 14:06:34 2009
+      123 named_attribute: rewrite_context=local
+      146 sender_fullname: Wietse Venema
+      161 sender: wietse@ahost.example.com
+      187 pointer_record:             0
+      202 pointer_record:               0
+      219 *** MESSAGE CONTENTS test-queue-file15f.tmp ***
+      221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      281 regular_text:        id 06F8B2510C2; Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      337 pointer_record:             641
+      641 regular_text: X-SPAM-FLAG: YES
+      659 regular_text: To: wietse@ahost.example.com
+      689 pointer_record:             367
+      367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
+      427 regular_text: Date: Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      520 pointer_record:               0
+      537 regular_text: 
+      539 regular_text: Fri Jun  5 14:06:34 EDT 2009
+      569 pointer_record:               0
+      586 *** HEADER EXTRACTED test-queue-file15f.tmp ***
+      588 pointer_record:             706
+      706 redirect_to: x@y.z
+      713 pointer_record:             605
+      605 original_recipient: wietse
+      613 recipient: wietse@ahost.example.com
+      639 *** MESSAGE FILE END test-queue-file15f.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref15g1 b/postfix/src/cleanup/cleanup_milter.ref15g1
new file mode 100644 (file)
index 0000000..295690a
--- /dev/null
@@ -0,0 +1,2 @@
+./cleanup_milter: NOQUEUE: milter-header-filter: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: x:y:z
+./cleanup_milter: flags = enable_header_body_filter enable_milters
diff --git a/postfix/src/cleanup/cleanup_milter.ref15g2 b/postfix/src/cleanup/cleanup_milter.ref15g2
new file mode 100644 (file)
index 0000000..fc67e56
--- /dev/null
@@ -0,0 +1,30 @@
+*** ENVELOPE RECORDS test-queue-file15g.tmp ***
+        0 message_size:             365             221               1               0             365
+       81 message_arrival_time: Fri Jun  5 14:06:34 2009
+       99 create_time: Fri Jun  5 14:06:34 2009
+      123 named_attribute: rewrite_context=local
+      146 sender_fullname: Wietse Venema
+      161 sender: wietse@ahost.example.com
+      187 pointer_record:             0
+      202 pointer_record:               0
+      219 *** MESSAGE CONTENTS test-queue-file15g.tmp ***
+      221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
+      281 regular_text:        id 06F8B2510C2; Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      337 pointer_record:             641
+      641 regular_text: X-SPAM-FLAG: YES
+      659 regular_text: To: wietse@ahost.example.com
+      689 pointer_record:             367
+      367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
+      427 regular_text: Date: Fri,  5 Jun 2009 14:06:34 -0400 (EDT)
+      472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
+      520 pointer_record:               0
+      537 regular_text: 
+      539 regular_text: Fri Jun  5 14:06:34 EDT 2009
+      569 pointer_record:               0
+      586 *** HEADER EXTRACTED test-queue-file15g.tmp ***
+      588 pointer_record:             706
+      706 content_filter: x:y:z
+      713 pointer_record:             605
+      605 original_recipient: wietse
+      613 recipient: wietse@ahost.example.com
+      639 *** MESSAGE FILE END test-queue-file15g.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.reg14a b/postfix/src/cleanup/cleanup_milter.reg14a
new file mode 100644 (file)
index 0000000..1a9ccf1
--- /dev/null
@@ -0,0 +1 @@
+/./ reject
diff --git a/postfix/src/cleanup/cleanup_milter.reg14b b/postfix/src/cleanup/cleanup_milter.reg14b
new file mode 100644 (file)
index 0000000..332ba69
--- /dev/null
@@ -0,0 +1 @@
+/./ FILTER transport:nexthop:port
diff --git a/postfix/src/cleanup/cleanup_milter.reg14c b/postfix/src/cleanup/cleanup_milter.reg14c
new file mode 100644 (file)
index 0000000..0421976
--- /dev/null
@@ -0,0 +1 @@
+/./ REDIRECT foo@examle.com
diff --git a/postfix/src/cleanup/cleanup_milter.reg14d b/postfix/src/cleanup/cleanup_milter.reg14d
new file mode 100644 (file)
index 0000000..78647a3
--- /dev/null
@@ -0,0 +1 @@
+/./ DISCARD
diff --git a/postfix/src/cleanup/cleanup_milter.reg14e b/postfix/src/cleanup/cleanup_milter.reg14e
new file mode 100644 (file)
index 0000000..c88ee2c
--- /dev/null
@@ -0,0 +1 @@
+/./ HOLD
diff --git a/postfix/src/cleanup/cleanup_milter.reg14f b/postfix/src/cleanup/cleanup_milter.reg14f
new file mode 100644 (file)
index 0000000..1a9ccf1
--- /dev/null
@@ -0,0 +1 @@
+/./ reject
diff --git a/postfix/src/cleanup/cleanup_milter.reg14g b/postfix/src/cleanup/cleanup_milter.reg14g
new file mode 100644 (file)
index 0000000..1a9ccf1
--- /dev/null
@@ -0,0 +1 @@
+/./ reject
diff --git a/postfix/src/cleanup/cleanup_milter.reg15a b/postfix/src/cleanup/cleanup_milter.reg15a
new file mode 100644 (file)
index 0000000..1a9ccf1
--- /dev/null
@@ -0,0 +1 @@
+/./ reject
diff --git a/postfix/src/cleanup/cleanup_milter.reg15b b/postfix/src/cleanup/cleanup_milter.reg15b
new file mode 100644 (file)
index 0000000..332ba69
--- /dev/null
@@ -0,0 +1 @@
+/./ FILTER transport:nexthop:port
diff --git a/postfix/src/cleanup/cleanup_milter.reg15c b/postfix/src/cleanup/cleanup_milter.reg15c
new file mode 100644 (file)
index 0000000..0421976
--- /dev/null
@@ -0,0 +1 @@
+/./ REDIRECT foo@examle.com
diff --git a/postfix/src/cleanup/cleanup_milter.reg15d b/postfix/src/cleanup/cleanup_milter.reg15d
new file mode 100644 (file)
index 0000000..78647a3
--- /dev/null
@@ -0,0 +1 @@
+/./ DISCARD
diff --git a/postfix/src/cleanup/cleanup_milter.reg15e b/postfix/src/cleanup/cleanup_milter.reg15e
new file mode 100644 (file)
index 0000000..c88ee2c
--- /dev/null
@@ -0,0 +1 @@
+/./ HOLD
diff --git a/postfix/src/cleanup/cleanup_milter.reg15f b/postfix/src/cleanup/cleanup_milter.reg15f
new file mode 100644 (file)
index 0000000..a629bf2
--- /dev/null
@@ -0,0 +1 @@
+/./ redirect x@y.z
diff --git a/postfix/src/cleanup/cleanup_milter.reg15g b/postfix/src/cleanup/cleanup_milter.reg15g
new file mode 100644 (file)
index 0000000..0a25be3
--- /dev/null
@@ -0,0 +1 @@
+/./ filter x:y:z
index 7ce732cd2724a82d340f358f69904f860d9af58c..8d9085262a68fd490cc794405b121da24b4af63e 100644 (file)
@@ -97,6 +97,10 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
     state->append_rcpt_pt_target = -1;
     state->append_hdr_pt_offset = -1;
     state->append_hdr_pt_target = -1;
+    state->append_meta_pt_offset = -1;
+    state->append_meta_pt_target = -1;
+    state->milter_hbc_checks = 0;
+    state->milter_hbc_reply = 0;
     state->rcpt_count = 0;
     state->reason = 0;
     state->smtp_reply = 0;
diff --git a/postfix/src/cleanup/test-queue-file14 b/postfix/src/cleanup/test-queue-file14
new file mode 100644 (file)
index 0000000..e9b388a
Binary files /dev/null and b/postfix/src/cleanup/test-queue-file14 differ
diff --git a/postfix/src/cleanup/test-queue-file15 b/postfix/src/cleanup/test-queue-file15
new file mode 100644 (file)
index 0000000..088bdfd
Binary files /dev/null and b/postfix/src/cleanup/test-queue-file15 differ
index 04c3f5747d623e79f077aefdc5a57a8e8da2335d..d67a2a6bcbffe00a9080df6c168869d65d4321a1 100644 (file)
@@ -2982,6 +2982,10 @@ extern char *var_milt_daemon_name;
 #define DEF_MILT_V                     "$" VAR_MAIL_NAME " $" VAR_MAIL_VERSION
 extern char *var_milt_v;
 
+#define VAR_MILT_HEAD_CHECKS           "milter_header_checks"
+#define DEF_MILT_HEAD_CHECKS           ""
+extern char *var_milt_head_checks;
+
  /*
   * What internal mail do we inspect/stamp/etc.? This is not yet safe enough
   * to enable world-wide.
index f17139bfc008ed502629da84518ebdee6aaa5235..8545f9f484b0927c1238771f96f12b3fc6f643e3 100644 (file)
@@ -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      "20090603"
+#define MAIL_RELEASE_DATE      "20090606"
 #define MAIL_VERSION_NUMBER    "2.7"
 
 #ifdef SNAPSHOT
index a91c9b95afc00a83c7ce45ba29335930aaf70850..bcc4dcbd0169c5b11030f645e15f6e87b4a497ab 100644 (file)
@@ -10,6 +10,7 @@ MAKES = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
        str_vars.h time_table.h time_vars.h raw_table.h raw_vars.h \
        nint_table.h nint_vars.h
 AUTOS  = auto_table.h auto_vars.h
+DUMMIES        = makes_dummy autos_dummy
 PROG   = postconf
 SAMPLES        = ../../conf/main.cf.default
 INC_DIR        = ../../include
@@ -43,11 +44,17 @@ update: ../../bin/$(PROG) $(SAMPLES)
 ../../bin/$(PROG): $(PROG)
        cp $(PROG) ../../bin
 
-$(MAKES): $(INC_DIR)/mail_params.h ../global/mail_params.c
+$(MAKES): makes_dummy
+
+makes_dummy: $(INC_DIR)/mail_params.h ../global/mail_params.c
        $(AWK) -f extract.awk ../*/*.c | $(SHELL)
+       touch makes_dummy
+
+$(AUTOS): autos_dummy
 
-$(AUTOS): auto.awk
+autos_dummy: auto.awk
        $(AWK) -f auto.awk
+       touch autos_dummy
 
 printfck: $(OBJS) $(PROG)
        rm -rf printfck
@@ -61,7 +68,7 @@ lint:
        lint $(DEFS) $(SRCS) $(LINTFIX)
 
 clean:
-       rm -f *.o *core $(PROG) $(TESTPROG) junk $(MAKES) $(AUTOS)
+       rm -f *.o *core $(PROG) $(TESTPROG) junk $(MAKES) $(AUTOS) $(DUMMIES)
        rm -rf printfck
 
 tidy:  clean
index d9266244a6f8649531b618ab76d76823ef32ee9f..bb6bd128213ba44cb89c23eede50bbad90cc249a 100644 (file)
@@ -105,22 +105,28 @@ int     unix_send_fd(int fd, int sendfd)
     msg.msg_iovlen = 1;
 
     /*
-     * The CMSG_LEN workaround was originally developed for OpenBSD 3.6 on
-     * 64-bit SPARC (later also confirmed on AMD64). It was hard-coded with
-     * Postfix 2.3 for all platforms because of increasing pressure to work
-     * on other things.
+     * The CMSG_LEN send/receive workaround was originally developed for
+     * OpenBSD 3.6 on SPARC64. After the workaround was verified to not break
+     * Solaris 8 on SPARC64, it was hard-coded with Postfix 2.3 for all
+     * platforms because of increasing pressure to work on other things. The
+     * workaround does nothing for 32-bit systems.
      * 
      * The investigation was reopened with Postfix 2.7 because the workaround
-     * broke on NetBSD 5.0. This time it was found that OpenBSD on AMD64
-     * needs the workaround for sending only. We assume that OpenBSD on AMD64
-     * and SPARC64 are similar, and turn on the workaround on-the-fly. The
-     * OpenBSD problem was fixed for AMD64 and SPARC64 with OpenBSD 4.4 or
-     * 4.5.
+     * broke with NetBSD 5.0 on 64-bit architectures. This time it was found
+     * that OpenBSD <= 4.3 on AMD64 and SPARC64 needed the workaround for
+     * sending only. The following platforms worked with and without the
+     * workaround: OpenBSD 4.5 on AMD64 and SPARC64, FreeBSD 7.2 on AMD64,
+     * Solaris 8 on SPARC64, and Linux 2.6-11 on x86_64.
      * 
-     * The workaround was made run-time configurable to make the investigation
-     * possible on many different platforms. Though the code is over-kill for
-     * this particular problem, it is left in place so that it can serve as
-     * an example of how to add run-time configurable workarounds to Postfix.
+     * As this appears to have been an OpenBSD-specific problem, we revert to
+     * the Postfix 2.2 behavior. Instead of hard-coding the workaround for
+     * all platforms, we now detect sendmsg() errors at run time and turn on
+     * the workaround dynamically.
+     * 
+     * The workaround was made run-time configurable to investigate the problem
+     * on multiple platforms. Though set_unix_pass_fd_fix() is over-kill for
+     * this specific problem, it is left in place so that it can serve as an
+     * example of how to add run-time configurable workarounds to Postfix.
      */
     if (sendmsg(fd, &msg, 0) >= 0)
        return (0);