Mercurial > prosody-modules
comparison mod_auth_ldap/mod_auth_ldap.lua @ 1190:c99d8b666eb4
mod_auth_ldap: Convert from plain_test to plain mode, allowing SCRAM and similar.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Mon, 09 Sep 2013 15:46:51 +0200 |
| parents | 52bee1247014 |
| children | db4085433e5f |
comparison
equal
deleted
inserted
replaced
| 1189:1630c6ed3814 | 1190:c99d8b666eb4 |
|---|---|
| 5 local ldap_server = module:get_option_string("ldap_server", "localhost"); | 5 local ldap_server = module:get_option_string("ldap_server", "localhost"); |
| 6 local ldap_rootdn = module:get_option_string("ldap_rootdn", ""); | 6 local ldap_rootdn = module:get_option_string("ldap_rootdn", ""); |
| 7 local ldap_password = module:get_option_string("ldap_password", ""); | 7 local ldap_password = module:get_option_string("ldap_password", ""); |
| 8 local ldap_tls = module:get_option_boolean("ldap_tls"); | 8 local ldap_tls = module:get_option_boolean("ldap_tls"); |
| 9 local ldap_scope = module:get_option_string("ldap_scope", "onelevel"); | 9 local ldap_scope = module:get_option_string("ldap_scope", "onelevel"); |
| 10 local ldap_filter = module:get_option_string("ldap_filter", "(uid=%s)"); | |
| 10 local ldap_base = assert(module:get_option_string("ldap_base"), "ldap_base is a required option for ldap"); | 11 local ldap_base = assert(module:get_option_string("ldap_base"), "ldap_base is a required option for ldap"); |
| 11 | 12 |
| 12 local lualdap = require "lualdap"; | 13 local lualdap = require "lualdap"; |
| 13 local ld = assert(lualdap.open_simple(ldap_server, ldap_rootdn, ldap_password, ldap_tls)); | 14 local ld = assert(lualdap.open_simple(ldap_server, ldap_rootdn, ldap_password, ldap_tls)); |
| 14 module.unload = function() ld:close(); end | 15 module.unload = function() ld:close(); end |
| 15 | 16 |
| 16 function do_query(query) | 17 local function ldap_filter_escape(s) return (s:gsub("[\\*\\(\\)\\\\%z]", function(c) return ("\\%02x"):format(c:byte()) end)); end |
| 17 for dn, attribs in ld:search(query) do | 18 |
| 18 return true; -- found a result | 19 local function get_user(username) |
| 19 end | 20 module:log("debug", "get_user(%q)", username); |
| 21 return ld:search({ | |
| 22 base = ldap_base; | |
| 23 scope = ldap_scope; | |
| 24 filter = ldap_filter:format(ldap_filter_escape(username)); | |
| 25 })(); | |
| 20 end | 26 end |
| 21 | 27 |
| 22 local provider = {}; | 28 local provider = {}; |
| 23 | 29 |
| 24 local function ldap_filter_escape(s) return (s:gsub("[\\*\\(\\)\\\\%z]", function(c) return ("\\%02x"):format(c:byte()) end)); end | 30 function provider.get_password(username) |
| 31 local dn, attr = get_user(username); | |
| 32 if dn and attr then | |
| 33 return attr.userPassword; | |
| 34 end | |
| 35 end | |
| 36 | |
| 25 function provider.test_password(username, password) | 37 function provider.test_password(username, password) |
| 26 return do_query({ | 38 return provider.get_password(username) == password; |
| 27 base = ldap_base; | |
| 28 scope = ldap_scope; | |
| 29 filter = "(&(uid="..ldap_filter_escape(username)..")(userPassword="..ldap_filter_escape(password)..")(accountStatus=active))"; | |
| 30 }); | |
| 31 end | 39 end |
| 32 function provider.user_exists(username) | 40 function provider.user_exists(username) |
| 33 return do_query({ | 41 return not not get_user(username); |
| 34 base = ldap_base; | |
| 35 scope = ldap_scope; | |
| 36 filter = "(uid="..ldap_filter_escape(username)..")"; | |
| 37 }); | |
| 38 end | 42 end |
| 39 | 43 |
| 40 function provider.get_password(username) return nil, "Passwords unavailable for LDAP."; end | |
| 41 function provider.set_password(username, password) return nil, "Passwords unavailable for LDAP."; end | 44 function provider.set_password(username, password) return nil, "Passwords unavailable for LDAP."; end |
| 42 function provider.create_user(username, password) return nil, "Account creation/modification not available with LDAP."; end | 45 function provider.create_user(username, password) return nil, "Account creation/modification not available with LDAP."; end |
| 43 | 46 |
| 44 function provider.get_sasl_handler() | 47 function provider.get_sasl_handler() |
| 45 local testpass_authentication_profile = { | 48 return new_sasl(module.host, { |
| 46 plain_test = function(sasl, username, password, realm) | 49 plain = function(sasl, username) |
| 47 return provider.test_password(username, password), true; | 50 local password = provider.get_password(username); |
| 51 if not password then return "", nil; end | |
| 52 return password, true; | |
| 48 end | 53 end |
| 49 }; | 54 }); |
| 50 return new_sasl(module.host, testpass_authentication_profile); | |
| 51 end | 55 end |
| 52 | 56 |
| 53 module:provides("auth", provider); | 57 module:provides("auth", provider); |
