Record audit trail even if indicies-resolver throws exception (elastic/elasticsearch#4116)

* Record audit trail even if indicies-resolver throws exception

If the IndicesAndAliasesResolver throws an exception, treat is as "accessDenied" for the purpose of the audit-trail.
This can occur when an index request has a wildcard that doesn't match (and "allowNoIndices" is false)

Closes elastic/elasticsearch#3719

Original commit: elastic/x-pack-elasticsearch@ca6567e5ed
This commit is contained in:
Tim Vernum 2016-11-21 09:18:49 +11:00 committed by GitHub
parent 1ae83f65a4
commit 74b0a1e71a
2 changed files with 31 additions and 1 deletions

View File

@ -216,7 +216,7 @@ public class AuthorizationService extends AbstractComponent {
MetaData metaData = clusterService.state().metaData();
AuthorizedIndices authorizedIndices = new AuthorizedIndices(authentication.getRunAsUser(), roles, action, metaData);
Set<String> indexNames = indicesAndAliasesResolver.resolve(request, metaData, authorizedIndices);
Set<String> indexNames = resolveIndexNames(authentication, action, request, metaData, authorizedIndices);
assert !indexNames.isEmpty() : "every indices request needs to have its indices set thus the resolved indices must not be empty";
//all wildcard expressions have been resolved and only the security plugin could have set '-*' here.
@ -265,6 +265,16 @@ public class AuthorizationService extends AbstractComponent {
grant(authentication, action, originalRequest);
}
private Set<String> resolveIndexNames(Authentication authentication, String action, TransportRequest request, MetaData metaData,
AuthorizedIndices authorizedIndices) {
try {
return indicesAndAliasesResolver.resolve(request, metaData, authorizedIndices);
} catch (Exception e) {
auditTrail.accessDenied(authentication.getUser(), action, request);
throw e;
}
}
private void setIndicesAccessControl(IndicesAccessControl accessControl) {
if (threadContext.getTransient(INDICES_PERMISSIONS_KEY) == null) {
threadContext.putTransient(INDICES_PERMISSIONS_KEY, accessControl);

View File

@ -21,6 +21,7 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsAction;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexAction;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.recovery.RecoveryAction;
import org.elasticsearch.action.admin.indices.recovery.RecoveryRequest;
@ -71,6 +72,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
@ -399,6 +401,24 @@ public class AuthorizationServiceTests extends ESTestCase {
verify(state, times(1)).metaData();
}
public void testAuditTrailIsRecordedWhenIndexWildcardThrowsError() {
IndicesOptions options = IndicesOptions.fromOptions(false, false, true, true);
TransportRequest request = new GetIndexRequest().indices("not-an-index-*").indicesOptions(options);
ClusterState state = mockEmptyMetaData();
User user = new User("test user", "a_all");
roleMap.put("a_all", Role.builder("a_all").add(IndexPrivilege.ALL, "a").build());
final IndexNotFoundException nfe = expectThrows(
IndexNotFoundException.class,
() -> authorize(createAuthentication(user), GetIndexAction.NAME, request));
assertThat(nfe.getIndex(), is(notNullValue()));
assertThat(nfe.getIndex().getName(), is("not-an-index-*"));
verify(auditTrail).accessDenied(user, GetIndexAction.NAME, request);
verifyNoMoreInteractions(auditTrail);
verify(clusterService).state();
verify(state, times(1)).metaData();
}
public void testRunAsRequestWithNoRolesUser() {
TransportRequest request = mock(TransportRequest.class);
User user = new User("test user", null, new User("run as me", new String[] { "admin" }));