Wietse Venema:
> J?rg Backschues:
> > Am 09.03.2016 um 01:20 schrieb Wietse Venema:
> > 
> > > How many recipients are there before the bcc action?
> > 
> > I've verified the issue with one recipient only and multiple recipients.
> > 
> > > That would be a bug. I'd appreciate it if you could run the cleanup
> > > server with the -v action and log what Postfix and batv-milter are
> > > saying to each other. That would save me the time to duplicate your
> > > setup.
> > 
> > The batv-milter log shows no errors.
> > 
> > cleanup-v has been enabled:
> > 
> 
> Thanks. This should be sufficient to reproduce what happens.

This is a minimal patch to fix the issue. It does not include the
tests that I added to verify that the problem is fixed.

        Wietse

20160310

        Bugfix (introduced: Postfix 2.6): the Milter SMFIR_CHGFROM
        (replace sender) request lost the sender_bcc_maps address.
        Fixed by moving some record keeping to the sender output
        function.

diff -ur '--exclude=*.in*' '--exclude=*.ref*' 
/var/tmp/postfix-3.2-20160224/src/cleanup/cleanup_addr.c 
src/cleanup/cleanup_addr.c
--- /var/tmp/postfix-3.2-20160224/src/cleanup/cleanup_addr.c    2015-01-27 
14:33:29.000000000 -0500
+++ src/cleanup/cleanup_addr.c  2016-03-11 08:15:45.768039070 -0500
@@ -81,6 +82,7 @@
 /* Global library. */
 
 #include <rec_type.h>
+#include <record.h>
 #include <cleanup_user.h>
 #include <mail_params.h>
 #include <ext_prop.h>
@@ -101,10 +103,13 @@
 
 /* cleanup_addr_sender - process envelope sender record */
 
-void    cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
+off_t   cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
 {
+    const char myname[] = "cleanup_addr_sender";
     VSTRING *clean_addr = vstring_alloc(100);
+    off_t   after_sender_offs = 0;
     const char *bcc;
+    size_t  len;
 
     /*
      * Note: an unqualified envelope address is for all practical purposes
@@ -148,6 +153,15 @@
     if (state->sender)                         /* XXX Can't happen */
        myfree(state->sender);
     state->sender = mystrdup(STR(clean_addr)); /* Used by Milter client */
+    /* Fix 20160310: Moved from cleanup_envelope.c. */
+    if (state->milters || cleanup_milters) {
+       /* Make room to replace sender. */
+       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 ((after_sender_offs = vstream_ftell(state->dst)) < 0)
+           msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
+    }
     if ((state->flags & CLEANUP_FLAG_BCC_OK)
        && *STR(clean_addr)
        && cleanup_send_bcc_maps) {
@@ -162,6 +176,7 @@
        }
     }
     vstring_free(clean_addr);
+    return after_sender_offs;
 }
 
 /* cleanup_addr_recipient - process envelope recipient */
diff -ur '--exclude=*.in*' '--exclude=*.ref*' 
/var/tmp/postfix-3.2-20160224/src/cleanup/cleanup_envelope.c 
src/cleanup/cleanup_envelope.c
--- /var/tmp/postfix-3.2-20160224/src/cleanup/cleanup_envelope.c        
2015-12-27 16:30:56.000000000 -0500
+++ src/cleanup/cleanup_envelope.c      2016-03-11 07:53:40.323914349 -0500
@@ -380,6 +380,8 @@
        return;
     }
     if (type == REC_TYPE_FROM) {
+       off_t after_sender_offs;
+
        /* Allow only one instance. */
        if (state->sender != 0) {
            msg_warn("%s: message rejected: multiple envelope sender records",
@@ -392,14 +394,10 @@
            if ((state->sender_pt_offset = vstream_ftell(state->dst)) < 0)
                msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
        }
-       cleanup_addr_sender(state, buf);
+       after_sender_offs = cleanup_addr_sender(state, buf);
        if (state->milters || cleanup_milters) {
-           /* Make room to replace sender. */
-           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);
+           state->sender_pt_target = after_sender_offs;
        }
        if (cleanup_milters != 0
            && state->milters == 0
diff -ur '--exclude=*.in*' '--exclude=*.ref*' 
/var/tmp/postfix-3.2-20160224/src/cleanup/cleanup.h src/cleanup/cleanup.h
--- /var/tmp/postfix-3.2-20160224/src/cleanup/cleanup.h 2015-12-27 
16:30:56.000000000 -0500
+++ src/cleanup/cleanup.h       2016-03-10 19:14:21.325407225 -0500
@@ -290,7 +290,7 @@
  /*
   * cleanup_addr.c.
   */
-extern void cleanup_addr_sender(CLEANUP_STATE *, const char *);
+extern off_t cleanup_addr_sender(CLEANUP_STATE *, const char *);
 extern void cleanup_addr_recipient(CLEANUP_STATE *, const char *);
 extern void cleanup_addr_bcc_dsn(CLEANUP_STATE *, const char *, const char *, 
int);
 
diff -ur '--exclude=*.in*' '--exclude=*.ref*' 
/var/tmp/postfix-3.2-20160224/src/cleanup/cleanup_milter.c 
src/cleanup/cleanup_milter.c
--- /var/tmp/postfix-3.2-20160224/src/cleanup/cleanup_milter.c  2016-01-23 
19:44:54.000000000 -0500
+++ src/cleanup/cleanup_milter.c        2016-03-11 08:19:08.731301859 -0500
@@ -1330,6 +1330,7 @@
     const char *myname = "cleanup_chg_from";
     CLEANUP_STATE *state = (CLEANUP_STATE *) context;
     off_t   new_sender_offset;
+    off_t   after_sender_offs;
     int     addr_count;
     TOK822 *tree;
     TOK822 *tp;
@@ -1393,10 +1394,11 @@
        }
     }
     tok822_free_tree(tree);
-    cleanup_addr_sender(state, STR(int_sender_buf));
+    after_sender_offs = cleanup_addr_sender(state, STR(int_sender_buf));
     vstring_free(int_sender_buf);
     cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
                       (long) state->sender_pt_target);
+    state->sender_pt_target = after_sender_offs;
 
     /*
      * Overwrite the original sender record with the pointer to the new

Reply via email to