[Dovecot] dovecot and vmailmgr
hello
now that dovecot supports authentication with checkpassword-compatible
modules, I tried to get it working for IMAP on a qmail + vmailmgr
server.
For a subtle detail, while claiming to be "a drop-in replacement for
the standard
checkpassword", checkvpw (auth module for vmailmgr) is not "drop in".
It actually
expects 2 args on its command line, not 1. So, a wrapper is needed to
get it
authenticating correctly with dovecot; a very simple one
(argswrapper.c below).
This wrapper is not sufficient though. In fact, vmailmgr represents
user homes
like this:
$HOME_LOCUSER/users/virtual_username
this is ok with
default_mail_env = maildir:%h/users/%n
$HOME_LOCUSER depends on the domain part of the user's email. The
relation
is held in /var/qmail/control/virtualdomains .
However, on the local part (virtual_username) some rewriting is done
on the username, as
dots are replaced by ":".
So in the end j.doe@foo.com becomes "~mxfoocom/users/j:doe".
Now, var-expand does not support any rewriting. I patched it by
adding another
modifier, m_str_replace(), which replaces REPLACE_SOURCE with
REPLACE_TARGET
in a given string. By defining REPLACE_SOURCE to '.' and
REPLACE_TARGET to ':'
one accomplishes the vmailmgr username rewriting. This modifier is
applied with "P",
so:
default_mail_env = maildir:%h/users/%Pn
A better, general solution would be for dovecot to implement some
kind of general
rewriting, say with regexps and sed-like replacement rules, or with
an external process
in a cgi fashion.
With this patch, dovecot gets the correct path for any user mailbox.
However, there's a bug
in dovecot storage modules (both maildir and mbox) which truncates
the path in the first ":",
when expecting ":INBOX" etc specifiers:
/* <Maildir> [:INBOX=<dir>] [:INDEX=<dir>] [:CONTROL=<dir>] */
if (debug)
i_info("maildir: data=%s", data);
p = strchr(data, ':');
if (p == NULL)
root_dir = data;
else {
root_dir = t_strdup_until(data, p);
this way, a former data = /var/maildirs/foo/users/j:doe:INDEX=... is
truncated to
/var/maildirs/foo/users/j . This opens the much worse possibility for
user "j:doe" to be
accounted into user "j" account after authentication.
It is difficult to get a solid fix here, because the grammar is
ambiguous for
INBOX, INDEX and CONTROL tokens. Since they are not separated with an
illegal
path symbol from the rest of the path in default_mail_env, it is not
possible to state
when a ":INBOX=" token belongs to the path and when it is a user
directive. The Best
is to move the specifiers into a different configuration directive.
However, a more solid check with the current modus operandi is
/* <Maildir> [:INBOX=<dir>] [:INDEX=<dir>] [:CONTROL=<dir>] */
if (debug)
i_info("maildir: data=%s", data);
/* extracting INBOX / INDEX / CONTROL suffices */
if (((p = strstr(data, ":INBOX=")) != NULL)
|| ((p = strstr(data, ":INDEX=")) != NULL)
|| ((p = strstr(data, ":CONTROL=")) != NULL)) {
root_dir = t_strdup_until(data, p);
which expects the full ":INBOX=" etc strings to be present in data
instead of the
single ":" separator.
The patches that implement this for both {maildir,mailbox}-storage
are also appended
below.
I will take a couple of hours tomorrow to wrap all the iter up on a
web page here
http://mij.oltrelinux.com/net/dovecot-qmail-vmailmgr/
All the patches are applied wrt 1.0-beta7
bye
On Wed, 2006-05-10 at 12:51 +0200, Mij wrote:
$HOME_LOCUSER depends on the domain part of the user's email. The
relation is held in /var/qmail/control/virtualdomains . However, on the local part (virtual_username) some rewriting is done
on the username, as dots are replaced by ":". So in the end j.doe@foo.com becomes "~mxfoocom/users/j:doe".Now, var-expand does not support any rewriting. I patched it by
adding another modifier, m_str_replace(), which replaces REPLACE_SOURCE with
REPLACE_TARGET in a given string. By defining REPLACE_SOURCE to '.' and
REPLACE_TARGET to ':' one accomplishes the vmailmgr username rewriting. This modifier is
applied with "P", so: default_mail_env = maildir:%h/users/%Pn
Could you change the dots in the username already in auth_username_translation? If vmailmgr expects them as '.' you could change them back to ':' in your script. A bit ugly, yes :)
A better, general solution would be for dovecot to implement some
kind of general rewriting, say with regexps and sed-like replacement rules, or with
an external process in a cgi fashion.
Hmm.. Actually I think it's already possible for you to return a new username in the checkpassword script by setting USER environment. You might need "EXTRA=USER" environment too.
With this patch, dovecot gets the correct path for any user mailbox.
However, there's a bug in dovecot storage modules (both maildir and mbox) which truncates
the path in the first ":", when expecting ":INBOX" etc specifiers:
Yes.. However I'm not sure if I want to do anything about this. I just didn't expect usernames to contain ':' characters, and adding extra checks to make this sort-of-work just feels like it's going to break at some point, more or less worse.
In Dovecot 2.0 framwork I already got rid of the ':' characters completely by making INBOX, INDEX, etc. separate settings.
I guess I could give the "Maildir" parameter to checkpassword script anyway always.
you can not, see http://cr.yp.to/checkpwd/interface.html
On 11/mag/06, at 11:12, Timo Sirainen wrote:
On Thu, 2006-05-11 at 12:09 +0300, Timo Sirainen wrote:
I guess I could give the "Maildir" parameter to checkpassword script anyway always.
Actually, you can just give Maildir as a parameter to the
checkpassword program in dovecot.conf.
On 11/mag/06, at 11:09, Timo Sirainen wrote:
A better, general solution would be for dovecot to implement some kind of general rewriting, say with regexps and sed-like replacement rules, or with an external process in a cgi fashion.
Hmm.. Actually I think it's already possible for you to return a new username in the checkpassword script by setting USER environment. You might need "EXTRA=USER" environment too.
if the mail address is joe.black@foo.com, the user is actually
joe.black, not
"joe:black".
For what concerns checkpassword, specifically, the interface spec is
very
clear about it: the mapping is black box, but if authentication
succeeds, your
"checkpassword-reply" program will get the mailbox path in form of the
current working directory. See http://cr.yp.to/checkpwd/interface.html .
In general, this decoupling is good. That is, it's good that the
authentication
module (or the userdb you use) compute the path on its own, in spite of
exporting pieces of data that the latter mailserver uses to build the
final path.
In the end, the Good Thing is to hold the final mailbox path in
auth_request, and
let the early passwd or userdb modules concern about this.
With this patch, dovecot gets the correct path for any user mailbox. However, there's a bug in dovecot storage modules (both maildir and mbox) which truncates the path in the first ":", when expecting ":INBOX" etc specifiers:
Yes.. However I'm not sure if I want to do anything about this. I just didn't expect usernames to contain ':' characters, and adding extra checks to make this sort-of-work just feels like it's going to
break at some point, more or less worse.
it's not usernames that contain ":".
Since is legal in path names to put colons, you're enabled and free
to choose
default_mail_env=/var/mailspace/remotes:imap/%u
Whatever the mail storage system is, ":" can just happen. Moreover,
this is
customary with qmail (see http://www.qmail.org/man/man5/dot-qmail.html )
I guess I could give the "Maildir" parameter to checkpassword script anyway always.
it is bad to apply implementation-specific (rel to vmailmgr)
workarounds to
implementation-independent interfaces; however in your case, where the
child program is under your direct control, this should not bother.
participants (2)
-
Mij
-
Timo Sirainen