LDAP group mapping not working properly

I need some help. I’m able to log in to the system with my LDAP users but all of them have the Admin role although I’ve configured the LDAP group mappings. I think that this could be related with the actual schema I’ve in my LDAP. I’m far from being an LDAP expert, so I would like to receive some help from you.

This is a common user account of LDAP:

#rmartinez, people, domain.com
dn: uid=rmartinez,ou=people,dc=domain,dc=domain
cn: Ricardo Martinez
gidNumber: 100
givenName: Ricardo
homeDirectory: /home/rmartinez
loginShell: /bin/bash
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
sn: Martinez
uid: rmartinez
uidNumber: 10009
userPassword:: e3NzaGF9dWN0RGJ1Njg4ejZPeittYUxrdlRoZWUrM2VWUFdFcFpVQT09

This is one of the groups mapped to Grafana:

# Directores, group, domain.com
dn: cn=Directores,ou=group,dc=domain,dc=com
cn: Directores
gidNumber: 10002
member: uid=sbenito,ou=people,dc=domain,dc=com
member: uid=jsaez,ou=people,dc=domain,dc=com
member: uid=rsanchez,ou=people,dc=domain,dc=com
objectClass: top
objectClass: posixGroup
objectClass: groupOfNames
userPassword:: e3NzaGF9cmhxUVdhWmdZNy83NHM3cGxPYVd6VFFDQVlOWlRsUk5TZz09

And this is how my ldap.toml looks like:

# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
#[log]
#filters = ldap:debug
verbose_logging = true
[[servers]]
# Ldap server host (specify multiple hosts space separated)
host = "dc01.domain.com"
# Default port is 389 or 636 if use_ssl = true
port = 389
# Set to true if ldap server supports TLS
use_ssl = true
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
start_tls = true
# set to true if you want to skip ssl cert validation
ssl_skip_verify = true
# set to the path to your root CA certificate or leave unset to use system defaults
 root_ca_cert = "/etc/ldap/certs/caskmf.pem"
# Authentication against LDAP servers requiring client certificates
 client_cert = "/etc/ldap/certs/dc01srvcert.pem"
 client_key = "/etc/ldap/certs/dc01key.pem"

# Search user bind dn
bind_dn = "cn=Manager,dc=domain,dc=com"
# Search user bind password
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
bind_password = 'admin'

# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"
search_filter = "(uid=%s)"

# An array of base dns to search through
search_base_dns = ["dc=domain,dc=com"]

## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
## Please check grafana LDAP docs for examples
group_search_filter = "(&(objectClass=posixGroup))"
group_search_base_dns = ["ou=group,dc=domain,dc=com"]
group_search_filter_user_attribute = "uid"

# Specify names of the ldap attributes your ldap uses
[servers.attributes]
name = "givenName"
surname = "sn"
username = "cn"
member_of = "memberOf"
#email =  "email"

# Map ldap groups to grafana org roles
[[servers.group_mappings]]
group_dn = "cn=Administradores,ou=group,dc=domain,dc=com"
org_role = "Admin"
# To make user an instance admin  (Grafana Admin) uncomment line below
grafana_admin = true
# The Grafana organization database id, optional, if left out the default org (id 1) will be used
# org_id = 1

[[servers.group_mappings]]
group_dn = "cn=Operadores,ou=group,dc=domain,dc=com"
org_role = "Editor"

[[servers.group_mappings]]
# If you want to match all (or no ldap groups) then you can use wildcard
group_dn = "cn=Directores,ou=group,dc=domain,dc=com"
org_role = "Viewer"

This is the log of a user who belongs to Directores group instead of Administradores

Dec 18 09:25:55 persephone grafana-server[4668]: t=2019-12-18T09:25:55+0100 lvl=info msg="LDAP enabled, reading config file" logger=ldap file=/etc/grafana/ldap.toml
Dec 18 09:25:55 persephone grafana-server[4668]: t=2019-12-18T09:25:55+0100 lvl=info msg="Searching for user's groups" logger=ldap filter="(&(objectClass=posixGroup))"
Dec 18 09:25:55 persephone grafana-server[4668]: t=2019-12-18T09:25:55+0100 lvl=dbug msg="LDAP users found" logger=ldap users="([]*models.ExternalUserInfo) (len=1 cap=1) {\n (*models.ExternalUserInfo)(0xc0000da510)({\n  OAuthToken: (*oauth2.Token)(<nil>),\n  AuthModule: (string) (len=4) \"ldap\",\n  AuthId: (string) (len=38) \"uid=pgambarte,ou=people,dc=domain,dc=com\",\n  UserId: (int64) 0,\n  Email: (string) \"\",\n  Login: (string) (len=14) \"Pilar Gambarte\",\n  Name: (string) (len=14) \"Pilar Gambarte\",\n  Groups: ([]string) (len=3 cap=4) {\n   (string) (len=37) \"cn=Operadores,ou=group,dc=domain,dc=com\",\n   (string) (len=42) \"cn=Administradores,ou=group,dc=domain,dc=com\",\n   (string) (len=37) \"cn=Directores,ou=group,dc=domain,dc=com\"\n  },\n  OrgRoles: (map[int64]models.RoleType) (len=1) {\n   (int64) 1: (models.RoleType) (len=5) \"Admin\"\n  },\n  IsGrafanaAdmin: (*bool)(0xc00082fa20)(true),\n  IsDisabled: (bool) false\n })\n}\n"
Dec 18 09:25:55 persephone grafana-server[4668]: t=2019-12-18T09:25:55+0100 lvl=dbug msg="user auth token created" logger=auth tokenId=14 userId=2 clientIP=10.0.2.2 userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36" authToken=f8152859f8f2421705b2b967a742bcfbfb7ec4d5e0ef0cebe9575dbb399a54c9
Dec 18 09:25:55 persephone grafana-server[4668]: t=2019-12-18T09:25:55+0100 lvl=info msg="Successful Login" logger=http.server User="Pilar Gambarte"
Dec 18 09:25:55 persephone grafana-server[4668]: t=2019-12-18T09:25:55+0100 lvl=dbug msg="seen token" logger=auth tokenId=14 userId=2 clientIP=10.0.2.2 userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36" authToken=f8152859f8f2421705b2b967a742bcfbfb7ec4d5e0ef0cebe9575dbb399a54c9

