diff --git a/drupalvb.inc.php b/drupalvb.inc.php
index 84241b8..aca14d5 100644
--- a/drupalvb.inc.php
+++ b/drupalvb.inc.php
@@ -79,6 +79,11 @@ function drupalvb_clear_cookies($userid = NULL) {
     $vb_cookie_domain = '';
   }
 
+  // @todo Without a vB user id, we cannot delete the session, so vBulletin
+  //   will automatically authenticate again. We badly need a solution here,
+  //   since this is the cause for broken session handling. Proposal: Use
+  //   drupalvb_get_ip() to count the # of sessions; if there exactly one,
+  //   kill it.
   if (!empty($userid)) {
     drupalvb_db_query("DELETE FROM {session} WHERE userid = %d", $userid);
     drupalvb_db_query("UPDATE {user} SET lastvisit = %d WHERE userid = %d", time(), $userid);
@@ -93,6 +98,8 @@ function drupalvb_clear_cookies($userid = NULL) {
 
 /**
  * Determines the IP address of current user.
+ *
+ * @todo Duplicate of ip_address() in D6+ ?
  */
 function drupalvb_get_ip() {
   $ip = $_SERVER['REMOTE_ADDR'];
diff --git a/drupalvb.module b/drupalvb.module
index 07293c1..90d0f6a 100644
--- a/drupalvb.module
+++ b/drupalvb.module
@@ -471,46 +471,64 @@ function drupalvb_user_delete($account) {
 function drupalvb_login() {
   global $user;
 
-  // Starting from 4.x, vB uses 'vb_login_*' login form input names, whereas
+  // Starting from 3.8.4+, vB uses 'vb_login_*' login form input names, whereas
   // earlier versions used 'name' and 'pass'.
-  if (isset($_POST['vb_login_username']) && isset($_POST['vb_login_password'])) {
-    $_POST['name'] = $_POST['vb_login_username'];
-    $_POST['pass'] = $_POST['vb_login_password'];
-    unset($_POST['vb_login_username'], $_POST['vb_login_password']);
-  }
+  $form_state = array(
+    'values' => array(
+      'name' => isset($_POST['vb_login_username']) ? $_POST['vb_login_username'] : $_POST['name'],
+      'pass' => isset($_POST['vb_login_password']) ? $_POST['vb_login_password'] : $_POST['pass'],
+    ),
+  );
 
-  if ($_POST['name']) {
-    $form_state = array('values' => $_POST);
-    if ($user->uid) {
-      // If the user is already logged in to Drupal, we ensure the same for
-      // vBulletin.
-      if (drupalvb_login_validate(array(), $form_state)) {
-        drupal_goto(!empty($_REQUEST['destination']) ? $_REQUEST['destination'] : 'user/'. $user->uid);
-      }
-      else {
-        // Where do we go from here? user/login won't work, as the user is
-        // already authenticated in Drupal.
-        unset($_REQUEST['destination']);
-        drupal_goto(variable_get('site_frontpage', 'node'));
-      }
+  // Redirect to the originating page (in vB), or fall back to the user account.
+  $redirect = referer_uri() ? referer_uri() : 'user';
+  // Prevent drupal_goto() from redirecting somewhere else.
+  unset($_REQUEST['destination']);
+
+  if ($user->uid) {
+    // If the user is already logged in to Drupal, we ensure the same for
+    // vBulletin.
+    if (drupalvb_login_validate(array(), $form_state)) {
+      drupal_goto($redirect);
     }
-    else {
-      // Otherwise perform the full login procedure.
-      foreach (user_login_default_validators() as $validator) {
-        $validator(array(), $form_state);
-      }
-      if (!form_get_errors()) {
-        user_login_submit(array(), $form_state);
-        $redirect = (isset($form_state['redirect']) ? $form_state['redirect'] : '');
-        drupal_goto(!empty($_REQUEST['destination']) ? $_REQUEST['destination'] : $redirect);
-      }
-      else {
-        // Login failed: send back to login form.
-        unset($_REQUEST['destination']);
-        drupal_goto('user/login');
-      }
+
+    // The user does not yet exist in vBulletin or wrong credentials were
+    // submitted. Log out from Drupal to enforce re-login (which will ultimately
+    // create the vBulletin account).
+    // The following is similar to drupalvb_logout(), but allows to set an
+    // explanation for the (then) anonymous user.
+    // @see user_authenticate()
+    watchdog('user', 'Login attempt failed for %user.', array('%user' => $form_values['name']));
+
+    // @see drupalvb_logout()
+    if (module_exists('singlesignon')) {
+      _singlesignon_session_logout($user->uid);
+    }
+
+    // @see user_logout()
+    watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
+
+    // Destroy the current session:
+    session_destroy();
+    // Only variables can be passed by reference workaround.
+    $null = NULL;
+    user_module_invoke('logout', $null, $user);
+
+    // Load the anonymous user
+    $user = drupal_anonymous_user();
+
+    // @see user_login_final_validate()
+    drupal_set_message(t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>', array('@password' => url('user/password'))), 'error');
+  }
+  else {
+    // Otherwise perform the full login procedure.
+    drupal_execute('user_login', $form_state);
+    if ($user->uid) {
+      drupal_goto($redirect);
     }
   }
+  // If all failed, redirect to user login form, but retain original referrer.
+  drupal_goto('user/login', 'destination=' . drupal_urlencode($redirect));
 }
 
 /**
