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.
| Comment | File | Size | Author |
|---|---|---|---|
| #20 | ldap_servers.functions.inc_.rej_.txt | 845 bytes | El Bandito |
| #17 | 2206539-16.patch | 29.36 KB | johnbarclay |
| #13 | login.png | 13.45 KB | El Bandito |
| #11 | 2206539-11-debug.patch | 24.55 KB | johnbarclay |
| #7 | ldap_user_provision_on_authenticated_server.patch | 22.9 KB | johnbarclay |
Comments
Comment #1
El Bandito commentedThe 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.
I can't claim to really understand the complexities of this module but I'll just keep on digging.
Comment #2
El Bandito commentedI'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.
Comment #3
johnbarclay commentedI'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:
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.
Comment #4
El Bandito commentedI'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 :
none of the subsequent code ever gets to execute.
Hope this helps.
Comment #5
johnbarclay commentedHere'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.
Comment #6
El Bandito commentedJohn
Looking forward to having something to test.
Thanks and good luck
Comment #7
johnbarclay commentedHere 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.
Comment #8
johnbarclay commentedComment #9
johnbarclay commentedComment #10
El Bandito commentedI 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 ).
Comment #11
johnbarclay commentedThe 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
Comment #12
El Bandito commentedThanks John. I'll try it out tomorrow.
Comment #13
El Bandito commentedThe 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
Comment #14
El Bandito commentedSorry, but another side effect of the patch is that when I run Cron I get the following 2 errors :
Comment #15
kenorb commentedComment #16
kenorb commentedComment #17
johnbarclay commentedHere'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.
Comment #18
El Bandito commentedThanks 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 ?
Comment #19
El Bandito commentedActually I'm wrong. The patch didn't apply totally successfully. Hidden ( from me anyway ! ) in the patch output :
Comment #20
El Bandito commentedLooks like the if statement doesn't exist in the 7.x-2.0-beta8 version of the code :
Reject file renamed and attached.
Comment #21
El Bandito commentedI 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.
Comment #22
grahlComment #23
grahlComment #31
grahlI'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.