diff --git modules/node/node.module modules/node/node.module
index 9957e74..472c8e8 100644
--- modules/node/node.module
+++ modules/node/node.module
@@ -170,6 +170,12 @@ function node_theme() {
     'node_admin_overview' => array(
       'variables' => array('name' => NULL, 'type' => NULL),
     ),
+    'node_recent_block' => array(
+      'variables' => array('nodes' => NULL),
+    ),
+    'node_recent_content' => array(
+      'variables' => array('node' => NULL),
+    ),
   );
 }
 
@@ -2006,6 +2012,9 @@ function node_block_info() {
   $blocks['syndicate']['info'] = t('Syndicate');
   // Not worth caching.
   $blocks['syndicate']['cache'] = DRUPAL_NO_CACHE;
+
+  $blocks['recent']['info'] = t('Recent content');
+
   return $blocks;
 }
 
@@ -2013,13 +2022,141 @@ function node_block_info() {
  * Implement hook_block_view().
  */
 function node_block_view($delta = '') {
-  $block['subject'] = t('Syndicate');
-  $block['content'] = theme('feed_icon', array('url' => url('rss.xml'), 'title' => t('Syndicate')));
+  $block = array();
 
+  switch ($delta) {
+    case 'syndicate':
+      $block['subject'] = t('Syndicate');
+      $block['content'] = theme('feed_icon', array('url' => url('rss.xml'), 'title' => t('Syndicate')));
+      break;
+
+    case 'recent':
+      if (user_access('access content') && ($nodes = node_get_recent(variable_get('node_recent_block_count', 10)))) {
+        $block['subject'] = t('Recent content');
+        $block['content'] = theme('node_recent_block', array(
+          'nodes' => $nodes,
+        ));
+      }
+      break;
+  }
   return $block;
 }
 
 /**
+ * Implements hook_block_configure().
+ */
+function node_block_configure($delta = '') {
+  $form = array();
+  if ($delta == 'recent') {
+    $form['node_recent_block_count'] = array(
+      '#type' => 'select',
+      '#title' => t('Number of recent content items to display'),
+      '#default_value' => variable_get('node_recent_block_count', 10),
+      '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)),
+    );
+  }
+  return $form;
+}
+
+/**
+ * Implements hook_block_save().
+ */
+function node_block_save($delta = '', $edit = array()) {
+  if ($delta == 'recent') {
+    variable_set('node_recent_block_count', $edit['node_recent_block_count']);
+  }
+}
+
+/**
+ * Find the most recent nodes that are available to the current user.
+ *
+ * @param $number
+ *   (optional) The maximum number of nodes to find. Defaults to 10.
+ *
+ * @return
+ *   An array of partial node objects or an empty array if there are no recent
+ *   nodes visible to the current user.
+ */
+function node_get_recent($number = 10) {
+  $query = db_select('node', 'n');
+
+  if (!user_access('bypass node access')) {
+    // 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('view own unpublished content') && $own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = :status', array(':uid' => $GLOBALS['user']->uid, ':status' => NODE_NOT_PUBLISHED))->fetchCol()) {
+      $query->condition(db_or()
+        ->condition('n.status', NODE_PUBLISHED)
+        ->condition('n.nid', $own_unpublished, 'IN')
+      );
+    }
+    else {
+      // If not, restrict the query to published nodes.
+      $query->condition('n.status', NODE_PUBLISHED);
+    }
+  }
+  $nids = $query
+    ->fields('n', array('nid'))
+    ->orderBy('changed', 'DESC')
+    ->range(0, $number)
+    ->addTag('node_access')
+    ->execute()
+    ->fetchCol();
+
+  $nodes = node_load_multiple($nids);
+
+  return $nodes ? $nodes : array();
+}
+
+/**
+ * Returns a formatted list of recent nodes.
+ *
+ * @return
+ *   The recent content table HTML.
+ * @ingroup themeable
+ */
+function theme_node_recent_block($variables) {
+  $rows = array();
+  $output = '';
+
+  $l_options = array('query' => drupal_get_destination());
+  foreach ($variables['nodes'] as $node) {
+    $row = array();
+    $row[] = theme('node_recent_content', array('node' => $node));
+    $row[] = node_access('update', $node) ? l(t('edit'), 'node/' . $node->nid . '/edit', $l_options) : '';
+    $row[] = node_access('delete', $node) ? l(t('delete'), 'node/' . $node->nid . '/delete', $l_options) : '';
+    $rows[] = $row;
+  }
+
+  if ($rows) {
+    $output = theme('table', array('rows' => $rows));
+    $output .= '<div class="list-all">' . l(t('Show all content'), 'admin/content') . '</div>';
+  }
+
+  return $output;
+}
+
+/**
+ * Returns a formatted recent node to be displayed in the recent content block.
+ *
+ * @return
+ *   The recent content node's HTML.
+ * @ingroup themeable
+ */
+function theme_node_recent_content($variables) {
+  $node = $variables['node'];
+
+  $output = '<div class="node-title">';
+  $output .= l($node->title[LANGUAGE_NONE][0]['safe'], 'node/' . $node->nid);
+  $output .= theme('mark', array('type' => node_mark($node->nid, $node->changed)));
+  $output .= '</div><div class="node-author">';
+  $output .= theme('username', array('account' => user_load($node->uid)));
+  $output .= '</div>';
+
+  return $output;
+}
+
+/**
  * A generic function for generating RSS feeds from a set of nodes.
  *
  * @param $nids
diff --git modules/node/node.test modules/node/node.test
index d2778e1..07b9b2c 100644
--- modules/node/node.test
+++ modules/node/node.test
@@ -1166,3 +1166,92 @@ class NodeFeedTestCase extends DrupalWebTestCase {
     $this->assertTrue(strpos($output, '<copyright>Drupal is a registered trademark of Dries Buytaert.</copyright>') !== FALSE);
   }
 }
+
+/**
+ * Functional tests for the comment module blocks.
+ */
+class NodeBlockFunctionalTest extends DrupalWebTestCase {
+  protected $admin_user;
+  protected $web_user;
+  protected $anon_user;
+  
+  public static function getInfo() {
+    return array(
+      'name' => 'Node blocks',
+      'description' => 'Test node block functionality.',
+      'group' => 'Node',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('node');
+    // Create users and test node.
+    $this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer nodes', 'administer blocks'));
+    $this->web_user = $this->drupalCreateUser(array('access content', 'create article content'));
+    $this->anon_user = $this->drupalCreateUser(array());
+  }
+
+
+  /**
+   * Test the recent comments block.
+   */
+  function testRecentNodeBlock() {
+    $this->drupalLogin($this->admin_user);
+
+    // Set the block to a region to confirm block is available.
+    $edit = array(
+      'node_recent[region]' => 'sidebar_first',
+    );
+    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
+    $this->assertText(t('The block settings have been updated.'), t('Block saved to first sidebar region.'));
+
+    // Set block title and variables.
+    $block = array(
+      'title' => $this->randomName(),
+      'node_recent_block_count' => 2,
+    );
+    $this->drupalPost('admin/structure/block/manage/node/recent/configure', $block, t('Save block'));
+    $this->assertText(t('The block configuration has been saved.'), t('Block saved.'));
+
+    $default_settings = array('uid' => $this->web_user->uid, 'type' => 'article');
+ 
+    // Add some test nodes.
+    $node1 = $this->drupalCreateNode($default_settings);
+    $node2 = $this->drupalCreateNode($default_settings);
+    $node3 = $this->drupalCreateNode($default_settings);
+
+    // Test that a user without the 'access content' permission cannot
+    // see the block.
+    $this->drupalLogin($this->anon_user);
+    $this->drupalGet('');
+    $this->assertNoText($block['title'], t('Block was not found.'));
+
+    $this->drupalLogin($this->web_user);
+    $this->drupalGet('');
+    $this->assertText($block['title'], t('Block was found.'));
+
+    // Test that only the 2 latest nodes are shown and in the proper order.
+    $this->assertNoText($node1->title['zxx'][0]['value'], t('Node not found in block.'));
+    $this->assertText($node2->title['zxx'][0]['value'], t('Node found in block.'));
+    $this->assertText($node3->title['zxx'][0]['value'], t('Node found in block.'));
+    $this->assertTrue(strpos($this->drupalGetContent(), $node3->title['zxx'][0]['value']) < strpos($this->drupalGetContent(), $node2->title['zxx'][0]['value']), t('Nodes were ordered correctly in block.'));
+
+    // Set the number of recent comments to show to 10.
+    $this->drupalLogout();
+    $this->drupalLogin($this->admin_user);
+    $block = array(
+      'node_recent_block_count' => 10,
+    );
+    $this->drupalPost('admin/structure/block/manage/node/recent/configure', $block, t('Save block'));
+    $this->assertText(t('The block configuration has been saved.'), t('Block saved.'));
+
+    // Post an additional node.
+    $node4 = $this->drupalCreateNode($default_settings);
+
+    // Test that all four nodes are shown.
+    $this->assertText($node1->title['zxx'][0]['value'], t('Node found in block.'));
+    $this->assertText($node2->title['zxx'][0]['value'], t('Node found in block.'));
+    $this->assertText($node3->title['zxx'][0]['value'], t('Node found in block.'));
+    $this->assertText($node4->title['zxx'][0]['value'], t('Node found in block.'));
+  }
+}
diff --git profiles/default/default.install profiles/default/default.install
index 7703595..743c3f4 100644
--- profiles/default/default.install
+++ profiles/default/default.install
@@ -121,6 +121,16 @@ function default_install() {
       'cache' => -1,
     ),
     array(
+      'module' => 'node',
+      'delta' => 'recent',
+      'theme' => 'seven',
+      'status' => 1,
+      'weight' => 10,
+      'region' => 'dashboard_main',
+      'pages' => '',
+      'cache' => -1,
+    ),
+    array(
       'module' => 'user',
       'delta' => 'new',
       'theme' => 'seven',
