--- drupal7_HEAD/modules/node/node.module	2008-07-24 13:38:29.983983000 +0300
+++ drupal7/modules/node/node.module	2008-07-24 14:36:52.625243000 +0300
@@ -2009,21 +2009,19 @@ function node_search_validate($form, &$f
  * blog author, and for the book module to always deny editing access to
  * PHP pages.
  *
- * If node module does not intervene (returns NULL), then the
- * node_access table is used to determine access. All node access
- * modules are queried using hook_node_grants() to assemble a list of
- * "grant IDs" for the user. This list is compared against the table.
- * If any row contains the node ID in question (or 0, which stands for "all
- * nodes"), one of the grant IDs returned, and a value of TRUE for the
- * operation in question, then access is granted. Note that this table is a
- * list of grants; any matching row is sufficient to grant access to the
- * node.
- *
- * In node listings, the process above is followed except that
- * hook_access() is not called on each node for performance reasons and for
- * proper functioning of the pager system. When adding a node listing to your
- * module, be sure to use db_rewrite_sql() to add
- * the appropriate clauses to your query for access checks.
+ * If node module does not intervene (returns NULL), then hook_node_access()
+ * is called, of all modules that implement it. The implementations are
+ * required to return TRUE for allow, FALSE for deny, and NULL for undecided.
+ * If any module returns deny, access is denied. If no module returns deny
+ * and any module returns allow, access is allowed. If no module returns
+ * either, access is denied by default. If no module implements the hook,
+ * view is allowed but edit and delete are denied by default.
+ *
+ * In node listings, the process above is followed except that hook_access()
+ * is not called on each node for performance reasons and for proper
+ * functioning of the pager system. When adding a node listing to your
+ * module, be sure to use db_rewrite_sql() to add the appropriate clauses
+ * to your query for access checks.
  *
  * To see how to write a node access module of your own, see
  * node_access_example.module.
@@ -2086,31 +2084,40 @@ function node_access($op, $node, $accoun
     return $access;
   }
 
-  // If the module did not override the access rights, use those set in the
-  // node_access table.
-  if ($op != 'create' && $node->nid && $node->status) {
-    $grants = array();
-    foreach (node_access_grants($op, $account) as $realm => $gids) {
-      foreach ($gids as $gid) {
-        $grants[] = "(gid = $gid AND realm = '$realm')";
-      }
-    }
-
-    $grants_sql = '';
-    if (count($grants)) {
-      $grants_sql = 'AND (' . implode(' OR ', $grants) . ')';
-    }
-
-    $sql = "SELECT COUNT(*) FROM {node_access} WHERE (nid = 0 OR nid = %d) $grants_sql AND grant_$op >= 1";
-    $result = db_query($sql, $node->nid);
-    return (db_result($result));
-  }
-
   // Let authors view their own nodes.
   if ($op == 'view' && $account->uid == $node->uid && $account->uid != 0) {
     return TRUE;
   }
 
+  // If the module did not override the access rights, call implementations of
+  // hook_node_access() on all modules.
+  if ($op != 'create' && $node->nid) {
+    $grants = module_invoke_all('node_access', $op, $node, $node->status, $account);
+    $deny_count = 0;
+    $allow_count = 0;
+    foreach ($grants as $grant) {
+      if ($grant === FALSE) {
+        // Deny request.
+        $deny_count += 1;
+      } elseif ($grant === TRUE) {
+        // Allow request, unless denied by another module.
+        $allow_count += 1;
+      } // Undecided, deny by default unless allowed by another module.
+    }
+    if ($deny_count) {
+      return FALSE;
+    } elseif ($allow_count) {
+      return TRUE;
+    } elseif (count($grants)) {
+      return FALSE;
+    } else {
+      if ($op == 'view') {
+        return TRUE;
+      } else {
+        return FALSE;
+      }
+    }
+  }
   return FALSE;
 }
 
