On Thu, Oct 26, 2023 at 12:38:22PM -0500, sandmant--- via Postfix-users wrote:

> I am updating a system from postfix-2.10.1 to postfix-3.5.9 (and
> RHEL7->RHEL9), and it seems my forward_path is no longer getting
> processed correctly.

The Postfix local delivery agent is extremently stable well-tested code,
with hardly any changes over the last decade.  There's generally little
reason to expect incompatible behaviour, however...

>   root@rt2:/etc/postfix-auth> postconf -c /etc/postfix-auth 
> recipient_delimiter
> 
>   recipient_delimiter = +
> 
>   rt2 postfix-auth/local[145348]: dict_lookup: forward_path = 
> $home/.forward${recipient_delimiter}${extension}+auth,  
> $home/.forward${recipient_delimiter}${extension},  
> $home/.forward${recipient_delimiter}auth,  $home/.forward
> 
> But does not seem to use it:
> 
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: deliver_dotforward[3]: 
> local rt recip r...@rt2.rice.edu exten  deliver r...@rt2.rice.edu exp_from
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: deliver_dotforward[3]: set 
> user_attr: rt
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: mac_parse: 
> $home/.forward${recipient_delimiter}${extension}+auth
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: mac_parse: 
> $home/.forward${recipient_delimiter}${extension}
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: mac_parse: 
> $home/.forward${recipient_delimiter}auth
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: mac_parse: $home/.forward
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: set_eugid: euid 378 egid 378
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: set_eugid: euid 89 egid 89
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: deliver_dotforward: path 
> /home/rt/.forward expand_status 0 look_status 0
>   Oct 26 12:13:50 rt2 postfix-auth/local[145348]: been_here: forward 
> /home/rt/.forward: 0

The responsible code in src/local/dotward.c has not changed:

        while ((lhs = mystrtok(&next, CHARS_COMMA_SP)) != 0) {
            expand_status = local_expand(path, lhs, &state, &usr_attr,
                                         var_fwd_exp_filter);
            if ((expand_status & (MAC_PARSE_ERROR | MAC_PARSE_UNDEF)) == 0) {
                lookup_status =
                    lstat_as(STR(path), &st, usr_attr.uid, usr_attr.gid);
                if (msg_verbose)
  --->              msg_info("%s: path %s expand_status %d look_status %d", 
myname,
  --->                       STR(path), expand_status, lookup_status);
                if (lookup_status >= 0) {
                    if ((expand_status & LOCAL_EXP_EXTENSION_MATCHED) != 0
                        || (local_ext_prop_mask & EXT_PROP_FORWARD) == 0)
                        state.msg_attr.unmatched = 0;
                    break;
                }
            }
        }

Note that the log entry highlighted only happened for the last
forward_path element.  So it seems that the previous elements must
have returned either MAC_PARSE_ERROR or MAC_PARSE_UNDEF from
local_expand().

That Function did change in Postfix 2.11, to support multiple
recipient delimiters:

    Author: Wietse Venema <wie...@porcupine.org>
    Date:   Fri Apr 5 00:00:00 2013 -0500

        postfix-2.11-20130405

    diff --git a/postfix/src/local/local_expand.c 
b/postfix/src/local/local_expand.c
    index db5121ee8..612e68094 100644
    --- a/postfix/src/local/local_expand.c
    +++ b/postfix/src/local/local_expand.c
    @@ -113,6 +113,7 @@ typedef struct {
     static const char *local_expand_lookup(const char *name, int mode, char 
*ptr)
     {
         LOCAL_EXP *local = (LOCAL_EXP *) ptr;
    +    static char rcpt_delim[2];

     #define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)

    @@ -135,7 +136,10 @@ static const char *local_expand_lookup(const char 
*name, int mode, char *ptr)
                local->status |= LOCAL_EXP_EXTENSION_MATCHED;
            return (local->state->msg_attr.extension);
         } else if (STREQ(name, "recipient_delimiter")) {
    -       return (*var_rcpt_delim ? var_rcpt_delim : 0);
    +       rcpt_delim[0] =
    +           
local->state->msg_attr.local[strlen(local->state->msg_attr.user)];
    +       rcpt_delim[1] = 0;
    +       return (rcpt_delim[0] ? rcpt_delim : 0);
     #if 0
         } else if (STREQ(name, "client_hostname")) {
            return (local->state->msg_attr.request->client_name);

Which means that the recipient delimiter is infered from the character
immediately following the end of the user part of the address, and is
will be NULL rather than the main.cf value when the user address has no
extension.

So the cases that use ${recipient_delimiter} will only match addresss
that actually have an extension.  If you want to use it unconditionally,
you'll need to use a literal "+", instead.

  HISTORY:

    20130405

           Feature: the recipient_delimiter parameter can now specify
           a set of characters. A user name is now separated from its
           address extension by the first character that matches the
           recipient_delimiter set.  ...

  RELEASE_NOTES:

    Major changes with snapshot 20130405
    ====================================
    
    The recipient_delimiter parameter can now specify a set of characters.
    A user name is now separated from its address extension by the first
    character that matches the recipient_delimiter set.
    
    For example, specify "recipient_delimiter = +-" to support both the
    Postfix-style "+" and the qmail-style "-" extension delimiter.
    
    As before, this implementation recognizes one delimiter character
    per email address, and one address extension per email address.

The subtle change in forward_path processing is perhaps unxpected,
and may need to be documented.  Or we could fall back to the first
recipient delimiter configured with mail to "bare" user names.

-- 
    Viktor.
_______________________________________________
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org

Reply via email to