In den letzten zwei Jahren hat es der IMAP/POP3-Server Dovecot geschafft, eine mehr als nur ernstzunehmende Alternative zu den Platzhirschen Cyrus und Courier zu werden. Schnell, pflegeleicht, sicher meistens stabil (obwohl der Autor hier schon ein paar Versionen rausgegeben hat, die als Reinfall gelten dürfen) und vor allem hochgradig flexibel und damit sehr leicht in bestehende Infrastrukturen einzubinden. Und so ist es auch nicht weiter verwunderlich, daß ich, wenn ich mal um Hilfe bei Mailservern gebeten werde, in letzter Zeit fast nur noch Dovecot-Server sehe.

Was die Authentifizierung angeht, so verwendet Dovecot ein Konzept, welches man so z.B. auch von PAM/NSS kennt. Es gibt zum einen eine Paßwort-Datenbank, die lediglich Benutzernamen und Paßwörter kennt. Die wird natürlich bei einem normalen Login benötigt, wenn sich also ein Client z.B. via IMAP verbinden will, aber auch, wenn Dovecot z.B. als SASL-Server für einen MTA dient, der Benutzer also Mails verschicken will und sich dazu beim Mailserver authentifizieren muß. Die zweite Datenbank liefert zu einem Benutzer Daten wie z.B. dessen Home-Directory, seine UID/GID, Quotas etc. (dabei kann es sich natürlich um “echte” Unix-User handeln oder um irgendwas Virtuelles). Und weil es so einfach ist, dafür Webappliaktionen zum Management zu schreiben, findet man im SOHO-Bereich eben oft die Konstellation, daß Dovecot die virtuellen Benutzer aus einer SQL-Datenbank zieht.

Und da kommt jetzt die Sache, die bei mir jedes Mal wieder Unverständnis auslöst: Viele Leute benutzen den Dovecot-LDA, besser bekannt als deliver. Das hat viele Vorteile, z.B. daß die Index-Files automatisch angepasst werden. Oder einfach die Tatsache, daß das Ding Sieve kann. Der LDA erwartet eine Adresse, an die er die Mail zustellen soll. In der Konfiguration muß also bei obigem Setup ein Query hinterlegt sein (und noch ein paar andere Einträge), so daß user@example.com irgendwie zu einem Pfad wie /srv/vmail/u/user/Maildir wird. Das ist trivial zu bewerkstelligen. Aber es gibt natürlich noch den zweiten Anwendungsfall: Ein Benutzer loggt sich via IMAP ein und will seine Mails abrufen. Wenn man jetzt davon ausgeht, daß der Benutzername nicht gleich der Mailadresse ist sondern z.B. nur user (wie es ja eigentlich best practice ist), dann müsste hierfür eigentlich ein ganz anderes Query hinterlegt sein. Und genau das ist es, was mir in der freien Wildbahn so gut wie nie begegnet. Im Gegenteil

  • hier mal eines meiner Highlights:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
user_query = SELECT
                       vum.uid,
                       vum.gid, ('*:storage=' || vum.quota_kbytes || 'k') AS quota_rule,
                       ('/export/vmailboxes/' || SUBSTR(vum.login, 1, 1) || '/' || vum.login) AS home
             FROM
                       virtual_mailbox_domains AS vmd
             LEFT JOIN virtual_mailbox_maps AS vmm ON (vmd.id = vmm.domain)
             LEFT JOIN virtual_user_maps AS vum ON (vmm.login = vum.id)
             WHERE
                       (
                        (vmm.localpart = '%n' AND vmd.name='%d')
             OR         (vum.login = '%u')
                       )
             AND       vum.active

Interessant ist hier natürlich genau der OR-Teil, denn er beschreibt ja genau obiges Dilemma. Dabei könnte mit den entsprechenden Views und zwei Konfigurationsdateien alles so einfach sein:

1
2
3
4
// IMAP access
user_query = SELECT home FROM imap_login_v   WHERE login   = '%u'
// LDA access
user_query = SELECT home FROM mailbox_maps_v WHERE address = '%u'

Und deswegen an dieser Stelle zwei Anmerkungen:

  • deliver kann man mit dem Parameter -c eine eigene Konfigurationsdatei mitgeben.
  • Wenn ihr schon Datenbanken benutzt, dann macht es gescheit!

Schönes Wochenende noch!