Hi, I haven't looked at the patch or in detail (I'm on my phone at the moment), but I've been through the same dance with one of my setups. Although I use Cyrus IMAP.
I also tracked the issue to RCTP TO. But instead of patching deliver to lmtp I simply use "recipient" instead of "virtual" and the relay to lmtp://127.0.0.1:port instead of deliver to the Unix socket. It at least works for my quite limited use in this case (only a handful users, but with multiple domains). As far as I know dovecot also allows LMTP over TCP instead of Unix sockets. Have you tried my approach? Best regards Eric Ripa On 11 Jun 2015, at 23:24, Joerg Jung <[email protected] <mailto:[email protected]> > wrote: Hi, 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. 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. 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 - 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. Please: comments, suggestions, other approaches, right/wrong direction, rants, flames,... ? Thanks, Regards, Joerg [1] https://www.mail-archive.com/[email protected]/msg00531.html [2] http://wiki2.dovecot.org/LDA <http://wiki2.dovecot.org/LDA> [3] http://wiki2.dovecot.org/LMTP <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 <http://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.
