Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 54996)
+++ wp-includes/post.php	(working copy)
@@ -4234,9 +4234,10 @@
  * @param string $post_type Post type.
  * @param bool $full Optional. Returns a full WHERE statement instead of just an 'andalso' term.
  * @param int $post_author Optional. Query posts having a single author ID.
+ * @param bool $public_only Optional. Only return public posts. Skips cap checks for $current_user.  Default is false.
  * @return string SQL WHERE code that can be added to a query.
  */
-function get_posts_by_author_sql( $post_type, $full = true, $post_author = null ) {
+function get_posts_by_author_sql( $post_type, $full = true, $post_author = null, $public_only = false ) {
 	global $user_ID, $wpdb;
 
 	// Private posts
@@ -4260,18 +4261,21 @@
 
 	$sql .= "(post_status = 'publish'";
 
-	if ( current_user_can( $cap ) ) {
-		// Does the user have the capability to view private posts? Guess so.
-		$sql .= " OR post_status = 'private'";
-	} elseif ( is_user_logged_in() ) {
-		// Users can view their own private posts.
-		$id = (int) $user_ID;
-		if ( null === $post_author || ! $full ) {
-			$sql .= " OR post_status = 'private' AND post_author = $id";
-		} elseif ( $id == (int) $post_author ) {
+	// Only need to check the cap if $public_only is false
+	if ( false === $public_only ) {
+		if ( current_user_can( $cap ) ) {
+			// Does the user have the capability to view private posts? Guess so.
 			$sql .= " OR post_status = 'private'";
+		} elseif ( is_user_logged_in() ) {
+			// Users can view their own private posts.
+			$id = (int) $user_ID;
+			if ( null === $post_author || ! $full ) {
+				$sql .= " OR post_status = 'private' AND post_author = $id";
+			} elseif ( $id == (int) $post_author ) {
+				$sql .= " OR post_status = 'private'";
+			} // else none
 		} // else none
-	} // else none
+	}
 
 	$sql .= ')';
 
Index: wp-includes/user.php
===================================================================
--- wp-includes/user.php	(revision 54996)
+++ wp-includes/user.php	(working copy)
@@ -167,9 +167,10 @@
  *
  * @param array $users Array of user IDs.
  * @param string|array $post_type Optional. Post type to check. Defaults to post.
+ * @param bool $public_only Optional. Only return counts for public posts.  Defaults to false.
  * @return array Amount of posts each user has written.
  */
-function count_many_users_posts( $users, $post_type = 'post' ) {
+function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) {
 	global $wpdb;
 
 	$count = array();
@@ -177,7 +178,7 @@
 		return $count;
 
 	$userlist = implode( ',', array_map( 'absint', $users ) );
-	$where = get_posts_by_author_sql( $post_type );
+	$where = get_posts_by_author_sql( $post_type, true, null, $public_only );
 
 	$result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N );
 	foreach ( $result as $row ) {
Index: wp-content/mu-plugins/widgets/authors.php
===================================================================
--- wp-content/mu-plugins/widgets/authors.php	(revision 54961)
+++ wp-content/mu-plugins/widgets/authors.php	(working copy)
@@ -152,9 +152,8 @@
  * Widget to display a grid of author avatar images
  * Default size is 32px
  */
-function wp_widget_author_grid($args) {
-	global $wpdb;
-
+function wp_widget_author_grid( $args ) {
+	// This is lame and should go away but we need to do something with the output from get_author_posts_url()
 	$cache_bucket = is_ssl() ? 'widget_author_grid_ssl' : 'widget_author_grid';
 
 	if ( '%BEG_OF_TITLE%' != $args['before_title'] ) {
@@ -167,26 +166,26 @@
 	$options = get_option('widget_author_grid');
 	$title = empty($options['title']) ? __('Authors') : $options['title'];
 	$display_all_authors = $options['all'] ? true : false;
+	$users_of_blog = get_users_of_blog();
+	foreach ( $users_of_blog as $user ) {
+		$user_ids[] = $user->ID;
+	}
+	$post_counts = count_many_users_posts( $user_ids, 'post', true );
 
-	$query_string = "SELECT user_id, display_name, user_login FROM $wpdb->users, $wpdb->usermeta WHERE $wpdb->users.ID = $wpdb->usermeta.user_id AND meta_key = '" . $wpdb->prefix . "capabilities'";
-	$results = $wpdb->get_results($query_string);
-
 	$size = $options[ 'avatar_size' ] ? $options[ 'avatar_size' ] : 32;
 
 	echo $before_widget;
 	echo "\t" . $before_title . esc_html($title) . $after_title;
 	echo "\t" . '<ul>' . "\n";
 
-	foreach ($results as $row) {
-		$r = new WP_Query("author=$row->user_id&showposts=$query_number&what_to_show=posts&nopaging=0&post_status=publish");
+	foreach ( $post_counts as $post_author => $post_count ) {
+		if ( 0 == $post_count && !$display_all_authors ) continue;
 
-		if ( !($r->have_posts() || $display_all_authors) ) continue;
-
 		echo "\t\t" . '<li>' . "\n";
 
 		//display avatar
-		echo "\t\t\t" . '<a href="' . get_option('home') . '/author/' . esc_attr($row->user_login) . '/"> ';
-		echo get_avatar($row->user_id, $size, '', true );
+		echo "\t\t\t" . '<a href="' . esc_url( get_author_posts_url( $post_author ) ) . '"> ';
+		echo get_avatar( $post_author, $size, '', true );
 		echo '</a>' . "\n";
 
 		echo "\t\t" . '</li>' . "\n";
