Index: tests/phpunit/tests/adminbar.php
===================================================================
--- tests/phpunit/tests/adminbar.php	(revision 33929)
+++ tests/phpunit/tests/adminbar.php	(working copy)
@@ -15,7 +15,6 @@
 	function setUp() {
 		parent::setUp();
 		$this->current_user = get_current_user_id();
-		wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) );
 	}
 
 	function tearDown() {
@@ -27,6 +26,8 @@
 	 * @ticket 21117
 	 */
 	function test_content_post_type() {
+		wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) );
+
 		register_post_type( 'content', array( 'show_in_admin_bar' => true ) );
 
 		$admin_bar = new WP_Admin_Bar;
@@ -44,6 +45,8 @@
 	 * @ticket 21117
 	 */
 	function test_merging_existing_meta_values() {
+		wp_set_current_user( $this->factory->user->create( array( 'role' => 'editor' ) ) );
+
 		$admin_bar = new WP_Admin_Bar;
 
 		$admin_bar->add_node( array(
@@ -61,4 +64,194 @@
 		$node = $admin_bar->get_node( 'test-node' );
 		$this->assertEquals( array( 'class' => 'test-class', 'some-meta' => 'value' ), $node->meta );
 	}
-}
\ No newline at end of file
+
+	/**
+	 * @ticket 25162
+	 */
+	public function test_admin_bar_contains_correct_links_for_users_with_no_role() {
+		if ( is_multisite() ) {
+			$this->markTestSkipped( 'Test does not run in multisite' );
+		}
+
+		$nobody = $this->factory->user->create( array( 'role' => '' ) );
+		$this->assertFalse( user_can( $nobody, 'read' ) );
+
+		wp_set_current_user( $nobody );
+
+		$wp_admin_bar = $this->get_standard_admin_bar();
+
+		$node_site_name    = $wp_admin_bar->get_node( 'site-name' );
+		$node_my_account   = $wp_admin_bar->get_node( 'my-account' );
+		$node_user_info    = $wp_admin_bar->get_node( 'user-info' );
+		$node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' );
+
+		// Site menu points to the home page instead of the admin URL
+		$this->assertEquals( home_url( '/' ), $node_site_name->href );
+
+		// No profile links as the user doesn't have any permissions on the site
+		$this->assertEquals( '#', $node_my_account->href );
+		$this->assertEquals( '#', $node_user_info->href );
+		$this->assertNull( $node_edit_profile );
+
+	}
+
+	/**
+	 * @ticket 25162
+	 */
+	public function test_admin_bar_contains_correct_links_for_users_with_role() {
+		if ( is_multisite() ) {
+			$this->markTestSkipped( 'Test does not run in multisite' );
+		}
+
+		$editor = $this->factory->user->create( array( 'role' => 'editor' ) );
+		$this->assertTrue( user_can( $editor, 'read' ) );
+
+		wp_set_current_user( $editor );
+
+		$wp_admin_bar = $this->get_standard_admin_bar();
+
+		$node_site_name    = $wp_admin_bar->get_node( 'site-name' );
+		$node_my_account   = $wp_admin_bar->get_node( 'my-account' );
+		$node_user_info    = $wp_admin_bar->get_node( 'user-info' );
+		$node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' );
+
+		// Site menu points to the admin URL
+		$this->assertEquals( admin_url( '/' ), $node_site_name->href );
+
+		$profile_url = admin_url( 'profile.php' );
+
+		// Profile URLs point to profile.php
+		$this->assertEquals( $profile_url, $node_my_account->href );
+		$this->assertEquals( $profile_url, $node_user_info->href );
+		$this->assertEquals( $profile_url, $node_edit_profile->href );
+
+	}
+
+	/**
+	 * @ticket 25162
+	 * @group multisite
+	 */
+	public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_blog() {
+		if ( ! is_multisite() ) {
+			$this->markTestSkipped( 'Test only runs in multisite' );
+		}
+
+		$admin  = $this->factory->user->create( array( 'role' => 'administrator' ) );
+		$editor = $this->factory->user->create( array( 'role' => 'editor' ) );
+
+		$this->assertTrue( user_can( $admin, 'read' ) );
+		$this->assertTrue( user_can( $editor, 'read' ) );
+
+		$new_blog_id = $this->factory->blog->create( array(
+			'user_id' => $admin,
+		) );
+
+		$this->assertTrue( is_user_member_of_blog( $admin, $new_blog_id ) );
+		$this->assertFalse( is_user_member_of_blog( $editor, $new_blog_id ) );
+
+		wp_set_current_user( $editor );
+
+		switch_to_blog( $new_blog_id );
+
+		$wp_admin_bar = $this->get_standard_admin_bar();
+
+		$node_site_name    = $wp_admin_bar->get_node( 'site-name' );
+		$node_my_account   = $wp_admin_bar->get_node( 'my-account' );
+		$node_user_info    = $wp_admin_bar->get_node( 'user-info' );
+		$node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' );
+
+		// get primary blog
+		$primary = get_active_blog_for_user( $editor );
+		$this->assertInternalType( 'object', $primary );
+
+		// No Site menu as the user isn't a member of this blog
+		$this->assertNull( $node_site_name );
+
+		$primary_profile_url = get_admin_url( $primary->blog_id, 'profile.php' );
+
+		// Ensure the user's primary blog is not the same as the main site
+		$this->assertNotEquals( $primary_profile_url, admin_url( 'profile.php' ) );
+
+		// Profile URLs should go to the user's primary blog
+		$this->assertEquals( $primary_profile_url, $node_my_account->href );
+		$this->assertEquals( $primary_profile_url, $node_user_info->href );
+		$this->assertEquals( $primary_profile_url, $node_edit_profile->href );
+
+		restore_current_blog();
+
+	}
+
+	/**
+	 * @ticket 25162
+	 * @group multisite
+	 */
+	public function test_admin_bar_contains_correct_links_for_users_with_no_role_on_network() {
+		if ( ! is_multisite() ) {
+			$this->markTestSkipped( 'Test only runs in multisite' );
+		}
+
+		$admin  = $this->factory->user->create( array( 'role' => 'administrator' ) );
+		$nobody = $this->factory->user->create( array( 'role' => '' ) );
+
+		$this->assertTrue( user_can( $admin, 'read' ) );
+		$this->assertFalse( user_can( $nobody, 'read' ) );
+
+		$new_blog_id = $this->factory->blog->create( array(
+			'user_id' => $admin,
+		) );
+
+		$this->assertTrue( is_user_member_of_blog( $admin, $new_blog_id ) );
+		$this->assertFalse( is_user_member_of_blog( $nobody, $new_blog_id ) );
+		$this->assertTrue( is_user_member_of_blog( $nobody, get_current_blog_id() ) );
+
+		// Remove `$nobody` from the current blog, so they're not a member of any blog
+		$removed = remove_user_from_blog( $nobody, get_current_blog_id() );
+
+		$this->assertTrue( $removed );
+		$this->assertFalse( is_user_member_of_blog( $nobody, get_current_blog_id() ) );
+
+		wp_set_current_user( $nobody );
+
+		switch_to_blog( $new_blog_id );
+
+		$wp_admin_bar = $this->get_standard_admin_bar();
+
+		$node_site_name    = $wp_admin_bar->get_node( 'site-name' );
+		$node_my_account   = $wp_admin_bar->get_node( 'my-account' );
+		$node_user_info    = $wp_admin_bar->get_node( 'user-info' );
+		$node_edit_profile = $wp_admin_bar->get_node( 'edit-profile' );
+
+		// get primary blog
+		$primary = get_active_blog_for_user( $nobody );
+		$this->assertNull( $primary );
+
+		// No Site menu as the user isn't a member of this site
+		$this->assertNull( $node_site_name );
+
+		$user_profile_url = user_admin_url( 'profile.php' );
+
+		$this->assertNotEquals( $user_profile_url, admin_url( 'profile.php' ) );
+
+		// Profile URLs should go to the user's primary blog
+		$this->assertEquals( $user_profile_url, $node_my_account->href );
+		$this->assertEquals( $user_profile_url, $node_user_info->href );
+		$this->assertEquals( $user_profile_url, $node_edit_profile->href );
+
+		restore_current_blog();
+
+	}
+
+	protected function get_standard_admin_bar() {
+		global $wp_admin_bar;
+
+		_wp_admin_bar_init();
+
+		$this->assertTrue( is_admin_bar_showing() );
+		$this->assertInstanceOf( 'WP_Admin_Bar', $wp_admin_bar );
+
+		do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) );
+
+		return $wp_admin_bar;
+	}
+
+}
Index: src/wp-includes/admin-bar.php
===================================================================
--- src/wp-includes/admin-bar.php	(revision 33929)
+++ src/wp-includes/admin-bar.php	(working copy)
@@ -179,11 +179,18 @@
 function wp_admin_bar_my_account_item( $wp_admin_bar ) {
 	$user_id      = get_current_user_id();
 	$current_user = wp_get_current_user();
-	$profile_url  = get_edit_profile_url( $user_id );
 
 	if ( ! $user_id )
 		return;
 
+	if ( current_user_can( 'read' ) ) {
+		$profile_url = get_edit_profile_url( $user_id );
+	} elseif ( is_multisite() ) {
+		$profile_url = get_dashboard_url( $user_id, 'profile.php' );
+	} else {
+		$profile_url = '#';
+	}
+
 	$avatar = get_avatar( $user_id, 26 );
 	$howdy  = sprintf( __('Howdy, %1$s'), $current_user->display_name );
 	$class  = empty( $avatar ) ? '' : 'with-avatar';
@@ -209,11 +216,18 @@
 function wp_admin_bar_my_account_menu( $wp_admin_bar ) {
 	$user_id      = get_current_user_id();
 	$current_user = wp_get_current_user();
-	$profile_url  = get_edit_profile_url( $user_id );
 
 	if ( ! $user_id )
 		return;
 
+	if ( current_user_can( 'read' ) ) {
+		$profile_url = get_edit_profile_url( $user_id );
+	} elseif ( is_multisite() ) {
+		$profile_url = get_dashboard_url( $user_id, 'profile.php' );
+	} else {
+		$profile_url = '#';
+	}
+
 	$wp_admin_bar->add_group( array(
 		'parent' => 'my-account',
 		'id'     => 'user-actions',
@@ -234,12 +248,16 @@
 			'tabindex' => -1,
 		),
 	) );
-	$wp_admin_bar->add_menu( array(
-		'parent' => 'user-actions',
-		'id'     => 'edit-profile',
-		'title'  => __( 'Edit My Profile' ),
-		'href' => $profile_url,
-	) );
+
+	if ( '#' !== $profile_url ) {
+		$wp_admin_bar->add_menu( array(
+			'parent' => 'user-actions',
+			'id'     => 'edit-profile',
+			'title'  => __( 'Edit My Profile' ),
+			'href'   => $profile_url,
+		) );
+	}
+
 	$wp_admin_bar->add_menu( array(
 		'parent' => 'user-actions',
 		'id'     => 'logout',
@@ -281,7 +299,7 @@
 	$wp_admin_bar->add_menu( array(
 		'id'    => 'site-name',
 		'title' => $title,
-		'href'  => is_admin() ? home_url( '/' ) : admin_url(),
+		'href'  => ( is_admin() || ! current_user_can( 'read' ) ) ? home_url( '/' ) : admin_url(),
 	) );
 
 	// Create submenu items.
@@ -304,7 +322,7 @@
 			) );
 		}
 
-	} else {
+	} else if ( current_user_can( 'read' ) ) {
 		// We're on the front end, link to the Dashboard.
 		$wp_admin_bar->add_menu( array(
 			'parent' => 'site-name',
