On Fri, Sep 05, 2025 at 03:22:59PM -0400, postfix--- via Postfix-users wrote:

> Postfix is setup using virtual domains and addresses, using SQL
> queries to get user addresses and aliases.  I am using a milter that
> runs during the RCPT and DATA stages.  An email is received to an
> al...@example.com address that maps to a real u...@example.com
> address.
> 
> During the RCPT stage the milter is given al...@example.com for the
> rcpt_addr.  But during the DATA stage the milter is given
> u...@example.com instead of al...@example.com.

For mail that (presumably) arrives via SMTP I'm quite surprised that
recipient information is given to the milter at both stages.  The
"DATA" processing happens in the cleanup(8) services, where the
intention seems to be:

    $ mantools/srctoman src/cleanup/cleanup_milter.c | nroff -mandoc | less -R
       ...
       cleanup_milter_emul_rcpt()  emulates  an  rcpt event for mail that does
       not arrive via the smtpd(8) server. This reports a server configuration
       error condition when the milter rejects an emulated rcpt event.
       ...

So one might expect that cleanup_milter_emul_rcpt() does not happen for
mail that arrives via SMTP, and yet, in cleanup_envelope_process():

    
https://github.com/vdukhovni/postfix/blob/e0168dc93254cf4e588919ea5e4b101cd7d7f541/postfix/src/cleanup/cleanup_envelope.c#L119-L506

we see a call to cleanup_milter_emul_rcpt() right after
cleanup_addr_recipient(), which sets the `state->recip` field reported
to the milter.

    
https://github.com/vdukhovni/postfix/blob/e0168dc93254cf4e588919ea5e4b101cd7d7f541/postfix/src/cleanup/cleanup_envelope.c#L278-L284

        cleanup_addr_recipient(state, buf);
        if (cleanup_milters != 0
            && state->milters == 0
            && CLEANUP_MILTER_OK(state))
            cleanup_milter_emul_rcpt(state, cleanup_milters, state->recip);
        myfree(state->orig_rcpt);
        state->orig_rcpt = 0;

The call does not seem to be conditional on whether the message is via
SMTP or local submission.  The value of `state->recip` set by
cleanup_addr_recipient() is recorded prior to virtual(8) alias
rewriting, but after basic normalisation by trivial-rewrite(8) and then
recipient_canonical rewriting, canonical rewriting and masquerading:

    
https://github.com/vdukhovni/postfix/blob/master/postfix/src/cleanup/cleanup_addr.c#L193-L236
    ...
    cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL,
                             clean_addr, *buf ? buf : var_empty_addr);
    if (state->flags & CLEANUP_FLAG_MAP_OK) {
        if (cleanup_rcpt_canon_maps
            && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
            cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
                                cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
        if (cleanup_comm_canon_maps
            && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
            cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
                                cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
        if (cleanup_masq_domains
            && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
            cleanup_masquerade_internal(state, clean_addr, 
cleanup_masq_domains);
    }
    ...


> My milter logic is processing for al...@example.com during RCPT but
> then during DATA the email address has changed to u...@example.com
> messing up the logic.  I have enable_original_recipient=yes, but I
> obviously misunderstood that setting as that isn't sending the
> original RCPT address to the milter.

So I'm inclined to speculate that the alias in question is via a
(recipient?) canonical mapping, rather than virtual(5) aliasing?

Or, perhaps more likely, that alternatively, the message is processed by
local(8), with local(8) aliases(5) doing the rewrite, and then again
goes through a milter because the target of the alias is not a local
recipient (domain is not in $mydestination) and the message is delivered
indirectly by creating a new queue file to handle the resulting
recipipient.

So the message goes through two milters, incoming (pre-queue) via
smtpd(8), and again outgoing (post-queue) when forwarded by local(8).


On Fri, Sep 05, 2025 at 05:00:35PM -0400, Wietse Venema via Postfix-users wrote:

> > Is there anyway for the (alias) envelope RCPT address to be sent
> > to the milter during DATA? Or any creative work arounds so the
> > milter logic is working with the alias during DATA?
> 
> This can be imlemented with two Postfix instances
> 
> - The first instance rejects non-existent recipients,
>   does the virtual alias expansion, and is configured to send all
>   mail into the second instance.
> 
> - The second instance uses the Milter to reject recipients.
>   The first instance then sends bounce messages to the sender.

I don't think this applies to the OP's question.

-- 
    Viktor.  🇺🇦 Слава Україні!
_______________________________________________
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org

Reply via email to