Skip to content

Commit 46614de

Browse files
committed
Change superuser role
1 parent c7aa2b5 commit 46614de

File tree

4 files changed

+137
-36
lines changed

4 files changed

+137
-36
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ public class ReservedRolesStore implements BiConsumer<Set<String>, ActionListene
4949
"superuser",
5050
new String[] { "all" },
5151
new RoleDescriptor.IndicesPrivileges[] {
52-
RoleDescriptor.IndicesPrivileges.builder().indices("*").privileges("all").allowRestrictedIndices(true).build() },
52+
RoleDescriptor.IndicesPrivileges.builder().indices("*").privileges("all").allowRestrictedIndices(false).build(),
53+
RoleDescriptor.IndicesPrivileges.builder()
54+
.indices("*")
55+
.privileges("monitor", "read", "view_index_metadata")
56+
.allowRestrictedIndices(true)
57+
.build() },
5358
new RoleDescriptor.ApplicationResourcePrivileges[] {
5459
RoleDescriptor.ApplicationResourcePrivileges.builder().application("*").privileges("*").resources("*").build() },
5560
null,

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,32 +1501,61 @@ public void testSuperuserRole() {
15011501
iac = superuserRole.indices().authorize(UpdateSettingsAction.NAME, Sets.newHashSet("aaaaaa", "ba"), lookup, fieldPermissionsCache);
15021502
assertThat(iac.getIndexPermissions("aaaaaa").isGranted(), is(true));
15031503
assertThat(iac.getIndexPermissions("b").isGranted(), is(true));
1504+
1505+
// Read security indices => allowed
1506+
iac = superuserRole.indices()
1507+
.authorize(
1508+
randomFrom(SearchAction.NAME, GetIndexAction.NAME),
1509+
Sets.newHashSet(RestrictedIndicesNames.SECURITY_MAIN_ALIAS),
1510+
lookup,
1511+
fieldPermissionsCache
1512+
);
1513+
assertThat("For " + iac, iac.getIndexPermissions(RestrictedIndicesNames.SECURITY_MAIN_ALIAS).isGranted(), is(true));
1514+
assertThat("For " + iac, iac.getIndexPermissions(internalSecurityIndex).isGranted(), is(true));
1515+
1516+
// Write security indices => denied
15041517
iac = superuserRole.indices()
15051518
.authorize(
1506-
randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME),
1519+
randomFrom(IndexAction.NAME, DeleteIndexAction.NAME),
15071520
Sets.newHashSet(RestrictedIndicesNames.SECURITY_MAIN_ALIAS),
15081521
lookup,
15091522
fieldPermissionsCache
15101523
);
1511-
assertThat(iac.getIndexPermissions(RestrictedIndicesNames.SECURITY_MAIN_ALIAS).isGranted(), is(true));
1512-
assertThat(iac.getIndexPermissions(internalSecurityIndex).isGranted(), is(true));
1524+
assertThat("For " + iac, iac.getIndexPermissions(RestrictedIndicesNames.SECURITY_MAIN_ALIAS).isGranted(), is(false));
1525+
assertThat("For " + iac, iac.getIndexPermissions(internalSecurityIndex).isGranted(), is(false));
1526+
15131527
assertTrue(superuserRole.indices().check(SearchAction.NAME));
15141528
assertFalse(superuserRole.indices().check("unknown"));
15151529

15161530
assertThat(superuserRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(true));
15171531

1532+
// Read security indices => allowed
15181533
assertThat(
15191534
superuserRole.indices()
1520-
.allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME))
1535+
.allowedIndicesMatcher(randomFrom(GetAction.NAME, IndicesStatsAction.NAME))
15211536
.test(mockIndexAbstraction(RestrictedIndicesNames.SECURITY_MAIN_ALIAS)),
15221537
is(true)
15231538
);
15241539
assertThat(
15251540
superuserRole.indices()
1526-
.allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME))
1541+
.allowedIndicesMatcher(randomFrom(GetAction.NAME, IndicesStatsAction.NAME))
15271542
.test(mockIndexAbstraction(internalSecurityIndex)),
15281543
is(true)
15291544
);
1545+
1546+
// Write security indices => denied
1547+
assertThat(
1548+
superuserRole.indices()
1549+
.allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME))
1550+
.test(mockIndexAbstraction(RestrictedIndicesNames.SECURITY_MAIN_ALIAS)),
1551+
is(false)
1552+
);
1553+
assertThat(
1554+
superuserRole.indices()
1555+
.allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME))
1556+
.test(mockIndexAbstraction(internalSecurityIndex)),
1557+
is(false)
1558+
);
15301559
}
15311560

