Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.1191 diff -u -p -r1.1191 user.module --- modules/user/user.module 9 Aug 2010 19:49:40 -0000 1.1191 +++ modules/user/user.module 9 Aug 2010 20:18:48 -0000 @@ -3605,9 +3605,34 @@ function user_modules_installed($modules * Implements hook_modules_uninstalled(). */ function user_modules_uninstalled($modules) { - db_delete('role_permission') - ->condition('module', $modules, 'IN') - ->execute(); + // Do not remove permissions that are defined by multiple modules. + $delete = array(); + foreach ($modules as $module) { + // hook_modules_uninstalled() is not supposed to be invoked via + // module_invoke() in uninstalled modules. + $function = $module . '_permission'; + if (function_exists($function)) { + $delete += $function(); + } + } + // If we have any permissions to delete, iterate over all other modules to + // identify uniquely defined permissions; the same permission can be defined + // by multiple modules. + if (!empty($delete)) { + foreach (array_diff(module_implements('permission'), $modules) as $module) { + if ($module_permissions = module_invoke($module, 'permission')) { + $delete = array_diff_key($delete, $module_permissions); + } + } + } + // If any unique permissions are left, delete them. + if ($delete) { + db_delete('role_permission') + ->condition('permission', array_keys($delete)) + // Extra safety. + ->condition('module', $modules) + ->execute(); + } } /**