From da3d5375b8b71d7aa57587a5e081c35db08f07ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 26 Oct 2015 16:21:03 +0100 Subject: [PATCH] feat(ldap): refactoring of PR #2928 updated docs --- conf/ldap.toml | 25 ++++-------- docs/sources/installation/ldap.md | 63 ++++++++++++++++++++++--------- pkg/login/ldap.go | 5 +++ 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/conf/ldap.toml b/conf/ldap.toml index bfe28d4e835..aa8a9679d68 100644 --- a/conf/ldap.toml +++ b/conf/ldap.toml @@ -18,30 +18,19 @@ bind_dn = "cn=admin,dc=grafana,dc=org" # Search user bind password bind_password = 'grafana' -# Schema's supporting memberOf - -# Search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" +# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)" search_filter = "(cn=%s)" + # An array of base dns to search through search_base_dns = ["dc=grafana,dc=org"] -# Uncomment this section (and comment out the previous 2 entries) to use POSIX schema. -# In POSIX LDAP schemas, querying the people 'ou' gives you entries that do not have a -# memberOf attribute, so a secondary query must be made for groups. This is done by -# enabling group_search_filter below. You must also set -# member_of = "cn" +# In POSIX LDAP schemas, without memberOf attribute a secondary query must be made for groups. +# This is done by enabling group_search_filter below. You must also set member_of= "cn" # in [servers.attributes] below. -# -# Search filter, used to retrieve the user -# search_filter = "(uid=%s)" -# -# An array of the base DNs to search through for users. Typically uses ou=people. -# search_base_dns = ["ou=people,dc=grafana,dc=org"] -# -# Group search filter, to retrieve the groups of which the user is a member + +## 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))" -# -# An array of the base DNs to search through for groups. Typically uses ou=groups +## 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"] # Specify names of the ldap attributes your ldap uses diff --git a/docs/sources/installation/ldap.md b/docs/sources/installation/ldap.md index 45552a8e2b0..82309ec0f19 100644 --- a/docs/sources/installation/ldap.md +++ b/docs/sources/installation/ldap.md @@ -21,26 +21,38 @@ specific configuration file (default: `/etc/grafana/ldap.toml`). verbose_logging = false [[servers]] -# LDAP server host +# Ldap server host (specify multiple hosts space separated) host = "127.0.0.1" -# Usual port is 389, or, if TLS is supported, 636 +# Default port is 389 or 636 if use_ssl = true port = 389 -# Set to true if LDAP server supports TLS +# Set to true if ldap server supports TLS use_ssl = false -# set to true if you want to skip SSL cert validation +# set to true if you want to skip ssl cert validation ssl_skip_verify = false +# set to the path to your root CA certificate or leave unset to use system defaults +# root_ca_cert = /path/to/certificate.crt # Search user bind dn bind_dn = "cn=admin,dc=grafana,dc=org" # Search user bind password -bind_password = "grafana" +bind_password = 'grafana' -# Search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" +# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)" search_filter = "(cn=%s)" + # An array of base dns to search through search_base_dns = ["dc=grafana,dc=org"] -# Map LDAP user attributes to Grafana user attributes +# In POSIX LDAP schemas, without memberOf attribute a secondary query must be made for groups. +# This is done by enabling group_search_filter below. You must also set member_of= "cn" +# in [servers.attributes] below. + +## 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))" +## 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"] + +# Specify names of the ldap attributes your ldap uses [servers.attributes] name = "givenName" surname = "sn" @@ -48,11 +60,11 @@ username = "cn" member_of = "memberOf" email = "email" -# Map LDAP groups to Grafana org roles +# Map ldap groups to grafana org roles [[servers.group_mappings]] group_dn = "cn=admins,dc=grafana,dc=org" org_role = "Admin" -# The Grafana organization database id, optional, if left out, the default org (id 1) will be used +# The Grafana organization database id, optional, if left out the default org (id 1) will be used # org_id = 1 [[servers.group_mappings]] @@ -60,9 +72,10 @@ group_dn = "cn=users,dc=grafana,dc=org" org_role = "Editor" [[servers.group_mappings]] -# If you want to match all (or no LDAP groups) then you can use wildcard +# If you want to match all (or no ldap groups) then you can use wildcard group_dn = "*" org_role = "Viewer" + ``` ## Bind & Bind Password @@ -87,17 +100,31 @@ bind_dn = "cn=%s,o=users,dc=grafana,dc=org" In this case you skip providing a `bind_password` and instead provide a `bind_dn` value with a `%s` somewhere. This will be replaced with the username entered in on the Grafana login page. The search filter and search bases settings are still needed to perform the LDAP search to retrieve the other LDAP information (like LDAP groups and email). +## POSIX schema (no memberOf attribute) +If your ldap server does not support the memberOf attribute add these options: + +```toml +## 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))" +## 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"] +``` + +Also change set `member_of = "cn"` in the `[servers.attributes]` section. + + ## LDAP to Grafana Org Role Sync -## Group Mappings -In `[[servers.group_mappings]]` you can map an LDAP group to a Grafana organization and role. These will be synced every time the user logs in, with LDAP being the authoritative source. -So, if you change a user's role in the Grafana Org. Users page, this change will be reset the next time the user logs in. If you change the LDAP groups of a user, the change will take effect the next time the user logs in. +### Mappings +In `[[servers.group_mappings]]` you can map an LDAP group to a Grafana organization +and role. These will be synced every time the user logs in, with LDAP being +the authoritative source. So, if you change a user's role in the Grafana Org. +Users page, this change will be reset the next time the user logs in. If you +change the LDAP groups of a user, the change will take effect the next +time the user logs in. -### Priority between Multiple Mappings +### Priority The first group mapping that an LDAP user is matched to will be used for the sync. If you have LDAP users that fit multiple mappings, the topmost mapping in the TOML config will be used. -## Ldap to Grafana Org Role Sync -In the `[[servers.group_mappings]]` you can map a LDAP group to a grafana organization and role. These will be synced every time the user logs in. So -if you change a users role in the Grafana Org. Users page, this change will be reset the next time the user logs in. Similarly if you -can LDAP groups for a user in LDAP the change will take effect the next time the user logs in to Grafana. + diff --git a/pkg/login/ldap.go b/pkg/login/ldap.go index 6337f932256..355b4fd100a 100644 --- a/pkg/login/ldap.go +++ b/pkg/login/ldap.go @@ -319,6 +319,11 @@ func (a *ldapAuther) searchForUser(username string) (*ldapUserInfo, error) { var groupSearchResult *ldap.SearchResult for _, groupSearchBase := range a.server.GroupSearchBaseDNs { filter := strings.Replace(a.server.GroupSearchFilter, "%s", username, -1) + + if ldapCfg.VerboseLogging { + log.Info("LDAP: Searching for user's groups: %s", filter) + } + groupSearchReq := ldap.SearchRequest{ BaseDN: groupSearchBase, Scope: ldap.ScopeWholeSubtree,