[LDAPS] - Issue with roles and ldaps groups

The problem

Hi,

I’m trying to link librenms to a ldaps server but I am facing an issue and i don’t know how to resolve it.

In the facts, librenms is correctly configured to authenticate an user through the ldaps server. It correctly recover the username, realnale and the user_id.

LDAP Configuration on Libernms :

librenms@lnms_srv:~$ lnms config:get --dump | jq | grep ldap
“auth_ldap_attr”: {
“uid”: “uid”
},
“auth_ldap_cache_ttl”: 300,
“auth_ldap_debug”: false,
“auth_ldap_ignorecert”: false,
“auth_ldap_emailattr”: null,
“auth_ldap_group”: “”,
“auth_ldap_groupbase”: “ou=groups,dc=test,dc=company”,
“auth_ldap_groupmemberattr”: “memberuid”,
“auth_ldap_groups”: {
“grp_admin”: {
“roles”: [
“admin”
]
}
},
“auth_ldap_port”: 389,
“auth_ldap_prefix”: “uid=”,
“auth_ldap_server”: “ldap_srv.test.company”,
“auth_ldap_require_groupmembership”: false,
“auth_ldap_starttls”: “required”,
“auth_ldap_suffix”: “,ou=people,dc=test,dc=company”,
“auth_ldap_timeout”: 5,
“auth_ldap_uid_attribute”: “uidnumber”,
“auth_ldap_userdn”: false,
“auth_ldap_wildcard_ou”: false,
“auth_ldap_version”: 3,
“auth_mechanism”: “ldap”,
“auth_ldap_cacertfile”: “/opt/librenms/bundle.pem”,
“auth_ldap_bindpassword”: “password_ldap”,
“auth_ldap_binddn”: “cn=ldap-srv,ou=infra,dc=test,dc=company”,
“auth_ldap_groupmembertype”: “puredn”,

Result of the auth_test.php script :

librenms@lnms_srv:~$ ./scripts/auth_test.php -u a0000001
Authentication Method: ldap
Password:
Authenticate user a0000001:
AUTH SUCCESS
User (20001):
username => a0000001
realname => user1
user_id => 20001
email =>
Groups: ; cn=grp_admin,ou=groups,dc=test,dc=company
Roles:

My problem is the following : as we can see in the result of the auth_test.php script the roles is not distributed. As a result, all users that logs into the librenms server through the ldaps auth methode is logged as an Normal User with no right.

The goal is to allow users from the group grp_admin to access librenms with the Administrator role. For all the other user known from the ldaps they are allowed with the Global Read role.

We can see down bellow that the request send to the ldaps server is the folloing : put_filter: “(&(cn=grp_admin)(memberuid=))” but the id declared in the group on the ldaps server is on libernms terms the user_id. How can I confugured libernms in order to send is request instead : put_filter: “(&(cn=grp_admin)(memberuid=user_id))” ?

Extract from the auth_test.php script in verbose mode :

put_filter: “(&(cn=grp_admin)(memberuid=))”
put_filter: AND
put_filter_list “(cn=grp_admin)(memberuid=)”
put_filter: “(cn=grp_admin)”
put_filter: simple
put_simple_filter: “cn=grp_admin”
put_filter: “(memberuid=)”
put_filter: simple
put_simple_filter: “memberuid=”

Structure of the ldap server users :

librenms@lnms_srv:~$ ldapsearch -H “ldaps://ldap.test.company” -x -b “uid=a0000001,ou=people,dc=test,dc=company”
cn: user1
gidNumber: 3009
homeDirectory: /home/Users/a0000001
sn: user1
uid: a0000001
uidNumber: 20001
loginShell: /bin/bash

Structure of the ldap server groups :

librenms@lnms_srv:~$ ldapsearch -H “ldaps://ldap.test.company” -x -b “cn=grp_admin,ou=groups,dc=test,dc=company”
cn: grp_admin
gidNumber: 3009
memberUid: 20001
memberUid: 20002
memberUid: 20003

Output of ./validate.php

===========================================
Component | Version
--------- | -------
LibreNMS  | 24.7.0 (2024-07-17T08:35:08+02:00)
DB Schema | 2024_07_13_133839_modify_ent_physical_defaults (295)
PHP       | 8.1.2-1ubuntu2.18
Python    | 3.10.12
Database  | MariaDB 10.6.18-MariaDB-0ubuntu0.22.04.1
RRDTool   | 1.7.2
SNMP      | 5.9.1
===========================================

[OK]    Installed from package; no Composer required
[OK]    Database connection successful
[OK]    Database Schema is current
[OK]    SQL Server meets minimum requirements
[OK]    lower_case_table_names is enabled
[OK]    MySQL engine is optimal
[OK]    Database and column collations are correct
[OK]    Database schema correct
[OK]    MySQL and PHP time match
[WARN]  Your tmp directory (/tmp/user/1111) is not set to 777 so graphs most likely won't be generated
[OK]    Distributed Polling setting is enabled globally
[OK]    Connected to rrdcached
[OK]    Active pollers found
[OK]    Dispatcher Service is enabled
[OK]    Locks are functional
[INFO]  Could not read cron files
[OK]    Redis is functional
[OK]    rrdtool version ok
[OK]    Connected to rrdcached
[WARN]  Non-git install, updates are manual or from package

