When I select the LDAP provisioning option 'Use server which performed the authentication' option although the account is provisioned and manually mapped attributes are successfully transferred from LDAP to the Drupal account, the 'field.ldap_user_current_dn' is not being populated. If I switch back to a specific server it works fine.

I want to access the dn from a hook_user_insert() function so its absence is a problem for me. I have no idea whether it will cause any other issues ?

I haven't yet got my head around the flag system that provisioning uses but the problem seems to stem from the call from the 'entryToUserEdit' function thus :

 if ($this->isSynched('[field.ldap_user_current_dn]', $prov_events, $direction)) {
      $edit['ldap_user_current_dn'][LANGUAGE_NONE][0]['value'] = $ldap_user['dn'];
    }

The IsSynched function is returning FALSE for all the attributes that aren't manually mapped.

Happy to help debug if I can.

Comments

El Bandito’s picture

The problem seems to be that the synchMapping array has no key 'prov_events' excepting for for the manually mapped attributes, so in every other case $result is FALSE.

  public function isSynched($attr_token, $prov_events, $direction) {

    $result = (boolean)(
      isset($this->synchMapping[$direction][$attr_token]['prov_events']) &&
      count(array_intersect($prov_events, $this->synchMapping[$direction][$attr_token]['prov_events']))
    );

I can't claim to really understand the complexities of this module but I'll just keep on digging.

El Bandito’s picture

StatusFileSize
new94.73 KB

I'm not a programmer so I've struggled really hard to get my head around the module, but so far I haven't cracked this one. In fact I realise that this may not even be a bug, but an intended behaviour.

However at the end of the setSynchMapping() function $this->syncMapping looks as per the attached debug. And the properties with 'prov_events' elements such as field_given_name sync fine, whilst all the basic ldap properties such as ldap_user_current_dn don't. This is because the isSynched() function always returns FALSE for the basic ldap properties as they don't have the prov_events elements.

However I have failed to unravel why they don't - and if they are meant to .... despite my best efforts.

Any pointers appreciated.

johnbarclay’s picture

StatusFileSize
new26.34 KB

I'm thinking this through out loud here. I looks like LdapUserConf.class.php on line 424 is setting the server id ($sid) in error before it calls drupal_alter('ldap_user_attrs_list', $available_user_attrs[$direction], $params);

So ldap_servers_ldap_user_attrs_list_alter() doesn't have a server id and doesn't bother to populate field.ldap_user_current_dn and others.

This should be an easy fix, provided a chicken and egg scenario doesn't exist.

Here's some background on how this part of the module works:

The basic idea with the attribute list for synching is populated via hook_ldap_user_attrs_list_alter().

The flow is like this:

  1. LdapUserConf.class.php -> setSynchMapping calls drupal_alter('ldap_user_attrs_list', $available_user_attrs[$direction], $params);
  2. from this, drupal calls all implementations of hook_ldap_user_attrs_list_alter(&$available_user_attrs, &$params). In particular:
  3. - ldap user module: ldap_user_ldap_user_attrs_list_alter() adds all the fields required by the ldap user module ([property.name], ...) and all the ones explicitly mapped in the ldap user config).
  4. - ldap server module: ldap_servers_ldap_user_attrs_list_alter().

ldap_servers_ldap_user_attrs_list_alter should add the [field.ldap_user_current_dn] around line 424, but it doesn't appear to be doing so for you.

      'name' => t('Field: Most Recent DN', $tokens),
      'configurable_to_drupal' => 0,
      'configurable_to_ldap' => 0,
      'source' => '[dn]',
      'notes' => 'not configurable',
      'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
      'enabled' => TRUE,
      'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER),
      'config_module' => 'ldap_servers',
      'prov_module' => 'ldap_user',
El Bandito’s picture

I've just put some debug code into function ldap_servers_ldap_user_attrs_list_alter() and then attempted logon using a user account unkown to Drupal but within LDAP. All the invocations of the function have $params['ldap_server'] set to FALSE. As the function starts :

if (isset($params['ldap_server']) && $params['ldap_server']) {
    $ldap_server = $params['ldap_server'];
  }
  else {
    return; // without a server id, ldap_servers module has nothing to offer
  }

none of the subsequent code ever gets to execute.

Hope this helps.

johnbarclay’s picture

Here's how I'm approaching this fix:

0. alter constructor for ldapUser to check for drupal account provision server being based on user's authenticing ldap server
1. make sure all new instances of LdapUserConf($drupal_user) have the current authenticated drupal user account passed into them when relevant so correct ldap_server can be used for provisioning.
2. Likewise, make sure all calls to ldap_user_conf($type = NULL, $reset = FALSE, $sid = NULL) include drupal user when relevant.
$sid = $ldap_user['sid'];
3. make sure drupal_alter('ldap_attributes_needed') has $params['sid'] set based on user so correct server conf can be used.

finally:
-- make sure _ldap_user_orphans is using correct ldap_user_conf for a given user
-- and ldap_user_form_register_form_submit2 is using correct ldap_user_conf for a given user

This approach keeps itself within ldap user module instead of overriding server selection universally.

El Bandito’s picture

John

Looking forward to having something to test.

Thanks and good luck

johnbarclay’s picture

Title: 'field.ldap_user_current_dn' field not populating » LDAP User: Not objeying configuration of use authenticing ldap server for provisioning and synching
Version: 7.x-2.0-beta8 » 7.x-2.x-dev
StatusFileSize
new22.9 KB

Here is a patch for this issue. It basically tries to use the user's authenticating server when ldap user option is set that way. I'm working on a better dev environment to test this, but please give it a try.

johnbarclay’s picture

Issue tags: +D7+stable+release+blocker
johnbarclay’s picture

Issue tags: -D7+stable+release+blocker +D7 stable release blocker
El Bandito’s picture

I successfully managed to apply the patch. I have 2 enabled LDAP servers, and provisioning is set to 'Use server which performed the authentication'. Unfortunately it results in the following message when I try to logon to the second domain I added :

"Server Error: Failed to create Drupal user account for ucvtest"

There is also a watchdog error generated saying :

"Failed to find or create ucvtest on logon."

Logging on with a user via the first domain still works.

If I swap all the code back to the beta8 version the login for exactly the same user is successful ( although the provisioning is not of course ).

johnbarclay’s picture

Title: LDAP User: Not objeying configuration of use authenticing ldap server for provisioning and synching » LDAP User: Not objeying configuration of user authenticating ldap server for provisioning and synching
StatusFileSize
new24.55 KB

The first question is if the correct ldap server is being attemped for provisioning. This value should be stored in $auth_conf->ldapUser->userAuthenticatedSid after authenticating and properly retrieved from $ldapUser->drupalAcctProvisionServerSid($account)

Attached is the same patch with some debugging statements 2206539-11-debug.patch (all tagged with test#2206539) that will indicate if the sid is correct throughout the provisioning process.

1. ldap_authentication.inc line 148 _ldap_authentication_user_login_authenticate_validate() is called.
-- on line 235, ldap_authentication_test_credentials is called. (
---- in ldap_authentication_test_credentials, line 682 the server id authenticated on is set: $auth_conf->ldapUser->userAuthenticatedSid = $ldap_server->sid; (test#2206539.1)
-- after call test#2206539.2
2. ldap_authentication.inc line 460 or so, $auth_conf->ldapUser->provisionDrupalAccount(NULL, $user_edit, NULL, TRUE) is called. (test#2206539.3)
-- early on in this function it tries to determine the appropriate ldap server sid with a call to drupalAcctProvisionServerSid

Can you check and see if the correct server id (sid) is derived in this proces

El Bandito’s picture

Thanks John. I'll try it out tomorrow.

El Bandito’s picture

StatusFileSize
new13.45 KB

The patch applied successfully but with a strange result. Now when I click on the log in button having entered creds for a user that does not yet have a Drupal account the browser thinks it is downloading a file and a download dialog opens ( attached ).

I then reversed the patch and can immediately log in using the non-existent account.

Happy to try again.

Thanks

El Bandito’s picture

Sorry, but another side effect of the patch is that when I run Cron I get the following 2 errors :

Notice: Object of class LdapServer could not be converted to int in LdapUserConf->drupalAcctProvisionServerSid() (line 30 of C:\www\our-people-dev.falmouth.ac.uk\sites\all\modules\ldap\ldap_user\LdapUserConf.class.php).

Recoverable fatal error: Object of class LdapServer could not be converted to string in LdapUserConf->drupalAcctProvisionServerSid() (line 31 of C:\www\our-people-dev.falmouth.ac.uk\sites\all\modules\ldap\ldap_user\LdapUserConf.class.php).

kenorb’s picture

Status: Active » Needs review
kenorb’s picture

Title: LDAP User: Not objeying configuration of user authenticating ldap server for provisioning and synching » LDAP User: Not obeying configuration of user authenticating ldap server for provisioning and synching.
johnbarclay’s picture

StatusFileSize
new29.36 KB

Here's a patch that works with the logon and creation of the account, obeying the authenticating server as the provisioning server. It has lots of dpm(s) so testing requires anonymous users be able to use devel. It still needs work as it appears to not record the provisioning SID in the user's account. I'll try to get back to that as well as remove the dpm() calls, but please test to make sure it creates and logs on users in a multiple server environement.

El Bandito’s picture

Thanks John. I've successfully installed the patch and created a setup that authenticates against 2 separate LDAP domains. The Drupal user accounts are successfully created whichever of the 2 domains the authentication occurs against. The manually mapped attributes specified at 'admin/config/people/ldap/user' are successfully provisoned into the Drupal account whichever the source domain. However the hidden fields such as 'ldap_user_current_dn' remain empty in the case of both domains.

Does this help you ?

El Bandito’s picture

Actually I'm wrong. The patch didn't apply totally successfully. Hidden ( from me anyway ! ) in the patch output :

Patching file `ldap_servers/ldap_servers.functions.inc' using Plan A...
Hunk #1 FAILED at 380.
1 out of 1 hunk FAILED -- saving rejects to ldap_servers/ldap_servers.functions.inc.rej

El Bandito’s picture

StatusFileSize
new845 bytes

Looks like the if statement doesn't exist in the 7.x-2.0-beta8 version of the code :

    function ldap_pear_hex2asc($string) {
        $string = preg_replace_callback(
          "/\\\([0-9A-Fa-f]{2})/",
          function ($m){
            return chr(hexdec($m[1]));
          },
          $string);

        return $string;
    }

Reject file renamed and attached.

El Bandito’s picture

I have now run the patch from #17 against ldap-7.x-2.x-dev and it applied successfully. However when logging on a string of errors ( undefined variable m ) were generated by the following statement in ldap_servers.functions.inc.

$f = create_function('$m', "return chr(hexdec($m[1]));");

I reverted function ldap_pear_hex2asc() to the version in ldap-7.x-2.x-dev and it stopped the undefined variable errors ( I'm running PHP 5.3.14 ).

More importantly although logon was succesful none of the ldap fields ( ldap_user_puid_sid, ldap_user_puid, ldap_user_current_dn etc. ) were populated. I tried again specifying the correct and specific server for 'LDAP Servers Providing Provisioning Data' and still none of the ldap fields were populated.

Happy to try and further suggestions, tests, patches.

grahl’s picture

Status: Needs review » Needs work
grahl’s picture

Status: Needs work » Needs review

The last submitted patch, 7: ldap_user_provision_on_authenticated_server.patch, failed testing.

The last submitted patch, 7: ldap_user_provision_on_authenticated_server.patch, failed testing.

The last submitted patch, 7: ldap_user_provision_on_authenticated_server.patch, failed testing.

The last submitted patch, 11: 2206539-11-debug.patch, failed testing.

The last submitted patch, 11: 2206539-11-debug.patch, failed testing.

The last submitted patch, 11: 2206539-11-debug.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 17: 2206539-16.patch, failed testing.

grahl’s picture

Status: Needs work » Closed (outdated)

I'm marking this outdated since the patch no longer applies and it's unlikely that all points are still valid. We also fixed a bug that could be related in #2959201: isDrupalAcctProvisionServer not working properly.

Please reopen if you are still affected and can provide more information.