You are here

function ldap_authentication_test_credentials in Lightweight Directory Access Protocol (LDAP) 7.2

Same name and namespace in other branches
  1. 8.2 ldap_authentication/ldap_authentication.inc \ldap_authentication_test_credentials()
1 call to ldap_authentication_test_credentials()
_ldap_authentication_user_login_authenticate_validate in ldap_authentication/ldap_authentication.inc
User form validation will take care of username, pwd fields this function validates ldap authentication specific.

File

ldap_authentication/ldap_authentication.inc, line 543
Ldap_authentication helper functions.

Code

function ldap_authentication_test_credentials($auth_conf, $sso_login, $authname, $password, &$watchdog_tokens) {
  $detailed_watchdog_log = variable_get('ldap_help_watchdog_detail', 0);
  $authentication_result = LDAP_AUTHENTICATION_RESULT_FAIL_GENERIC;
  $ldap_user = FALSE;
  $ldap_server = NULL;
  foreach ($auth_conf->enabledAuthenticationServers as $sid => $ldap_server) {
    $watchdog_tokens['%sid'] = $sid;
    $watchdog_tokens['%bind_method'] = $ldap_server->bind_method;
    if ($detailed_watchdog_log) {
      watchdog('ldap_authentication', '%username : Trying server %sid where bind_method = %bind_method', $watchdog_tokens, WATCHDOG_DEBUG);
    }

    // #1 CONNECT TO SERVER.
    $authentication_result = LDAP_AUTHENTICATION_RESULT_FAIL_GENERIC;
    $result = $ldap_server
      ->connect();
    if ($result != LDAP_SUCCESS) {
      $authentication_result = LDAP_AUTHENTICATION_RESULT_FAIL_CONNECT;
      $watchdog_tokens['%err_msg'] = $ldap_server
        ->errorMsg('ldap');
      if ($detailed_watchdog_log) {
        watchdog('ldap_authentication', '%username : Failed connecting to %sid.  Error: %err_msg', $watchdog_tokens, WATCHDOG_DEBUG);
      }
      $watchdog_tokens['%err_msg'] = NULL;

      // Next server, please.
      continue;
    }
    elseif ($detailed_watchdog_log) {
      watchdog('ldap_authentication', '%username : Success at connecting to %sid', $watchdog_tokens, WATCHDOG_DEBUG);
    }
    $bind_success = FALSE;
    if ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_SERVICE_ACCT) {
      $bind_success = $ldap_server
        ->bind(NULL, NULL, FALSE) == LDAP_SUCCESS;
    }
    elseif ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON || $ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON_USER) {
      $bind_success = $ldap_server
        ->bind(NULL, NULL, TRUE) == LDAP_SUCCESS;
    }
    elseif ($sso_login) {
      watchdog('ldap_authentication', 'Trying to use SSO with LDAP_SERVERS_BIND_METHOD_USER bind method.', $watchdog_tokens, WATCHDOG_ERROR);
    }
    elseif ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_USER && $sso_login == FALSE) {

      // With sso enabled this method of binding isn't valid.
      foreach ($ldap_server->basedn as $basedn) {
        $search = [
          '%basedn',
          '%username',
        ];
        $transformname = $ldap_server
          ->userUsernameToLdapNameTransform($authname, $watchdog_tokens);
        $replace = [
          $basedn,
          $transformname,
        ];
        $userdn = str_replace($search, $replace, $ldap_server->user_dn_expression);
        $bind_success = $ldap_server
          ->bind($userdn, $password, FALSE) == LDAP_SUCCESS;
        if ($bind_success) {
          break;
        }
      }
    }
    else {
      watchdog('ldap_authentication', 'No bind method set in ldap_server->bind_method in _ldap_authentication_user_login_authenticate_validate.', $watchdog_tokens, WATCHDOG_ERROR);
    }
    if (!$bind_success) {
      if ($detailed_watchdog_log) {
        $watchdog_tokens['%err_text'] = $ldap_server
          ->errorMsg('ldap');
        watchdog('ldap_authentication', '%username : Trying server %sid where bind_method = %bind_method.  Error: %err_text', $watchdog_tokens, WATCHDOG_DEBUG);
        $watchdog_tokens['%err_text'] = NULL;
      }
      $authentication_result = $ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_USER ? LDAP_AUTHENTICATION_RESULT_FAIL_CREDENTIALS : LDAP_AUTHENTICATION_RESULT_FAIL_BIND;

      // If bind fails, onto next server.
      continue;
    }

    // #3 DOES USER EXIST IN SERVER'S LDAP.
    if ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON_USER) {
      $ldap_user = $ldap_server
        ->userUserNameToExistingLdapEntry($authname);
    }
    elseif ($sso_login) {
      $ldap_user = $ldap_server
        ->userUserNameToExistingLdapEntry($authname);
      if ($detailed_watchdog_log) {
        $watchdog_tokens['%result'] = var_export($result, TRUE);
        watchdog('ldap_authentication', '%username : attempting single sign-on
          login in bind_method of LDAP_SERVERS_BIND_METHOD_USER. Result of
          userUserNameToExistingLdapEntry: <pre>%result</pre>', $watchdog_tokens, WATCHDOG_DEBUG);
      }
    }
    else {
      $ldap_user = $ldap_server
        ->userUserNameToExistingLdapEntry($authname);
    }
    if (!$ldap_user) {
      if ($detailed_watchdog_log) {
        $watchdog_tokens['%err_text'] = $ldap_server
          ->errorMsg('ldap');
        watchdog('ldap_authentication', '%username : Trying server %sid where bind_method = %bind_method.  Error: %err_text', $watchdog_tokens, WATCHDOG_DEBUG);
        $watchdog_tokens['%err_text'] = NULL;
      }
      if ($ldap_server
        ->ldapErrorNumber()) {
        $authentication_result = LDAP_AUTHENTICATION_RESULT_FAIL_SERVER;
        break;
      }
      $authentication_result = LDAP_AUTHENTICATION_RESULT_FAIL_FIND;

      // Next server, please.
      continue;
    }
    $watchdog_tokens['%dn'] = $ldap_user['dn'];
    $watchdog_tokens['%mail'] = $ldap_user['mail'];

    /**
     * #4 CHECK ALLOWED AND EXCLUDED LIST AND PHP FOR ALLOWED USERS
     */
    if (!$auth_conf
      ->allowUser($authname, $ldap_user)) {
      $authentication_result = LDAP_AUTHENTICATION_RESULT_FAIL_DISALLOWED;

      // Regardless of how many servers, disallowed user fails.
      break;
    }

    /**
     * #5 TEST PASSWORD
     */
    $credentials_pass = FALSE;
    if ($sso_login) {

      /** If we have $sso_login passed in as true from the fake form state in
       * passed from _ldap_authentication_user_login_sso(), we will be relying
       * on the webserver for actually authenticating the user, either by NTLM
       * or user/password if configured as a fallback. Since the webserver has
       * already authenticated the user, and the web server only contains the
       * user's LDAP user name, instead of binding on the username/pass, we
       * simply look up the user's account in LDAP, and make sure it matches
       * what is contained in the global $_SERVER array populated by the web
       * server authentication.
       */
      $credentials_pass = (bool) $ldap_user;
    }
    elseif ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_USER) {

      /**
       * With user bind method, the only way we can reach this part of the
       * code is when the pw has already been checked and $ldap_user could be
       * loaded, so we're good to go.
       */
      $credentials_pass = TRUE;
    }
    else {
      $credentials_pass = $ldap_server
        ->bind($ldap_user['dn'], $password, FALSE) == LDAP_SUCCESS;
    }
    if (!$credentials_pass) {
      if ($detailed_watchdog_log) {
        $watchdog_tokens['%err_text'] = $ldap_server
          ->errorMsg('ldap');
        watchdog('ldap_authentication', '%username : Testing user credentials on server %sid where bind_method = %bind_method.  Error: %err_text', $watchdog_tokens, WATCHDOG_DEBUG);
        $watchdog_tokens['%err_text'] = NULL;
      }
      $authentication_result = LDAP_AUTHENTICATION_RESULT_FAIL_CREDENTIALS;

      // Next server, please.
      continue;
    }
    else {
      $authentication_result = LDAP_AUTHENTICATION_RESULT_SUCCESS;
      if ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON_USER) {

        // After successful bind, lookup user again to get private attributes.
        $ldap_user = $ldap_server
          ->userUserNameToExistingLdapEntry($authname);
        $watchdog_tokens['%mail'] = $ldap_user['mail'];
      }
      if ($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_SERVICE_ACCT || $ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON_USER) {
        $ldap_server
          ->disconnect();
      }

      // Update ldapUser with the sid of the server that the user authenticated
      // on if that option was enabled in the LDAP user configuration.
      if ($auth_conf->ldapUser->drupalAcctProvisionServer == LDAP_USER_AUTH_SERVER_SID) {
        $auth_conf->ldapUser->drupalAcctProvisionServer = $ldap_server->sid;
      }

      // Success.
      break;
    }
  }

  // End loop through servers.
  $watchdog_tokens['%result'] = $result;
  $watchdog_tokens['%auth_result'] = $authentication_result;
  $watchdog_tokens['%err_text'] = _ldap_authentication_err_text($authentication_result);
  if ($detailed_watchdog_log) {
    watchdog('ldap_authentication', '%username : Authentication result id=%result auth_result=%auth_result (%err_text)', $watchdog_tokens, WATCHDOG_DEBUG);
  }
  return [
    $authentication_result,
    $ldap_user,
    $ldap_server,
  ];
}