Moodle
  1. Moodle
  2. MDL-15799

LDAP - user data mapping doesn't work

    Details

    • Type: Bug Bug
    • Status: 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
    • Rank:
      31272

      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 added a comment -

        thanks for volunteering

        Show
        Petr Škoda 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

          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: