[module] protect_critical_uids module for Drupal 4.6/4.7
 
 
Post new topic   Reply to topic   printer-friendly view    phpMiX.org Forum Index -> Drupal Modules
View previous topic :: View next topic  
Author Message
markus
[Administrator]
[Administrator]


Joined: 28 Jul 2003
Posts: 1124

PostPosted: Mon Feb 13, 2006 4:10 am    Post subject: [module] protect_critical_uids module for Drupal 4.6/4.7 Reply with quote

Module: protect_critical_uids
Version: Drupal 4.6 & 4.7

Description:
protect_critical_uids is a Drupal module that protects UID 1 from being deleted and UID 0 from being edited/deleted. It also prevents a user from being able to delete himself. When such a request is detected, a "403 access denied" or "404 not found" error is generated, depending on the operation.

About UID 0:
UID 0 is the anonymous user. In current Drupal implementation, while the user profile of UID 0 cannot be viewed, it can be edited or even deleted. Try:
http://www.example.com/user/0/edit
http://www.example.com/user/0/delete

This module intercepts such requests and generates a "404 not found" error, if an attempt to edit or delete UID 0 is detected.


About UID 1:
UID 1 is the super site administrator. It is mostly hardcoded all around the core and contrib modules too. It is certainly a limitation that might be changed in the future, but in the meantime, UID 1 is the most critical account in the system.

If by mistake or whatever else reason it was deleted, you could probably start experiencing all sorts of problems. Recovering from UID 1 deletion may be a really hard task that not many people would be able to achieve successfully or in a short period of time.

Although UID 1 is critical, it is actually possible to delete its account. Not only that, but also anything related to it. When a user is deleted, the user module invokes a hook that allows other modules to react on that event, often removing anything owned by that user, including nodes, comments, etc.

Drupal comes with a permission system based on roles, however when a user has permission to administer users, there is no way to protect critical users. Anyone with administer users permission could do:

http://www.example.com/user/1/delete

and then confirm the operation.

This module intercepts such requests and generates a 403 access denied error, if an attempt to delete UID 1 is detected.


References:
#46149: Drupal module issue that ended up marked as "won't fix" (project issue).
#49101: Protect critical user account from being deleted (forum topic).

 
 
_________________
http://www.phpmix.org
 
Back to top
View user's profile Send private message
markus
[Administrator]
[Administrator]


Joined: 28 Jul 2003
Posts: 1124

PostPosted: Mon Feb 13, 2006 3:56 pm    Post subject: Reply with quote

The module is so simple that I decided to post the code here:

1) Telling the system about the module.
PHP:
/**
 * Implementation of hook_help().
 */
function protect_critical_uids_help($section) {
  switch(
$section) {
    case 
'admin/modules#description':
      
$output t('This module protects UID 1 from being deleted and UID 0 from begin edited/deleted.');
      break;
  }
  return 
$output;
}

2) Intercepting potentially harmful requests.
PHP:
/**
 * Implementation of hook_init().
 */
function protect_critical_uids_init() {
  global 
$user;

  if (
arg(0) == 'user') {
    
// Protect UID 0 from being viewed/edited/deleted
    
if (arg(1) == '0') {
      
drupal_not_found();
      return;
    }
    
// Protect UID 1 (or active user) from being deleted
    
if (arg(2) == 'delete' && (arg(1) == '1' || arg(1) == $user->uid)) {
      
drupal_access_denied();
      return;
    }
  }
}

3) Hiding the delete button when not desired.
PHP:
/**
 * Implementation of hook_form_alter().
 */
function protect_critical_uids_form_alter($form_id, &$form) {
  global 
$user;

  switch (
$form_id) {
    case 
'user_edit':
      
// Even if the user is allowed to administer users, for critical
      // users, we hide the delete button from the user edit form.
      
if (isset($form['delete']) && (arg(1) == '1' || arg(1) == $user->uid)) {
        unset(
$form['delete']);
      }
      break;
  }
}

That's it.

 
 
_________________
http://www.phpmix.org
 
Back to top
View user's profile Send private message
markus
[Administrator]
[Administrator]


Joined: 28 Jul 2003
Posts: 1124

PostPosted: Wed Feb 15, 2006 4:26 pm    Post subject: Reply with quote

Per Oadae's suggestion I have committed this module to the Drupal's contributions repository. More information about this module, bug reports, etc. ought now to be found at the project page of the module. Probably the tar files will be there with the next run of the cvs module cron.
 
 
_________________
http://www.phpmix.org
 
Back to top
View user's profile Send private message
markus
[Administrator]
[Administrator]


Joined: 28 Jul 2003
Posts: 1124

PostPosted: Wed Feb 15, 2006 7:41 pm    Post subject: Reply with quote

Before, I committed a version of the module for Drupal 4.7, now I have adapted the module for Drupal 4.6.x as well. The ZIP that was attached in the topic starter is now gone, both versions of the module should now be available from Drupal CVS itself.

Actually, the code for 4.6 was quite different. To intercept the request I had to use hook_menu rather than hook_init, where the translation system doesn't seem to be available.

If curious Smile , this is how hook_menu for 4.6 looks:

PHP:
/**
 * Implementation of hook_menu().
 */
function protect_critical_uids_menu($maycache) {
  global 
$user;

  if (!
$maycache) {
    if (
arg(0) == 'user') {
      
// Protect UID 0 from being viewed/edited/deleted
      
if (arg(1) == '0') {
        
drupal_not_found();
        return;
      }
      
// Protect UID 1 (or active user) from being deleted
      
if ((arg(2) == 'delete' || $_POST['op'] == t('Delete')) && (arg(1) == '1' || arg(1) == $user->uid)) {
        
drupal_access_denied();
        return;
      }
    }
  }
}

Note that I had to add the check for $_POST['op'] == t('Delete'). Yep! the request is not exactly equal. In 4.7 can only be a GET request, whereas in 4.6 can be a GET or a POST request.

 
 
_________________
http://www.phpmix.org
 
Back to top
View user's profile Send private message
markus
[Administrator]
[Administrator]


Joined: 28 Jul 2003
Posts: 1124

PostPosted: Wed Mar 08, 2006 2:15 am    Post subject: Reply with quote

Since it seems that the project module, at drupal.org, doesn't update the tarballs as often as it should, I'll be keeping this topic up to date (see topic starter) with latest build and bump it with information on changes, etc.

Changes in build 1.1.2.1 for Drupal 4.7:
  • bugfix #52651: double output, reported by jadwigo

 
 
_________________
http://www.phpmix.org
 
Back to top
View user's profile Send private message
markus
[Administrator]
[Administrator]


Joined: 28 Jul 2003
Posts: 1124

PostPosted: Mon Mar 13, 2006 1:47 am    Post subject: Reply with quote

protect_critical_uids for Drupal 4.7 has been updated (file attached to topic starter).

Changes in build 1.1.2.2 for Drupal 4.7:
  • bugfix #53720: Fatal error: Call to undefined function: arg() in protect_critical_uids.module on line 27, when page cache is enabled

 
 
_________________
http://www.phpmix.org
 
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    phpMiX.org Forum Index -> Drupal Modules All times are GMT + 1 Hour
 
Page 1 of 1


 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum