Index: src/wp-admin/includes/class-wp-ms-sites-list-table.php
===================================================================
--- src/wp-admin/includes/class-wp-ms-sites-list-table.php	(revision 39532)
+++ src/wp-admin/includes/class-wp-ms-sites-list-table.php	(working copy)
@@ -516,30 +516,38 @@
 			'visit' => '',
 		);
 
-		$actions['edit']	= '<a href="' . esc_url( network_admin_url( 'site-info.php?id=' . $blog['blog_id'] ) ) . '">' . __( 'Edit' ) . '</a>';
+		if ( current_user_can( 'edit_site', $blog['blog_id'] ) ) {
+			$actions['edit']	= '<a href="' . esc_url( network_admin_url( 'site-info.php?id=' . $blog['blog_id'] ) ) . '">' . __( 'Edit' ) . '</a>';
+		}
+
 		$actions['backend']	= "<a href='" . esc_url( get_admin_url( $blog['blog_id'] ) ) . "' class='edit'>" . __( 'Dashboard' ) . '</a>';
-		if ( get_network()->site_id != $blog['blog_id'] ) {
+
+		if ( current_user_can( 'activate_site', $blog['blog_id'] ) ) {
 			if ( $blog['deleted'] == '1' ) {
 				$actions['activate']   = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=activateblog&amp;id=' . $blog['blog_id'] ), 'activateblog_' . $blog['blog_id'] ) ) . '">' . __( 'Activate' ) . '</a>';
 			} else {
 				$actions['deactivate'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=deactivateblog&amp;id=' . $blog['blog_id'] ), 'deactivateblog_' . $blog['blog_id'] ) ) . '">' . __( 'Deactivate' ) . '</a>';
 			}
+		}
 
+		if ( current_user_can( 'archive_site', $blog['blog_id'] ) ) {
 			if ( $blog['archived'] == '1' ) {
 				$actions['unarchive'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=unarchiveblog&amp;id=' . $blog['blog_id'] ), 'unarchiveblog_' . $blog['blog_id'] ) ) . '">' . __( 'Unarchive' ) . '</a>';
 			} else {
 				$actions['archive']   = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=archiveblog&amp;id=' . $blog['blog_id'] ), 'archiveblog_' . $blog['blog_id'] ) ) . '">' . _x( 'Archive', 'verb; site' ) . '</a>';
 			}
+		}
 
+		if ( current_user_can( 'spam_site', $blog['blog_id'] ) ) {
 			if ( $blog['spam'] == '1' ) {
 				$actions['unspam'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=unspamblog&amp;id=' . $blog['blog_id'] ), 'unspamblog_' . $blog['blog_id'] ) ) . '">' . _x( 'Not Spam', 'site' ) . '</a>';
 			} else {
 				$actions['spam']   = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=spamblog&amp;id=' . $blog['blog_id'] ), 'spamblog_' . $blog['blog_id'] ) ) . '">' . _x( 'Spam', 'site' ) . '</a>';
 			}
+		}
 
-			if ( current_user_can( 'delete_site', $blog['blog_id'] ) ) {
-				$actions['delete'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=deleteblog&amp;id=' . $blog['blog_id'] ), 'deleteblog_' . $blog['blog_id'] ) ) . '">' . __( 'Delete' ) . '</a>';
-			}
+		if ( current_user_can( 'delete_site', $blog['blog_id'] ) ) {
+			$actions['delete'] = '<a href="' . esc_url( wp_nonce_url( network_admin_url( 'sites.php?action=confirm&amp;action2=deleteblog&amp;id=' . $blog['blog_id'] ), 'deleteblog_' . $blog['blog_id'] ) ) . '">' . __( 'Delete' ) . '</a>';
 		}
 
 		$actions['visit']	= "<a href='" . esc_url( get_home_url( $blog['blog_id'], '/' ) ) . "' rel='permalink'>" . __( 'Visit' ) . '</a>';
Index: src/wp-admin/menu.php
===================================================================
--- src/wp-admin/menu.php	(revision 39532)
+++ src/wp-admin/menu.php	(working copy)
@@ -241,7 +241,7 @@
 	$submenu['tools.php'][10] = array( __('Import'), 'import', 'import.php' );
 	$submenu['tools.php'][15] = array( __('Export'), 'export', 'export.php' );
 	if ( is_multisite() && !is_main_site() )
-		$submenu['tools.php'][25] = array( __('Delete Site'), 'delete_site', 'ms-delete-site.php' );
+		$submenu['tools.php'][25] = array( __('Delete Site'), 'delete_admin_site', 'ms-delete-site.php' );
 	if ( ! is_multisite() && defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE )
 		$submenu['tools.php'][50] = array(__('Network Setup'), 'manage_options', 'network.php');
 
Index: src/wp-admin/ms-delete-site.php
===================================================================
--- src/wp-admin/ms-delete-site.php	(revision 39532)
+++ src/wp-admin/ms-delete-site.php	(working copy)
@@ -12,7 +12,7 @@
 if ( !is_multisite() )
 	wp_die( __( 'Multisite support is not enabled.' ) );
 
-if ( ! current_user_can( 'delete_site' ) )
+if ( ! current_user_can( 'delete_admin_site' ) )
 	wp_die(__( 'Sorry, you are not allowed to delete this site.'));
 
 if ( isset( $_GET['h'] ) && $_GET['h'] != '' && get_option( 'delete_blog_hash' ) != false ) {
Index: src/wp-admin/network/site-info.php
===================================================================
--- src/wp-admin/network/site-info.php	(revision 39532)
+++ src/wp-admin/network/site-info.php	(working copy)
@@ -10,7 +10,9 @@
 /** Load WordPress Administration Bootstrap */
 require_once( dirname( __FILE__ ) . '/admin.php' );
 
-if ( ! current_user_can( 'manage_sites' ) ) {
+$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
+
+if ( ! current_user_can( 'edit_site', $id ) ) {
 	wp_die( __( 'Sorry, you are not allowed to edit this site.' ) );
 }
 
@@ -31,16 +33,7 @@
 	'<p>' . __( '<a href="https://wordpress.org/support/forum/multisite/">Support Forums</a>' ) . '</p>'
 );
 
-$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
-
-if ( ! $id ) {
-	wp_die( __('Invalid site ID.') );
-}
-
 $details = get_site( $id );
-if ( ! $details ) {
-	wp_die( __( 'The requested site does not exist.' ) );
-}
 
 if ( ! can_edit_network( $details->site_id ) ) {
 	wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );
@@ -183,12 +176,18 @@
 		</tr>
 		<?php
 		$attribute_fields = array( 'public' => __( 'Public' ) );
-		if ( ! $is_main_site ) {
+		if ( current_user_can( 'archive_site', $details->id ) ) {
 			$attribute_fields['archived'] = __( 'Archived' );
-			$attribute_fields['spam']     = _x( 'Spam', 'site' );
-			$attribute_fields['deleted']  = __( 'Deleted' );
 		}
-		$attribute_fields['mature'] = __( 'Mature' );
+		if ( current_user_can( 'spam_site', $details->id ) ) {
+			$attribute_fields['spam'] = _x( 'Spam', 'site' );
+		}
+		if ( current_user_can( 'activate_site', $details->id ) ) {
+			$attribute_fields['deleted'] = __( 'Deleted' );
+		}
+		if ( current_user_can( 'mature_site', $details->id ) ) {
+			$attribute_fields['mature'] = __( 'Mature' );
+		}
 		?>
 		<tr>
 			<th scope="row"><?php _e( 'Attributes' ); ?></th>
Index: src/wp-admin/network/site-new.php
===================================================================
--- src/wp-admin/network/site-new.php	(revision 39532)
+++ src/wp-admin/network/site-new.php	(working copy)
@@ -13,7 +13,7 @@
 /** WordPress Translation Install API */
 require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
 
-if ( ! current_user_can( 'manage_sites' ) )
+if ( ! current_user_can( 'create_sites' ) )
 	wp_die( __( 'Sorry, you are not allowed to add sites to this network.' ) );
 
 get_current_screen()->add_help_tab( array(
Index: src/wp-admin/network/site-settings.php
===================================================================
--- src/wp-admin/network/site-settings.php	(revision 39532)
+++ src/wp-admin/network/site-settings.php	(working copy)
@@ -10,8 +10,11 @@
 /** Load WordPress Administration Bootstrap */
 require_once( dirname( __FILE__ ) . '/admin.php' );
 
-if ( ! current_user_can( 'manage_sites' ) )
+$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
+
+if ( ! current_user_can( 'edit_site', $id ) ) {
 	wp_die( __( 'Sorry, you are not allowed to edit this site.' ) );
+}
 
 get_current_screen()->add_help_tab( array(
 	'id'      => 'overview',
@@ -30,15 +33,7 @@
 	'<p>' . __('<a href="https://wordpress.org/support/forum/multisite/">Support Forums</a>') . '</p>'
 );
 
-$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
-
-if ( ! $id )
-	wp_die( __('Invalid site ID.') );
-
 $details = get_site( $id );
-if ( ! $details ) {
-	wp_die( __( 'The requested site does not exist.' ) );
-}
 
 if ( !can_edit_network( $details->site_id ) )
 	wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );
Index: src/wp-admin/network/site-themes.php
===================================================================
--- src/wp-admin/network/site-themes.php	(revision 39532)
+++ src/wp-admin/network/site-themes.php	(working copy)
@@ -10,8 +10,11 @@
 /** Load WordPress Administration Bootstrap */
 require_once( dirname( __FILE__ ) . '/admin.php' );
 
-if ( ! current_user_can( 'manage_sites' ) )
-	wp_die( __( 'Sorry, you are not allowed to manage themes for this site.' ) );
+$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
+
+if ( ! current_user_can( 'edit_site', $id ) ) {
+	wp_die( __( 'Sorry, you are not allowed to edit this site.' ) );
+}
 
 get_current_screen()->add_help_tab( array(
 	'id'      => 'overview',
@@ -51,18 +54,10 @@
 	$referer = add_query_arg( 'paged', (int) $_REQUEST['paged'], $referer );
 }
 
-$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
-
-if ( ! $id )
-	wp_die( __('Invalid site ID.') );
+$details = get_site( $id );
 
 $wp_list_table->prepare_items();
 
-$details = get_site( $id );
-if ( ! $details ) {
-	wp_die( __( 'The requested site does not exist.' ) );
-}
-
 if ( !can_edit_network( $details->site_id ) )
 	wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );
 
Index: src/wp-admin/network/site-users.php
===================================================================
--- src/wp-admin/network/site-users.php	(revision 39532)
+++ src/wp-admin/network/site-users.php	(working copy)
@@ -10,8 +10,11 @@
 /** Load WordPress Administration Bootstrap */
 require_once( dirname( __FILE__ ) . '/admin.php' );
 
-if ( ! current_user_can('manage_sites') )
-	wp_die(__('Sorry, you are not allowed to edit this site.'));
+$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
+
+if ( ! current_user_can( 'edit_site', $id ) ) {
+	wp_die( __( 'Sorry, you are not allowed to edit this site.' ) );
+}
 
 $wp_list_table = _get_list_table('WP_Users_List_Table');
 $wp_list_table->prepare_items();
@@ -46,15 +49,7 @@
 	$referer = add_query_arg( 'paged', (int) $_REQUEST['paged'], $referer );
 }
 
-$id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
-
-if ( ! $id )
-	wp_die( __('Invalid site ID.') );
-
 $details = get_site( $id );
-if ( ! $details ) {
-	wp_die( __( 'The requested site does not exist.' ) );
-}
 
 if ( ! can_edit_network( $details->site_id ) )
 	wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );
Index: src/wp-admin/network/sites.php
===================================================================
--- src/wp-admin/network/sites.php	(revision 39532)
+++ src/wp-admin/network/sites.php	(working copy)
@@ -126,7 +126,7 @@
 				wp_die( __( 'Sorry, you are not allowed to access this page.' ), '', array( 'response' => 403 ) );
 
 			$updated_action = 'not_deleted';
-			if ( $id != '0' && $id != get_network()->site_id && current_user_can( 'delete_site', $id ) ) {
+			if ( current_user_can( 'delete_site', $id ) ) {
 				wpmu_delete_blog( $id, true );
 				$updated_action = 'delete';
 			}
@@ -137,24 +137,24 @@
 				$doaction = $_POST['action'] != -1 ? $_POST['action'] : $_POST['action2'];
 
 				foreach ( (array) $_POST['allblogs'] as $key => $val ) {
-					if ( $val != '0' && $val != get_network()->site_id ) {
-						switch ( $doaction ) {
-							case 'delete':
-								if ( ! current_user_can( 'delete_site', $val ) )
-									wp_die( __( 'Sorry, you are not allowed to delete the site.' ) );
-
-								$updated_action = 'all_delete';
-								wpmu_delete_blog( $val, true );
-							break;
-
-							case 'spam':
-							case 'notspam':
-								$updated_action = ( 'spam' === $doaction ) ? 'all_spam' : 'all_notspam';
-								update_blog_status( $val, 'spam', ( 'spam' === $doaction ) ? '1' : '0' );
-							break;
-						}
-					} else {
-						wp_die( __( 'Sorry, you are not allowed to change the current site.' ) );
+					switch ( $doaction ) {
+						case 'delete':
+							if ( ! current_user_can( 'delete_site', $val ) )
+								wp_die( __( 'Sorry, you are not allowed to delete the site.' ) );
+
+							$updated_action = 'all_delete';
+							wpmu_delete_blog( $val, true );
+						break;
+
+						case 'spam':
+						case 'notspam':
+							if ( ! current_user_can( 'spam_site', $val ) ) {
+								wp_die( __( 'Sorry, you are not allowed to change the spam status of the site.' ) );
+							}
+
+							$updated_action = ( 'spam' === $doaction ) ? 'all_spam' : 'all_notspam';
+							update_blog_status( $val, 'spam', ( 'spam' === $doaction ) ? '1' : '0' );
+						break;
 					}
 				}
 				if ( ! in_array( $doaction, array( 'delete', 'spam', 'notspam' ), true ) ) {
@@ -177,10 +177,18 @@
 
 		case 'archiveblog':
 		case 'unarchiveblog':
+			if ( ! current_user_can( 'archive_site', $val ) ) {
+				wp_die( __( 'Sorry, you are not allowed to change the archive status of the site.' ) );
+			}
+
 			update_blog_status( $id, 'archived', ( 'archiveblog' === $_GET['action'] ) ? '1' : '0' );
 		break;
 
 		case 'activateblog':
+			if ( ! current_user_can( 'activate_site', $val ) ) {
+				wp_die( __( 'Sorry, you are not allowed to activate the site.' ) );
+			}
+
 			update_blog_status( $id, 'deleted', '0' );
 
 			/**
@@ -194,6 +202,10 @@
 		break;
 
 		case 'deactivateblog':
+			if ( ! current_user_can( 'activate_site', $val ) ) {
+				wp_die( __( 'Sorry, you are not allowed to deactivate the site.' ) );
+			}
+
 			/**
 			 * Fires before a network site is deactivated.
 			 *
@@ -207,11 +219,19 @@
 
 		case 'unspamblog':
 		case 'spamblog':
+			if ( ! current_user_can( 'spam_site', $val ) ) {
+				wp_die( __( 'Sorry, you are not allowed to change the spam status of the site.' ) );
+			}
+
 			update_blog_status( $id, 'spam', ( 'spamblog' === $_GET['action'] ) ? '1' : '0' );
 		break;
 
 		case 'unmatureblog':
 		case 'matureblog':
+			if ( ! current_user_can( 'mature_site', $val ) ) {
+				wp_die( __( 'Sorry, you are not allowed to change the mature status of the site.' ) );
+			}
+
 			update_blog_status( $id, 'mature', ( 'matureblog' === $_GET['action'] ) ? '1' : '0' );
 		break;
 	}
Index: src/wp-includes/capabilities.php
===================================================================
--- src/wp-includes/capabilities.php	(revision 39532)
+++ src/wp-includes/capabilities.php	(working copy)
@@ -421,7 +421,7 @@
 	case 'customize' :
 		$caps[] = 'edit_theme_options';
 		break;
-	case 'delete_site':
+	case 'delete_admin_site':
 		if ( is_multisite() ) {
 			$caps[] = 'manage_options';
 		} else {
@@ -465,6 +465,41 @@
 	case 'assign_post_tags':
 		$caps[] = 'edit_posts';
 		break;
+	case 'edit_site':
+	case 'delete_site':
+	case 'archive_site':
+	case 'spam_site':
+	case 'activate_site':
+	case 'mature_site':
+		if ( is_multisite() ) {
+			$site_id = $args[0];
+			if ( 0 == $site_id ) {
+				$caps[] = 'do_not_allow';
+				break;
+			}
+
+			$site = get_site( $site_id );
+			if ( ! $site ) {
+				$caps[] = 'do_not_allow';
+				break;
+			}
+
+			if ( 'edit_site' !== $cap && 'mature_site' !== $cap ) {
+				if ( $site->id == get_network()->site_id ) {
+					$caps[] = 'do_not_allow';
+					break;
+				}
+			}
+
+			if ( 'delete_site' === $cap ) {
+				$caps[] = 'delete_sites';
+			} else {
+				$caps[] = 'manage_sites';
+			}
+		} else {
+			$caps[] = 'do_not_allow';
+		}
+		break;
 	case 'create_sites':
 	case 'delete_sites':
 	case 'manage_network':
