uid == $GLOBALS['user']->uid || variable_get('password_change_all', 0)) { if (password_change_is_reset()) { // Make the normal password field required if the password was just // reset. $form['account']['pass']['#required'] = TRUE; } else { // Add the current password field just below the 'Save' button. $form['pass_current'] = array( '#type' => 'password', '#title' => t('Your current password'), '#description' => t('For security reasons, enter your current password to confirm your changes.'), '#size' => 25, '#weight' => $form['submit']['#weight'] - 0.5, '#required' => TRUE, '#element_validate' => array('password_change_validate_password'), ); } // Put the submit handler first so we can clear the values before they // could be saved into $user->data. array_unshift($form['#submit'], 'password_change_form_submit_clear_reset'); } } } // based on function _phpass_user_authenticate from phpass.module function password_change_validate_password($element, $form_state) { // map variables $user = $GLOBALS['user']->name; $userpass = $GLOBALS['user']->pass; $pass = $element['#value']; // detect presence of phpass (pass hash method set as 'phpass') and validate with phpass if (module_exists("phpass") && variable_get('user_hash_method', 'phpass') == 'phpass') { // report error if passwordhash is missing through a phpass.module function _phpass_is_passwordhash_php_missing(); // fetch the saved user pass and phpass hash $userpass = db_fetch_object(db_query("SELECT u.*, p.hash FROM {users} u LEFT JOIN {user_phpass} p ON u.uid = p.uid WHERE u.name = '%s' AND u.status = 1", $user)); // if vars aren't empty and password matches 'phpass', password hash is in phpass table (user_phpass) if ($userpass->hash && $userpass->pass && ($userpass->pass == 'phpass')) { require_once(drupal_get_path('module', 'phpass') .'/PasswordHash.php'); // call CheckPassword from phpass.library $phpass = new PasswordHash(variable_get('user_hash_strength', 8), variable_get('user_hash_portable', TRUE)); $check = $phpass->CheckPassword($pass, $userpass->hash); // check if the password matches the phpass hash (function returns 1) if ($check != 1) { // mismatch of supplied pass and pass hash returns error form_error($element, t('Incorrect current password.')); } // if vars aren't empty and password doesn't match 'phpass', password hash is in regular table (user) } elseif ($userpass->pass && ($userpass->pass != 'phpass')) { // check if the password matches the old md5 hash if ($userpass->pass !== md5($pass)) { // mismatch of supplied pass and pass hash returns error form_error($element, t('Incorrect current password.')); } } // validate with the old way } else { // check if the password matches the old md5 hash if ($userpass !== md5($pass)) { // mismatch of supplied pass and pass hash returns error form_error($element, t('Incorrect current password.')); } } } /** * Submit handler; reset the reset flag and unset the current password value. */ function password_change_form_submit_clear_reset($form, &$form_state) { password_change_is_reset(FALSE); unset($form_state['values']['pass_current']); } /** * Implements hook_form_FORM_ID_alter(). */ function password_change_form_user_admin_settings_alter(&$form, $form_state) { $form += array( 'security' => array( '#type' => 'fieldset', '#title' => t('Security'), ), ); $form['security']['password_change_all'] = array( '#type' => 'checkbox', '#title' => t("Require the current user to confirm his or her current password when changing any user's account."), '#description' => t('Users will still be required to confirm their password when changing their own account regardless of this setting.'), '#default_value' => variable_get('password_change_all', FALSE), ); }