You are here

function ldapauth_authenticate in LDAP integration 6

Main user authentication function. Called by form validator.

If successful, sets the global $user object.

1 call to ldapauth_authenticate()
ldapauth_login_authenticate_validate in ./ldapauth.module
Main user validation function. Replaces Drupal default login form validation.

File

./ldapauth.module, line 387
ldapauth provides authentication against ldap server.

Code

function ldapauth_authenticate($form_values = array()) {
  global $user, $_ldapauth_ldap;
  $name = $form_values['name'];
  $pass = $form_values['pass'];

  // The user_login_name_validate() is not called if the user is being authenticated
  // from the httpauth or services modules, therefore call it here.
  $form_state['values'] = $form_values;
  user_login_name_validate(NULL, $form_state);
  if (form_get_errors()) {
    ldapauth_debug_msg(t("authenticate: User, @user, failed Drupal core login name validation test.", array(
      '@user' => $name,
    )));
    return;
  }

  // (Design decision) uid=1 (admin user) must always authenticate to local database
  // this user is critical for all drupal admin and upgrade operations so it is best
  // left with drupal's native authentication.
  $result = db_query("SELECT uid FROM {users} WHERE LOWER(name) = LOWER('%s') AND uid = '1'", $name);
  if ($account = db_fetch_object($result)) {
    ldapauth_debug_msg(t("authenticate: User, @user, is local admin(uid=1)", array(
      '@user' => $name,
    )));
    user_authenticate($form_values);
    return;
  }
  if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED) {

    // Authenticate local users first.
    $result = db_query("SELECT name, data FROM {users} WHERE LOWER(name) = LOWER('%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.
        ldapauth_debug_msg(t("authenticate: User, @user, is a local Drupal user - calling Drupal authentication", array(
          '@user' => $name,
        )));
        if (user_authenticate($form_values)) {

          // Nullify global ldap resource for good measure.
          unset($_ldapauth_ldap);
          return;
        }
        ldapauth_debug_msg(t("authenticate: User, @user: Drupal authentication failed, seeing if id/password works with an LDAP user.", array(
          '@user' => $name,
        )));
      }
    }
  }

  // Find and Authenticate LDAP user.
  if (!($dn = _ldapauth_auth($name, $pass))) {
    ldapauth_debug_msg(t("authenticate: User, @user, was not found in LDAP or authentication failed..", array(
      '@user' => $name,
    )));
    return;
  }
  ldapauth_debug_msg(t("authenticate: User, @user, mapped to LDAP DN, @dn.", array(
    '@user' => $name,
    '@dn' => $dn,
  )));

  // See if there is a matching Drupal user account
  $error = '';
  $account = ldapauth_drupal_user_lookup($_ldapauth_ldap, $name, $dn, $error);
  if ($account === NULL) {
    form_set_error("name", $error);
    watchdog('ldapauth', $error, NULL, WATCHDOG_ERROR);
  }

  // Allow other modules to determine if this ldap user can access server.
  if (ldapauth_user_denied($_ldapauth_ldap, $name, $dn, $account)) {
    ldapauth_debug_msg(t("authenticate: User, @user, denied by another module via hook_ldap_user_deny().", array(
      '@user' => $name,
    )));
    return;
  }

  // Have account: Do some default login checks
  if ($account !== FALSE) {
    ldapauth_debug_msg(t("authenticate: User, @user, was linked to existing Drupal account, @duser(uid=@uid).", array(
      '@user' => $name,
      '@duser' => $account->name,
      '@uid' => $account->uid,
    )));
    if ($account->status != 1) {

      // User is blocked.
      ldapauth_debug_msg(t("authenticate: User, @user, was marked as blocked in Drupal database.", array(
        '@user' => $name,
      )));
      return;

      // Returns default unknown id/password msg per core
    }
    if (drupal_is_denied('mail', $account->mail)) {
      ldapauth_debug_msg(t("authenticate: User, @user, was denied because it was registered using a reserved e-mail address.", array(
        '@user' => $name,
      )));
      form_set_error('name', t('The name %name is registered using a reserved e-mail address and therefore could not be logged in.', array(
        '%name' => $account->name,
      )));
    }
    if ($account->uid == 1) {
      ldapauth_debug_msg(t("authenticate: User, @user, denied by another module via hook_ldap_user_deny().", array(
        '@user' => $name,
      )));
      return;

      // LDAP user matched superuser!! Shouldn't get here but just in case
    }
  }

  // If there is any validations errors, we do not query LDAP.
  if (form_get_errors()) {
    return;
  }

  // No matching Drupal user, try to create one for this LDAP account.
  if (!$account) {
    ldapauth_debug_msg(t("authenticate: Attempting to creating local Drupal user, @user.", array(
      '@user' => $name,
    )));
    $error = '';
    $account = ldapauth_drupal_user_create($_ldapauth_ldap, $name, $dn, $error);
    if ($account === FALSE) {
      form_set_error('name', $error);
      return;
    }
    $user = $account;
  }
  else {
    $data = array(
      'ldap_dn' => $dn,
      'ldap_config' => $_ldapauth_ldap
        ->getOption('sid'),
      'ldap_name' => $name,
    );

    // LDAP and local user conflict.
    if (!isset($account->ldap_authentified)) {
      if (LDAPAUTH_LOGIN_CONFLICT == LDAPAUTH_CONFLICT_LOG) {
        watchdog('ldapauth', 'LDAP user with DN %dn has a naming conflict with a local drupal user %name', array(
          '%dn' => $dn,
          '%name' => $account->name,
        ), WATCHDOG_ERROR);
        drupal_set_message(t('Another user already exists in the system with the same login name. You should contact the system administrator in order to solve this conflict.'), 'error');
        return;
      }
      else {
        $data['ldap_authentified'] = TRUE;
        $drupal_name = ldapauth_drupal_user_name($name, $_ldapauth_ldap, $dn);
        $data['authname_ldapauth'] = $drupal_name;
      }
    }

    // Successfull login.
    // Save the new login data.
    if (LDAPAUTH_LOGIN_PROCESS == LDAPAUTH_AUTH_MIXED && LDAPAUTH_SYNC_PASSWORDS) {
      $data['pass'] = $pass;
    }
    $user = user_save($account, $data);

    // Make sure the ldapauth_users info is current (User object may have been moved).
    $user_info = ldapauth_userinfo_load_by_uid($user->uid);
    if (empty($user_info)) {

      // Don't have entry, so make one.
      $user_info = new stdClass();
      $user_info->uid = $user->uid;
    }
    $user_info->sid = $user->ldap_config;
    $user_info->machine_name = $_ldapauth_ldap
      ->getOption('machine_name');
    $user_info->dn = $dn;
    $user_info->puid = $account->ldap_puid;

    // set in drupal_user_lookup
    ldapauth_userinfo_save($user_info);
  }
  ldapauth_debug_msg(t("authenticate: User, @user, has been authenticated as an LDAP user.", array(
    '@user' => $name,
  )));

  // Save user's authentication data to the session.
  $_SESSION['ldap_login']['dn'] = $dn;
  $_SESSION['ldap_login']['pass'] = $pass;
  user_authenticate_finalize($form_values);
  return $user;
}