Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.1055 diff -u -p -r1.1055 user.module --- modules/user/user.module 2 Oct 2009 14:49:10 -0000 1.1055 +++ modules/user/user.module 6 Oct 2009 23:12:49 -0000 @@ -2676,6 +2676,10 @@ function user_multiple_cancel_confirm_su if ($form_state['values']['confirm']) { foreach ($form_state['values']['accounts'] as $uid => $value) { + // Prevent user 1 from being deleted. + if ($uid <= 1) { + continue; + } // Prevent user administrators from deleting themselves without confirmation. if ($uid == $user->uid) { $admin_form_state = $form_state; Index: modules/user/user.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v retrieving revision 1.57 diff -u -p -r1.57 user.pages.inc --- modules/user/user.pages.inc 29 Sep 2009 15:31:17 -0000 1.57 +++ modules/user/user.pages.inc 6 Oct 2009 23:05:56 -0000 @@ -240,7 +240,7 @@ function user_profile_form($form, &$form $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 30); - if (($account->uid == $user->uid && user_access('cancel account')) || user_access('administer users')) { + if ((($account->uid == $user->uid && user_access('cancel account')) || user_access('administer users')) && $account->uid > 1) { $form['cancel'] = array( '#type' => 'submit', '#value' => t('Cancel account'), Index: modules/user/user.test =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.test,v retrieving revision 1.62 diff -u -p -r1.62 user.test --- modules/user/user.test 19 Sep 2009 10:54:35 -0000 1.62 +++ modules/user/user.test 6 Oct 2009 23:54:21 -0000 @@ -338,6 +338,40 @@ class UserCancelTestCase extends DrupalW } /** + * Test protection of user 1. + * + * This should never be possible, or the site's owner could become unable to + * administer the site. + */ + function testUserCancelUser1() { + // Load user #1 from the database. + $user1 = user_load(1, TRUE); + // Make sure we know what is in user1's object. + $password = user_password(); + $account = array(); + $account['name'] = 'user1'; + $account['pass'] = $password; + require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc'); + $account['pass'] = user_hash_password(trim($account['pass'])); + // Do not use user_save() here. + db_update('users') + ->fields($account) + ->condition('uid', 1) + ->execute(); + $user1 = user_load(1, TRUE); + $user1->pass_raw = $password; + $this->drupalLogin($user1); + // Prefill some form fields. + $edit = array(); + $edit['operation'] = 'cancel'; + $edit['accounts[1]'] = TRUE; + $this->drupalPost('admin/people', $edit, t('Update')); + $user1 = user_load(1, TRUE); + $this->assertRaw(t('You attempted to cancel %name which is the superuser account (ID #1)', array('%name' => $user1->name)), t('User #1 attempted to cancel user #1 account, but was successfully thwarted.')); + $this->assertTrue($user1->status == 1, t('User #1 still exists and is enabled.')); + } + + /** * Attempt invalid account cancellations. */ function testUserCancelInvalid() { @@ -613,6 +647,7 @@ class UserCancelTestCase extends DrupalW $edit['accounts[' . $uid . ']'] = TRUE; } $edit['accounts[' . $admin_user->uid . ']'] = TRUE; + $edit['accounts[1]'] = TRUE; $this->drupalPost('admin/people', $edit, t('Update')); $this->assertText(t('Are you sure you want to cancel these user accounts?'), t('Confirmation form to cancel accounts displayed.')); $this->assertText(t('When cancelling these accounts'), t('Allows to select account cancellation method.')); @@ -632,6 +667,8 @@ class UserCancelTestCase extends DrupalW $this->assertText(t('A confirmation request to cancel your account has been sent to your e-mail address.'), t('Account cancellation request mailed message displayed.')); $admin_user = user_load($admin_user->uid); $this->assertTrue($admin_user->status == 1, t('Administrative user is found in the database and enabled.')); + $uid1 = user_load(1); + $this->assertTrue($uid1->status == 1, t('User #1 still exists and is enabled.')); } }