Hi,

> Am 12.06.2015 um 01:52 schrieb Hugo Osvaldo Barrera <[email protected]>:
> 
>> On 2015-06-11 23:23, Joerg Jung wrote:
>> 
>> please find below a diff which enhances deliver to LMTP.
>> 
>> Gilles suggested to bring this diff to misc@ to gain a wider audience
>> and hopefully receive some comments from actual LMTP users.
>> 
>> tl;dr
>>  "deliver to lmtp" delivers to (system) users only, making it hard to
>>  be used in common virtual users setups (with single system user).
>>  Therefore, I provide a diff which adds a parameter to
>>  specify/expands RCPT TO within LMTP.
>> 
>> This was described earlier already [1], but no solution.
>> 
>> Let me explain the rationale/background of the diff below a bit: One of
>> my production servers runs Sendmail/Dovecot and I would like to migrate
>> it to OpenSMTPD/Dovecot.  The server uses virtual users in a common
>> scenario: with all mail addresses mapped to a single system user/uid/gid
>> (called vmail in my case).  Dovecot uses a (static) userdb to map the
>> IMAP maildirs and addresses. [...]
> 
> In my case, I got around this by using a shared SQL db, and have dovecot work
> with virtual mailboxes too:
> 
> https://hugo.barrera.io/journal/2015/02/15/opensmtpd-dovecot-shared-sql-db/
> (note that there are improvements to what is described here that I still need
> to document).

Yes I have seen this, good stuff.
Your creative replace() workaround in the SQL queries made me smile :)

> A big upside is having users for SMTP and IMAP in a single place.
> The only downside this that mail has a header of
> 
>    Delivered-To: hugo_barrera.io
> 
> instead of
> 
>    Delivered-To: [email protected]

Yes, that is big downside.

>> [...] Now I have three options to bring incoming
>> mails from OpenSMTPD to Dovecot:
>> 
>> 1. deliver to maildir
>>  Unfortunately, not an option in my case, because I heavily use Sieve
>>  and Quotas on the Dovecot server.  Both require updates/processing on
>>  delivery.
>> 
>> 2. deliver to mda "dovecot-lda -a ${rcpt} ..."
>>  Would work fine, and is what I have done before with Sendmail as
>>  well.  But requires me to fiddle with dovecot-lda options, poor
>>  performance, and expansions and user permissions, as it needs
>>  adjusting for the "single system user all virtual" setup mentioned
>>  above... thus a bit annoying to setup.
> 
> I agree completely that this option is "fragile" and inefficient.
> 
>> 3. deliver to lmtp "/var/dovecot/lmtp"
>>  IMHO, the most easy and straight forward option, also preferred
>>  nowadays, due to better performance [2].  Not useable in my
>>  scenarios, as deliver_lmtp.c always uses the (system) user in
>>  RCPT TO.
>> 
>> So the diff below addresses this and makes it possible to
>> specify/expand the RCPT TO.
>> 
>> Items for Discussion:
>> -  In a first version of this diff and as suggested in [1], I added a
>>  new keyword RCPT, e.g. ... deliver to lmtp "..." rcpt "${rcpt}", I
>>  decided to leave it away as it simplifies things and does not require
>>  to mess with rule_to_text() and A_LMTP
> 
> I'd personally prefer a table for this, so I can move this out to SQL (with
> some fancy query) for maximum flexibility. I'm pretty sure I would need it for
> my current setup.

Oh? Not sure if understand that, can you provide an example how the table
should look like?

>> -  In a second version I added an additional variable to store and
>>  separate actual lmtp host:port/socket and expanded recipient...
>>  (similar to r_delivery_user) but this required a lot of more changes
>>  in several files to copy things around, and even an additional enum
>>  expand_type might be required: EXPAND_LMTP, or something. So for the
>>  sake of simplicity I decided against this approach.
>> -  Another approach to solve this problem, as suggested in Dovecot
>>  Wiki [3], is to override the RCPT TO with setting
>>  X-Original-Recipient Header (different approach, different diff).
>>  I do not like this idea of injecting additional header in LMTP
>>  session, thus I went with the approach below.
> 
> On this last idea, I'd also like to add that an SMTP fiddling with custom
> headers is pretty ugly and should be avoided if possible.

Yes.

There is another approach possible, I forgot to mention earlier:

- use userinfo but allow mail addresses as usernames (different approach,
   different diff) as usernames, then one can map them and stay with LMTP
   using user in RCPT TO. But this feels a bit like a clumsy and dirty 
workaround
   which misuses a clean thing.

Thanks,
Regards,
Joerg

