diff --git a/presto-hive/src/test/java/com/facebook/presto/hive/security/ranger/TestRangerBasedAccessControl.java b/presto-hive/src/test/java/com/facebook/presto/hive/security/ranger/TestRangerBasedAccessControl.java index b93d5ac824877..8558f69cf9057 100644 --- a/presto-hive/src/test/java/com/facebook/presto/hive/security/ranger/TestRangerBasedAccessControl.java +++ b/presto-hive/src/test/java/com/facebook/presto/hive/security/ranger/TestRangerBasedAccessControl.java @@ -48,7 +48,7 @@ public class TestRangerBasedAccessControl { public static final ConnectorTransactionHandle TRANSACTION_HANDLE = new ConnectorTransactionHandle() {}; - public static final AccessControlContext CONTEXT = new AccessControlContext(new QueryId("query_id"), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()); + public static final AccessControlContext CONTEXT = new AccessControlContext(new QueryId("query_id"), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()); @Test public void testTablePriviledgesRolesNotAllowed() diff --git a/presto-main/src/main/java/com/facebook/presto/Session.java b/presto-main/src/main/java/com/facebook/presto/Session.java index 8ccca2db4d3de..cc302e7253bea 100644 --- a/presto-main/src/main/java/com/facebook/presto/Session.java +++ b/presto-main/src/main/java/com/facebook/presto/Session.java @@ -176,7 +176,7 @@ public Session( this.warningCollector = requireNonNull(warningCollector, "warningCollector is null"); this.runtimeStats = requireNonNull(runtimeStats, "runtimeStats is null"); this.queryType = requireNonNull(queryType, "queryType is null"); - this.context = new AccessControlContext(queryId, clientInfo, clientTags, source, warningCollector, runtimeStats, queryType); + this.context = new AccessControlContext(queryId, clientInfo, clientTags, source, warningCollector, runtimeStats, queryType, catalog, schema); } public QueryId getQueryId() diff --git a/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java b/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java index 1b57af2b25880..c7cad332d7a0f 100644 --- a/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java +++ b/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java @@ -32,11 +32,13 @@ import com.facebook.presto.server.SessionSupplier; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.QueryId; +import com.facebook.presto.spi.WarningCollector; import com.facebook.presto.spi.analyzer.AnalyzerOptions; import com.facebook.presto.spi.analyzer.QueryPreparerProvider; import com.facebook.presto.spi.resourceGroups.SelectionContext; import com.facebook.presto.spi.resourceGroups.SelectionCriteria; import com.facebook.presto.spi.security.AccessControl; +import com.facebook.presto.spi.security.AccessControlContext; import com.facebook.presto.sql.analyzer.QueryPreparerProviderManager; import com.facebook.presto.transaction.TransactionManager; import com.google.common.util.concurrent.AbstractFuture; @@ -271,6 +273,19 @@ private void createQueryInternal(QueryId queryId, String slug, int retryCoun // decode session sessionBuilder = sessionSupplier.createSessionBuilder(queryId, sessionContext, warningCollectorFactory); + + AccessControlContext accessControlContext = new AccessControlContext( + queryId, + Optional.ofNullable(sessionContext.getClientInfo()), + sessionContext.getClientTags(), + Optional.ofNullable(sessionContext.getSource()), + WarningCollector.NOOP, + sessionContext.getRuntimeStats(), + Optional.empty(), + Optional.ofNullable(sessionContext.getCatalog()), + Optional.ofNullable(sessionContext.getSchema())); + + accessControl.checkQueryIntegrity(sessionContext.getIdentity(), accessControlContext, query); session = sessionBuilder.build(); // prepare query diff --git a/presto-main/src/main/java/com/facebook/presto/security/AccessControlUtils.java b/presto-main/src/main/java/com/facebook/presto/security/AccessControlUtils.java index c29c65d46023d..a22344d988a17 100644 --- a/presto-main/src/main/java/com/facebook/presto/security/AccessControlUtils.java +++ b/presto-main/src/main/java/com/facebook/presto/security/AccessControlUtils.java @@ -47,7 +47,9 @@ public static void checkPermissions(AccessControl accessControl, SecurityConfig Optional.ofNullable(sessionContext.getSource()), WarningCollector.NOOP, sessionContext.getRuntimeStats(), - Optional.empty()), + Optional.empty(), + Optional.ofNullable(sessionContext.getCatalog()), + Optional.ofNullable(sessionContext.getSchema())), identity.getPrincipal(), identity.getUser()); } @@ -73,7 +75,9 @@ public static Optional getAuthorizedIdentity(AccessControl a Optional.ofNullable(sessionContext.getSource()), WarningCollector.NOOP, sessionContext.getRuntimeStats(), - Optional.empty()), + Optional.empty(), + Optional.ofNullable(sessionContext.getCatalog()), + Optional.ofNullable(sessionContext.getSchema())), identity.getUser(), sessionContext.getCertificates()); return Optional.of(authorizedIdentity); diff --git a/presto-main/src/test/java/com/facebook/presto/security/TestAccessControlManager.java b/presto-main/src/test/java/com/facebook/presto/security/TestAccessControlManager.java index 767e0a06d35b3..20a0809799115 100644 --- a/presto-main/src/test/java/com/facebook/presto/security/TestAccessControlManager.java +++ b/presto-main/src/test/java/com/facebook/presto/security/TestAccessControlManager.java @@ -82,7 +82,7 @@ public void testInitializing() AccessControlManager accessControlManager = new AccessControlManager(createTestTransactionManager()); accessControlManager.checkCanSetUser( new Identity(USER_NAME, Optional.of(PRINCIPAL)), - new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()), + new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()), Optional.empty(), "foo"); } @@ -94,7 +94,7 @@ public void testNoneSystemAccessControl() accessControlManager.setSystemAccessControl(AllowAllSystemAccessControl.NAME, ImmutableMap.of()); accessControlManager.checkCanSetUser( new Identity(USER_NAME, Optional.of(PRINCIPAL)), - new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()), + new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()), Optional.empty(), USER_NAME); } @@ -106,7 +106,7 @@ public void testReadOnlySystemAccessControl() QualifiedObjectName tableName = new QualifiedObjectName("catalog", "schema", "table"); TransactionManager transactionManager = createTestTransactionManager(); AccessControlManager accessControlManager = new AccessControlManager(transactionManager); - AccessControlContext context = new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()); + AccessControlContext context = new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()); accessControlManager.setSystemAccessControl(ReadOnlySystemAccessControl.NAME, ImmutableMap.of()); accessControlManager.checkCanSetUser(identity, context, Optional.of(PRINCIPAL), USER_NAME); @@ -149,7 +149,7 @@ public void testSetAccessControl() accessControlManager.checkCanSetUser( new Identity(USER_NAME, Optional.of(PRINCIPAL)), - new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()), + new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()), Optional.of(PRINCIPAL), USER_NAME); assertEquals(accessControlFactory.getCheckedUserName(), USER_NAME); @@ -160,7 +160,7 @@ public void testSetAccessControl() public void testCheckQueryIntegrity() { AccessControlManager accessControlManager = new AccessControlManager(createTestTransactionManager()); - AccessControlContext context = new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()); + AccessControlContext context = new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()); TestSystemAccessControlFactory accessControlFactory = new TestSystemAccessControlFactory("test"); accessControlManager.addSystemAccessControlFactory(accessControlFactory); @@ -210,7 +210,7 @@ public void testNoCatalogAccessControl() transaction(transactionManager, accessControlManager) .execute(transactionId -> { accessControlManager.checkCanSelectFromColumns(transactionId, new Identity(USER_NAME, Optional.of(PRINCIPAL)), - new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()), + new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()), new QualifiedObjectName("catalog", "schema", "table"), ImmutableSet.of(new Subfield("column"))); }); } @@ -232,7 +232,7 @@ public void testDenyCatalogAccessControl() transaction(transactionManager, accessControlManager) .execute(transactionId -> { accessControlManager.checkCanSelectFromColumns(transactionId, new Identity(USER_NAME, Optional.of(PRINCIPAL)), - new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()), + new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()), new QualifiedObjectName("catalog", "schema", "table"), ImmutableSet.of(new Subfield("column"))); }); } @@ -254,7 +254,7 @@ public void testDenySystemAccessControl() transaction(transactionManager, accessControlManager) .execute(transactionId -> { accessControlManager.checkCanSelectFromColumns(transactionId, new Identity(USER_NAME, Optional.of(PRINCIPAL)), - new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()), + new AccessControlContext(new QueryId(QUERY_ID), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()), new QualifiedObjectName("secured_catalog", "schema", "table"), ImmutableSet.of(new Subfield("column"))); }); } diff --git a/presto-main/src/test/java/com/facebook/presto/security/TestFileBasedSystemAccessControl.java b/presto-main/src/test/java/com/facebook/presto/security/TestFileBasedSystemAccessControl.java index f9f661381e659..924160adf650b 100644 --- a/presto-main/src/test/java/com/facebook/presto/security/TestFileBasedSystemAccessControl.java +++ b/presto-main/src/test/java/com/facebook/presto/security/TestFileBasedSystemAccessControl.java @@ -70,7 +70,7 @@ public class TestFileBasedSystemAccessControl private static final QualifiedObjectName aliceTable = new QualifiedObjectName("alice-catalog", "schema", "table"); private static final QualifiedObjectName aliceView = new QualifiedObjectName("alice-catalog", "schema", "view"); private static final CatalogSchemaName aliceSchema = new CatalogSchemaName("alice-catalog", "schema"); - private static final AccessControlContext context = new AccessControlContext(new QueryId("query_id"), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()); + private static final AccessControlContext context = new AccessControlContext(new QueryId("query_id"), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()); @Test public void testCanSetUserOperations() throws IOException { diff --git a/presto-plugin-toolkit/src/test/java/com/facebook/presto/plugin/base/security/TestFileBasedAccessControl.java b/presto-plugin-toolkit/src/test/java/com/facebook/presto/plugin/base/security/TestFileBasedAccessControl.java index daf64d750d421..14f5649ef9ba3 100644 --- a/presto-plugin-toolkit/src/test/java/com/facebook/presto/plugin/base/security/TestFileBasedAccessControl.java +++ b/presto-plugin-toolkit/src/test/java/com/facebook/presto/plugin/base/security/TestFileBasedAccessControl.java @@ -43,7 +43,7 @@ public class TestFileBasedAccessControl { public static final ConnectorTransactionHandle TRANSACTION_HANDLE = new ConnectorTransactionHandle() {}; - public static final AccessControlContext CONTEXT = new AccessControlContext(new QueryId("query_id"), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty()); + public static final AccessControlContext CONTEXT = new AccessControlContext(new QueryId("query_id"), Optional.empty(), Collections.emptySet(), Optional.empty(), WarningCollector.NOOP, new RuntimeStats(), Optional.empty(), Optional.empty(), Optional.empty()); @Test public void testSchemaRules() diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/security/AccessControlContext.java b/presto-spi/src/main/java/com/facebook/presto/spi/security/AccessControlContext.java index 3cc3a2a08a230..11b2720fb3473 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/security/AccessControlContext.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/security/AccessControlContext.java @@ -32,8 +32,19 @@ public class AccessControlContext private final WarningCollector warningCollector; private final RuntimeStats runtimeStats; private final Optional queryType; + private final Optional catalog; + private final Optional schema; - public AccessControlContext(QueryId queryId, Optional clientInfo, Set clientTags, Optional source, WarningCollector warningCollector, RuntimeStats runtimeStats, Optional queryType) + public AccessControlContext( + QueryId queryId, + Optional clientInfo, + Set clientTags, + Optional source, + WarningCollector warningCollector, + RuntimeStats runtimeStats, + Optional queryType, + Optional catalog, + Optional schema) { this.queryId = requireNonNull(queryId, "queryId is null"); this.clientInfo = requireNonNull(clientInfo, "clientInfo is null"); @@ -42,6 +53,8 @@ public AccessControlContext(QueryId queryId, Optional clientInfo, Set getQueryType() { return queryType; } + + public Optional getCatalog() + { + return catalog; + } + + public Optional getSchema() + { + return schema; + } } diff --git a/presto-tests/src/test/java/com/facebook/presto/tests/TestQueryManager.java b/presto-tests/src/test/java/com/facebook/presto/tests/TestQueryManager.java index 7e82c52e51bf2..7708be91978f3 100644 --- a/presto-tests/src/test/java/com/facebook/presto/tests/TestQueryManager.java +++ b/presto-tests/src/test/java/com/facebook/presto/tests/TestQueryManager.java @@ -220,6 +220,8 @@ public void testQueryCpuLimit() BasicQueryInfo queryInfo = queryManager.getQueryInfo(queryId); assertEquals(queryInfo.getState(), FAILED); assertEquals(queryInfo.getErrorCode(), EXCEEDED_CPU_LIMIT.toErrorCode()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getSchema(), TEST_SESSION.getSchema()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getCatalog(), TEST_SESSION.getCatalog()); } } @@ -234,6 +236,8 @@ public void testQueryScanExceeded() BasicQueryInfo queryInfo = queryManager.getQueryInfo(queryId); assertEquals(queryInfo.getState(), FAILED); assertEquals(queryInfo.getErrorCode(), EXCEEDED_SCAN_RAW_BYTES_READ_LIMIT.toErrorCode()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getSchema(), TEST_SESSION.getSchema()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getCatalog(), TEST_SESSION.getCatalog()); } } @@ -248,6 +252,8 @@ public void testQueryOutputPositionsExceeded() BasicQueryInfo queryInfo = queryManager.getQueryInfo(queryId); assertEquals(queryInfo.getState(), FAILED); assertEquals(queryInfo.getErrorCode(), EXCEEDED_OUTPUT_POSITIONS_LIMIT.toErrorCode()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getSchema(), TEST_SESSION.getSchema()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getCatalog(), TEST_SESSION.getCatalog()); } } @@ -262,6 +268,8 @@ public void testQueryOutputSizeExceeded() BasicQueryInfo queryInfo = queryManager.getQueryInfo(queryId); assertEquals(queryInfo.getState(), FAILED); assertEquals(queryInfo.getErrorCode(), EXCEEDED_OUTPUT_SIZE_LIMIT.toErrorCode()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getSchema(), TEST_SESSION.getSchema()); + assertEquals(queryManager.getQuerySession(queryId).getAccessControlContext().getCatalog(), TEST_SESSION.getCatalog()); } }