Hello everyone,

Under the LDAP Authentication configuration I have selected Mixed Mode. The module tells me that "The LDAP authentication is performed only if Drupal authentication fails" but I'm not seeing this behavior. I have a user account in Drupal that I have logged in with before and know works but when the LDAP server becomes unreachable all I get when trying to log in is a white screen. I see no PHP errors in my server logs either. My admin account with ID 1 is still able to log in thankfully.

Here are all the options I have configured:

- Authentication mode: Mixed mode.
- User conflict resolve procedure: Associate local account with the LDAP entry
- Do not store users' passwords during sessions
- Sync LDAP password with the Drupal password

Any Idea whats going wrong?
Thank you!
- Vince

Comments

vincetingey’s picture

Can anyone else replicate this? Is it only my install?

Thanks,
- Vince

vincetingey’s picture

Does anyone have this feature working properly? Can I at least get a confirmation that it SHOULD work?

Thanks,
- Vince

pschopf’s picture

I have the same problem. I guess not many people make use of this feature.

smokris’s picture

Line 548 of ldapauth.module:

      if (!isset($data['ldap_authentified']) || $data['ldap_authentified'] == 0) {

...so, in "mixed mode", local authentication is only attempted if the user doesn't have the "ldap_authentified" attribute set. This attribute appears to only be set for users who were created initially in LDAP who then logged in to Drupal (i.e., without having an account explicitly created within Drupal).

Commenting out this conditional (and its corresponding closing curly brace a few lines down) causes "mixed mode" to work for me --- users can authenticate using either the locally-stored Drupal password, or via LDAP.

vincetingey’s picture

Thanks for finding this out smokris! I took a look at the database and the user table. I found the "ldap_authentified" attribute is set in the large "data" column. Do you know if there would be an easy way of setting the "ldap_authentified" attribute for the users that don't have it set? I'd prefer to not have to hack the module.

I tested creating a user account using Drupal and the LDAP Provisioning module (to create the account in LDAP) and the attribute is set. This is how we will be creating accounts going forward but if I could find an easy way of setting current accounts that did not get created this way to have the "ldap_authentified" attribute that would be best. Too bad its not just a normal column in the user table as that would make this far easier.

smokris’s picture

Category: support » bug
Status: Active » Needs review

+1 for database normalization. No, I don't know an easy way to modify data in serialized columns..

IMO that conditional is erroneous and should be removed from the main distribution, though I'm not sure whether that would have additional unintended consequences. Could a maintainer take a look at this?

qsir1’s picture

I'm having this EXACT same issue as well and am fluent in PHP but do not know the consequences/side-effects of commenting this out. Fix coming soon?

Renee S’s picture

This works for me!

johnbarclay’s picture

Status: Needs review » Closed (won't fix)

The conditional is to check if the same username has already authenticated via ldap. Mixed mode is not intended to let the same username authenticate via ldap and drupal; its for some acounts to use each.

If an account can use both or go back and forth, a number of other design issues would need to be resolved with ldap groups and ldap data.

There is a provision for drupal users to be converted to ldap users in the authentication settings: Associate local account with the LDAP entry

But there is no provision for going the other way or going back and forth.

Renee S’s picture

johnbarclay, I'm confused. We need to create a drupal account for users, but we want them authenticating via LDAP unless they're a certain type of guest (who lacks an LDAP entry). Before applying this fix, if an account was listed in Drupal, it would never check the LDAP if local authentication failed. With this fix, it will check local, and if local fails, try LDAP. It's not about letting somebody go back and forth, it's about holding both local and LDAP accounts in a single user database.

johnbarclay’s picture

Version: 6.x-1.0-beta2 » 6.x-1.x-dev
Status: Closed (won't fix) » Active

by commenting out
if (!isset($data['ldap_authentified']) || $data['ldap_authentified'] == 0) {

a user could be granted drupal roles via their ldapgroup query. Then their ldap account could be removed. Then they could logon with their drupal account and have their same roles. They would simply need to request a new password.

This is the issue with an ldap provisioned drupal user becoming an non ldap provisioned drupal user.

But it still a bug if its not working the way the UI says it should.

Renee S’s picture

Ah, that's true. But I can't see any other way of having both ldap and non-ldap users, except perhaps having a checkbox to exempt a user from the LDAP stuff.

cgmonroe’s picture

Status: Active » Closed (works as designed)

Marking fixed works as designed because it does allow local Drupal users to exist and be authenticated along with LDAP users. It is by design that existing users marked as "ldap authenticated" do not get authenticated against the database.

The UI description for the password sync now reads:

It might introduce security issues in the Mixed mode since after the deletion of the LDAP account, the Drupal user will still exist and may be able to login to Drupal with his password if ldapauth is disabled.

Renee S’s picture

Then there's some other bug here - the described behaviour is that mixed mode doesn't work, because the user will always exist in the Drupal database, but we want them authenticating via LDAP if they should be doing that. Currently mixed mode (without that line commented out) simply doesn't fail-over to check one if the other doesn't work. If we want it to work the other way it needs to be reversed from how it works now - check ldap, fail over to Drupal.

cgmonroe’s picture

This is not a bug... it is working as designed. You may have users who authenticate against the database and users who authenticate against LDAP. That is what Mixed mode means by LDAP authentication done only if Drupal authentication fails. In addition, the password "sync" option clearly states that this is for OTHER modules that might need it.

If what you are looking for is to have fail over support, then this is a feature request and a new issue with details of why this is important and how it might work (and patches to do it!) should be opened. This should include some thoughts as to how ldapdata will work if the LDAP is down and the ldap user authenticates via the DB, because it will want to retrieve info from the unavailable LDAP server.

IMHO, if LDAP is your enterprise user authority, then it should properly be set up with a replicated backup (e.g. secondary domain controller). Fail over should be supplied by adding the backup server to ldapauth. In the new dev version, you can define a PUID like objectGUID (AD) or entryUUID (OpenLDAP, Apache DS, and others) that will allow users authenticated by the fail over server to properly be mapped to their Drupal ids.

Renee S’s picture

"That is what Mixed mode means by LDAP authentication done only if Drupal authentication fails."

The bug, as reported, is that this is not happening.

I'm not sure what you mean about LDAP and fail-over - that's not remotely related. What we want is users who don't exist in the LDAP but do exist in Drupal to be able to log in. That wasn't happening. Another thread indicated that a bunch of other changes to this mechanism have been made, so this may have inadvertently be fixed. I will try it.

johnbarclay’s picture

I see what you are both getting at. Perhaps this is a documentation issue. @Reinette maybe you could update the documentation some. I'll explain how the code works and you can update the documentation at: http://drupal.org/node/118092 and maybe submit a patch to the user interface.

There are two classes of users from the perspective of ldapauth: 1) "LDAP Authentified" (authenticated and identified) which are users who at some point authenticated via ldap and were associated with ldap and 2) "local" accounts.

Once an account is "ldap authentified", they can only log in with ldap credentials. This is your case when you use your account when the ldap server is down.

What cgmonroe was getting at is that mixed mode is not designed for a failover situation; its designed for "local" users to authenticate against their credentials stored in drupal and "ldap authentified" users to authenticate against drupal.

The relevant code is in http://drupalcode.org/project/ldap_integration.git/blob_plain/refs/heads... and it does not even try local credentials (user_authenticate($form_values)) unless the account is not ldap authentified ( if (!isset($data['ldap_authentified']) || $data['ldap_authentified'] == 0) {)

  if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED) {
    // Authenticate local users first.
    $result = db_query("SELECT name, data FROM {users} WHERE name='%s'", $name);
    if ($row = db_fetch_array($result)) {
      $data = unserialize($row['data']);
      if (!isset($data['ldap_authentified']) || $data['ldap_authentified'] == 0) {
        // A local user with same name exists - authenticate that user.
        if (user_authenticate($form_values)) {
          // Nullify global ldap resource for good measure.
          unset($_ldapauth_ldap);
          return;
        }
      }
    }
  }

also...in the drupal 7 version, it does behave as a failover (see http://www.gliffy.com/publish/2362004/) but only because of bug in core. In drupal 8 I would hope it would not be the case. The failover isn't useful since there is likely a random password stored in the local account in most use cases.

hope this helps more than it muddies things.

Renee S’s picture

Thanks, johnbarclay, very helpful. That's it exactly.

Re failover, we don't *want* people able to log in with their LDAP credentials if LDAP isn't available; our security policy precludes their credentials being stored in Drupal at all. That would be Bad. But we do have a few oddities that require a local account for various purposes. They won't be in our LDAP because they aren't part of our organization.