--- a/mod_auth_dovecot/mod_auth_dovecot.lua Sat Oct 30 23:38:39 2010 +0200
+++ b/mod_auth_dovecot/mod_auth_dovecot.lua Sat Oct 30 23:38:52 2010 +0200
@@ -19,12 +19,18 @@
local provider = { name = "dovecot", c = nil };
log("debug", "initializing dovecot authentication provider for host '%s'", host);
+ -- Closes the socket
+ function provider.close(self)
+ if (provider.c ~= nil) then
+ provider.c:close();
+ end
+ provider.c = nil;
+ end
+
-- The following connects to a new socket and send the handshake
function provider.connect(self)
-- Destroy old socket
- if (provider.c ~= nil) then
- provider.c:close();
- end
+ provider:close();
provider.c = socket.unix();
@@ -33,6 +39,7 @@
local r, e = provider.c:connect(socket);
if (not r) then
log("warn", "error connecting to dovecot socket at '%s'. error was '%s'. check permissions", socket, e);
+ provider:close();
return false;
end
@@ -62,6 +69,7 @@
if (not (v1 == "1" and v2 == "1")) then
log("warn", "server version is not 1.1. it is %s.%s", v1, v2);
+ provider:close();
return false;
end
elseif (first == "MECH") then
@@ -74,6 +82,7 @@
end
if (not ok) then
log("warn", "server doesn't support PLAIN mechanism. It supports '%s'", l);
+ provider:close();
return false;
end
elseif (first == "DONE") then
@@ -83,19 +92,23 @@
return true;
end
+ -- Wrapper for send(). Handles errors
function provider.send(self, data)
local r, e = provider.c:send(data);
if (not r) then
log("warn", "error sending '%s' to dovecot. error was '%s'", data, e);
+ provider:close();
return false;
end
return true;
end
+ -- Wrapper for receive(). Handles errors
function provider.receive(self)
local r, e = provider.c:receive();
if (not r) then
log("warn", "error receiving data from dovecot. error was '%s'", socket, e);
+ provider:close();
return false;
end
return r;
@@ -104,8 +117,12 @@
function provider.test_password(username, password)
log("debug", "test password '%s' for user %s at host %s", password, username, module.host);
- if (not provider:connect()) then
- return nil, "Auth failed. Dovecot communications error";
+ local tries = 0;
+
+ if (provider.c == nil or tries > 0) then
+ if (not provider:connect()) then
+ return nil, "Auth failed. Dovecot communications error";
+ end
end
-- Send auth data
@@ -130,7 +147,7 @@
return nil, "Auth failed. Invalid username or password.";
end
end
-
+
function provider.get_password(username)
return nil, "Cannot get_password in dovecot backend.";
end
@@ -138,16 +155,16 @@
function provider.set_password(username, password)
return nil, "Cannot set_password in dovecot backend.";
end
-
+
function provider.user_exists(username)
--TODO: Send an auth request. If it returns FAIL <id> user=<user> then user exists.
- return nil, "user_exists not yet implemented in dovecot backend.";
+ return nil, "user_exists not yet implemented in dovecot backend.";
end
-
+
function provider.create_user(username, password)
return nil, "Cannot create_user in dovecot backend.";
end
-
+
function provider.get_sasl_handler()
local realm = module:get_option("sasl_realm") or module.host;
local getpass_authentication_profile = {
@@ -159,12 +176,11 @@
end
return usermanager.test_password(prepped_username, realm, password), true;
end
- };
- return new_sasl(realm, getpass_authentication_profile);
-end
-
-return provider;
+ };
+ return new_sasl(realm, getpass_authentication_profile);
+ end
+
+ return provider;
end
module:add_item("auth-provider", new_default_provider(module.host));
-