>> Please: comments, suggestions, other approaches, right/wrong direction,
>> rants, flames,... ?
> 
> I like what your view on the problem and your idea on how to solve it.
> I'm not familiar enough with the code (and my C level is not up to this
> project), so I can't comment on the diffs themselves.
> 
>> Thanks,
>> Regards,
>> Joerg
>> 
>> [1] https://www.mail-archive.com/[email protected]/msg00531.html
>> [2] http://wiki2.dovecot.org/LDA
>> [3] http://wiki2.dovecot.org/LMTP
>> 
>> 
>> ----------------------------------------------------------------
>> 
>> 
>> smtpd/delivery_lmtp.c | 10 ++++------
>> smtpd/parse.y         | 22 ++++++++++++++++++++++
>> smtpd/smtpd.conf.5    | 13 ++++++++++++-
>> 3 files changed, 38 insertions(+), 7 deletions(-)
>> 
>> diff --git a/smtpd/delivery_lmtp.c b/smtpd/delivery_lmtp.c
>> index 5080c46..6c55994 100644
>> --- a/smtpd/delivery_lmtp.c
>> +++ b/smtpd/delivery_lmtp.c
>> @@ -137,16 +137,14 @@ unix_socket(char *path) {
>> static void
>> delivery_lmtp_open(struct deliver *deliver)
>> {
>> -     char *buffer;
>> -     char *lbuf;
>> +     char *buffer, *lbuf, *rcpt = deliver->to;
>>    char lhloname[255];
>>    int s;
>> -     FILE    *fp;
>> +     FILE    *fp = NULL;
>>    enum lmtp_state state = LMTP_BANNER;
>>    size_t    len;
>> 
>> -     fp = NULL;
>> -
>> +     strsep(&rcpt, " ");
>>    if (deliver->to[0] == '/')
>>        s = unix_socket(deliver->to);
>>    else
>> @@ -183,7 +181,7 @@ delivery_lmtp_open(struct deliver *deliver)
>>        case LMTP_MAIL_FROM:
>>            if (buffer[0] != '2')
>>                errx(1, "MAIL FROM rejected: %s\n", buffer);
>> -             fprintf(fp, "RCPT TO:<%s>\r\n", deliver->user);
>> +             fprintf(fp, "RCPT TO:<%s>\r\n", rcpt ? rcpt : deliver->user);
>>            state = LMTP_RCPT_TO;
>>            break;
>> 
>> diff --git a/smtpd/parse.y b/smtpd/parse.y
>> index b73ed7f..8523dd4 100644
>> --- a/smtpd/parse.y
>> +++ b/smtpd/parse.y
>> @@ -1161,6 +1161,28 @@ deliver_action    : DELIVER TO MAILDIR            {
>>               fatal("invalid lmtp destination");
>>           free($4);
>>       }
>> +        | DELIVER TO LMTP STRING STRING deliver_as    {
>> +            rule->r_action = A_LMTP;
>> +            if (strchr($4, ':') || $4[0] == '/') {
>> +                if (strlcpy(rule->r_value.buffer, $4,
>> +                    sizeof(rule->r_value.buffer))
>> +                    >= sizeof(rule->r_value.buffer))
>> +                    fatal("lmtp destination too long");
>> +            } else
>> +                fatal("invalid lmtp destination");
>> +            if (strchr($5, '%')) {
>> +                if (strlcat(rule->r_value.buffer, " ",
>> +                    sizeof(rule->r_value.buffer))
>> +                    >= sizeof(rule->r_value.buffer) ||
>> +                    strlcat(rule->r_value.buffer, $5,
>> +                    sizeof(rule->r_value.buffer))
>> +                    >= sizeof(rule->r_value.buffer))
>> +                    fatal("lmtp recipient too long");
>> +            } else
>> +                fatal("invalid lmtp recipient");
>> +            free($4);
>> +            free($5);
>> +        }
>>       | DELIVER TO MDA STRING deliver_as       {
>>           rule->r_action = A_MDA;
>>           if (strlcpy(rule->r_value.buffer, $4,
>> diff --git a/smtpd/smtpd.conf.5 b/smtpd/smtpd.conf.5
>> index 72d3811..eb76ad6 100644
>> --- a/smtpd/smtpd.conf.5
>> +++ b/smtpd/smtpd.conf.5
>> @@ -287,13 +287,22 @@ accept for domain opensmtpd.org forward-only
>> .Pp
>> Finally, the method of delivery is specified:
>> .Bl -tag -width Ds
>> -.It Ic deliver to lmtp Op Ar host : Ns Ar port | socket
>> +.It Xo
>> +.Ic deliver to lmtp
>> +.Op Ar host : Ns Ar port | socket
>> +.Op Ar rcpt
>> +.Xc
>> Mail is delivered to
>> .Ar host : Ns Ar port ,
>> or to the
>> .Ux
>> .Ar socket
>> over LMTP.
>> +Optionally,
>> +.Ar rcpt
>> +might specify a recipient.
>> +The latter parameter may use conversion specifiers that are expanded before 
>> use
>> +.Pq see Sx FORMAT SPECIFIERS .
>> .It Ic deliver to maildir Ar path
>> Mail is added to a maildir.
>> Its location,
>> @@ -911,7 +920,9 @@ descriptions.
>> .Ss FORMAT SPECIFIERS
>> Some configuration directives support expansion of their parameters at 
>> runtime.
>> Such directives (for example
>> +.Ic deliver to lmtp ,
>> .Ic deliver to maildir ,
>> +and
>> .Ic deliver to mda )
>> may use format specifiers which will be expanded before delivery or
>> relaying.
> 
> -- 
> Hugo Osvaldo Barrera
> A: Because we read from top to bottom, left to right.
> Q: Why should I start my reply below the quoted text?

--
You received this mail because you are subscribed to [email protected]
To unsubscribe, send a mail to: [email protected]

Reply via email to