From 87aca5bf1b3fc142fbe56571f60d77e5f6a9da39 Mon Sep 17 00:00:00 2001 From: David Warden Date: Wed, 23 Mar 2016 08:21:25 -0400 Subject: [PATCH] new config option for source of %s in group_search_filter, useful for nested LDAP groups --- conf/ldap.toml | 28 +++++++++++++++++----------- pkg/login/ldap.go | 7 ++++++- pkg/login/settings.go | 5 +++-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/conf/ldap.toml b/conf/ldap.toml index 5cc374b83da..395179e219f 100644 --- a/conf/ldap.toml +++ b/conf/ldap.toml @@ -28,25 +28,31 @@ search_base_dns = ["dc=grafana,dc=org"] # This is done by enabling group_search_filter below. You must also set member_of= "cn" # in [servers.attributes] below. -# Users with nested/recursive group membership must have an LDAP server that supports LDAP_MATCHING_RULE_IN_CHAIN -# and set group_search_filter below in such a way that it returns the groups the submitted username is a member of. +# Users with nested/recursive group membership and an LDAP server that supports LDAP_MATCHING_RULE_IN_CHAIN +# can set group_search_filter, group_search_filter_user_attribute, group_search_base_dns and member_of +# below in such a way that the user's recursive group membership is considered. # # Nested Groups + Active Directory (AD) Example: # -# AD groups store the Distinguished Names (DNs) of members, so your filter will need to know the DN -# for the user based only on the submitted username. Multiple DN templates can be -# searched by combining filters with the LDAP or operator. +# AD groups store the Distinguished Names (DNs) of members, so your filter must +# recursively search your groups for the authenticating user's DN. For example: # -# Some examples: -# group_search_filter = "(member:1.2.840.113556.1.4.1941:=CN=%s,[user container/OU])" -# group_search_filter = "(|(member:1.2.840.113556.1.4.1941:=CN=%s,[user container/OU])(member:1.2.840.113556.1.4.1941:=CN=%s,[another user container/OU]))" +# group_search_filter = "(member:1.2.840.113556.1.4.1941:=%s)" +# group_search_filter_user_attribute = "distinguishedName" +# group_search_base_dns = ["ou=groups,dc=grafana,dc=org"] # -# You might also want to change member_of in [servers.attributes] to "distinguishedName". This -# does not appear to be necessary but it will show you more accurate group membership if -# verbose_logging is enabled. +# [servers.attributes] +# ... +# member_of = "distinguishedName" ## Group search filter, to retrieve the groups of which the user is a member (only set if memberOf attribute is not available) # group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))" +## Group search filter user attribute defines what user attribute gets substituted for %s in group_search_filter. +## Defaults to the value of username in [server.attributes] +## Valid options are any of your values in [servers.attributes] +## If you are using nested groups you probably want to set this and member_of in +## [servers.attributes] to "distinguishedName" +# group_search_filter_user_attribute = "distinguishedName" ## An array of the base DNs to search through for groups. Typically uses ou=groups # group_search_base_dns = ["ou=groups,dc=grafana,dc=org"] diff --git a/pkg/login/ldap.go b/pkg/login/ldap.go index ef611ed358f..48f226ccfa5 100644 --- a/pkg/login/ldap.go +++ b/pkg/login/ldap.go @@ -318,7 +318,12 @@ func (a *ldapAuther) searchForUser(username string) (*ldapUserInfo, error) { // If we are using a POSIX LDAP schema it won't support memberOf, so we manually search the groups var groupSearchResult *ldap.SearchResult for _, groupSearchBase := range a.server.GroupSearchBaseDNs { - filter := strings.Replace(a.server.GroupSearchFilter, "%s", username, -1) + var filter_replace string + filter_replace = getLdapAttr(a.server.GroupSearchFilterUserAttribute, searchResult) + if a.server.GroupSearchFilterUserAttribute == "" { + filter_replace = getLdapAttr(a.server.Attr.Username, searchResult) + } + filter := strings.Replace(a.server.GroupSearchFilter, "%s", filter_replace, -1) if ldapCfg.VerboseLogging { log.Info("LDAP: Searching for user's groups: %s", filter) diff --git a/pkg/login/settings.go b/pkg/login/settings.go index b181dac3281..a42476157fe 100644 --- a/pkg/login/settings.go +++ b/pkg/login/settings.go @@ -27,8 +27,9 @@ type LdapServerConf struct { SearchFilter string `toml:"search_filter"` SearchBaseDNs []string `toml:"search_base_dns"` - GroupSearchFilter string `toml:"group_search_filter"` - GroupSearchBaseDNs []string `toml:"group_search_base_dns"` + GroupSearchFilter string `toml:"group_search_filter"` + GroupSearchFilterUserAttribute string `toml:"group_search_filter_user_attribute"` + GroupSearchBaseDNs []string `toml:"group_search_base_dns"` LdapGroups []*LdapGroupToOrgRole `toml:"group_mappings"` }