From 9b66d15c6abe32fd2d977daa4ad43a4a47daf61f Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Thu, 26 Jul 2018 22:40:46 +0200 Subject: [PATCH] Allow searching group members by username (#9) This change allows to use the specified `username_attribute` in a search for group members. This can especially be useful in case the `uid` is used as the `username_attribute` and also in `member` or `uniqueMember` attribute of groups instead of the DN. --- README.md | 2 +- auth_ldap.go | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8646baf..34817d7 100644 --- a/README.md +++ b/README.md @@ -194,7 +194,7 @@ To use this provider you need to have a LDAP server set up and filled with users - `user_search_base` - optional - Using this parameter you can limit the user search to a certain sub-tree. Within this sub-tree the `uid` must be unique (as the name already states). If unset the `root_dn` is used here - `user_search_filter` - optional - The query to issue to find the user from its `uid` (`{0}` is replaced with the `uid`). If unset the query `(uid={0})` is used - `group_search_base` - optional - Like the `user_search_base` this limits the sub-tree where to search for groups, also defaults to `root_dn` -- `group_membership_filter` - optional - The query to issue to list all groups the user is a member of. The DN of each group is used as the group name. If unset the query `(|(member={0})(uniqueMember={0}))` is used +- `group_membership_filter` - optional - The query to issue to list all groups the user is a member of. The DN of each group is used as the group name. If unset the query `(|(member={0})(uniqueMember={0}))` is used (`{0}` is replaced with the users DN, `{1}` is replaced with the content of the `username_attribute`) - `username_attribute` - optional - The attribute containing the username returned to nginx instead of the dn. If unset the `dn` is used When using the LDAP provider you need to pay attention when writing your ACL. As DNs are used as names for users and groups you also need to specify those in the ACL: diff --git a/auth_ldap.go b/auth_ldap.go index c621a58..a0ba74b 100644 --- a/auth_ldap.go +++ b/auth_ldap.go @@ -124,7 +124,7 @@ func (a authLDAP) DetectUser(res http.ResponseWriter, r *http.Request) (string, } } - groups, err := a.getUserGroups(user) + groups, err := a.getUserGroups(user, alias) return alias, groups, err } @@ -262,7 +262,7 @@ func (a authLDAP) dial() (*ldap.Conn, error) { } // getUserGroups searches for groups containing the user -func (a authLDAP) getUserGroups(userDN string) ([]string, error) { +func (a authLDAP) getUserGroups(userDN, alias string) ([]string, error) { l, err := a.dial() if err != nil { return nil, err @@ -274,7 +274,10 @@ func (a authLDAP) getUserGroups(userDN string) ([]string, error) { ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, - strings.Replace(a.GroupMembershipFilter, `{0}`, userDN, -1), + strings.NewReplacer( + `{0}`, userDN, + `{1}`, alias, + ).Replace(a.GroupMembershipFilter), []string{"dn"}, nil, )