What was the last working version of LibreNMS?

24.7.0

Anything in the logs that might be useful for us?

No response

I’m not sure many code changes have gone in since the version you are on but please update to a more recent version first.

Hi,

We updated libernms to the last version available and the problem is still the same, the outputs are still the the same.

librenms@dunadmmmmlnms01b:~$ ./validate.php 
===========================================
Component | Version
--------- | -------
LibreNMS  | 25.2.0 (2025-02-20T11:55:43+01:00)
DB Schema | 2025_01_30_000121_add_ifindex_index_to_ports_table (315)
PHP 	  | 8.3.6
Python 	  | 3.12.3
Database  | MariaDB 10.11.8-MariaDB-0ubuntu0.24.04.1
RRDTool   | 1.7.2
SNMP 	  | 5.9.4.pre2 
===========================================
[OK] Installed from package; no Composer required
[OK] Database connection successful
[OK] Database connection successful
[OK] Database Schema is current
[OK] SQL Server meets minimum requirements
[OK] lower_case_table_names is enabled
[OK] MySQL engine is optimal
[OK] Database and column collations are correct
[OK] Database schema correct
[OK] MySQL and PHP time match
[OK] Distributed Polling setting is enabled globally
[OK] Connected to rrdcached
[OK] Active pollers found
[OK]    Dispatcher Service is enabled
[OK] Locks are functional
[INFO] Could not read cron files
[OK] Redis is functional
[OK] rrdtool version ok
[OK] Connected to rrdcached
[WARN] Non-git install, updates are manual or from package

I encountered that error when i was drunk and Here’s a dumb solution that i made in my staging LibreNMS

edited
getRoles in LdapAuthorizer.php
and made this changes

public function getRoles(string $username): array|false
{
    try {
        $connection = $this->getLdapConnection();
        $groups = Config::get('auth_ldap_groups');

        // Find all defined groups $username is in
        $group_names = array_keys($groups);
        $ldap_group_filter = '';
        foreach ($group_names as $group_name) {
            $ldap_group_filter .= '(cn=' . trim($group_name) . ')';
        }
        if (count($group_names) > 1) {
            $ldap_group_filter = "(|{$ldap_group_filter})";
        }
        if (Config::get('auth_ldap_userdn') === true) {
            $filter = "(&{$ldap_group_filter}(" . trim(Config::get('auth_ldap_groupmemberattr', 'memberUid')) . '=' . $this->getFullDn($username) . '))';
        } else {
            $filter = "(&{$ldap_group_filter}(" . trim(Config::get('auth_ldap_groupmemberattr', 'memberUid')) . '=' . $this->getMembername($username) . '))';
        }
        $search = ldap_search($connection, Config::get('auth_ldap_groupbase'), $filter);
        $entries = ldap_get_entries($connection, $search);

        $roles = ['admin']; // Override roles with 'admin'
        
        return array_unique($roles);
    } catch (AuthenticationException $e) {
        echo $e->getMessage() . PHP_EOL;
    }

    return false;
}

And also
edit getRoles in LdapAuthorizationAuthorizer.php

public function getRoles(string $username): array|false
{
    try {
        // Hardcoding all roles as "admin"
        return ['admin'];
    } catch (AuthenticationException $e) {
        echo $e->getMessage() . PHP_EOL;
    }

    return false;
}

problem solved all LDAP login are now admin
Just edit the codes to your desired liking :rofl:

Do you have any roles in the database?

php artisan tinker --execute="dump(DB::table('roles')->pluck('name')->all())"

if that is empty, run lnms db:seed to populate the roles.

Thanks for your suggestion, but it did not work for me.

thanks for this solution but this workaround override every right with the admin role.

The goal with the ldap connection is to allow only the admin of lnms as admin and the other users in a read only profile.

I thinks that the origial problem above is not that we cannot fetch for the roles but that the request send to the ldaps server is the folloing : put_filter: “(&(cn=grp_admin)(memberuid=))” but the id declared in the group on the ldaps server is on libernms terms the user_id. How can I confugured libernms in order to send is request instead : put_filter: “(&(cn=grp_admin)(memberuid=user_id))” ?

Doesn’t lnms config:set auth_ldap_groupmemberattr user_id do that?

Hi,

No it doesn’t work ether. We also need the parametrer “auth_ldap_groupmemberattr”: “memberuid” in order to establish the ldap connection. We already tried this.

Then use auth_ldap_binddn for the bind user, then auth_ldap_groupmemberattr is not used by bind.