Hello,

I found a bug on the configuration page in the "Role Mapping" section. When searching for LDAP available tokens (LDAP [cas:ldap:?] An LDAP attribute of the CAS user. Available tokens.), drupal returns "No LDAP attributes were returned by the LDAP server." (see attachment).

The bug is produced by a non unserialized variable in the LDAPServer class (ldap > ldap_servers > LdapServer.class.php) at line 1085 :
$basedns = (is_array($this->basedn)) ? $this->basedn : array();

at this point $this->basedn is not unserialized. The unserialization of the variable solves the bug.

Regards, FDG

CommentFileSizeAuthor
#7 serialized-issue.patch706 bytesGagaro
Capture.PNG37.97 KBfranckdg
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bfroehle’s picture

FDG: Any idea who should be unserializing the variable? Is it something with our code or is it a bug with the LDAP module?

franckdg’s picture

The initDerivedProperties method @ line 186 of the LDAP server class is supposed to do the job.

At line 81 of the _cas_ldap_attributes method in the cas_ldap.module file, you retrieve a ldapserver object, I don't clearly understood where this object is instanciated (I'm new in drupal and I'd like to understand how you registered variables to access it with variable_get). Perhaps the initDerivedProperties method is not called at this moment, underlaying the unserialize state.

Franck DG

Olarin’s picture

Regarding your question about variables: you don't have to register the Drupal variables that are accessed with drupal_get. If you call variable_set with the name of a variable that doesn't exist yet, it gets created. With variable_get, you can use the second parameter specify a default value to pass back if the variable name you specify doesn't exist (if you don't specify it, you'll just get NULL back for a nonexistent variable). In this case, _cas_ldap_attributes specifies an empty array to get back for $cas_attributes if the variable 'cas_attributes' doesn't exist, so the if clause on the next line will evaluate to true and the function will just return an empty array.

bfroehle’s picture

Title: "No LDAP attributes were returned by the LDAP server." when searching for available tokens in ldap » ldap_server_get_servers: $this->basedn is not unserialized
Project: CAS Attributes » Lightweight Directory Access Protocol
Version: 7.x-1.0-rc1 » 7.x-2.x-dev
Component: CAS Attributes » Code

Franck: Thanks for looking up the bits of code. We're just using the API that the LDAP module provides. We call the provided ldap_server_get_servers() function which should take care of all of the necessary unserialization.

Personally I've had better luck using the 7.x-1.x version of the LDAP module --- you may want to consider that as a temporary measure.

I'm moving this issue over to the LDAP queue, since that's where the bug would be. I've flagged it as version 7.x-2.x-dev, but you should probably chime in if you are using a different version of that module.

Gagaro’s picture

Version: 7.x-2.x-dev » 7.x-2.0-beta3

Hello,

I have the same issue using the 7.x-2.0-beta3 version of the module.

It happens when trying to login with a user located in the server's LDAP. The LDAP Authenticate module calls userUserNameToExistingLdapEntry() to check if the user does exist in the server's LDAP. $basedn being unserialized in this function, the user is never found.

Thus, the authentication of a user to the server's LDAP is impossible.

I am not sure how to properly solve this bug as I don't know this module well enough. I have just added the unserialize calls in the userUserNameToExistingLdapEntry() function for now.

EDIT:

I have actually found why the variable is not unserialized. $basedn is actually equals to:
's:54:"a:1:{i:0;s:36:"ou=People,dc=test-hits-ucopia,dc=net";}";'
Which is, once unserialized:
'a:1:{i:0;s:36:"ou=People,dc=test-hits-ucopia,dc=net";}'

$basedn is actually serialized one time too many !

Another strange thing is that activating Chaos Tools Suite solve this problem. $basedn is serialized juste once (or, most probably, deserialized once before). I keep digging into the module to try and solve this.

EDIT 2:

ctools_export_load_object() does appears to unserialize the data. The problem shouldn't be solved there though, as a check is made in initDerivedProperties() to make sure the variable is not already unserialized. The problem should be solved during the save to the database. I'm going to take a look to this side.

EDIT 3:

I found the issue and I'm writing a patch. All explanations coming soon !

johnbarclay’s picture

Priority: Normal » Major
Gagaro’s picture

Status: Needs review » Patch (to be ported)
FileSize
706 bytes

So, the thing is basedn is already described as serialized in the db schema:

LdapServerAdmin.class.php l. 758

'basedn' => array(
        'form' => array(
          'fieldset' => 'users',
          '#type' => 'textarea',
          '#cols' => 50,
          '#rows' => 6,
          '#title' => t('Base DNs for LDAP users, groups, and other entries.'),
          '#description' => '<div>' . t('What DNs have entries relavant to this configuration?        
            e.g. ou=campus accounts,dc=ad,dc=uiuc,dc=edu                                 
            Keep in mind that every additional basedn likely doubles the number of queries.  Place th\
e                                                                                                     
            more heavily used one first and consider using one higher base DN rather than 2 or more l\
ower base DNs.                                                                                        
            Enter one per line in case if you need more than one.') . '</div>',
        ),
        'schema' => array(
          'type' => 'text',
          'serialize' => TRUE,
        ),
      )

The function drupal_write_record() automatically serializes the variable described as serialized (API). But the variable is already serialized before:

LdapServerAdmin.class.php l. 109

if (is_scalar($this->{$property_name})) {
    $values->{$field_name_lcase} = $this->{$property_name};
}
else {
    $values->{$field_name_lcase} = serialize($this->{$property_name});
}

So the variable is serialized twice ! This also explained why CTools deserializes automatically the variable.

The solution is either to remove the serialized information from the schema definition, or to remove the serialization of every non-scalar variable. I personally think that the description of the variables is more important, that's why I chose to remove the serialization before the save to the database. Every data needing serialization before storage into the database must thus be defined with "serialize" to true in the schema definition.

My patch is attached.

EDIT: Of course the servers configurations need to be saved again in order to take the modification into account.

Gagaro’s picture

Version: 7.x-2.0-beta3 » 7.x-2.x-dev
Status: Active » Needs review

Used the wrong status, sorry !

John Franklin’s picture

Status: Patch (to be ported) » Needs review

Patch works here. Fixes what I would consider to be a 'critical' bug with the module.

johnbarclay’s picture

this is committed to 7,x-2.x-dev with an update hook to unserialize anything that is 2x serialized from the past. @Gagaro: appreciate the articulation of the problem; this one has been floating around a while.

Please test with the update hook.

johnbarclay’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.