The $user object that gets passed to _ldapdata_user_login comes from, you guessed it, user_load(). This means that the mail attribute in the $user object has already been updated by _ldapdata_user_load (line 219). So whenever _ldapdata_user_login gets run and it compares the $user->mail to a result from LDAP (line 261), they are always the same.

Comments

miglius’s picture

Assigned: Unassigned » miglius
Status: Needs review » Fixed

I have fixed this issue by not changing $user->mail value to ldap mail attribute at the user load time. Then the mail is updated and saved to drupal at the login.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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

yoho’s picture

We have a problem on our server because of this patch : the mail attribute is not loaded at all by drupal when viewing a user profile (including its own).

My own user account has a "mail" attribute but I can't see it in my profile. I don't quite understand this bug : if _ldapdata_user_load is not supposed to load the mail attribute from LDAP, which function is responsible for doing so ?

yoho’s picture

Status: Closed (fixed) » Active

On a sidenote, I think this is more or less linked to this bug : http://drupal.org/node/355053

miglius’s picture

Status: Active » Needs review
StatusFileSize
new293 bytes

I believe that the mail data is pulled from the LDAP when user authenticates and is saved as drupal mail attribute if the sync is configured. However I noticed that gobal $user object is not updated at this stage.

Can you try attached patch to see if it solves your issues?

yoho’s picture

Nope, doesn't solve the problem :(

$mail_attr is correctly set to "mail" but $mail seems to be empty, maybe a problem with retrieveAttributes ?

miglius’s picture

which $mail do you refer to? global $user->mail? At which line?

yoho’s picture

Sorry to answer so late : I refer to the $mail variable in your patch which is assigned the value of $entry[$mail_attr][0]. The last one is empty. I'll try to investigate a bit further.

yoho’s picture

StatusFileSize
new1.08 KB

I think I've found the problem.

My LDAP server is configured so that an anonymous user can bind, but is not able to retrieve entries or attributes (ala Active Directory, although it's an OpenLDAP server) : it just have access to the root DSE.

I have not supplied any credentials in the ldap_data admin pages as I don't like the idea of creating a "super" user for drupal. So when a user is logged in, ldap_data uses the users's credentials.

But when a user is logging in, there is no credentials set (yet), so drupal binds as anonymous to the LDAP and whereas the bind succeeds, the mail attribute can't be read from the user (because of my LDAP server restricted configuration), so it's set to "blank".

To solve the problem, the code shouldn't user the ldap_data binddn, but the "ldap_auth" one (ldap_data requires ldap_auth, so it's still clean). This user account is set (on my configuratio) to a read-only account able to browse the LDAP server, so it should be able to retrieve the mail attribute of all the users.

I attach a proposed patch, review welcome.

miglius’s picture

The ldap_auth module's bindn is used to search for a user in ldap which is going to authenticate against ldap. Why do you assume that in the general case this bind dn has right to read a mail attribute in the ldap?

I wouldn't want to mix permissions and use ldap_auth binddn in the ldap_data module. You should use ldap_data's binddn to retrieve a mail from the ldap.

yoho’s picture

Ok, that's right.

But hook_user() login operation is called before hook_user() authenticate operation (I've tested it). So user credentials are not yet saved in the session variables ($_SESSION*) when hook_user() login is called. That's why _ldapdata_edition returns anonymous credentials and retrieving the mail attribute fails.

So we have two choices :
1) Retrieve the user's mail attribute later in the login process : after hook_user() authenticate has been called (and store it in the DB at that point in time).
2) Use other credentials to retrieve the mail attribute : neither ldapauth's nor ldapdata's one, but a third kind, specified in the admin pages. (This is the heavy solution)

miglius’s picture

Status: Needs review » Postponed (maintainer needs more info)
Issue tags: +ldapdata

1) hook_user() does not have 'authenticate' operation, http://api.drupal.org/api/function/hook_user/6 .
2) Don't understand why ldapdata admin credentials cannot be used to search the ldap. They are there for that.

miglius’s picture

Status: Postponed (maintainer needs more info) » Fixed

The patch #5 is committed.

yoho’s picture

1) Well, I wrote that a long time ago, so I need some time to figure out what I was referring to

2) Because ldapdata is designed so :
A) Either you enter ldapdata credentials in the configuration of the module and ldapdata will ALWAYS use these credentials
B) Either you leave the field blank and ldapdata will use the users's OWN credentials
I've chosen B because A is totally unsecure (at least in my case) : you can't deny or grant permissions to users in the LDAP by using ACLs because they will always have the same rights ldapdata module has... So in case "B" and at the point in time where hook_user() login operation is called, the user is still not fully authenticated and $_SESSION* is empty. The only credentials known at that point in time are the one from ldap_auth module, that's why my patch was using them.

yoho’s picture

Ok, in 1), I was refering to "ldapauth_authenticate" and not hook_user() authenticate, but the problem is the same. In this function, you store ldap credentials into the session variables ($_SESSION*), but unfortunately, this function is called AFTER hook_user() login operation, so these session variables are empty when hook_user() login is called.

miglius’s picture

Here is a list of the functions in question ordered by the time they are called on my site:

ldapauth_user(load,...)
ldapauth_authenticate()
ldapauth_user(load,...)
ldapauth_user(update,...)
ldapauth_user(load,...)
ldapauth_user(after_update,...)
ldapauth_user(login,...)
ldapauth_user(update,...)
ldapauth_user(load,...)
ldapauth_user(after_update,...)

ldapauth_authenticate() is called before hook_user() login operation.

aren cambre’s picture

Status: Fixed » Active

I'm assuming that patch #5 was committed before the 2009-Mar-25 dev release. If so, it's still not working.

I confirmed through Wireshark that Drupal is receiving the mail attribute with a valid email address as one of 89 attributes returned as a response to the searchRequest against the account's DN. This searchRequest is done upon initial login. However, when checking the user's account, the email address field is blank.

miglius’s picture

Status: Active » Postponed (maintainer needs more info)

I have refactored the synchronization bits. Please try again.

aren cambre’s picture

Status: Postponed (maintainer needs more info) » Fixed

I updated to the Mar-30 DEV code, and it works now.

Status: Fixed » Closed (fixed)
Issue tags: -ldapdata

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