Re: [Exim] Exim version 4.14 - address_data from last router…

Top Page
Delete this message
Reply to this message
Author: Rick Ennis
Date:  
To: Philip Hazel
CC: Nico Erfurth, exim users
Subject: Re: [Exim] Exim version 4.14 - address_data from last router run
I think I found a solution to my problem of getting the real [routed]
user name into $address_data, and hence back to local_scan. But I'm not
too familiar with most of these internal variables. So maybe Philip can
tell me if this change would cause a memory leak or anything.

Taking it from the top, my problem was that I wanted to get the real
user name (i.e. the address after its been verified/routed and is no
longer potentially an alias) into local_scan. So I put

address_data = $local_part

in both my "redirect" and "accept" routers, and added

warn set acl_m1 = $address_data

to my rcpt acl right after the verify = recipient. Then I'd reference
$acl_m1 in local_scan.

It works great for messages sent directly to my user name. But for ones
sent to an alias, only the "redirect" router appears to be setting
address_data. The "accept" router that runs right after that isn't
updating address_data.

I think the problem is that there's an address_data per address. So
when verify_address() is called on an alias it knows to process the
newly generated child address like it says in section 37.12 of the spec...

> When an incoming address is redirected to just one child address,
> verification continues with the child address, and if that fails to
> verify, the original verification also fails.


But I don't think it's updating the original address' address_data with
the child's address_data. So in effect only the first router's
address_data is available back in the acl.

In verify.c:verify_address() there's...

     if (!full_info &&                /* Stop if short info wanted AND */
          (addr_new == NULL ||        /* No new address OR */
           addr_new->next != NULL ||  /* More than one new address OR */
           testflag(addr_new, af_pfr))) /* New address is pfr */
       {
       if (f != NULL) fprintf(f, "%s %s\n", address,
         address_test_mode? "is deliverable" : "verified");
       vaddr->p.address_data = addr->p.address_data;  /* <-- NEW LINE */
       return OK;
       }
     }
   }     /* Loop for generated addresses */


I added that assignment right before the return OK (line 982). I
believe it sets the top level verify-address' address_data to the
child's address_data. That way the data propogates up and becomes the
value set by the last router to run.

Does that seem right? Like I said, I'm not too sure about exactly what
all those variables are. But in test runs it appears to work perfectly
for me. Granted in a multiple recipient situation you'll still only get
one address.

-Rick



Rick Ennis wrote:
>>> 1) I tried setting address_data = $local_part in my router
>>> that's doing the verify. But I didn't have much luck with
>>> expand_string("$address_data") in local_scan.
>>
>> That's because $address_data is cleared at the end of the ACL
>> (because it's a per-recipient thing, and there may be multiple
>> recipients).
>>
>>
>>> 2) I tried the same thing as #1 above, but added warn set acl_m1
>>> = $address_data in an acl immediately after my verify =
>>> recipient. I then used expand_string("$acl_m1") in local_scan and
>>> still didn't get
>
> what
>
>>> I wanted.
>>
>> At first sight, I would have expected that to work.
>
>
> Well I've noticed that the second configuration there does work, part
> of the time. It works provided the message is addressed to a local
> part that is my actual user name. If, on the other hand, it's
> addressed to an alias, which would match one of my redirect routers,
> then the expand_string("$acl_m1") ends up being blank. Here are the
> two routers that I think would come into play...
>
> virtual_aliases: driver = redirect allow_defer allow_fail data =
> ${lookup{$local_part}lsearch{ETC_PATH/$domain/aliases}} domains =
> ETC_PATH/virtual_domains file_transport = address_file pipe_transport
> = address_pipe retry_use_local_part
>
> local_user: driver = accept check_local_user headers_remove =
> disposition-notification-to:return-receipt-to transport =
> local_delivery address_data = $local_part
>
> So when a message is sent (for example) to ennis@ (which is my actual
> user name), it just hits the local_user router and local_scan gets
> the data. But when something is sent to rge1@ it hits the
> virtual_aliases router. After that the new address that's generated
> (again my actual user name) still still has to go through the
> local_user router. So shouldn't that still work? The mail gets
> delivered correctly, but for some reason I get a blank value for
> acl_m1 in local_scan.
>
>
>
>>> Is there a standard solution to this one? There must be a way to
>>> get at
>
> the
>
>>> routed address from within local_scan b/c the verifying stage has
>>> to
>
> have
>
>>> already completed. Am I just being dense?
>>
>> Well, the list of recipients is available to local_scan()...
>
>
> True. It's just that (in my example) if the message is addressed to
> rge1@ then I won't be able to check anything in the user's home
> directory for use in my scanning decision b/c I won't know which user
> that really is.