Moodle

LDAP - user data mapping doesn't work

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.9.1
  • Fix Version/s: 1.8.7, 1.9.3, 2.0
  • Component/s: Authentication
  • Labels:
    None
  • Environment:
    Moodle on Windows 2003 server, ldaps connection agains a remote IBM LDAP server.
  • Database:
    MySQL
  • Affected Branches:
    MOODLE_19_STABLE
  • Fixed Branches:
    MOODLE_18_STABLE, MOODLE_19_STABLE, MOODLE_20_STABLE

Description

After configuring the LDAPS connetion, with the PEM certificate, the data mapping of the user doesn't work. So after succesful login the username, surname, email... should be mapped to the user profile, but all fields are empty. After trying a lot with the parameters and checking the code I found a posible bug in the file \moodle\auth\ldap\auth.php
Changing the next two lines it works fine:

186 if (!$user_info_result = ldap_read($ldapconnection, $user_dn, $this->config->objectclass, $search_attribs)) {
if (!$user_info_result = ldap_read($ldapconnection, $user_dn, '(objectClass=*)', $search_attribs)) {

1057 $user_info_result = ldap_read($ldapconnection, $user_dn, $this->config->objectclass, $search_attribs);
$user_info_result = ldap_read($ldapconnection, $user_dn, '(objectClass=*)', $search_attribs);

The 3rd parameter of the funtion should be "objectClass=" or "uid=", etc. But $this->config->objectclass could be empty or be something like "uid" or "cn".
I don't know how it could work this way for other people or if there is a configuration combination to avoid this. Anyway for me it works with this fix.

Victor.

Activity

Hide
Iñaki Arenaza added a comment - - edited

Hi victorf,

$this->config->objectclass can't be empty, or something like just "uid" or "cn" (well, it shouldn't, there was a bug sometime ago that permitted some incorrect search filters).

If you don't fill in the 'objectClass' setting, then it gets set to 'objectClass=*' (which is exactly your proposed fix). If you set it to someting that doesn't start with 'objectClass=', then it gets set to 'objectClass=your-typed-setting'. Otherwise it gets set to exactly what you typed.

May I ask what have you configured in the 'objectClass' LDAP setting in your setup?

Saludos. Iñaki.

Show
Iñaki Arenaza added a comment - - edited Hi victorf, $this->config->objectclass can't be empty, or something like just "uid" or "cn" (well, it shouldn't, there was a bug sometime ago that permitted some incorrect search filters). If you don't fill in the 'objectClass' setting, then it gets set to 'objectClass=*' (which is exactly your proposed fix). If you set it to someting that doesn't start with 'objectClass=', then it gets set to 'objectClass=your-typed-setting'. Otherwise it gets set to exactly what you typed. May I ask what have you configured in the 'objectClass' LDAP setting in your setup? Saludos. Iñaki.
Hide
victorf added a comment -

Hola Iñaki,

for me it doesn't work, doesn't matter what I put in the Object Class setting in the setup. I have try with empty, with 'uid', with (objectClass=*), etc. Only works when I change the php code as described.

Actually I tried with a short php script the next function:

ldap_read( $ldapconnection, $user_dn, $myObjClass, $search_attribs))

When $myObjClass is empty doesn't work. That's why I changed it by '(objectClass=)'. If you search in the same file (auth.php) for the 'ldap_read' function call, in all the other places they put also '(objectClass=)' instead of $this->config->objectclass. I don't know if the behaviour of my company ldap server is different in this case.

Victor

Show
victorf added a comment - Hola Iñaki, for me it doesn't work, doesn't matter what I put in the Object Class setting in the setup. I have try with empty, with 'uid', with (objectClass=*), etc. Only works when I change the php code as described. Actually I tried with a short php script the next function: ldap_read( $ldapconnection, $user_dn, $myObjClass, $search_attribs)) When $myObjClass is empty doesn't work. That's why I changed it by '(objectClass=)'. If you search in the same file (auth.php) for the 'ldap_read' function call, in all the other places they put also '(objectClass=)' instead of $this->config->objectclass. I don't know if the behaviour of my company ldap server is different in this case. Victor
Hide
victorf added a comment -