And here is the Administradores group ldapsearch output. As you can see pgambarte belongs to it. the issue is that Grafana is not filtering correctly the membership of the users to the different groups and all the users, no matter what group belongs to, have the same role: admin. Pgambarte is in Administradores Group:

# Administradores, group, domain.com
dn: cn=Administradores,ou=group,dc=domain,dc=com
cn: Administradores
gidNumber: 10001
member: uid=pgambarte,ou=people,dc=domain,dc=com
member: uid=rmartin,ou=people,dc=domain,dc=com
member: uid=rmartinez,ou=people,dc=domain,dc=com
member: uid=pgomez,ou=people,dc=domain,dc=com
member: uid=jramirez,ou=people,dc=domain,dc=com
objectClass: posixGroup
objectClass: groupOfNames
objectClass: top

Thank you so much.
Regards

1 Like

Hi there,

I was wondering if somebody could help me since I’m broking my head with this issue.

Thank you so much,
Regards.

Hi,
not an expert but rather struggling as well, I would try:

  1. Solution og Community Issue 4753 That means: groupdn=Adminsitradores (only)

  2. Is there anything that tells for each user to which group he belongs?

  3. Check with your admin to make sure that memberOf is enabled on the OpenLDAP server

  4. Check with your admin that anonymous access is allowed to this attribute

Ciao,

Below you can find my working LDAP configuration with SSL activated (my Grafana server is configured with HTTPS).

To troubleshoot and get more log info enable ldap debug logging in grafana.ini

#[log]
#filters = ldap:debug

[[servers]]

Ldap server host (specify multiple hosts space separated)

host = “ldap.your_domain.com”

Default port is 389 or 636 if use_ssl = true

port = 636

Set to true if LDAP server should use an encrypted TLS connection (either with STARTTLS or LDAPS)

use_ssl = true

If set to true, use LDAP with STARTTLS instead of LDAPS

start_tls = false

set to true if you want to skip ssl cert validation

ssl_skip_verify = true

set to the path to your root CA certificate or leave unset to use system defaults

root_ca_cert = “/path/to/certificate.crt”

Authentication against LDAP servers requiring client certificates

client_cert = “/path/to/client.crt”

client_key = “/path/to/client.key”

Search user bind dn

#bind_dn = “cn=admin,dc=grafana,dc=org”
bind_dn = “uid=bind_user,ou=People,dc=your_domain,dc=com”

Search user bind password

If the password contains # or ; you have to wrap it with triple quotes. Ex “”"#password;"""

#bind_password = ‘grafana’
bind_password = “”“your_password”""

User search filter, for example “(cn=%s)” or “(sAMAccountName=%s)” or “(uid=%s)”

search_filter = “(uid=%s)”

An array of base dns to search through

#search_base_dns = [“dc=grafana,dc=org”]
search_base_dns = [“ou=People,dc=your_domain,dc=com”]

For Posix or LDAP setups that does not support member_of attribute you can define the below settings

Please check grafana LDAP docs for examples

group_search_filter = “(&(objectClass=posixGroup)(memberUid=%s))”

group_search_base_dns = [“ou=groups,dc=grafana,dc=org”]

group_search_filter_user_attribute = “uid”

Specify names of the ldap attributes your ldap uses

[servers.attributes]
name = “givenName”
surname = “sn”
username = “uid”
member_of = “ismemberOf” #### >>> If your LDAP team have correctly set the attribute “memberOf” on the LDAP server side, then configure here → member_of = “memberOf” ####
email = “mail”

Map ldap groups to grafana org roles

#[[servers.group_mappings]]
#group_dn = “cn=admins,ou=groups,dc=grafana,dc=org”
#org_role = “Admin”

To make user an instance admin (Grafana Admin) uncomment line below

grafana_admin = true

The Grafana organization database id, optional, if left out the default org (id 1) will be used

org_id = 1

ADMIN GROUPS

[[servers.group_mappings]]
group_dn = “cn=your_group,ou=groups,dc=your_domain,dc=com”
org_role = “Admin”

####################

EDITOR GROUPS

#[[servers.group_mappings]]
#group_dn = “cn=your_group,ou=groups,dc=your_domain,dc=com”
#org_role = “Editor”

#####################

READ-ONLY GROUPS

#[[servers.group_mappings]]

If you want to match all (or no ldap groups) then you can use wildcard

#group_dn = “cn=your_group,ou=groups,dc=your_domain,dc=com”
#org_role = “Viewer”

########################

Regards,

AlexPreformatted text