--- role_delegation.module.orig	2010-12-09 13:25:31.000000000 -0500
+++ role_delegation.module.mod	2011-02-10 16:11:06.000000000 -0500
@@ -64,7 +64,7 @@
   $roles = _role_delegation_roles();
   $roles_preserve = array('authenticated user');
   foreach ($roles as $rid => $role) {
-    if (!(user_access('assign all roles') || user_access(_role_delegation_make_perm($role)) || user_access('administer permissions'))) {
+    if (!(user_access('assign all roles') || user_access(_role_delegation_make_perm($role)))) {
       // Hide roles the user can't assign.
       $form['roles'][$rid] = array(
         '#type' => 'value',
@@ -129,9 +129,6 @@
     return FALSE;
   }
   // Check access to role assignment page.
-  if (user_access('administer permissions')) {
-    return TRUE;
-  }
   $perms = role_delegation_perm();
   foreach ($perms as $perm) {
     if (user_access($perm)) {
@@ -219,8 +216,6 @@
  */
 function role_delegation_user($op, &$edit, &$account, $category = NULL) {
   if ($op == 'register' || ($op == 'form' && $category == 'account')) {
-    // Only alter user form when user can't assign permissions without Role Delegation.
-    if (!user_access('administer permissions')) {
       // Split up roles based on whether they can be delegated or not.
       $current_roles = isset($account->roles) ? $account->roles : array();
       $rids_default = array();
@@ -269,7 +264,6 @@
       }
       return $form;
     }
-  }
   elseif (isset($edit['roles_assign']) && ($op == 'insert' || $op == 'submit')) {
     $edit['roles'] = $edit['roles_preserve'] + array_filter($edit['roles_assign']);
   }
@@ -291,12 +285,6 @@
  * Implementation of hook_user_operations().
  */
 function role_delegation_user_operations($form_state = array()) {
-  // Only provide role add/remove operations when user can't assign permissions
-  // without Role Delegation.
-  if (user_access('administer permissions')) {
-    return;
-  }
-
   // Provide add/remove operations for delegated roles.
   $roles = _role_delegation_roles();
   $add_roles = array();
@@ -343,3 +331,76 @@
 
   return $operations;
 }
+
+/**
+ * Implementation of hook_form_alter().
+ * Main method which will strip out all restricted roles and 'assign ROLE' permissions
+ */
+function role_delegation_form_alter(&$form, $form_state, $form_id){
+  switch($form_id){
+    case "user_profile_form":
+      if(!user_access('assign all roles') and user_access('administer permissions')) unset($form['account']['roles']);
+      break;
+
+    case "user_admin_perm":
+      if(user_access('assign all roles')) break;
+      $form["#validate"][] = 'role_delegation_user_admin_perm_validate';
+      $role_names     = $form['role_names'];
+      foreach($role_names as $rid => $role){
+        if($rid != DRUPAL_ANONYMOUS_RID && $rid != DRUPAL_AUTHENTICATED_RID && !user_access(_role_delegation_make_perm($role['#value']))){
+          // Remove entire role
+          $removedRoles[] = $role['#value'];
+          unset($form['checkboxes'][$rid]);
+          unset($form['role_names'][$rid]);
+        }
+      }
+      // Okay, we can delegate the remaining roles, but we need to remove the 'assign ROLE' permissions for the ones we just removed
+      $form['hiddenPermissions'] = array('#type'  => 'value', '#value' => array());
+      foreach(_role_delegation_roles() as $perm){
+        if(in_array($perm, $removedRoles)){
+          $rolePerm = _role_delegation_make_perm($perm);
+          foreach($form['role_names'] as $rid => $role){
+            if(in_array($rolePerm, $form['checkboxes'][$rid]['#default_value'])){
+              $form['hiddenPermissions']['#value'][$rid][] = $rolePerm;
+              unset($form['checkboxes'][$rid]['#default_value'][$rolePerm]);
+            }
+            unset($form['checkboxes'][$rid]['#options'][$rolePerm]);
+            unset($form['permission'][$rolePerm]);
+          }
+        }
+      }
+      // Manualy remove 'assign all roles' permissions (because if we're here, the user dosne't have it)
+      foreach($form['role_names'] as $rid => $role){
+        $permKey  = array_search("assign all roles", $form['checkboxes'][$rid]['#default_value']);
+        if($permKey){
+          $form['hiddenPermissions']['#value'][$rid]["assign all roles"] = (int)($permKey !== false);
+          unset($form['checkboxes'][$rid]['#default_value']["assign all roles"]);
+        }
+        unset($form['checkboxes'][$rid]['#options']["assign all roles"]);
+        unset($form['permission']["assign all roles"]);
+      }
+      break;
+  }
+}
+
+/**
+ * Validation function to re-insert restricted permissions back into the permissions matrix before save.
+ * This will prevent permissions from being dropped from a subordinate user's submission (with missing permissions due to restrictions)
+ */
+function role_delegation_user_admin_perm_validate($form, &$form_state){
+  if(array_key_exists('hiddenPermissions', $form_state['values'])) foreach($form_state['values']['hiddenPermissions'] as $rid => $permissions){
+    foreach($permissions as $permission){
+      $form_state['values'][$rid][$permission] = 1;
+      unset($form_state['values']['hiddenPermissions'][$rid][$permission]);
+    }
+    unset($form_state['values']['hiddenPermissions']);
+  }
+}
+
+/**
+ * Implementation of hook_menu_alter().
+ * Restrict access to the roles listing (backdoor into role permissions)
+ */
+function role_delegation_menu_alter(&$items){
+  $items['admin/user/roles']['access arguments'] = array("assign all roles");
+}
