OCSInventory-NG / OCSInventory-ocsreports

Webconsole for OCS Inventory NG
https://www.ocsinventory-ng.org
GNU General Public License v2.0
226 stars 149 forks source link

LDAP login not working with MemberOf #561

Open inferno66 opened 6 years ago

inferno66 commented 6 years ago

It's hard to solve a problem when important details are missing, that why we added this template, to help you and us.

General informations

Operating system : Centos 7

Server installation method ( Only one choice )

Server informations

Php version : 7.1 Mysql / Mariadb / Percona version : Mysql 507 Apache version : 2.4.27

OCS Inventory informations

Ocsreports version : 2.5

Problem's description

Describe your problem here

Hello,

I've an issue when I try to use "member of" ldap to logon on OCS Interface

CONEX_LDAP_CHECK_FIELD1_NAME ==> memberof

CONEX_LDAP_CHECK_FIELD1_VALUE ==> Tried with group name and distinguishedName with same issue

More exactly, I can connect but I'm not connected with the correct OCS rights profile

If I use another attribute, for example "title", it's working fine.

On the OCS Web Interface, the message is : "You are not allowed to connectNO RIGHTS LEVEL DEFINED TO YOUR PROFILE"

No error on apache log

I've enabled logs and from what I see it don't my groups (memberOf value is empty)

"ffield1: memberOf value= condition: CN=Equipe_Admin_NT,OU=......"

I already had this issue with OCS 2.4 and now with OCS 2.5 (on a new server), the issue is still there.

Could you help me with that?

Best regards

StCyr commented 5 years ago

Wow, I can't even find back my LDAP configuration on version 2.5 !?!

StCyr commented 5 years ago

and I can't log using LDAP anymore :-(

StCyr commented 5 years ago

nevermind my last comment, it's just that my change in backend/AUTH/auth.php got erased by the upgrade.

Though, it looks like I still cannot find back the LDAP configuration:

image

tiagobortolini commented 5 years ago

@StCyr go to "Configuration/General Configuration/Server/ADVANCE_CONFIGURATION"

StCyr commented 5 years ago

aaaahhh, thanks @tiagobortolini

Again, something that got changed due to the upgrade to 2.5

gillesdubois commented 5 years ago

Hi,

Please see our new documentation for 2.5 informations : http://wiki.ocsinventory-ng.org/02.Basic-documentation/Administration-of-OCS-Inventory-NG/#simplified-configuration

Regards, Gilles Dubois.

inferno66 commented 5 years ago

Hello,

No idea regarding this issue?

Regards

ghost commented 5 years ago

Hi All, I found following: Problem only occur if CONEX_LDAP_CHECK_FIELD1_NAME is memberof. If you use other attribute such as comment, department, etc then login correctly. So this could be a work around while waiting for bug fixed Regards,

StCyr commented 5 years ago

There's some specific code related to the ´memberOf´ attribute in function search_on_loginnt in file backend/AUTH/methode/ldap.php:

    // if the extra attributes are there, save them as well
    if ($info[0][$f1_name][0] != '') {
        //attribute name 'memberof' is for group searching
        //FIXME: casing? -> 'memberOf'
        if ($f1_name == "memberof") {    //this is to store the entire array instead of just the first string
            //may be redundant and could be simplified, but it works.
            $_SESSION['OCS']['details'][$f1_name] = $info[0][strtolower($f1_name)];
        } else {
            $_SESSION['OCS']['details'][$f1_name] = $info[0][strtolower($f1_name)][0];
        }
    }

    if ($info[0][strtolower($f2_name)][0] != '') {
        if ($f2_name == "memberof") {
            $_SESSION['OCS']['details'][$f2_name] = $info[0][strtolower($f2_name)];
        } else {
            $_SESSION['OCS']['details'][$f2_name] = $info[0][strtolower($f2_name)][0];
        }
    }
    return $info;

Maybe that's what causes the issue?

StCyr commented 5 years ago

Then, later in file backend/identity/methode/ldap.php, this value is user to assign role as follow:

if ($f1_value != '') {
    //NEW CODE BELOW
    //FIXME: casing? -> 'memberOf'
    if ($f1_name == "memberof") {
        //the idea here is to iterate through the groups array looking for a match
        //if we find it, unset the array and store only the match, else leave as it is
        foreach ($f1_value as $group) {
            if ($group == $config['LDAP_CHECK_FIELD1_VALUE']) {
                $f1_value = array();
                $f1_value = $group;
            }
        }
    }
    //the if below is now redundant since we already know that we have a match
    //the coding can be improved, but the logic works.
    //END NEW CODE
    if ($f1_value == $config['LDAP_CHECK_FIELD1_VALUE']) {
        $defaultRole = $config['LDAP_CHECK_FIELD1_ROLE'];
    }
}

if ($f2_value != '') {
    //NEW CODE BELOW
    if ($f2_name == "memberof") {
        foreach ($f2_value as $group) {
            if ($group == $config['LDAP_CHECK_FIELD2_VALUE']) {
                $f2_value = array();
                $f2_value = $group;
            }
        }
    }
    //END NEW CODE
    if ($f2_value == $config['LDAP_CHECK_FIELD2_VALUE']) {
        $defaultRole = $config['LDAP_CHECK_FIELD2_ROLE'];
    }
}
StCyr commented 5 years ago

Unfortunately, I can't test here as we are using another attribute than memberOf and it just works fine.

deividsanches commented 5 years ago

I've tested this solution but it didn't work

AlexBtrZ commented 5 years ago

Hi. I was have the same issue. CONEX_LDAP_CHECK_FIELD1_NAME=CONEX_LDAP_CHECK_FIELD2_NAME=memberOf LDAP_CHECK_FIELD1_VALUE=LDAP_CHECK_FIELD2_VALUE="group distinguishedName" then need replase all "memberof" -> "memberOf" (case sensetivity) in files: /backend/identity/methode/ldap.php /backend/AUTH/methode/ldap.php

User who connect to ldap (CONEX_ROOT_DN) must have right to read user groups. You can check it use this php script(from google):

<?php
function get_groups($user) {
    // Active Directory server
    $ldap_host = "ldaps://dc.local";
    // Active Directory DN, base path for our querying user
    $ldap_dn = "DC=dc,DC=local"; 
    // Active Directory user for querying
    $query_user = "user@dc.local";
    $password = "password";
    // Connect to AD
    $ldap = ldap_connect($ldap_host) or die("Could not connect to LDAP");
    ldap_bind($ldap,$query_user,$password) or die("Could not bind to LDAP");
    // Search AD
    $results = ldap_search($ldap,$ldap_dn,"(sAMAccountName=user.name)",array("memberOf","primarygroupid"));
    $entries = ldap_get_entries($ldap, $results);
    // No information found, bad user
    if($entries['count'] == 0) return false;
    // Get groups and primary group token
    $output = $entries[0]['memberof'];
    $token = $entries[0]['primarygroupid'][0];
    // Remove extraneous first entry
    array_shift($output);
    // We need to look up the primary group, get list of all groups
    $results2 = ldap_search($ldap,$ldap_dn,"(objectcategory=group)",array("distinguishedname","primarygrouptoken"));
    $entries2 = ldap_get_entries($ldap, $results2);
    // Remove extraneous first entry
    array_shift($entries2);
    // Loop through and find group with a matching primary group token
    foreach($entries2 as $e) {
        if($e['primarygrouptoken'][0] == $token) {
            // Primary group found, add it to output array
            $output[] = $e['distinguishedname'][0];
            // Break loop
            break;
        }
    }
    return $output;
}
// Example Usage
print_r(get_groups("user.name"));
?>

You must see all groups user "user.name" If you can't see - check security permission. It is working for me with AD.

Also we can add LDAP user by hands. For this we need insert row with user data to OCS base:

#mysql -u root -p 
[(none)]> use ocsweb;
[ocsweb]> insert into operators (ID,FIRSTNAME,LASTNAME,COMMENTS,NEW_ACCESSLVL,USER_GROUP,PASSWORD_VERSION) VALUES ("user.name","User","Name","LDAP","admin","NULL","0");

"admin" -it is permision group name, change to what you need

devuan2 commented 5 years ago

