Index: modules/profile/profile.module =================================================================== RCS file: /cvs/drupal/drupal/modules/profile/profile.module,v retrieving revision 1.284 diff -u -r1.284 profile.module --- modules/profile/profile.module 14 Dec 2009 20:38:15 -0000 1.284 +++ modules/profile/profile.module 23 Dec 2009 03:08:28 -0000 @@ -511,7 +511,7 @@ /** * Menu item access callback - check if a user has access to a profile category. */ -function profile_category_access($account, $category) { +function profile_category_access($uid, $category) { if (user_access('administer users') && $account->uid > 0) { return TRUE; } @@ -520,7 +520,7 @@ ':category' => $category, ':visibility' => PROFILE_HIDDEN ))->fetchField(); - return user_edit_access($account) && $category_visible; + return user_edit_access($uid) && $category_visible; } } Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1188 diff -u -r1.1188 node.module --- modules/node/node.module 22 Dec 2009 20:38:23 -0000 1.1188 +++ modules/node/node.module 23 Dec 2009 03:08:28 -0000 @@ -1736,9 +1736,10 @@ return $output; } -function _node_revision_access($node, $op = 'view') { +function _node_revision_access($nid, $vid, $op = 'view') { $access = &drupal_static(__FUNCTION__, array()); - if (!isset($access[$node->vid])) { + if (!isset($access[$vid])) { + $node = node_load($nid, $vid); $node_current_revision = node_load($node->nid); $is_current_revision = $node_current_revision->vid == $node->vid; // There should be at least two revisions. If the vid of the given node @@ -1760,7 +1761,7 @@ $access[$node->vid] = isset($map[$op]) && user_access($map[$op]) && node_access($op, $node_current_revision) && ($is_current_revision || node_access($op, $node)); } } - return $access[$node->vid]; + return $access[$vid]; } function _node_add_access() { @@ -1941,7 +1942,7 @@ 'page callback' => 'node_show', 'page arguments' => array(1, TRUE), 'access callback' => '_node_revision_access', - 'access arguments' => array(1), + 'access arguments' => array(1, 3), 'type' => MENU_CALLBACK, ); $items['node/%node/revisions/%/revert'] = array( @@ -1950,7 +1951,7 @@ 'page callback' => 'drupal_get_form', 'page arguments' => array('node_revision_revert_confirm', 1), 'access callback' => '_node_revision_access', - 'access arguments' => array(1, 'update'), + 'access arguments' => array(1, 3, 'update'), 'type' => MENU_CALLBACK, 'file' => 'node.pages.inc', ); @@ -1960,7 +1961,7 @@ 'page callback' => 'drupal_get_form', 'page arguments' => array('node_revision_delete_confirm', 1), 'access callback' => '_node_revision_access', - 'access arguments' => array(1, 'delete'), + 'access arguments' => array(1, 3, 'delete'), 'type' => MENU_CALLBACK, 'file' => 'node.pages.inc', ); @@ -2462,15 +2463,34 @@ function node_access($op, $node, $account = NULL) { global $user; - if (!$node || !in_array($op, array('view', 'update', 'delete', 'create'), TRUE)) { - // If there was no node to check against, or the $op was not one of the - // supported ones, we return access denied. + if (!in_array($op, array('view', 'update', 'delete', 'create'), TRUE)) { + // If $op was not one of the supported ones, we return access denied. return FALSE; } - // If no user object is supplied, the access check is for the current user. - if (empty($account)) { + + // If no account is supplied, the access check is for the current user. + if (!isset($account) || (is_numeric($account) && $account == $user->uid)) { $account = $user; } + elseif (is_numeric($account)) { + // Construct a skeleton $account if only a uid is given. + $account = (object)array('uid' => intval($account)); + } + + if ($op == 'create') { + // If $op is 'create', all we have is $node->type. + $node = (object)array('nid' => NULL, 'type' => $node, 'uid' => NULL); + } + else { + // If given a nid in place of $node, construct a skeleton $node. + if (is_numeric($node)) { + $node = db_query("SELECT nid, type, uid, status FROM {node} WHERE nid = :nid", array(':nid' => $node))->fetch(); + } + // If the node does not exist, the operation is not allowed. + if (!$node) { + return FALSE; + } + } if (user_access('bypass node access', $account)) { return TRUE; @@ -2485,7 +2505,7 @@ // - At least one module says to grant access. // If no module specified either allow or deny, we fall back to the // node_access table. - $access = module_invoke_all('node_access', $node, $op, $account); + $access = module_invoke_all('node_access', $op, $node->type, $account->uid, $node->nid, $node->uid); if (in_array(NODE_ACCESS_DENY, $access, TRUE)) { return FALSE; } @@ -2494,7 +2514,7 @@ } // Check if authors can view their own unpublished nodes. - if ($op == 'view' && !$node->status && user_access('view own unpublished content', $account) && $account->uid == $node->uid && $account->uid != 0) { + if ($op == 'view' && !$node->status && $account->uid != 0 && $account->uid == $node->uid && user_access('view own unpublished content', $account)) { return TRUE; } @@ -2512,7 +2532,7 @@ $query->range(0, 1); $grants = db_or(); - foreach (node_access_grants($op, $account) as $realm => $gids) { + foreach (node_access_grants($op, $account->uid) as $realm => $gids) { foreach ($gids as $gid) { $grants->condition(db_and() ->condition('gid', $gid) @@ -2534,22 +2554,21 @@ /** * Implements hook_node_access(). */ -function node_node_access($node, $op, $account) { - $type = is_string($node) ? $node : $node->type; +function node_node_access($op, $type, $uid, $nid, $node_uid) { if (in_array($type, node_permissions_get_configured_types())) { - if ($op == 'create' && user_access('create ' . $type . ' content', $account)) { + if ($op == 'create' && user_access('create ' . $type . ' content', $uid)) { return NODE_ACCESS_ALLOW; } if ($op == 'update') { - if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->uid == $node->uid))) { + if (user_access('edit any ' . $type . ' content', $uid) || (user_access('edit own ' . $type . ' content', $uid) && ($uid == $node_uid))) { return NODE_ACCESS_ALLOW; } } if ($op == 'delete') { - if (user_access('delete any ' . $type . ' content', $account) || (user_access('delete own ' . $type . ' content', $account) && ($account->uid == $node->uid))) { + if (user_access('delete any ' . $type . ' content', $uid) || (user_access('delete own ' . $type . ' content', $uid) && ($uid == $node_uid))) { return NODE_ACCESS_ALLOW; } } @@ -2640,15 +2659,19 @@ * arrays of grants for those realms. */ function node_access_grants($op, $account = NULL) { + global $user; - if (!isset($account)) { - $account = $GLOBALS['user']; + if (!isset($account) || (is_numeric($account) && $account == $user->uid)) { + $account = $user; + } + elseif (is_numeric($account)) { + $account = (object)array('uid' => $account); } // Fetch node access grants from other modules. - $grants = module_invoke_all('node_grants', $account, $op); + $grants = module_invoke_all('node_grants', $account->uid, $op); // Allow modules to alter the assigned grants. - drupal_alter('node_grants', $grants, $account, $op); + drupal_alter('node_grants', $grants, $account->uid, $op); return array_merge(array('all' => array(0)), $grants); } @@ -2713,6 +2736,7 @@ $or = db_or(); // If any grant exists for the specified user, then user has access to the // node for the specified operation. + // TODO: where does the 'account' metadata get set? foreach (node_access_grants($op, $query->getMetaData('account')) as $realm => $gids) { foreach ($gids as $gid) { $or->condition(db_and() Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.369 diff -u -r1.369 menu.inc --- includes/menu.inc 17 Dec 2009 13:10:18 -0000 1.369 +++ includes/menu.inc 23 Dec 2009 03:08:27 -0000 @@ -419,8 +419,6 @@ } if ($router_item['access']) { $router_item['map'] = $map; - $router_item['page_arguments'] = array_merge(menu_unserialize($router_item['page_arguments'], $map), array_slice($map, $router_item['number_parts'])); - $router_item['theme_arguments'] = array_merge(menu_unserialize($router_item['theme_arguments'], $map), array_slice($map, $router_item['number_parts'])); } } $router_items[$path] = $router_item; @@ -456,10 +454,18 @@ // to make alterations just for this request. drupal_alter('menu_active_handler', $router_item, $path); if ($router_item['access']) { - if ($router_item['file']) { - require_once DRUPAL_ROOT . '/' . $router_item['file']; + if (!empty($router_item['load_functions']) && !_menu_load_objects($router_item, $router_item['map'])) { + // An error occurred loading an object. + $page_callback_result = MENU_ACCESS_DENIED; + } + else { + $router_item['page_arguments'] = array_merge(menu_unserialize($router_item['page_arguments'], $router_item['map']), array_slice($router_item['map'], $router_item['number_parts'])); + menu_set_item($path, $router_item); + if ($router_item['file']) { + require_once DRUPAL_ROOT . '/' . $router_item['file']; + } + $page_callback_result = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']); } - $page_callback_result = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']); } else { $page_callback_result = MENU_ACCESS_DENIED; @@ -698,11 +704,6 @@ // The $path_map saves the pieces of the path as strings, while elements in // $map may be replaced with loaded objects. $path_map = $map; - if (!empty($router_item['load_functions']) && !_menu_load_objects($router_item, $map)) { - // An error occurred loading an object. - $router_item['access'] = FALSE; - return FALSE; - } // Generate the link path for the page request or local tasks. $link_map = explode('/', $router_item['path']); @@ -715,6 +716,9 @@ $router_item['options'] = array(); _menu_check_access($router_item, $map); + // Translate theme arguments now, so menu_get_custom_theme() can work. + $router_item['theme_arguments'] = array_merge(menu_unserialize($router_item['theme_arguments'], $map), array_slice($map, $router_item['number_parts'])); + // For performance, don't localize an item the user can't access. if ($router_item['access']) { _menu_item_localize($router_item, $map); @@ -789,13 +793,9 @@ } // menu_tree_check_access() may set this ahead of time for links to nodes. if (!isset($item['access'])) { - if (!empty($item['load_functions']) && !_menu_load_objects($item, $map)) { - // An error occurred loading an object. - $item['access'] = FALSE; - return FALSE; - } _menu_check_access($item, $map); } + // For performance, don't localize a link the user can't access. if ($item['access']) { _menu_item_localize($item, $map, TRUE); Index: modules/poll/poll.module =================================================================== RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v retrieving revision 1.329 diff -u -r1.329 poll.module --- modules/poll/poll.module 14 Dec 2009 20:38:15 -0000 1.329 +++ modules/poll/poll.module 23 Dec 2009 03:08:28 -0000 @@ -116,7 +116,8 @@ /** * Callback function to see if a node is acceptable for poll menu items. */ -function _poll_menu_access($node, $perm, $inspect_allowvotes) { +function _poll_menu_access($nid, $perm, $inspect_allowvotes) { + $node = node_load($nid); return user_access($perm) && ($node->type == 'poll') && ($node->allowvotes || !$inspect_allowvotes); } Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.1094 diff -u -r1.1094 user.module --- modules/user/user.module 22 Dec 2009 14:47:14 -0000 1.1094 +++ modules/user/user.module 23 Dec 2009 03:08:29 -0000 @@ -721,9 +721,13 @@ function user_access($string, $account = NULL) { global $user; - if (!isset($account)) { + if (!isset($account) || (is_numeric($account) && $account == $user->uid)) { $account = $user; } + elseif (is_numeric($account)) { + // Construct a skeleton $account if only a uid is given. + $account = (object)array('uid' => intval($account)); + } // User #1 has all privileges: if ($account->uid == 1) { @@ -737,6 +741,11 @@ isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__)); $perm = &$drupal_static[__FUNCTION__]; if (!isset($perm[$account->uid])) { + // Load roles for this user. + if (empty($account->roles) && $account->uid) { + $account->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; + $account->roles += db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = :uid", array(':uid' => $account->uid))->fetchAllKeyed(0, 1); + } $role_permissions = user_role_permissions($account->roles); $perms = array(); @@ -1350,10 +1359,17 @@ } function user_view_access($account) { + global $user; + if (is_numeric($account) && $account == $user->uid) { + $account = $user; + } + elseif (is_numeric($account)) { + $account = db_query("SELECT uid, access, status FROM {users} WHERE uid = :uid", array(':uid' => $account))->fetch(); + } return $account && $account->uid && ( // Always let users view their own profile. - ($GLOBALS['user']->uid == $account->uid) || + ($user->uid == $account->uid) || // Administrators can view all accounts. user_access('administer users') || // The user is not blocked and logged in at least once. @@ -1364,8 +1380,8 @@ /** * Access callback for user account editing. */ -function user_edit_access($account) { - return (($GLOBALS['user']->uid == $account->uid) || user_access('administer users')) && $account->uid > 0; +function user_edit_access($uid) { + return (($GLOBALS['user']->uid == $uid) || user_access('administer users')) && $uid > 0; } /** @@ -1374,8 +1390,8 @@ * Limit access to users with the 'cancel account' permission or administrative * users, and prevent the anonymous user from cancelling the account. */ -function user_cancel_access($account) { - return ((($GLOBALS['user']->uid == $account->uid) && user_access('cancel account')) || user_access('administer users')) && $account->uid > 0; +function user_cancel_access($uid) { + return ((($GLOBALS['user']->uid == $uid) && user_access('cancel account')) || user_access('administer users')) && $uid > 0; } function user_load_self($arg) { @@ -2849,10 +2865,9 @@ // the authenticated role. If so, then all users would be listed, and we can // skip adding it to the filter query. if ($key == 'permission') { - $account = new stdClass(); - $account->uid = 'user_filter'; - $account->roles = array(DRUPAL_AUTHENTICATED_RID => 1); - if (user_access($value, $account)) { + $role_permissions = user_role_permissions(array(DRUPAL_AUTHENTICATED_RID => 1)); + + if (isset($role_permissions[DRUPAL_AUTHENTICATED_RID]) && isset($role_permissions[DRUPAL_AUTHENTICATED_RID][$value])) { continue; } $query->leftJoin('role_permission', 'p', 'ur.rid = p.rid'); Index: modules/translation/translation.module =================================================================== RCS file: /cvs/drupal/drupal/modules/translation/translation.module,v retrieving revision 1.68 diff -u -r1.68 translation.module --- modules/translation/translation.module 6 Dec 2009 17:56:05 -0000 1.68 +++ modules/translation/translation.module 23 Dec 2009 03:08:28 -0000 @@ -77,7 +77,8 @@ * and where the current node is not language neutral (which should span * all languages). */ -function _translation_tab_access($node) { +function _translation_tab_access($nid) { + $node = node_load($nid); if ($node->language != LANGUAGE_NONE && translation_supported_type($node->type)) { return user_access('translate content'); } Index: modules/blog/blog.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blog/blog.module,v retrieving revision 1.347 diff -u -r1.347 blog.module --- modules/blog/blog.module 22 Dec 2009 20:38:23 -0000 1.347 +++ modules/blog/blog.module 23 Dec 2009 03:08:27 -0000 @@ -153,21 +153,22 @@ /** * Access callback for user blog pages. */ -function blog_page_user_access($account) { +function blog_page_user_access($uid) { // The visitor must be able to access the site's content. // For a blog to 'exist' the user must either be able to // create new blog entries, or it must have existing posts. - return $account->uid && user_access('access content') && (user_access('create blog content', $account) || _blog_post_exists($account)); + $account = db_query("SELECT uid FROM {users} WHERE uid = :uid", array(':uid' => $uid))->fetch(); + return $account && user_access('access content') && (user_access('create blog content', $uid) || _blog_post_exists($uid)); } /** * Helper function to determine if a user has blog posts already. */ -function _blog_post_exists($account) { +function _blog_post_exists($uid) { return (bool)db_select('node', 'n') ->fields('n', array('nid')) ->condition('type', 'blog') - ->condition('uid', $account->uid) + ->condition('uid', $uid) ->condition('status', 1) ->range(0, 1) ->addTag('node_access') Index: modules/contact/contact.module =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.module,v retrieving revision 1.140 diff -u -r1.140 contact.module --- modules/contact/contact.module 14 Dec 2009 20:38:15 -0000 1.140 +++ modules/contact/contact.module 23 Dec 2009 03:08:27 -0000 @@ -120,9 +120,11 @@ * TRUE if the current user has access to the requested user's contact form, * or FALSE otherwise. */ -function _contact_personal_tab_access(stdClass $account) { +function _contact_personal_tab_access($uid) { global $user; + $account = user_load($uid); + // Anonymous users cannot have contact forms. if (!$account->uid) { return FALSE; Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.820 diff -u -r1.820 comment.module --- modules/comment/comment.module 22 Dec 2009 20:38:23 -0000 1.820 +++ modules/comment/comment.module 23 Dec 2009 03:08:27 -0000 @@ -1250,6 +1250,10 @@ function comment_access($op, $comment) { global $user; + if (is_numeric($comment)) { + $comment = db_query("SELECT cid, uid FROM {comment} WHERE cid = :cid", array(':cid' => $comment))->fetch(); + } + if ($op == 'edit') { return ($user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0) || user_access('administer comments'); } Index: modules/tracker/tracker.module =================================================================== RCS file: /cvs/drupal/drupal/modules/tracker/tracker.module,v retrieving revision 1.171 diff -u -r1.171 tracker.module --- modules/tracker/tracker.module 4 Dec 2009 16:49:47 -0000 1.171 +++ modules/tracker/tracker.module 23 Dec 2009 03:08:28 -0000 @@ -151,16 +151,16 @@ /** * Access callback for tracker/%user_uid_optional. */ -function _tracker_myrecent_access($account) { +function _tracker_myrecent_access($uid) { // This path is only allowed for authenticated users looking at their own content. - return $account->uid && ($GLOBALS['user']->uid == $account->uid) && user_access('access content'); + return $uid && ($GLOBALS['user']->uid == $uid) && user_access('access content'); } /** * Access callback for user/%user/track. */ -function _tracker_user_access($account) { - return user_view_access($account) && user_access('access content'); +function _tracker_user_access($uid) { + return user_view_access($uid) && user_access('access content'); } /** Index: modules/filter/filter.module =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v retrieving revision 1.313 diff -u -r1.313 filter.module --- modules/filter/filter.module 22 Dec 2009 14:47:14 -0000 1.313 +++ modules/filter/filter.module 23 Dec 2009 03:08:28 -0000 @@ -124,8 +124,9 @@ * TRUE if the text format can be deleted by the current user, FALSE * otherwise. */ -function _filter_delete_format_access($format) { +function _filter_delete_format_access($format_id) { // The fallback format can never be deleted. + $format = filter_format_load($format_id); return user_access('administer filters') && ($format->format != filter_fallback_format()); } Index: modules/book/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.module,v retrieving revision 1.531 diff -u -r1.531 book.module --- modules/book/book.module 21 Dec 2009 13:47:31 -0000 1.531 +++ modules/book/book.module 23 Dec 2009 03:08:27 -0000 @@ -201,15 +201,16 @@ /** * Menu item access callback - determine if the outline tab is accessible. */ -function _book_outline_access($node) { - return user_access('administer book outlines') && node_access('view', $node); +function _book_outline_access($nid) { + return user_access('administer book outlines') && node_access('view', $nid); } /** * Menu item access callback - determine if the user can remove nodes from the outline. */ -function _book_outline_remove_access($node) { - return isset($node->book) && ($node->book['bid'] != $node->nid) && _book_outline_access($node); +function _book_outline_remove_access($nid) { + $node = node_load($nid); + return isset($node->book) && ($node->book['bid'] != $nid) && _book_outline_access($nid); } /** Index: modules/shortcut/shortcut.module =================================================================== RCS file: /cvs/drupal/drupal/modules/shortcut/shortcut.module,v retrieving revision 1.12 diff -u -r1.12 shortcut.module --- modules/shortcut/shortcut.module 14 Dec 2009 20:38:15 -0000 1.12 +++ modules/shortcut/shortcut.module 23 Dec 2009 03:08:28 -0000 @@ -165,14 +165,14 @@ * TRUE if the current user has access to edit the shortcut set, FALSE * otherwise. */ -function shortcut_set_edit_access($shortcut_set = NULL) { +function shortcut_set_edit_access($set_name = NULL) { // Sufficiently-privileged users can edit their currently displayed shortcut // set, but not other sets. Shortcut administrators can edit any set. if (user_access('administer shortcuts')) { return TRUE; } if (user_access('customize shortcut links')) { - return !isset($shortcut_set) || $shortcut_set == shortcut_current_displayed_set(); + return !isset($set_name) || (($default_set = shortcut_current_displayed_set()) && $set_name == $default_set->set_name); } return FALSE; } @@ -187,20 +187,21 @@ * TRUE if the current user has access to switch the shortcut set of the * provided account, FALSE otherwise. */ -function shortcut_set_switch_access($account = NULL) { +function shortcut_set_switch_access($uid = NULL) { global $user; // Sufficiently-privileged users can switch their own shortcut sets, but not // those of other users. Shortcut administrators can switch any user's set. - return user_access('administer shortcuts') || (user_access('switch shortcut sets') && (!isset($account) || $user->uid == $account->uid)); + return user_access('administer shortcuts') || (user_access('switch shortcut sets') && (!isset($uid) || $user->uid == $uid)); } /** * Access callback for editing a link in a shortcut set. */ -function shortcut_link_access($menu_link) { +function shortcut_link_access($mlid) { // The link must belong to a shortcut set that the current user has access // to edit. - if ($shortcut_set = shortcut_set_load($menu_link['menu_name'])) { + $menu_name = db_query("SELECT menu_name FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $mlid))->fetchField(); + if ($menu_name && ($shortcut_set = shortcut_set_load($menu_name))) { return shortcut_set_edit_access($shortcut_set); } return FALSE; Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.552 diff -u -r1.552 taxonomy.module --- modules/taxonomy/taxonomy.module 21 Dec 2009 13:47:32 -0000 1.552 +++ modules/taxonomy/taxonomy.module 23 Dec 2009 03:08:28 -0000 @@ -313,8 +313,9 @@ /** * Return edit access for a given term. */ -function taxonomy_term_edit_access($term) { - return user_access("edit terms in $term->vid") || user_access('administer taxonomy'); +function taxonomy_term_edit_access($tid) { + $vid = db_query("SELECT vid FROM {taxonomy_term_data} WHERE tid = :tid", array(':tid' => $tid))->fetchField(); + return user_access("edit terms in $vid") || user_access('administer taxonomy'); } /**