# HG changeset patch # User Kim Alvefur # Date 1771964897 -3600 # Node ID dddb6c34b964cd76264ad6ddf1409f14bf148644 # Parent 2336915333187d3b911c7ecdc27fbadc69824635 mod_auth_ldap: Remove, was merged into Prosody 0.12.0 diff -r 233691533318 -r dddb6c34b964 mod_auth_ldap/README.md --- a/mod_auth_ldap/README.md Tue Feb 24 15:26:37 2026 -0500 +++ b/mod_auth_ldap/README.md Tue Feb 24 21:28:17 2026 +0100 @@ -3,62 +3,7 @@ - 'Stage-Merged' - 'Type-Auth' summary: LDAP authentication module +superseded_by: mod_auth_ldap ... -Introduction -============ - -This is a Prosody authentication plugin which uses LDAP as the backend. - -Dependecies -=========== - -This module depends on [LuaLDAP](https://github.com/lualdap/lualdap) -for connecting to an LDAP server. - -Configuration -============= - -Copy the module to the prosody modules/plugins directory. - -In Prosody's configuration file, under the desired host section, add: - -``` {.lua} -authentication = "ldap" -ldap_base = "ou=people,dc=example,dc=com" -``` - -Further LDAP options are: - - Name Description Default value - --------------------- ---------------------------------------------------------------------------------------------------------------------- -------------------- - ldap\_base LDAP base directory which stores user accounts **Required field** - ldap\_server Space-separated list of hostnames or IPs, optionally with port numbers (e.g. "localhost:8389") `"localhost"` - ldap\_rootdn The distinguished name to auth against `""` (anonymous) - ldap\_password Password for rootdn `""` - ldap\_filter Search filter, with `$user` and `$host` substituted for user- and hostname `"(uid=$user)"` - ldap\_scope Search scope. other values: "base" and "onelevel" `"subtree"` - ldap\_tls Enable TLS (StartTLS) to connect to LDAP (can be true or false). The non-standard 'LDAPS' protocol is not supported. `false` - ldap\_mode How passwords are validated. `"bind"` - ldap\_admin\_filter Search filter to match admins, works like ldap\_filter - -**Note:** lua-ldap reads from `/etc/ldap/ldap.conf` and other files like -`~prosody/.ldaprc` if they exist. Users wanting to use a particular TLS -root certificate can specify it in the normal way using TLS\_CACERT in -the OpenLDAP config file. - -Modes -===== - -The `"getpasswd"` mode requires plain text access to passwords in LDAP -and feeds them into Prosodys authentication system. This enables more -secure authentication mechanisms but does not work for all deployments. - -The `"bind"` mode performs an LDAP bind, does not require plain text -access to passwords but limits you to the PLAIN authentication -mechanism. - -Compatibility -============= - -Works with 0.8 and later. +This module is [included with Prosody][doc:modules:mod_auth_ldap] since version 0.12.0 diff -r 233691533318 -r dddb6c34b964 mod_auth_ldap/mod_auth_ldap.lua --- a/mod_auth_ldap/mod_auth_ldap.lua Tue Feb 24 15:26:37 2026 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ --- mod_auth_ldap - -local jid_split = require "util.jid".split; -local new_sasl = require "util.sasl".new; -local lualdap = require "lualdap"; - -local function ldap_filter_escape(s) - return (s:gsub("[*()\\%z]", function(c) return ("\\%02x"):format(c:byte()) end)); -end - --- Config options -local ldap_server = module:get_option_string("ldap_server", "localhost"); -local ldap_rootdn = module:get_option_string("ldap_rootdn", ""); -local ldap_password = module:get_option_string("ldap_password", ""); -local ldap_tls = module:get_option_boolean("ldap_tls"); -local ldap_scope = module:get_option_string("ldap_scope", "subtree"); -local ldap_filter = module:get_option_string("ldap_filter", "(uid=$user)"):gsub("%%s", "$user", 1); -local ldap_base = assert(module:get_option_string("ldap_base"), "ldap_base is a required option for ldap"); -local ldap_mode = module:get_option_string("ldap_mode", "bind"); -local ldap_admins = module:get_option_string("ldap_admin_filter", - module:get_option_string("ldap_admins")); -- COMPAT with mistake in documentation -local host = ldap_filter_escape(module:get_option_string("realm", module.host)); - --- Initiate connection -local ld = nil; -module.unload = function() if ld then pcall(ld, ld.close); end end - -function ldap_do_once(method, ...) - if ld == nil then - local err; - ld, err = lualdap.open_simple(ldap_server, ldap_rootdn, ldap_password, ldap_tls); - if not ld then return nil, err, "reconnect"; end - end - - -- luacheck: ignore 411/success - local success, iterator, invariant, initial = pcall(ld[method], ld, ...); - if not success then ld = nil; return nil, iterator, "search"; end - - local success, dn, attr = pcall(iterator, invariant, initial); - if not success then ld = nil; return success, dn, "iter"; end - - return dn, attr, "return"; -end - -function ldap_do(method, retry_count, ...) - local dn, attr, where; - for _=1,1+retry_count do - dn, attr, where = ldap_do_once(method, ...); - if dn or not(attr) then break; end -- nothing or something found - module:log("warn", "LDAP: %s %s (in %s)", tostring(dn), tostring(attr), where); - -- otherwise retry - end - if not dn and attr then - module:log("error", "LDAP: %s", tostring(attr)); - end - return dn, attr; -end - -function get_user(username) - module:log("debug", "get_user(%q)", username); - return ldap_do("search", 2, { - base = ldap_base; - scope = ldap_scope; - sizelimit = 1; - filter = ldap_filter:gsub("%$(%a+)", { - user = ldap_filter_escape(username); - host = host; - }); - }); -end - -local provider = {}; - -function provider.create_user(username, password) -- luacheck: ignore 212 - return nil, "Account creation not available with LDAP."; -end - -function provider.user_exists(username) - return not not get_user(username); -end - -function provider.set_password(username, password) - local dn, attr = get_user(username); - if not dn then return nil, attr end - if attr.userPassword == password then return true end - return ldap_do("modify", 2, dn, { '=', userPassword = password }); -end - -if ldap_mode == "getpasswd" then - function provider.get_password(username) - local dn, attr = get_user(username); - if dn and attr then - return attr.userPassword; - end - end - - function provider.test_password(username, password) - return provider.get_password(username) == password; - end - - function provider.get_sasl_handler() - return new_sasl(module.host, { - plain = function(sasl, username) -- luacheck: ignore 212/sasl - local password = provider.get_password(username); - if not password then return "", nil; end - return password, true; - end - }); - end -elseif ldap_mode == "bind" then - local function test_password(userdn, password) - local ok, err = lualdap.open_simple(ldap_server, userdn, password, ldap_tls); - if not ok then - module:log("debug", "ldap open_simple error: %s", err); - end - return not not ok; - end - - function provider.test_password(username, password) - local dn = get_user(username); - if not dn then return end - return test_password(dn, password) - end - - function provider.get_sasl_handler() - return new_sasl(module.host, { - plain_test = function(sasl, username, password) -- luacheck: ignore 212/sasl - return provider.test_password(username, password), true; - end - }); - end -else - module:log("error", "Unsupported ldap_mode %s", tostring(ldap_mode)); -end - -if ldap_admins then - function provider.is_admin(jid) - local username, user_host = jid_split(jid); - if user_host ~= module.host then - return false; - end - return ldap_do("search", 2, { - base = ldap_base; - scope = ldap_scope; - sizelimit = 1; - filter = ldap_admins:gsub("%$(%a+)", { - user = ldap_filter_escape(username); - host = host; - }); - }); - end -end - -module:provides("auth", provider);