Hi,
I had to configure a (single) ldap server with binding method being :
"Anonymous Bind for search, then Bind with Users Credentials. Searches for user DN then uses users' entered credentials to bind to LDAP. This is only useful for modules that work during user logon such as ldap authentication and ldap authorization. The users dn must be discovered by an anonymous search for this option to work." which is represented as 4 in code.

When using this binding method the test will be a success (even though throwing this error in the middle of testing : Failed to bind to server. ldap error #49 Invalid credentials).
But the login is not working at all and throw something like "failed to bind to ldap server".
I found after debugging that in the first step of searching for the DN (so anonymous binding), the binding is not anonymous but will have a NULL username and the current logged in user's password.
I made a very dirty but working patch, I do not knew at all the whole code so I just don't know how to make it "sexy".

Modifications :

ldap_authentification.inc line 236 :

    $bind_success = FALSE;
    if ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_SERVICE_ACCT ||
        $ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON) {
      $bind_success = ($ldap_server->bind() == LDAP_SUCCESS);
    }
    elseif ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON_USER) {
	$bind_success = ($ldap_server->bind(NULL, NULL, TRUE) == LDAP_SUCCESS);
    }

LdapServer.class.php line 249 :

  function bind($userdn = NULL, $pass = NULL, $anonQuery = FALSE) {
    $userdn = ($userdn != NULL) ? $userdn : $this->binddn;
    $pass = ($pass != NULL) ? $pass : $this->bindpw;
    // Ensure that we have an active server connection.
    if (!$this->connection) {
      watchdog('ldap', "LDAP bind failure for user %user. Not connected to LDAP server.", array('%user' => $userdn));
      return LDAP_CONNECT_ERROR;
    }

    if ($anonQuery) {
	if (@!ldap_bind($this->connection)) {
	  watchdog('ldap', "LDAP bind failure for user %user. Error %errno: %error", array('%user' => $userdn, '%errno' => ldap_errno($this->connection), '%error' => ldap_error($this->connection)));
	  return ldap_errno($this->connection);
	}

    }
    else {
	if (@!ldap_bind($this->connection, $userdn, $pass)) {
	  watchdog('ldap', "LDAP bind failure for user %user. Error %errno: %error", array('%user' => $userdn, '%errno' => ldap_errno($this->connection), '%error' => ldap_error($this->connection)));
	  return ldap_errno($this->connection);
	}
    }

    return LDAP_SUCCESS;
  }
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

miscul’s picture

Status: Active » Needs work
johnbarclay’s picture

Title: Authenfication : login impossible with bind_method = 4 » Authentication : login impossible with bind_method = 4

Thanks. Method 4 is quite common, so this definately major. Do you mind making a traditional patch? that will allow me to see it better while travelling and let others try it out without hand picking the code.

miscul’s picture

Patches attached, I do not master this so maybe I did it wrong ... tell me if it is.
The goal was to force the first step of the login, searching for the DN, to be anonymous.

johnbarclay’s picture

Title: Authentication : login impossible with bind_method = 4 » LDAP Authentication : login impossible with bind_method = 4
Status: Needs work » Needs review

Patch addresses issue correctly. I changed it a bit in LdapServer.class.php, but basically functions the same. I'm leaving this as needs review for now, but its committed to 7.x-1.x-dev.

  function bind($userdn = NULL, $pass = NULL, $anon_bind = FALSE) {

    // Ensure that we have an active server connection.
    if (!$this->connection) {
      watchdog('ldap', "LDAP bind failure for user %user. Not connected to LDAP server.", array('%user' => $userdn));
      return LDAP_CONNECT_ERROR;
    }
    if ($anon_bind) {
      if (@!ldap_bind($this->connection)) {
        watchdog('ldap', "LDAP anonymous bind error. Error %errno: %error", array('%errno' => ldap_errno($this->connection), '%error' => ldap_error($this->connection)));
        return ldap_errno($this->connection);
      }
    }
    else {
      $userdn = ($userdn != NULL) ? $userdn : $this->binddn;
      $pass = ($pass != NULL) ? $pass : $this->bindpw;
      if (@!ldap_bind($this->connection, $userdn, $pass)) {
        watchdog('ldap', "LDAP bind failure for user %user. Error %errno: %error", array('%user' => $userdn, '%errno' => ldap_errno($this->connection), '%error' => ldap_error($this->connection)));
        return ldap_errno($this->connection);
      }
    }

    return LDAP_SUCCESS;
  }
johnbarclay’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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