Re: [exim-dev] RFC: implementing 551-redirection (client sid…

Top Page
Delete this message
Reply to this message
Author: Philip Hazel
Date:  
To: Robert Millan
CC: exim-dev
Subject: Re: [exim-dev] RFC: implementing 551-redirection (client side)
On Mon, 24 Jul 2006, Robert Millan wrote:

> Ok. Let's try another approach. I've noticed that, if we ignore how the
> message got into our mail queue, the following situations are almost the same:
>
> - We're a forwarder, smtp'ing to the next hop after we parsed ~/.forward.
> - We're a sender, smtp'ing to the next hop after we got a 551.
>
> Can we handle #2 the same way #1 is?


No, because routing is done before transporting. To do #2 means going
back to the routing phase in the middle of the transport phase. *That*
is the main difficulty. Exim is designed to complete all the routing
before it does any transporting.

> Then the privilege separation issues you mentioned before would be sorted out
> the same way they're in forwarding, which I suppose is by generating a new
> envelope from the unprivileged process.


All redirection is handled during the routing phase, which runs as root
(except for processing user filters, which do run unprivileged). When
routing is over, deliveries are done in unprivileged subprocesses. See
chapter 3 of my book, or section 3.13 of the manual, or you could have
come to my course last week <grin>.

> > Final thought: How to check against loops?
>
> We could add an X-Redirect header, much like X-Forward.


No, that doesn't work. Address A1 routes to host H1; host H1 redirects to
address A2. We haven't sent anything, so we can't add a header (because it
could only be added to this particular copy of the message - other
recipients shouldn't see it). If A2 routes to H2, and H2 redirects back
to A1 we are in trouble. I suppose one would have to keep a trail of
redirections with the address[*] -- this would mean adding data to the
spool file in order to remember the information from delivery to
delivery. You see? It gets more and more complicated...

> Does this make sense?


In the abstract, it looks straightforward, doesn't it? The problem is
that Exim is not abstract; it is an existing body of code that does
things in such a way as to make this hard. Very hard to get completely
right, I suspect. Just as rewriting is not a good tool for routing,
neither is transporting. :-)

A totally different approach would be to arrange for the smtp transport
to save the redirection in a hints database, and convert the 551 into
451 (optionally, of course). Then write a router that (in the next
delivery) checks the hints database and does the appropriate
redirection (and optionally adds a header). This could be done using the
existing options for the redirect router. Loops would then be
automatically caught.

I must say that I still think this is a very minority thing.


-----------
[*] Exactly as happens for the list of "ancestors" during redirection;
the difference is that they don't have to be remembered for the next
delivery attempt.


-- 
Philip Hazel            University of Cambridge Computing Service
Get the Exim 4 book:    http://www.uit.co.uk/exim-book