From 834d92a47ba782b0f6cf609799864c4c73d44c5e Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Tue, 16 Feb 2016 12:33:16 +0100 Subject: [PATCH] LDAP: Fetch attributes in Bind DN context option This is feature is workaround for #2628 (JumpCloud) and some other services that allow LDAP search only under BindDN user account, but not allow any LDAP search query in logged user DN context. Such approach is an alternative to minimal permissions security pattern for BindDN user. --- conf/locale/locale_en-US.ini | 1 + modules/auth/auth_form.go | 1 + modules/auth/ldap/ldap.go | 32 ++++++++++++++++++++++++++------ routers/admin/auths.go | 1 + templates/admin/auth/edit.tmpl | 8 ++++++++ 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini index 5c279c3df..fbe70ddb2 100644 --- a/conf/locale/locale_en-US.ini +++ b/conf/locale/locale_en-US.ini @@ -921,6 +921,7 @@ auths.attribute_username_placeholder = Leave empty to use sign-in form field val auths.attribute_name = First name attribute auths.attribute_surname = Surname attribute auths.attribute_mail = Email attribute +auths.attributes_in_bind = Fetch attributes in Bind DN context auths.filter = User Filter auths.admin_filter = Admin Filter auths.ms_ad_sa = Ms Ad SA diff --git a/modules/auth/auth_form.go b/modules/auth/auth_form.go index 68a968830..15dbb3605 100644 --- a/modules/auth/auth_form.go +++ b/modules/auth/auth_form.go @@ -23,6 +23,7 @@ type AuthenticationForm struct { AttributeName string AttributeSurname string AttributeMail string + AttributesInBind bool Filter string AdminFilter string IsActive bool diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go index 8fbefb434..376092fcb 100644 --- a/modules/auth/ldap/ldap.go +++ b/modules/auth/ldap/ldap.go @@ -31,6 +31,7 @@ type Source struct { AttributeName string // First name attribute AttributeSurname string // Surname attribute AttributeMail string // E-mail attribute + AttributesInBind bool // fetch attributes in bind context (not user) Filter string // Query filter to validate entry AdminFilter string // Query filter to check if user is admin Enabled bool // if this source is disabled @@ -130,14 +131,14 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str } } - log.Trace("Binding with userDN: %s", userDN) - err = l.Bind(userDN, passwd) - if err != nil { - log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err) - return "", "", "", "", false, false + if directBind || !ls.AttributesInBind { + // binds user (checking password) before looking-up attributes in user context + err = bindUser(l, userDN, passwd) + if err != nil { + return "", "", "", "", false, false + } } - log.Trace("Bound successfully with userDN: %s", userDN) userFilter, ok := ls.sanitizedUserQuery(name) if !ok { return "", "", "", "", false, false @@ -184,9 +185,28 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str } } + if !directBind && ls.AttributesInBind { + // binds user (checking password) after looking-up attributes in BindDN context + err = bindUser(l, userDN, passwd) + if err != nil { + return "", "", "", "", false, false + } + } + return username_attr, name_attr, sn_attr, mail_attr, admin_attr, true } +func bindUser(l *ldap.Conn, userDN, passwd string) error { + log.Trace("Binding with userDN: %s", userDN) + err := l.Bind(userDN, passwd) + if err != nil { + log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err) + return err + } + log.Trace("Bound successfully with userDN: %s", userDN) + return err +} + func ldapDial(ls *Source) (*ldap.Conn, error) { if ls.UseSSL { log.Debug("Using TLS for LDAP without verifying: %v", ls.SkipVerify) diff --git a/routers/admin/auths.go b/routers/admin/auths.go index 659b8fcf6..c519d5a7e 100644 --- a/routers/admin/auths.go +++ b/routers/admin/auths.go @@ -81,6 +81,7 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig { AttributeName: form.AttributeName, AttributeSurname: form.AttributeSurname, AttributeMail: form.AttributeMail, + AttributesInBind: form.AttributesInBind, Filter: form.Filter, AdminFilter: form.AdminFilter, Enabled: true, diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl index 426d37e40..9bda87798 100644 --- a/templates/admin/auth/edit.tmpl +++ b/templates/admin/auth/edit.tmpl @@ -79,6 +79,14 @@ + {{if .Source.IsLDAP}} +
+
+ + +
+
+ {{end}} {{end}}