15321561
public void testLogstashSystemRole() {

x-pack/plugin/security/src/test/java/org/elasticsearch/test/SecurityTestsUtils.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import org.apache.lucene.util.LuceneTestCase;
1010
import org.elasticsearch.ElasticsearchSecurityException;
11+
import org.elasticsearch.common.Strings;
1112
import org.elasticsearch.license.LicenseUtils;
1213
import org.elasticsearch.rest.RestStatus;
1314
import org.hamcrest.Matcher;
@@ -38,7 +39,24 @@ public static void assertAuthenticationException(ElasticsearchSecurityException
3839
}
3940

4041
public static void assertThrowsAuthorizationException(LuceneTestCase.ThrowingRunnable throwingRunnable, String action, String user) {
41-
assertThrowsAuthorizationException(throwingRunnable, containsString("[" + action + "] is unauthorized for user [" + user + "]"));
42+
assertThrowsAuthorizationException(null, throwingRunnable, action, user);
43+
}
44+
45+
public static void assertThrowsAuthorizationException(
46+
String context,
47+
LuceneTestCase.ThrowingRunnable throwingRunnable,
48+
String action,
49+
String user
50+
) {
51+
String message = "Expected authorization failure for user=[" + user + "], action=[" + action + "]";
52+
if (Strings.hasText(context)) {
53+
message += " - " + context;
54+
}
55+
assertThrowsAuthorizationException(
56+
message,
57+
throwingRunnable,
58+
containsString("[" + action + "] is unauthorized for user [" + user + "]")
59+
);
4260
}
4361

4462
public static void assertThrowsAuthorizationExceptionRunAs(
@@ -48,6 +66,7 @@ public static void assertThrowsAuthorizationExceptionRunAs(
4866
String runAs
4967
) {
5068
assertThrowsAuthorizationException(
69+
"Expected authorization failure for user=[" + user + "], run-as=[" + runAs + "], action=[" + action + "]",
5170
throwingRunnable,
5271
containsString("[" + action + "] is unauthorized for user [" + user + "] run as [" + runAs + "]")
5372
);
@@ -70,10 +89,15 @@ public static void assertAuthorizationExceptionDefaultUsers(Throwable throwable,
7089
}
7190

7291
public static void assertThrowsAuthorizationException(
92+
String failureMessageIfNoException,
7393
LuceneTestCase.ThrowingRunnable throwingRunnable,
7494
Matcher<String> messageMatcher
7595
) {
76-
ElasticsearchSecurityException securityException = expectThrows(ElasticsearchSecurityException.class, throwingRunnable);
96+
ElasticsearchSecurityException securityException = expectThrows(
97+
ElasticsearchSecurityException.class,
98+
failureMessageIfNoException,
99+
throwingRunnable
100+
);
77101
assertAuthorizationException(securityException, messageMatcher);
78102
}
79103

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
3030
import org.elasticsearch.action.admin.indices.get.GetIndexAction;
3131
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
32+
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction;
33+
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
3234
import org.elasticsearch.action.admin.indices.recovery.RecoveryAction;
3335
import org.elasticsearch.action.admin.indices.recovery.RecoveryRequest;
3436
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsAction;
@@ -2042,10 +2044,10 @@ public void testMonitoringOperationsAgainstSecurityIndexRequireAllowRestricted()
20422044
}
20432045
}
20442046

2045-
public void testSuperusersCanExecuteOperationAgainstSecurityIndex() throws IOException {
2047+
public void testSuperusersCanExecuteReadOperationAgainstSecurityIndex() throws IOException {
20462048
final User superuser = new User("custom_admin", ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName());
20472049
roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR);
2048-
ClusterState state = mockClusterState(
2050+
mockClusterState(
20492051
Metadata.builder()
20502052
.put(
20512053
new IndexMetadata.Builder(INTERNAL_SECURITY_MAIN_INDEX_7).putAlias(
@@ -2062,40 +2064,80 @@ public void testSuperusersCanExecuteOperationAgainstSecurityIndex() throws IOExc
20622064
final String requestId = AuditUtil.getOrGenerateRequestId(threadContext);
20632065

20642066
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
2067+
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7))));
2068+
requests.add(
2069+
new Tuple<>(
2070+
TermVectorsAction.NAME,
2071+
new TermVectorsRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id")
2072+
)
2073+
);
2074+
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id")));
20652075
requests.add(
2066-
new Tuple<>(DeleteAction.NAME, new DeleteRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id"))
2076+
new Tuple<>(ClusterHealthAction.NAME, new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7)))
20672077
);
20682078
requests.add(
20692079
new Tuple<>(
2070-
BulkAction.NAME + "[s]",
2071-
createBulkShardRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), DeleteRequest::new)
2080+
ClusterHealthAction.NAME,
2081+
new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "foo", "bar")
20722082
)
20732083
);
2074-
requests.add(
2075-
new Tuple<>(UpdateAction.NAME, new UpdateRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id"))
2084+
2085+
for (final Tuple<String, TransportRequest> requestTuple : requests) {
2086+
final String action = requestTuple.v1();
2087+
final TransportRequest request = requestTuple.v2();
2088+
try (ThreadContext.StoredContext ignore = threadContext.newStoredContext(false)) {
2089+
final Authentication authentication = createAuthentication(superuser);
2090+
authorize(authentication, action, request);
2091+
verify(auditTrail).accessGranted(
2092+
eq(requestId),
2093+
eq(authentication),
2094+
eq(action),
2095+
eq(request),
2096+
authzInfoRoles(superuser.roles())
2097+
);
2098+
}
2099+
}
2100+
}
2101+
2102+
public void testSuperusersCannotExecuteWriteOperationAgainstSecurityIndex() throws IOException {
2103+
final User superuser = new User("custom_admin", ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName());
2104+
roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR);
2105+
mockClusterState(
2106+
Metadata.builder()
2107+
.put(
2108+
new IndexMetadata.Builder(INTERNAL_SECURITY_MAIN_INDEX_7).putAlias(
2109+
new AliasMetadata.Builder(SECURITY_MAIN_ALIAS).build()
2110+
)
2111+
.settings(Settings.builder().put("index.version.created", Version.CURRENT).build())
2112+
.numberOfShards(1)
2113+
.numberOfReplicas(0)
2114+
.build(),
2115+
true
2116+
)
2117+
.build()
20762118
);
2077-
requests.add(new Tuple<>(IndexAction.NAME, new IndexRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7))));
2119+
final String requestId = AuditUtil.getOrGenerateRequestId(threadContext);
2120+
2121+
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
20782122
requests.add(
20792123
new Tuple<>(
20802124
BulkAction.NAME + "[s]",
2081-
createBulkShardRequest(
2082-
randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7),
2083-
(index, id) -> new IndexRequest(index).id(id)
2084-
)
2125+
createBulkShardRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), DeleteRequest::new)
20852126
)
20862127
);
2087-
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7))));
20882128
requests.add(
20892129
new Tuple<>(
2090-
TermVectorsAction.NAME,
2091-
new TermVectorsRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id")
2130+
BulkAction.NAME + "[s]",
2131+
createBulkShardRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), UpdateRequest::new)
20922132
)
20932133
);
2094-
requests.add(new Tuple<>(GetAction.NAME, new GetRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id")));
20952134
requests.add(
20962135
new Tuple<>(
2097-
TermVectorsAction.NAME,
2098-
new TermVectorsRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "id")
2136+
BulkAction.NAME + "[s]",
2137+
createBulkShardRequest(
2138+
randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7),
2139+
(index, id) -> new IndexRequest(index).id(id)
2140+
)
20992141
)
21002142
);
21012143
requests.add(
@@ -2105,22 +2147,23 @@ public void testSuperusersCanExecuteOperationAgainstSecurityIndex() throws IOExc
21052147
)
21062148
);
21072149
requests.add(
2108-
new Tuple<>(ClusterHealthAction.NAME, new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7)))
2150+
new Tuple<>(PutMappingAction.NAME, new PutMappingRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7)))
21092151
);
21102152
requests.add(
2111-
new Tuple<>(
2112-
ClusterHealthAction.NAME,
2113-
new ClusterHealthRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7), "foo", "bar")
2114-
)
2153+
new Tuple<>(DeleteIndexAction.NAME, new DeleteIndexRequest(randomFrom(SECURITY_MAIN_ALIAS, INTERNAL_SECURITY_MAIN_INDEX_7)))
21152154
);
2116-
21172155
for (final Tuple<String, TransportRequest> requestTuple : requests) {
21182156
final String action = requestTuple.v1();
21192157
final TransportRequest request = requestTuple.v2();
21202158
try (ThreadContext.StoredContext ignore = threadContext.newStoredContext(false)) {
21212159
final Authentication authentication = createAuthentication(superuser);
2122-
authorize(authentication, action, request);
2123-
verify(auditTrail).accessGranted(
2160+
assertThrowsAuthorizationException(
2161+
"authentication=[" + authentication + "], action=[" + action + "], request=[" + request + "]",
2162+
() -> authorize(authentication, action, request),
2163+
action,
2164+
superuser.principal()
2165+
);
2166+
verify(auditTrail).accessDenied(
21242167
eq(requestId),
21252168
eq(authentication),
21262169
eq(action),
@@ -2131,11 +2174,11 @@ public void testSuperusersCanExecuteOperationAgainstSecurityIndex() throws IOExc
21312174
}
21322175
}
21332176

2134-
public void testSuperusersCanExecuteOperationAgainstSecurityIndexWithWildcard() throws IOException {
2177+
public void testSuperusersCanExecuteReadOperationAgainstSecurityIndexWithWildcard() throws IOException {
21352178
final User superuser = new User("custom_admin", ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName());
21362179
final Authentication authentication = createAuthentication(superuser);
21372180
roleMap.put(ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR.getName(), ReservedRolesStore.SUPERUSER_ROLE_DESCRIPTOR);
2138-
ClusterState state = mockClusterState(
2181+
mockClusterState(
21392182
Metadata.builder()
21402183
.put(
21412184
new IndexMetadata.Builder(INTERNAL_SECURITY_MAIN_INDEX_7).putAlias(

0 commit comments

Comments
 (0)