I've run into this same problem on Ubuntu 18.04 and OCS v2.2. I'm using OpenLDAP as the backend, not AD so the PHP script dropped by @AlexBtrZ needed some changes (Used cn instead of sAMAccountName for instance). What was most helpful was the mysql snippet he/she added. After adding my user into the DB that way, I was able to login. I'm using memberof for the values in _CONEX_LDAP_CHECK_FIELD1NAME and _CONEX_LDAP_CHECK_FIELD2NAME. The case seems to make no difference.

Some shell commands I've used to fiddle with the operators table to add our LDAP based admins:

# remove user
echo 'delete from ocsweb.operators where FIRSTNAME="user101"' | mysql -u root -p

# view users 
echo 'select * from ocsweb.operators \G' | mysql -u root 

# add a superadmin user
echo 'insert into ocsweb.operators (ID,FIRSTNAME,LASTNAME,COMMENTS,NEW_ACCESSLVL,USER_GROUP,PASSWORD_VERSION) VALUES ("user101", "Firstname", "Lastname", "LDAP", "sadmin","NULL","0")' | mysql -u root
diekson commented 5 years ago

I'm using OCS 2.6 and it worked for me. I had to put a full filter for the field value.

CONEX_LDAP_CHECK_FIELD1_NAME="memberof". CONEX_LDAP_CHECK_FIELD1_VALUE="CN=OCS_ADMIM,OU=myOUName,OU=myOUMainName,DC=mydomainpart1,DC=mydomainpart2 CONEX_LDAP_CHECK_FIELD1_ROLE="Administrators"

Similarly, "FIELD2" worked too.

CONEX_LDAP_CHECK_FIELD2_NAME="memberof". In field CONEX_LDAP_CHECK_FIELD2_VALUE="CN=OCS_READONLY,OU=myOUName,OU=myOUMainName,DC=mydomainpart1,DC=mydomainpart2 CONEX_LDAP_CHECK_FIELD2_ROLE="RO".

nwildner commented 4 years ago

I'm using OCS 2.6 and it worked for me. I had to put a full filter for the field value.

CONEX_LDAP_CHECK_FIELD1_NAME="memberof". CONEX_LDAP_CHECK_FIELD1_VALUE="CN=OCS_ADMIM,OU=myOUName,OU=myOUMainName,DC=mydomainpart1,DC=mydomainpart2 CONEX_LDAP_CHECK_FIELD1_ROLE="Administrators"

Similarly, "FIELD2" worked too.

CONEX_LDAP_CHECK_FIELD2_NAME="memberof". In field CONEX_LDAP_CHECK_FIELD2_VALUE="CN=OCS_READONLY,OU=myOUName,OU=myOUMainName,DC=mydomainpart1,DC=mydomainpart2 CONEX_LDAP_CHECK_FIELD2_ROLE="RO".

That's weird cause, i have the same situation here and using full filters would not solve the issue:

CONEX_LOGIN_FIELD = sAMAccountName

CONEX_LDAP_CHECK_FIELD1_NAME = memberOf CONEX_LDAP_CHECK_FIELD1_VALUE = CN=TBL-TI_Admins,OU=Administrativos,OU=Grupos,OU=Recursos,DC=company,DC=net CONEX_LDAP_CHECK_FIELD1_ROLE="sadmins"

CONEX_LDAP_CHECK_FIELD2_NAME = memberOf CONEX_LDAP_CHECK_FIELD2_VALUE = CN=BGV-TI_Operadores,OU=Administrativos,OU=Grupos,OU=Recursos,DC=company,DC=net CONEX_LDAP_CHECK_FIELD2_ROLE = "admins"

Have tried all variants with and without double quotes inside those fields, memberOf capitalization (membeof, MemberOf) and this exact configuration used to work with OCS 2.1, before i make the upgrade path 2.1 -> 2.3 -> 2.6.

Needless to say that i've already edited AUTH/auth.php and identity/identity.php, and tried the "SSO" and "HTML" login methods.

nwildner commented 4 years ago

Well. It seems that i was not suffering from this issue, but instead, i've found another problem with LDAP authentication involving password storing inside MySQL.

So, to me memberOf is not a problem, but helped me to find another bug ( #888 )

gillesdubois commented 3 years ago

Hi,

LDAP auth has been reworked, you should have a better handling now. Can you test with a nightly ?

Regards, Gilles

rneto12 commented 3 years ago

I'm using OCS 2.8.1 and memberof is working now.