I'm running the Dovecot imap server with users and mailboxes managed by vpopmail and for various reasons I want to gradually move away from vpopmail but without losing the maildir++ storage structure for messages.
The first issue is that vpopmail authentication in dovecot is not compiled in by default on the Debian packages so every time I upgrade I have to recompile the packages to support the vpopmail driver.
This post explains how to use the lua authentication with the vpopmail vpasswd files so we continue to use the same users and passwords without relying on the special dovecot vpopmail driver. If assumes your vpopmail installation is in /home/vpopmail , if it's somewhere else just change the location in the auth.lua file.
Disable the vpopmail authentication module in conf.d/10-auth.conf
Add /etc/dovecot/conf.d/auth-lua.conf.ext with this content:
passdb {
driver = lua
args = file=/etc/dovecot/auth.lua blocking=yes # default is yes
}
userdb {
driver = lua
args = file=/etc/dovecot/auth.lua blocking=yes # default is yes
}
Create /etc/dovecot/auth.lua with the following content:
local function isempty(s)
return s == nil or s == ''
end
function auth_password_verify(req, pass)
local str=req.user
local lastAt = str:find("[^%@]+$")
local localPart = str:sub(1, (lastAt - 2))
local domainPart = str:sub(lastAt, #str)
local file = "/home/vpopmail/domains/"..domainPart.."/vpasswd"
for line in io.lines(file) do
local u,epass=string.match(line,"([^%:]+):([^%:]+)");
if not isempty(epass) and localPart==u and req:password_verify("{MD5-CRYPT}"..epass,pass)>0 then
return dovecot.auth.PASSDB_RESULT_OK, {}
end
end
end
function auth_userdb_lookup(req)
local str=req.user
local lastAt = str:find("[^%@]+$")
local localPart = str:sub(1, (lastAt - 2))
local domainPart = str:sub(lastAt, #str)
local file = "/home/vpopmail/domains/"..domainPart.."/vpasswd"
for line in io.lines(file) do
local u,epass=string.match(line,"([^%:]+):([^%:]*):");
if localPart==u then
return dovecot.auth.USERDB_RESULT_OK, "uid=vpopmail gid=vchkpw"
end
end
return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no such user"
end
You should modify this line in function auth_userdb_lookup and auth_password_verify :
local str=req.user
by :
local str=string.lower(req.user)