diff --git a/core/trino-main/src/main/java/io/trino/connector/DefaultCatalogFactory.java b/core/trino-main/src/main/java/io/trino/connector/DefaultCatalogFactory.java index b9759c83fced..4830deeb1d47 100644 --- a/core/trino-main/src/main/java/io/trino/connector/DefaultCatalogFactory.java +++ b/core/trino-main/src/main/java/io/trino/connector/DefaultCatalogFactory.java @@ -178,7 +178,9 @@ private CatalogConnector createCatalog(CatalogHandle catalogHandle, ConnectorNam new SystemConnector( nodeManager, systemTablesProvider, - transactionId -> transactionManager.getConnectorTransaction(transactionId, catalogHandle))); + transactionId -> transactionManager.getConnectorTransaction(transactionId, catalogHandle), + accessControl, + catalogHandle.getCatalogName().toString())); return new CatalogConnector( catalogHandle, diff --git a/core/trino-main/src/main/java/io/trino/connector/system/SystemConnector.java b/core/trino-main/src/main/java/io/trino/connector/system/SystemConnector.java index 1871c8f4717b..a77bc4c7beba 100644 --- a/core/trino-main/src/main/java/io/trino/connector/system/SystemConnector.java +++ b/core/trino-main/src/main/java/io/trino/connector/system/SystemConnector.java @@ -14,6 +14,7 @@ package io.trino.connector.system; import io.trino.metadata.InternalNodeManager; +import io.trino.security.AccessControl; import io.trino.spi.connector.ConnectorMetadata; import io.trino.spi.connector.ConnectorPageSourceProvider; import io.trino.spi.connector.ConnectorSession; @@ -38,15 +39,19 @@ public class SystemConnector public SystemConnector( InternalNodeManager nodeManager, SystemTablesProvider tables, - Function transactionHandleFunction) + Function transactionHandleFunction, + AccessControl accessControl, + String catalogName) { requireNonNull(nodeManager, "nodeManager is null"); requireNonNull(tables, "tables is null"); requireNonNull(transactionHandleFunction, "transactionHandleFunction is null"); + requireNonNull(accessControl, "accessControl is null"); + requireNonNull(catalogName, "catalogName is null"); this.metadata = new SystemTablesMetadata(tables); this.splitManager = new SystemSplitManager(nodeManager, tables); - this.pageSourceProvider = new SystemPageSourceProvider(tables); + this.pageSourceProvider = new SystemPageSourceProvider(tables, accessControl, catalogName); this.transactionHandleFunction = transactionHandleFunction; } diff --git a/core/trino-main/src/main/java/io/trino/connector/system/SystemPageSourceProvider.java b/core/trino-main/src/main/java/io/trino/connector/system/SystemPageSourceProvider.java index 5bc99192a1d9..0ac26c243b0d 100644 --- a/core/trino-main/src/main/java/io/trino/connector/system/SystemPageSourceProvider.java +++ b/core/trino-main/src/main/java/io/trino/connector/system/SystemPageSourceProvider.java @@ -15,11 +15,17 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import io.trino.FullConnectorSession; import io.trino.plugin.base.MappedPageSource; import io.trino.plugin.base.MappedRecordSet; +import io.trino.security.AccessControl; +import io.trino.security.InjectedConnectorAccessControl; +import io.trino.security.SecurityContext; +import io.trino.spi.QueryId; import io.trino.spi.TrinoException; import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; +import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorPageSource; import io.trino.spi.connector.ConnectorPageSourceProvider; import io.trino.spi.connector.ConnectorSession; @@ -44,6 +50,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR; import static io.trino.spi.StandardErrorCode.NOT_FOUND; +import static io.trino.spi.connector.SystemTable.Distribution.ALL_NODES; import static java.lang.String.format; import static java.util.Objects.requireNonNull; @@ -51,10 +58,14 @@ public class SystemPageSourceProvider implements ConnectorPageSourceProvider { private final SystemTablesProvider tables; + private final AccessControl accessControl; + private final String catalogName; - public SystemPageSourceProvider(SystemTablesProvider tables) + public SystemPageSourceProvider(SystemTablesProvider tables, AccessControl accessControl, String catalogName) { this.tables = requireNonNull(tables, "tables is null"); + this.accessControl = requireNonNull(accessControl, "accessControl is null"); + this.catalogName = requireNonNull(catalogName, "catalogName is null"); } @Override @@ -105,8 +116,31 @@ public ConnectorPageSource createPageSource( TupleDomain newConstraint = systemSplit.getConstraint().transformKeys(columnHandle -> columnsByName.get(((SystemColumnHandle) columnHandle).columnName())); + ConnectorAccessControl accessControl1 = new InjectedConnectorAccessControl( + accessControl, + new SecurityContext( + systemTransaction.getTransactionId(), + ((FullConnectorSession) session).getSession().getIdentity(), + QueryId.valueOf(session.getQueryId()), + session.getStart()), + catalogName); try { - return new MappedPageSource(systemTable.pageSource(systemTransaction.getConnectorTransactionHandle(), session, newConstraint), userToSystemFieldIndex.build()); + // Do not pass access control for tables that execute on workers + if (systemTable.getDistribution().equals(ALL_NODES)) { + return new MappedPageSource( + systemTable.pageSource( + systemTransaction.getConnectorTransactionHandle(), + session, + newConstraint), + userToSystemFieldIndex.build()); + } + return new MappedPageSource( + systemTable.pageSource( + systemTransaction.getConnectorTransactionHandle(), + session, + newConstraint, + accessControl1), + userToSystemFieldIndex.build()); } catch (UnsupportedOperationException e) { return new RecordPageSource(new MappedRecordSet( @@ -116,7 +150,8 @@ public ConnectorPageSource createPageSource( session, newConstraint, requiredColumns.build(), - systemSplit), + systemSplit, + accessControl1), userToSystemFieldIndex.build())); } } @@ -127,7 +162,8 @@ private static RecordSet toRecordSet( ConnectorSession session, TupleDomain constraint, Set requiredColumns, - ConnectorSplit split) + ConnectorSplit split, + ConnectorAccessControl accessControl1) { return new RecordSet() { @@ -144,7 +180,11 @@ public List getColumnTypes() @Override public RecordCursor cursor() { - return table.cursor(sourceTransaction, session, constraint, requiredColumns, split); + // Do not pass access control for tables that execute on workers + if (table.getDistribution().equals(ALL_NODES)) { + return table.cursor(sourceTransaction, session, constraint, requiredColumns, split); + } + return table.cursor(sourceTransaction, session, constraint, requiredColumns, split, accessControl1); } }; } diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/SystemTable.java b/core/trino-spi/src/main/java/io/trino/spi/connector/SystemTable.java index b687ba4a2f31..1617dff83ba4 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/connector/SystemTable.java +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/SystemTable.java @@ -53,6 +53,17 @@ default RecordCursor cursor( return cursor(transactionHandle, session, constraint); } + default RecordCursor cursor( + ConnectorTransactionHandle transactionHandle, + ConnectorSession session, + TupleDomain constraint, + Set requiredColumns, + ConnectorSplit split, + ConnectorAccessControl accessControl) + { + return cursor(transactionHandle, session, constraint, requiredColumns, split); + } + /** * Create a page source for the data in this table. * @@ -64,6 +75,15 @@ default ConnectorPageSource pageSource(ConnectorTransactionHandle transactionHan throw new UnsupportedOperationException(); } + default ConnectorPageSource pageSource( + ConnectorTransactionHandle transactionHandle, + ConnectorSession session, + TupleDomain constraint, + ConnectorAccessControl accessControl) + { + return pageSource(transactionHandle, session, constraint); + } + default Optional splitSource(ConnectorSession connectorSession, TupleDomain constraint) { return Optional.empty(); diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeSystemTable.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeSystemTable.java index d80920149ddf..eacb36b708f2 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeSystemTable.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeSystemTable.java @@ -16,6 +16,7 @@ import com.google.inject.Inject; import io.trino.spi.classloader.ThreadContextClassLoader; import io.trino.spi.connector.ColumnHandle; +import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorPageSource; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorSplit; @@ -81,6 +82,20 @@ public RecordCursor cursor( } } + @Override + public RecordCursor cursor( + ConnectorTransactionHandle transactionHandle, + ConnectorSession session, + TupleDomain constraint, + Set requiredColumns, + ConnectorSplit split, + ConnectorAccessControl accessControl) + { + try (ThreadContextClassLoader _ = new ThreadContextClassLoader(classLoader)) { + return delegate.cursor(transactionHandle, session, constraint, requiredColumns, split, accessControl); + } + } + @Override public ConnectorPageSource pageSource(ConnectorTransactionHandle transactionHandle, ConnectorSession session, TupleDomain constraint) { @@ -89,6 +104,18 @@ public ConnectorPageSource pageSource(ConnectorTransactionHandle transactionHand } } + @Override + public ConnectorPageSource pageSource( + ConnectorTransactionHandle transactionHandle, + ConnectorSession session, + TupleDomain constraint, + ConnectorAccessControl accessControl) + { + try (ThreadContextClassLoader _ = new ThreadContextClassLoader(classLoader)) { + return delegate.pageSource(transactionHandle, session, constraint, accessControl); + } + } + @Override public Optional splitSource(ConnectorSession connectorSession, TupleDomain constraint) {