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