[Dovecot] Dovecot LDA and address extensions
I'm converting over a virtual user installation that used Postfix and maildrop with a MySQL back-end for mailbox lookups to use Dovecot LDA. The maildrop setup used a database table like:
+-------------------------+--------+-------------+--------------------+ | address | owner | domain | mailbox | +-------------------------+--------+-------------+--------------------+ | postmaster@example.com | tmetro | example.com | .admin.postmaster/ | | root@example.com | tmetro | example.com | .admin.root.lex/ | | tmetro@example.com | tmetro | example.com | .INBOX/ | | tmetro+spam@example.com | tmetro | example.com | .spam.tmetro/ | [...]
where maildrop was handed ${recipient} from postfix, and it queries the above table matching ${recipient} to the address column, getting back the expression CONCAT_WS('/','/var/mail',domain,owner) as the home directory, and CONCAT_WS('/','/var/mail',domain,owner,mailbox) as the mailbox. The UID/GID are fixed, as this is a virtual user setup.
So looking up the mailbox for the user postmaster@example.com returns: /var/mail/example.com/tmetro/.admin.postmaster/
Currently I'm using a static user database with Dovecot. This SQL appears to replicate the maildrop setup: user_query = SELECT CONCAT_WS('/','/var/mail',domain,owner) as home, CONCAT_WS('/','maildir:/var/mail',domain,owner,mailbox) as mail, 5000 as uid, 5000 as gid FROM vmbx2 WHERE userid = '%u'
And this works for mail deliveries.
The problem with this is that not only is a database lookup overkill for the IMAP server, as the root mail location for IMAP users follows a simple pattern adequately represented by the static userdb, it also breaks IMAP, because the returned 'mail' overrides mail_location, (currently set to maildir:/var/mail/%d/%n/), so for user tmetro@example.com it returns: maildir:/var/mail/example.com/tmetro/.INBOX/
instead of: maildir:/var/mail/example.com/tmetro/
(which is the same as the home directory).
Can the "userdb sql" directive be added to the "protocol lda" section? Or perhaps instead create a new "auth lda" section, and move the "userdb sql" and "socket listen" directives to that section?
The second issue is how to best deal with address extensions, something that wasn't fully implemented in the maildrop setup. Ideally I'd like a setup where a lookup is first performed for user+ext@domain, and if it fails to return a mailbox, then lookup user@domain. Assuming Dovecot can handle a multi-row query result (grabbing the first record and ignoring the rest), this can probably be hacked using an appropriate WHERE expression.
But the difficulty is getting the address components. Postfix will provide them, but Dovecot's deliver doesn't seem to have a way of receiving them and passing them on to the user query. The example LDA setup shown here: http://wiki.dovecot.org/LDA/Postfix
suggests passing the extension as an argument to the mailbox (-m) switch. But this assumes that one wants a one-to-one direct mapping between extensions and mailbox names.
I suppose I could switch from: -d ${user}@${nexthop} to: -d ${recipient} and add even more complexity to the SQL to parse out the extension. But I'd rather avoid embedding the extension separator character in the SQL, and would rather eliminate it from the database as well.
Maybe Sieve is the answer. I presume the argument to -m could be inspected in a Sieve script, which could then map to the desired target mailbox. The non-IMAP users (like postmaster@example.com) could be reimplemented as aliases that redirect to a user+ext@example.com address for the user responsible for that domain. But using Sieve scripts for extension to mailbox mappings seems far less elegant than using a database.
Maybe I need to wedge a wrapper program between Postfix and deliver that will accept the address components from postfix, perform the lookup, and convert the results into a -d argument pointing to the "owner" (see table above) and a -m argument pointing to the mailbox.
On a side note...
When I used this command in postfix's master.cf: /usr/lib/dovecot/deliver -d ${user}@${nexthop} -n -m ${extension}
as recommended in the wiki, the following error gets logged:
... status=bounced (command line usage error. Command output: Fatal: Unknown argument: -d Usage: deliver [-c <config file>] [-d <destination user>] [-m <mailbox>] [-f <envelope sender>] )
which doesn't make a lot of sense. I suspect what it is trying to say is that it didn't like something about the argument to the -d switch. Maybe that should be ${domain} instead of ${nexthop}.
(What's up with all the whitespace between "[-m <mailbox>]" and "[-f <envelope sender>]"? Also, might be a good idea to have deliver always write errors - even startup errors - to the specified logging facility, given that not all programs that launch it will report what it writes to STDERR. I notice most postfix commands - even the ones people interact with - log errors.)
I ended up switching to -d ${recipient} to emulate the old maildrop setup for now, and that worked fine.
The sample dovecot.conf has:
## dovecot-lda specific settings ## # socket listen { # master { # path = /var/run/dovecot/auth-master
I uncommented the first two lines, but left the 'path' directive commented, under the assumption that the comment was showing the default. But without it uncommented, the socket doesn't get created. This is an inconsistency compared to how defaults are shown elsewhere in dovecot.conf.
-Tom
On Wed, 2007-05-23 at 21:25 -0400, Tom Metro wrote:
Can the "userdb sql" directive be added to the "protocol lda" section? Or perhaps instead create a new "auth lda" section, and move the "userdb sql" and "socket listen" directives to that section?
In Dovecot v2.0 there might be some better ways to do this, but for now the only way to do this is to run two Dovecot instances.
The second issue is how to best deal with address extensions,
Can't really help there. Use whatever kludge happens to work. :)
When I used this command in postfix's master.cf: /usr/lib/dovecot/deliver -d ${user}@${nexthop} -n -m ${extension}
as recommended in the wiki, the following error gets logged:
... status=bounced (command line usage error. Command output: Fatal: Unknown argument: -d Usage: deliver [-c <config file>] [-d <destination user>] [-m <mailbox>] [-f <envelope sender>] )
which doesn't make a lot of sense. I suspect what it is trying to say is that it didn't like something about the argument to the -d switch. Maybe that should be ${domain} instead of ${nexthop}.
No, it really says that -d parameter was unknown. The only thing I can think of is that it contained some extra character, such as -d<LF> or maybe "-d " or something..
(What's up with all the whitespace between "[-m <mailbox>]" and "[-f <envelope sender>]"?
There's a LF between them. Postfix strips away LFs.
Also, might be a good idea to have deliver always write errors - even startup errors - to the specified logging facility,
Not really possible, because the config file hasn't been read at that point yet. And reading config file (possibly wrong one, because -c parameter could have been used) just to log an error is pretty ugly. Besides if I run deliver manually I expect the error to be written to stderr instead of to some weird log file.
given that not all programs that launch it will report what it writes to STDERR. I notice most postfix commands - even the ones people interact with - log errors.)
I believe all software that runs MDAs will catch the stderr output.
The sample dovecot.conf has:
## dovecot-lda specific settings ## # socket listen { # master { # path = /var/run/dovecot/auth-master
I uncommented the first two lines, but left the 'path' directive commented, under the assumption that the comment was showing the default. But without it uncommented, the socket doesn't get created. This is an inconsistency compared to how defaults are shown elsewhere in dovecot.conf.
participants (2)
-
Timo Sirainen
-
Tom Metro