Index: modules/node/node.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v
retrieving revision 1.60
diff -u -p -r1.60 node.admin.inc
--- modules/node/node.admin.inc	30 Jul 2009 19:24:21 -0000	1.60
+++ modules/node/node.admin.inc	15 Aug 2009 22:10:14 -0000
@@ -397,7 +397,9 @@ function node_admin_nodes() {
 
   // Build the sortable table header.
   $header = array();
-  $header[] = theme('table_select_header_cell');
+  if (user_access('administer nodes') && user_access('bypass node access')) {
+    $header[] = theme('table_select_header_cell');
+  }
   $header[] = array('data' => t('Title'), 'field' => 'n.title');
   $header[] = array('data' => t('Type'), 'field' => 'n.type');
   $header[] = array('data' => t('Author'), 'field' => 'u.name');
@@ -414,14 +416,25 @@ function node_admin_nodes() {
   );
 
   $query = db_select('node', 'n')->extend('PagerDefault')->extend('TableSort');
-  $query->join('users', 'u', 'n.uid = u.uid');
   node_build_filter_query($query);
 
-  $result = $query
+  // If the user is able to view their own unpublished nodes, allow them
+  // to see these in addition to published nodes. Check that they actually
+  // have some unpublished nodes to view before adding the condition.
+  if (!user_access('bypass node access') && user_access('view own unpublished content') && $own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = 0', array(':uid' => $GLOBALS['user']->uid))->fetchCol();) {
+    $query->condition(db_or()->condition('n.status', 1)->condition('n.nid', $own_unpublished, 'IN'));
+  }
+  // If not, restrict the query to published nodes unless the user has the
+  // bypass node access permission.
+  else if (!user_access('bypass node access')) {
+    $query->condition('n.status', 1);
+  }
+
+  $nids = $query
     ->fields('n')
-    ->fields('u', array('name'))
     ->limit(50)
-    ->execute();
+    ->execute()->fetchCol();
+  $nodes = node_load_multiple($nids);
 
   // Build the 'Update options' form.
   $form['options'] = array(
@@ -429,6 +442,7 @@ function node_admin_nodes() {
     '#title' => t('Update options'),
     '#prefix' => '<div class="container-inline">',
     '#suffix' => '</div>',
+    '#access' => user_access('administer nodes') && user_access('bypass node access'),
   );
   $options = array();
   foreach (module_invoke_all('node_operations') as $operation => $array) {
@@ -447,9 +461,9 @@ function node_admin_nodes() {
 
   $languages = language_list();
   $destination = drupal_get_destination();
-  $nodes = array();
-  foreach ($result as $node) {
-    $nodes[$node->nid] = '';
+  $nids = array();
+  foreach ($nodes as $node) {
+    $nids[$node->nid] = '';
     $options = empty($node->language) ? array() : array('language' => $languages[$node->language]);
     $form['title'][$node->nid] = array('#markup' => l($node->title, 'node/' . $node->nid, $options) . ' ' . theme('mark', node_mark($node->nid, $node->changed)));
     $form['name'][$node->nid] =  array('#markup' => check_plain(node_type_get_name($node)));
@@ -459,11 +473,12 @@ function node_admin_nodes() {
     if ($multilanguage) {
       $form['language'][$node->nid] = array('#markup' => empty($node->language) ? t('Language neutral') : t($languages[$node->language]->name));
     }
-    $form['operations'][$node->nid] = array('#markup' => l(t('edit'), 'node/' . $node->nid . '/edit', array('query' => $destination)));
+    $form['operations'][$node->nid] = array('#access' => node_access('update', $node), '#markup' => l(t('edit'), 'node/' . $node->nid . '/edit', array('query' => $destination)));
   }
   $form['nodes'] = array(
     '#type' => 'checkboxes',
-    '#options' => $nodes,
+    '#options' => $nids,
+    '#access' => user_access('administer nodes') && user_access('bypass node access'),
   );
   $form['pager'] = array('#markup' => theme('pager', NULL));
   $form['#theme'] = 'node_admin_nodes';
@@ -529,7 +544,9 @@ function theme_node_admin_nodes($form) {
     $rows = array();
     foreach (element_children($form['title']) as $key) {
       $row = array();
-      $row[] = drupal_render($form['nodes'][$key]);
+      if (user_access('administer nodes') && user_access('bypass node access')) {
+        $row[] = drupal_render($form['nodes'][$key]);
+      }
       $row[] = drupal_render($form['title'][$key]);
       $row[] = drupal_render($form['name'][$key]);
       $row[] = drupal_render($form['username'][$key]);
@@ -599,4 +616,4 @@ function node_multiple_delete_confirm_su
 function node_modules_installed($modules) {
   // Clear node type cache for node permissions.
   node_type_clear();
-}
\ No newline at end of file
+}
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1099
diff -u -p -r1.1099 node.module
--- modules/node/node.module	14 Aug 2009 13:53:01 -0000	1.1099
+++ modules/node/node.module	15 Aug 2009 22:10:14 -0000
@@ -1285,6 +1285,10 @@ function node_permission() {
       'title' => t('Bypass node access'),
       'description' => t('View, edit and delete all site content. Users with this permission will bypass any content-related access control. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))),
     ),
+    'access content overview' => array(
+      'title' => t('Access content overview'),
+      'description' => t('Access the content overview page.'),
+    ),
     'view revisions' => array(
       'title' => t('View revisions'),
       'description' => t('View content revisions.'),
@@ -1645,7 +1649,7 @@ function node_menu() {
     'title' => 'Content',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('node_admin_content'),
-    'access arguments' => array('administer nodes'),
+    'access callback' => 'node_admin_page_access',
     'weight' => -10,
   );
   $items['admin/content/node'] = array(
@@ -3150,3 +3154,10 @@ function node_requirements($phase) {
   );
   return $requirements;
 }
+
+/**
+ * Checks whether the current user has access to the content list page.
+ */
+function node_admin_page_access() {
+return user_access('administer nodes') || user_access('access content overview');
+}
Index: modules/node/node.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.test,v
retrieving revision 1.38
diff -u -p -r1.38 node.test
--- modules/node/node.test	28 Jul 2009 19:18:06 -0000	1.38
+++ modules/node/node.test	15 Aug 2009 22:10:16 -0000
@@ -362,6 +362,47 @@ class PageViewTestCase extends DrupalWeb
   }
 }
 
+/**
+ * Test the functionality of the administer content page.
+ */
+class ContentAdminTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+     return array(
+      'name' => t('Content administration overview'),
+      'description' => t('Create users and content to test the content admin pages functionality.'),
+      'group' => t('Node'),
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer nodes', 'bypass node access'));
+    $this->base_user = $this->drupalCreateUser(array('access content overview'));
+  }
+
+  /**
+   * Ensure that both administrative users and basic content editors have
+   * access to the appropriate functionality on the node administration page.
+   */
+  function testContentAdminPages() {
+    $this->drupalLogin($this->admin_user);
+
+    // Ensure the admin user can edit any content.
+    $created_node = $this->drupalCreateNode(array('type' => 'page'));
+    $this->drupalGet('admin/content/node');
+    $this->assertResponse(200);
+    $this->assertText('edit', t('Admin user has edit link.'));
+    $this->drupalLogout();
+
+    // Ensure users don't see edit links for content they don't have rights to edit.
+    $this->drupalLogin($this->base_user);
+    $this->drupalGet('admin/content/node');
+    $this->assertResponse(200);
+    $this->assertText($created_node->title, t('Edit links disabled without edit permissions.'));
+    $this->assertNoText('edit', t('Edit links do not show up for users without rights.'));
+  }
+}
+
 class SummaryLengthTestCase extends DrupalWebTestCase {
   public static function getInfo() {
     return array(
