require "lualdap" function auth_passdb_lookup(req) local ldap_host = "{{ getenv "LDAP_HOST" }}" local ldap_bin_dn = "{{ getenv "LDAP_BIND_DN" }}" local ldap_bind_password = "{{ getenv "LDAP_BIND_PASSWORD" }}" local ldap_use_tls = {{ getenv "LDAP_USE_TLS" }} ld = assert (lualdap.open_simple( ldap_host, ldap_bin_dn, ldap_bind_password, ldap_use_tls)) local username = req.user local ldap_pass_filter = "{{ getenv "LDAP_PASS_FILTER" }}" local ldap_pass_filter_formatted = ldap_pass_filter:gsub("%%u", username) local ldap_base_dn = "{{ getenv "LDAP_BASE_DN" }}" local user_count = 0 for dn, attribs in ld:search { base = ldap_base_dn, scope = "subtree", filter = ldap_pass_filter_formatted } do user_count = user_count + 1 end local user_exists = user_count == 1 if user_exists then local app_base_dn = "{{ getenv "LDAP_APP_PASSWORDS_BASE_DN" }}" local app_base_dn_formatted = app_base_dn:gsub("%%u", username) local app_pass_filter = "{{ getenv "LDAP_APP_PASSWORDS_FILTER" }}" local ldap_user_attribute = "{{ getenv "LDAP_USER_ATTRIBUTE" }}" local user_password = req.password for dn, attribs in ld:search { base = app_base_dn_formatted, scope = "subtree", filter = app_pass_filter } do lualdap.open_simple( ldap_host, dn, user_password, ldap_use_tls) if test_conn ~= nil then return dovecot.auth.PASSDB_RESULT_OK, string.format("%s=user", ldap_user_attribute) end end else return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "no such user" end return dovecot.auth.PASSDB_RESULT_NEXT, "no app password matches" end function script_init() return 0 end function script_deinit() end