Snapshop of the ldap setup section.

Show
victorf added a comment - Snapshop of the ldap setup section.
Hide
Iñaki Arenaza added a comment -

Leaving that setting empty should fill $this->config->objectclass with 'objectClass='. Which makes me wonder.... this is not right. It should be '(objectClass=)' (the opening anc closing parentheses are missing). That's why the search if failing. It didn't happen to me during my testing probably because both OpenLDAP and Active Directory are more forgiving with the filter syntax than your LDAP server.

If Petr doesn't mind, I can fix it.

Saludos. Iñaki.

Show
Iñaki Arenaza added a comment - Leaving that setting empty should fill $this->config->objectclass with 'objectClass='. Which makes me wonder.... this is not right. It should be '(objectClass=)' (the opening anc closing parentheses are missing). That's why the search if failing. It didn't happen to me during my testing probably because both OpenLDAP and Active Directory are more forgiving with the filter syntax than your LDAP server. If Petr doesn't mind, I can fix it. Saludos. Iñaki.
Hide
Petr Škoda (skodak) added a comment -

thanks for volunteering

Show
Petr Škoda (skodak) added a comment - thanks for volunteering
Hide
victorf added a comment -

Ok, great.

I have also seen that in this file there are several other calls to ldap_read, and in some cases $this->config->objectclass is used, in other cases is hardcoded 'objectClass=' , and in other cases is hardcoded ('objectClass='). I supose that at least the version without parentesi is unsafe, depending on the ldap server.

And what I still don't understand is why if I type ('objectClass=*') in the field, it doesn't work.

Anyway thanks for all. I think that moodle is a great system!
Victor

Show
victorf added a comment - Ok, great. I have also seen that in this file there are several other calls to ldap_read, and in some cases $this->config->objectclass is used, in other cases is hardcoded 'objectClass=' , and in other cases is hardcoded ('objectClass='). I supose that at least the version without parentesi is unsafe, depending on the ldap server. And what I still don't understand is why if I type ('objectClass=*') in the field, it doesn't work. Anyway thanks for all. I think that moodle is a great system! Victor
Hide
Iñaki Arenaza added a comment -

There is certainly a mix of syntax, and it seems both OpenLDAP, eDirectory and Active Directory are quite permissive with LDAP filter syntax. Otherwise more people would have had trouble in the past with this.

The Right Way(tm) to write a LDAP filter is enclosing it in parentheses (you can see RFC 4515/2254). So I'm going to change all of the ocurrences to make them RFC compliant.

As to why there are places where we use $this->config->objectclass and others where we use '(objectClass=*)' is because we are interested in different data, so we use different filters.

As a last remark, ('objectClass=*') is not a valid filter (in the sense that doesn't do what you want, not that its syntax is invalid). You don't have to use simple quotes in the filter. Otherwise you are saying you are interested in an attribute called 'objectClass (which obviously doesn't exist) with a value of anything followed by a single quote.

Saludos. Iñaki.

Show
Iñaki Arenaza added a comment - There is certainly a mix of syntax, and it seems both OpenLDAP, eDirectory and Active Directory are quite permissive with LDAP filter syntax. Otherwise more people would have had trouble in the past with this. The Right Way(tm) to write a LDAP filter is enclosing it in parentheses (you can see RFC 4515/2254). So I'm going to change all of the ocurrences to make them RFC compliant. As to why there are places where we use $this->config->objectclass and others where we use '(objectClass=*)' is because we are interested in different data, so we use different filters. As a last remark, ('objectClass=*') is not a valid filter (in the sense that doesn't do what you want, not that its syntax is invalid). You don't have to use simple quotes in the filter. Otherwise you are saying you are interested in an attribute called 'objectClass (which obviously doesn't exist) with a value of anything followed by a single quote. Saludos. Iñaki.
Hide
Iñaki Arenaza added a comment -

Fixed in CVS (1.8, 1.9 and HEAD).

Thanks a lot for the bug report!

Saludos. Iñaki.

Show
Iñaki Arenaza added a comment - Fixed in CVS (1.8, 1.9 and HEAD). Thanks a lot for the bug report! Saludos. Iñaki.

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: