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