From 4aa32aaa990ccea7511fa87b59c9fb2b37b17c80 Mon Sep 17 00:00:00 2001 From: Sebastian Hugentobler Date: Tue, 27 Feb 2018 13:56:32 +0100 Subject: [PATCH] add lua app password script --- README.md | 10 +++- .../confd/templates/auth-ldap.conf.ext.tmpl | 5 ++ .../templates/dovecot-ldap.conf.ext.tmpl | 2 +- rootfs/etc/dovecot/app-password-lookup.lua | 50 +++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 rootfs/etc/dovecot/app-password-lookup.lua diff --git a/README.md b/README.md index b752132..bc34aab 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ Which authentication mechanism to use for the smtp relay. Whether to use starttls for the smtp relay. -## LDAP_URI -Complete uri for the authentication ldap host. +## LDAP_HOST +Ldap hostname (can include the port). ## LDAP_SIEVE_HOST Has to be the same as `LDAP_URI` but in a different format (like `ldap:389`). @@ -73,6 +73,12 @@ The ldap attribute which contains the sieve rules. Whether to use tls when connecting to the ldap host. +## LDAP_APP_PASSWORDS_BASE_DN +Base DN to look for app passwords for a user. + +## LDAP_APP_PASSWORDS_FILTER +Specifies the filter on what counts as an app password. + ## LDAP_DEFAULT_PASSSCHEME - default: SSHA diff --git a/rootfs/etc/confd/templates/auth-ldap.conf.ext.tmpl b/rootfs/etc/confd/templates/auth-ldap.conf.ext.tmpl index 9ef7ec4..6c4f295 100644 --- a/rootfs/etc/confd/templates/auth-ldap.conf.ext.tmpl +++ b/rootfs/etc/confd/templates/auth-ldap.conf.ext.tmpl @@ -3,6 +3,11 @@ passdb { args = /etc/dovecot/dovecot-ldap.conf.ext } +passdb { + driver = lua + args = file=/etc/dovecot/app-password-lookup.lua +} + userdb { driver = static args = uid=vmail gid=vmail home=/var/lib/vmail/mail/%d/%n diff --git a/rootfs/etc/confd/templates/dovecot-ldap.conf.ext.tmpl b/rootfs/etc/confd/templates/dovecot-ldap.conf.ext.tmpl index 751b3ab..16c419c 100644 --- a/rootfs/etc/confd/templates/dovecot-ldap.conf.ext.tmpl +++ b/rootfs/etc/confd/templates/dovecot-ldap.conf.ext.tmpl @@ -1,4 +1,4 @@ -uris = {{getenv "LDAP_URI"}} +uris = ldap://{{getenv "LDAP_URI"}} dn = {{getenv "LDAP_BIND_DN"}} dnpass = {{getenv "LDAP_BIND_PASSWORD"}} tls = {{getenv "LDAP_USE_TLS" "yes"}} diff --git a/rootfs/etc/dovecot/app-password-lookup.lua b/rootfs/etc/dovecot/app-password-lookup.lua new file mode 100644 index 0000000..ebb38ba --- /dev/null +++ b/rootfs/etc/dovecot/app-password-lookup.lua @@ -0,0 +1,50 @@ +require "lualdap" + +function auth_passdb_lookup(req) + ldap_use_tls_env = os.getenv("LDAP_USE_TLS") + ldap_use_tls = ldap_use_tls_env == "true" and true or false + + ld = assert (lualdap.open_simple( + os.getenv("LDAP_HOST"), + os.getenv("LDAP_BIND_DN"), + os.getenv("LDAP_BIND_PASSWORD"), + ldap_use_tls)) + + local username = req.username + local ldap_pass_filter = os.getenv("LDAP_PASS_FILTER"):gsub("%%u", username) + + local user_count = 0 + for dn, attribs in ld:search { base = os.getenv("LDAP_BASE_DN"), scope = "subtree", filter = ldap_pass_filter } do + user_count = user_count + 1 + end + + local user_exists = user_count == 1 + if user_exists then + local app_base_dn = os.getenv("LDAP_APP_PASSWORDS_BASE_DN") + local app_pass_filter = os.getenv("LDAP_APP_PASSWORDS_FILTER") + + local user_password = reg.password + + for dn, attribs in ld:search { base = app_base_dn:gsub("%%u", username), scope = "subtree", filter = app_pass_filter } do + lualdap.open_simple( + os.getenv("LDAP_HOST"), + dn, + user_password, + ldap_use_tls) + if test_conn ~= nil then + return dovecot.auth.PASSDB_RESULT_OK, string.format("%s=user", os.getenv("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