=== modified file 'modules/user/user.pages.inc'
--- modules/user/user.pages.inc	2009-07-31 19:01:01 +0000
+++ modules/user/user.pages.inc	2009-08-09 05:04:07 +0000
@@ -75,7 +75,7 @@ function user_pass_submit($form, &$form_
 /**
  * Menu callback; process one time login link and redirects to the user page on success.
  */
-function user_pass_reset(&$form_state, $uid, $timestamp, $hashed_pass, $action = NULL) {
+function user_pass_reset(&$form_state, $uid, $timestamp, $hashed_pass) {
   global $user;
 
   // Check if the user is already logged in. The back button is often the culprit here.
@@ -96,24 +96,7 @@ function user_pass_reset(&$form_state, $
         drupal_goto('user/password');
       }
       elseif ($account->uid && $timestamp >= $account->login && $timestamp <= $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login)) {
-        // First stage is a confirmation form, then login
-        if ($action == 'login') {
-          watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp));
-          // Set the new user.
-          $user = $account;
-          // user_login_finalize() also updates the login timestamp of the
-          // user, which invalidates further use of the one-time login link.
-          user_login_finalize();
-          drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password.'));
-          drupal_goto('user/' . $user->uid . '/edit');
-        }
-        else {
-          $form['message'] = array('#markup' => t('<p>This is a one-time login for %user_name and will expire on %expiration_date.</p><p>Click on this button to login to the site and change your password.</p>', array('%user_name' => $account->name, '%expiration_date' => format_date($timestamp + $timeout))));
-          $form['help'] = array('#markup' => '<p>' . t('This login can be used only once.') . '</p>');
-          $form['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
-          $form['#action'] = url("user/reset/$uid/$timestamp/$hashed_pass/login");
-          return $form;
-        }
+        return _user_pass_reset_form($account, $timestamp);
       }
       else {
         drupal_set_message(t('You have tried to use a one-time login link which has either been used or is no longer valid. Please request a new one using the form below.'));
@@ -129,6 +112,40 @@ function user_pass_reset(&$form_state, $
 }
 
 /**
+ * Generate the form to change password and log in using a one-time login link.
+ *
+ * @param stdClass $account
+ *   This account will be logged in after a password change.
+ * @param $expire
+ *   The timestamp when the login link expires. Used only to display.
+ */
+function _user_pass_reset_form($account, $expire) {
+  $form['message'] = array('#markup' => t('<p>This is a one-time login for %user_name and will expire on %expiration_date.</p>', array('%user_name' => $account->name, '%expiration_date' => format_date($expire))));
+  $form['help'] = array('#markup' => '<p>' . t('This login can be used only once.') . '</p>');
+  $form['pass'] = array('#type' => 'password_confirm', '#required' => TRUE);
+  $form['submit'] = array('#type' => 'submit', '#value' => t('Change password and log in'));
+  $form['#account'] = $account;
+  $form['#redirect'] = "user/$account->uid";
+  return $form;
+}
+
+/**
+ * Change password and log in the user.
+ */
+function user_pass_reset_submit($form, $form_state) {
+  global $user;
+  watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $form['#account']->name, '%timestamp' => REQUEST_TIME));
+  drupal_set_message(t('You have just used your one-time login link. It is no longer possible to use this link to login.'));
+  // Set the new user.
+  $user = $form['#account'];
+  user_save($user, array('pass' => $form_state['values']['pass']));
+  drupal_set_message(t('Password changed.'));
+  // user_login_finalize() also updates the login timestamp of the
+  // user, which invalidates further use of the one-time login link.
+  user_login_finalize();
+}
+
+/**
  * Menu callback; logs the current user out, and redirects to the home page.
  */
 function user_logout() {

=== modified file 'modules/user/user.test'
--- modules/user/user.test	2009-07-31 21:14:01 +0000
+++ modules/user/user.test	2009-08-09 05:07:53 +0000
@@ -59,29 +59,27 @@ class UserRegistrationTestCase extends D
     $url = user_pass_reset_url($user);
     $this->drupalGet($url);
     $this->assertText(t('This login can be used only once.'), t('Login can be used only once.'));
-
-    $this->drupalPost(NULL, NULL, t('Log in'));
-    $this->assertText(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password.'), t('This link is no longer valid.'));
-
+    // This should not succeed.
+    $this->drupalPost(NULL, array(), t('Change password and log in'));
+    $this->assertText(t('This login can be used only once.'), t('Login can be used only once.'));
     // Check password type validation
     $edit = array();
     $edit['pass[pass1]'] = '99999.0';
     $edit['pass[pass2]'] = '99999';
-    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->drupalPost(NULL, $edit, t('Change password and log in'));
     $this->assertText(t('The specified passwords do not match.'), t('Type mismatched passwords display an error message.'));
-    $this->assertNoText(t('The changes have been saved.'), t('Save user password with mismatched type in password confirm.'));
-
+    $this->assertText(t('This login can be used only once.'), t('Login can be used only once.'));
     // Change user password.
     $new_pass = user_password();
     $edit = array();
     $edit['pass[pass1]'] = $new_pass;
     $edit['pass[pass2]'] = $new_pass;
-    $this->drupalPost(NULL, $edit, t('Save'));
-    $this->assertText(t('The changes have been saved.'), t('Password changed to @password', array('@password' => $new_pass)));
-
+    $this->drupalPost(NULL, $edit, t('Change password and log in'));
+    file_put_contents('/tmp/log.htm', $this->content);
+    $this->assertText(t('You have just used your one-time login link. It is no longer possible to use this link to login.'), t('This link is no longer valid.'));
+    $this->assertText(t('Password changed.'), t('Password changed.'));
     // Make sure password changes are present in database.
     require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
-
     $user = user_load($user->uid, TRUE);
     $this->assertTrue(user_check_password($new_pass, $user), t('Correct password in database.'));
 

