Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.375 diff -u -p -r1.375 form.inc --- includes/form.inc 21 Sep 2009 06:44:13 -0000 1.375 +++ includes/form.inc 26 Sep 2009 09:14:58 -0000 @@ -218,7 +218,7 @@ function drupal_build_form($form_id, &$f // in the latest $form_state in addition to any other variables passed // into drupal_get_form(). - if ((!empty($form_state['storage']) || $form_state['rebuild']) && $form_state['submitted'] && !form_get_errors()) { + if ((!empty($form_state['storage']) || $form_state['rebuild']) && !form_get_errors()) { $form = drupal_rebuild_form($form_id, $form_state); } @@ -311,8 +311,8 @@ function drupal_rebuild_form($form_id, & $form_state['groups'] = array(); // Do not call drupal_process_form(), since it would prevent the rebuilt form - // to submit. - $form = form_builder($form_id, $form, $form_state); + // to submit. Why? + drupal_process_form($form_id, $form, $form_state); return $form; } @@ -1033,7 +1033,7 @@ function form_builder($form_id, $element } // Store a complete copy of the form in form_state prior to building the form. - $form_state['complete form'] = $element; + $form_state['complete form'] = &$element; // Set a flag if we have a correct form submission. This is always TRUE for // programmed forms coming from drupal_form_submit(), or if the form_id coming // from the POST data is set and matches the current form_id. Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.1053 diff -u -p -r1.1053 user.module --- modules/user/user.module 25 Sep 2009 15:14:18 -0000 1.1053 +++ modules/user/user.module 26 Sep 2009 09:14:36 -0000 @@ -585,6 +585,63 @@ function user_validate_picture(&$form, & } } +function user_process_current_password($element, &$form_state, &$complete_form) { + $element['#element_validate'][] = 'user_validate_current_password'; + // @todo If this would be possible somehow, that would be awesomess. + #$complete_form['#process'][] = 'user_process_current_password_replace_form'; + return $element; +} + +function user_validate_current_password(&$element, &$form_state, &$complete_form) { + $value_changed = ($element['#default_value'] !== $element['#value']); + if ($value_changed) { + // If the value of this form element changed, we backup the current form + // values and request a rebuild of the form, so + // user_process_current_password_replace_form() kicks in. + $form_state['storage']['needs_password_validation']['input'] = $form_state['input']; + $form_state['storage']['needs_password_validation']['values'] = $form_state['values']; + $form_state['rebuild'] = TRUE; + $form_state['redirect'] = FALSE; + } +} + +function user_process_current_password_replace_form($element, &$form_state, $complete_form) { + if (!empty($form_state['storage']['needs_password_validation'])) { + foreach (element_children($element) as $item) { + if (in_array($item, array('form_build_id', 'form_token', 'form_id', 'submit'))) { + continue; + } + $element[$item]['#access'] = FALSE; + } + $element['helpme'] = array( + '#markup' => '

' . t('The action you are trying to perform is a bit wacky. Please confirm.') . '

', + ); + $element['current_password'] = array( + '#type' => 'password', + '#title' => t('Current password'), + '#description' => t('Turn on your brain-cells to get this done.'), + '#element_validate' => array('user_validate_current_password_confirm'), + ); + } + return $element; +} + +function user_validate_current_password_confirm(&$element, &$form_state, $complete_form) { + global $user; + + if (user_authenticate($user->name, $form_state['values']['current_password'])) { + // This is totally wacky, as it replaces your password with an array. :-D + // Otherwise, works! + $form_state['input'] = $form_state['storage']['needs_password_validation']['input']; + $form_state['values'] = $form_state['storage']['needs_password_validation']['values']; + + unset($form_state['storage']['needs_password_validation']); + } + else { + form_error($element, t('Stupid password. Try again, cowboy.')); + } +} + /** * Generate a random alphanumeric password. */ @@ -1809,20 +1866,19 @@ function user_edit_form(&$form, &$form_s '#title' => t('Account information'), '#weight' => -10, ); - // Only show name field when: registration page; or user is editing own - // account and can change username; or an admin user. - if ($register || ($user->uid == $account->uid && user_access('change own username')) || $admin) { - $form['account']['name'] = array( - '#type' => 'textfield', - '#title' => t('Username'), - '#maxlength' => USERNAME_MAX_LENGTH, - '#description' => t('Spaces are allowed; punctuation is not allowed except for periods, hyphens, apostrophes, and underscores.'), - '#required' => TRUE, - '#attributes' => array('class' => array('username')), - ); - if (!$register) { - $form['account']['name']['#default_value'] = $account->name; - } + $form['account']['name'] = array( + '#type' => 'textfield', + '#title' => t('Username'), + '#maxlength' => USERNAME_MAX_LENGTH, + '#description' => t('Spaces are allowed; punctuation is not allowed except for periods, hyphens, apostrophes, and underscores.'), + '#required' => TRUE, + '#attributes' => array('class' => array('username')), + // Only show name field when: registration page; or user is editing own + // account and can change username; or an admin user. + '#access' => $register || ($user->uid == $account->uid && user_access('change own username')) || $admin, + ); + if (!$register) { + $form['account']['name']['#default_value'] = $account->name; } $form['account']['mail'] = array( '#type' => 'textfield', @@ -1833,6 +1889,8 @@ function user_edit_form(&$form, &$form_s ); if (!$register) { $form['account']['mail']['#default_value'] = $account->mail; + $form['account']['mail']['#process'] = array('user_process_current_password'); + $form['#process'][] = 'user_process_current_password_replace_form'; } if (!$register) { $form['account']['pass'] = array( Index: modules/user/user.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v retrieving revision 1.56 diff -u -p -r1.56 user.pages.inc --- modules/user/user.pages.inc 22 Sep 2009 07:50:16 -0000 1.56 +++ modules/user/user.pages.inc 26 Sep 2009 07:09:45 -0000 @@ -260,12 +260,6 @@ function user_profile_form_validate($for field_attach_form_validate('user', $edit, $form, $form_state); $edit = (array)$edit; user_module_invoke('validate', $edit, $form['#user'], $form['#user_category']); - // Validate input to ensure that non-privileged users can't alter protected data. - if ((!user_access('administer users') && array_intersect(array_keys($edit), array('uid', 'init', 'session'))) || (!user_access('administer permissions') && isset($form_state['values']['roles']))) { - watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING); - // set this to a value type field - form_set_error('category', t('Detected malicious attempt to alter protected user fields.')); - } } /**