From 2f25d78ff08e9199ac017c72fcda0845f4c5889d Mon Sep 17 00:00:00 2001 From: Yuya Ebihara Date: Wed, 13 Oct 2021 22:35:25 +0900 Subject: [PATCH] Check SET PROPERTIES permission in CREATE TABLE task --- .../io/trino/execution/CreateTableTask.java | 20 +++++++++++++++++-- .../java/io/trino/security/AccessControl.java | 9 +++++++++ .../trino/security/AccessControlManager.java | 13 ++++++++++++ .../trino/security/AllowAllAccessControl.java | 5 +++++ .../trino/security/DenyAllAccessControl.java | 6 ++++++ .../security/ForwardingAccessControl.java | 6 ++++++ .../InjectedConnectorAccessControl.java | 7 +++++++ .../io/trino/sql/analyzer/FeaturesConfig.java | 13 ++++++++++++ .../io/trino/testing/LocalQueryRunner.java | 2 +- .../testing/TestingAccessControlManager.java | 14 +++++++++++++ .../trino/execution/TestCreateTableTask.java | 19 +++++++++--------- .../sql/analyzer/TestFeaturesConfig.java | 7 +++++-- .../spi/connector/ConnectorAccessControl.java | 12 +++++++++++ .../spi/security/SystemAccessControl.java | 12 +++++++++++ ...ClassLoaderSafeConnectorAccessControl.java | 8 ++++++++ .../base/security/AllowAllAccessControl.java | 5 +++++ .../security/AllowAllSystemAccessControl.java | 5 +++++ .../base/security/FileBasedAccessControl.java | 9 +++++++++ .../FileBasedSystemAccessControl.java | 9 +++++++++ .../ForwardingConnectorAccessControl.java | 6 ++++++ .../ForwardingSystemAccessControl.java | 6 ++++++ .../base/security/ReadOnlyAccessControl.java | 6 ++++++ .../hive/security/LegacyAccessControl.java | 5 +++++ .../security/SqlStandardAccessControl.java | 8 ++++++++ 24 files changed, 198 insertions(+), 14 deletions(-) diff --git a/core/trino-main/src/main/java/io/trino/execution/CreateTableTask.java b/core/trino-main/src/main/java/io/trino/execution/CreateTableTask.java index d560efd1543d..dff8c57e0434 100644 --- a/core/trino-main/src/main/java/io/trino/execution/CreateTableTask.java +++ b/core/trino-main/src/main/java/io/trino/execution/CreateTableTask.java @@ -33,6 +33,7 @@ import io.trino.spi.security.AccessDeniedException; import io.trino.spi.type.Type; import io.trino.spi.type.TypeNotFoundException; +import io.trino.sql.analyzer.FeaturesConfig; import io.trino.sql.analyzer.Output; import io.trino.sql.analyzer.OutputColumn; import io.trino.sql.tree.ColumnDefinition; @@ -44,6 +45,8 @@ import io.trino.sql.tree.TableElement; import io.trino.transaction.TransactionManager; +import javax.inject.Inject; + import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -81,6 +84,14 @@ public class CreateTableTask implements DataDefinitionTask { + private final boolean disableSetPropertiesSecurityCheckForCreateDdl; + + @Inject + public CreateTableTask(FeaturesConfig featuresConfig) + { + this.disableSetPropertiesSecurityCheckForCreateDdl = featuresConfig.isDisableSetPropertiesSecurityCheckForCreateDdl(); + } + @Override public String getName() { @@ -231,8 +242,6 @@ else if (element instanceof LikeClause) { } } - accessControl.checkCanCreateTable(session.toSecurityContext(), tableName); - Map sqlProperties = mapFromProperties(statement.getProperties()); Map properties = metadata.getTablePropertyManager().getProperties( catalogName, @@ -244,6 +253,13 @@ else if (element instanceof LikeClause) { parameterLookup, true); + if (!disableSetPropertiesSecurityCheckForCreateDdl && !properties.isEmpty()) { + accessControl.checkCanCreateTable(session.toSecurityContext(), tableName, properties); + } + else { + accessControl.checkCanCreateTable(session.toSecurityContext(), tableName); + } + Map finalProperties = combineProperties(sqlProperties.keySet(), properties, inheritedProperties); ConnectorTableMetadata tableMetadata = new ConnectorTableMetadata(tableName.asSchemaTableName(), ImmutableList.copyOf(columns.values()), finalProperties, statement.getComment()); diff --git a/core/trino-main/src/main/java/io/trino/security/AccessControl.java b/core/trino-main/src/main/java/io/trino/security/AccessControl.java index c39acb2a11a8..a6b58d61c5c6 100644 --- a/core/trino-main/src/main/java/io/trino/security/AccessControl.java +++ b/core/trino-main/src/main/java/io/trino/security/AccessControl.java @@ -164,9 +164,18 @@ public interface AccessControl * Check if identity is allowed to create the specified table. * * @throws AccessDeniedException if not allowed + * @deprecated use {@link #checkCanCreateTable(SecurityContext context, QualifiedObjectName tableName, Map properties)} */ + @Deprecated void checkCanCreateTable(SecurityContext context, QualifiedObjectName tableName); + /** + * Check if identity is allowed to create the specified table with properties. + * + * @throws AccessDeniedException if not allowed + */ + void checkCanCreateTable(SecurityContext context, QualifiedObjectName tableName, Map properties); + /** * Check if identity is allowed to drop the specified table. * diff --git a/core/trino-main/src/main/java/io/trino/security/AccessControlManager.java b/core/trino-main/src/main/java/io/trino/security/AccessControlManager.java index 3ba8b00df12e..324447885e26 100644 --- a/core/trino-main/src/main/java/io/trino/security/AccessControlManager.java +++ b/core/trino-main/src/main/java/io/trino/security/AccessControlManager.java @@ -426,6 +426,19 @@ public void checkCanCreateTable(SecurityContext securityContext, QualifiedObject catalogAuthorizationCheck(tableName.getCatalogName(), securityContext, (control, context) -> control.checkCanCreateTable(context, tableName.asSchemaTableName())); } + @Override + public void checkCanCreateTable(SecurityContext securityContext, QualifiedObjectName tableName, Map properties) + { + requireNonNull(securityContext, "securityContext is null"); + requireNonNull(tableName, "tableName is null"); + + checkCanAccessCatalog(securityContext, tableName.getCatalogName()); + + systemAuthorizationCheck(control -> control.checkCanCreateTable(securityContext.toSystemSecurityContext(), tableName.asCatalogSchemaTableName(), properties)); + + catalogAuthorizationCheck(tableName.getCatalogName(), securityContext, (control, context) -> control.checkCanCreateTable(context, tableName.asSchemaTableName(), properties)); + } + @Override public void checkCanDropTable(SecurityContext securityContext, QualifiedObjectName tableName) { diff --git a/core/trino-main/src/main/java/io/trino/security/AllowAllAccessControl.java b/core/trino-main/src/main/java/io/trino/security/AllowAllAccessControl.java index e0039bcab85d..5f0327c90b49 100644 --- a/core/trino-main/src/main/java/io/trino/security/AllowAllAccessControl.java +++ b/core/trino-main/src/main/java/io/trino/security/AllowAllAccessControl.java @@ -122,6 +122,11 @@ public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tab { } + @Override + public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tableName, Map properties) + { + } + @Override public void checkCanDropTable(SecurityContext context, QualifiedObjectName tableName) { diff --git a/core/trino-main/src/main/java/io/trino/security/DenyAllAccessControl.java b/core/trino-main/src/main/java/io/trino/security/DenyAllAccessControl.java index 9cd21f4f1f5d..1a1741e971f8 100644 --- a/core/trino-main/src/main/java/io/trino/security/DenyAllAccessControl.java +++ b/core/trino-main/src/main/java/io/trino/security/DenyAllAccessControl.java @@ -184,6 +184,12 @@ public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tab denyCreateTable(tableName.toString()); } + @Override + public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tableName, Map properties) + { + denyCreateTable(tableName.toString()); + } + @Override public void checkCanDropTable(SecurityContext context, QualifiedObjectName tableName) { diff --git a/core/trino-main/src/main/java/io/trino/security/ForwardingAccessControl.java b/core/trino-main/src/main/java/io/trino/security/ForwardingAccessControl.java index aa4e0379454a..2d3d952888d0 100644 --- a/core/trino-main/src/main/java/io/trino/security/ForwardingAccessControl.java +++ b/core/trino-main/src/main/java/io/trino/security/ForwardingAccessControl.java @@ -159,6 +159,12 @@ public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tab delegate().checkCanCreateTable(context, tableName); } + @Override + public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tableName, Map properties) + { + delegate().checkCanCreateTable(context, tableName, properties); + } + @Override public void checkCanDropTable(SecurityContext context, QualifiedObjectName tableName) { diff --git a/core/trino-main/src/main/java/io/trino/security/InjectedConnectorAccessControl.java b/core/trino-main/src/main/java/io/trino/security/InjectedConnectorAccessControl.java index 76fe495600fd..556f8bca4d51 100644 --- a/core/trino-main/src/main/java/io/trino/security/InjectedConnectorAccessControl.java +++ b/core/trino-main/src/main/java/io/trino/security/InjectedConnectorAccessControl.java @@ -111,6 +111,13 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam accessControl.checkCanCreateTable(securityContext, getQualifiedObjectName(tableName)); } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + checkArgument(context == null, "context must be null"); + accessControl.checkCanCreateTable(securityContext, getQualifiedObjectName(tableName), properties); + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) { diff --git a/core/trino-main/src/main/java/io/trino/sql/analyzer/FeaturesConfig.java b/core/trino-main/src/main/java/io/trino/sql/analyzer/FeaturesConfig.java index 98fc68b0f14c..fb4fd55a9b32 100644 --- a/core/trino-main/src/main/java/io/trino/sql/analyzer/FeaturesConfig.java +++ b/core/trino-main/src/main/java/io/trino/sql/analyzer/FeaturesConfig.java @@ -141,6 +141,7 @@ public class FeaturesConfig private int maxGroupingSets = 2048; private boolean legacyCatalogRoles; + private boolean disableSetPropertiesSecurityCheckForCreateDdl; public enum JoinReorderingStrategy { @@ -1090,4 +1091,16 @@ public FeaturesConfig setLegacyCatalogRoles(boolean legacyCatalogRoles) this.legacyCatalogRoles = legacyCatalogRoles; return this; } + + public boolean isDisableSetPropertiesSecurityCheckForCreateDdl() + { + return disableSetPropertiesSecurityCheckForCreateDdl; + } + + @Config("deprecated.disable-set-properties-security-check-for-create-ddl") + public FeaturesConfig setDisableSetPropertiesSecurityCheckForCreateDdl(boolean disableSetPropertiesSecurityCheckForCreateDdl) + { + this.disableSetPropertiesSecurityCheckForCreateDdl = disableSetPropertiesSecurityCheckForCreateDdl; + return this; + } } diff --git a/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java b/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java index 82ae9a727159..cde4cb22f6e4 100644 --- a/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java +++ b/core/trino-main/src/main/java/io/trino/testing/LocalQueryRunner.java @@ -451,7 +451,7 @@ private LocalQueryRunner( defaultSession.getProtocolHeaders()); dataDefinitionTask = ImmutableMap., DataDefinitionTask>builder() - .put(CreateTable.class, new CreateTableTask()) + .put(CreateTable.class, new CreateTableTask(featuresConfig)) .put(CreateView.class, new CreateViewTask(sqlParser, groupProvider, statsCalculator)) .put(DropTable.class, new DropTableTask()) .put(DropView.class, new DropViewTask()) diff --git a/core/trino-main/src/main/java/io/trino/testing/TestingAccessControlManager.java b/core/trino-main/src/main/java/io/trino/testing/TestingAccessControlManager.java index 77c8b4f263ba..61436468bb23 100644 --- a/core/trino-main/src/main/java/io/trino/testing/TestingAccessControlManager.java +++ b/core/trino-main/src/main/java/io/trino/testing/TestingAccessControlManager.java @@ -340,6 +340,20 @@ public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tab } } + @Override + public void checkCanCreateTable(SecurityContext context, QualifiedObjectName tableName, Map properties) + { + if (shouldDenyPrivilege(context.getIdentity().getUser(), tableName.getObjectName(), CREATE_TABLE)) { + denyCreateTable(tableName.toString()); + } + if (shouldDenyPrivilege(context.getIdentity().getUser(), tableName.getObjectName(), SET_TABLE_PROPERTIES)) { + denySetTableProperties(tableName.toString()); + } + if (denyPrivileges.isEmpty()) { + super.checkCanCreateTable(context, tableName, properties); + } + } + @Override public void checkCanDropTable(SecurityContext context, QualifiedObjectName tableName) { diff --git a/core/trino-main/src/test/java/io/trino/execution/TestCreateTableTask.java b/core/trino-main/src/test/java/io/trino/execution/TestCreateTableTask.java index 68ccacb579b2..0b115bc9ad94 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestCreateTableTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestCreateTableTask.java @@ -40,6 +40,7 @@ import io.trino.spi.type.Type; import io.trino.spi.type.TypeId; import io.trino.spi.type.TypeSignature; +import io.trino.sql.analyzer.FeaturesConfig; import io.trino.sql.planner.TestingConnectorTransactionHandle; import io.trino.sql.tree.ColumnDefinition; import io.trino.sql.tree.CreateTable; @@ -144,7 +145,7 @@ public void testCreateTableNotExistsTrue() ImmutableList.of(), Optional.empty()); - getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {})); + getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {})); assertEquals(metadata.getCreateTableCallCount(), 1); } @@ -157,7 +158,7 @@ public void testCreateTableNotExistsFalse() ImmutableList.of(), Optional.empty()); - assertTrinoExceptionThrownBy(() -> getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {}))) + assertTrinoExceptionThrownBy(() -> getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {}))) .hasErrorCode(ALREADY_EXISTS) .hasMessage("Table already exists"); @@ -173,7 +174,7 @@ public void testCreateTableWithMaterializedViewPropertyFails() ImmutableList.of(new Property(new Identifier("foo"), new StringLiteral("bar"))), Optional.empty()); - assertTrinoExceptionThrownBy(() -> getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {}))) + assertTrinoExceptionThrownBy(() -> getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {}))) .hasErrorCode(INVALID_TABLE_PROPERTY) .hasMessage("Catalog 'catalog' does not support table property 'foo'"); @@ -190,7 +191,7 @@ public void testCreateWithNotNullColumns() new ColumnDefinition(identifier("c"), toSqlType(VARBINARY), false, emptyList(), Optional.empty())); CreateTable statement = new CreateTable(QualifiedName.of("test_table"), inputColumns, true, ImmutableList.of(), Optional.empty()); - getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {})); + getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {})); assertEquals(metadata.getCreateTableCallCount(), 1); List columns = metadata.getReceivedTableMetadata().get(0).getColumns(); assertEquals(columns.size(), 3); @@ -223,7 +224,7 @@ public void testCreateWithUnsupportedConnectorThrowsWhenNotNull() Optional.empty()); assertTrinoExceptionThrownBy(() -> - getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {}))) + getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList(), output -> {}))) .hasErrorCode(NOT_SUPPORTED) .hasMessage("Catalog 'catalog' does not support non-null column for column name 'b'"); } @@ -233,7 +234,7 @@ public void testCreateLike() { CreateTable statement = getCreatleLikeStatement(false); - getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, List.of(), output -> {})); + getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, List.of(), output -> {})); assertEquals(metadata.getCreateTableCallCount(), 1); assertThat(metadata.getReceivedTableMetadata().get(0).getColumns()) @@ -246,7 +247,7 @@ public void testCreateLikeWithProperties() { CreateTable statement = getCreatleLikeStatement(true); - getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, List.of(), output -> {})); + getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, List.of(), output -> {})); assertEquals(metadata.getCreateTableCallCount(), 1); assertThat(metadata.getReceivedTableMetadata().get(0).getColumns()) @@ -263,7 +264,7 @@ public void testCreateLikeDenyPermission() TestingAccessControlManager accessControl = new TestingAccessControlManager(transactionManager, new EventListenerManager(new EventListenerConfig())); accessControl.deny(privilege("parent_table", SELECT_COLUMN)); - assertThatThrownBy(() -> getFutureValue(new CreateTableTask().internalExecute(statement, metadata, accessControl, testSession, List.of(), output -> {}))) + assertThatThrownBy(() -> getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, accessControl, testSession, List.of(), output -> {}))) .isInstanceOf(AccessDeniedException.class) .hasMessageContaining("Cannot reference columns of table"); } @@ -276,7 +277,7 @@ public void testCreateLikeWithPropertiesDenyPermission() TestingAccessControlManager accessControl = new TestingAccessControlManager(transactionManager, new EventListenerManager(new EventListenerConfig())); accessControl.deny(privilege("parent_table", SHOW_CREATE_TABLE)); - assertThatThrownBy(() -> getFutureValue(new CreateTableTask().internalExecute(statement, metadata, accessControl, testSession, List.of(), output -> {}))) + assertThatThrownBy(() -> getFutureValue(new CreateTableTask(new FeaturesConfig()).internalExecute(statement, metadata, accessControl, testSession, List.of(), output -> {}))) .isInstanceOf(AccessDeniedException.class) .hasMessageContaining("Cannot reference properties of table"); } diff --git a/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java b/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java index 59070eb173f4..7d6235667d7d 100644 --- a/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java +++ b/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java @@ -113,7 +113,8 @@ public void testDefaults() .setUseTableScanNodePartitioning(true) .setTableScanNodePartitioningMinBucketToTaskRatio(0.5) .setMergeProjectWithValues(true) - .setLegacyCatalogRoles(false)); + .setLegacyCatalogRoles(false) + .setDisableSetPropertiesSecurityCheckForCreateDdl(false)); } @Test @@ -192,6 +193,7 @@ public void testExplicitPropertyMappings() .put("optimizer.table-scan-node-partitioning-min-bucket-to-task-ratio", "0.0") .put("optimizer.merge-project-with-values", "false") .put("deprecated.legacy-catalog-roles", "true") + .put("deprecated.disable-set-properties-security-check-for-create-ddl", "true") .build(); FeaturesConfig expected = new FeaturesConfig() @@ -266,7 +268,8 @@ public void testExplicitPropertyMappings() .setUseTableScanNodePartitioning(false) .setTableScanNodePartitioningMinBucketToTaskRatio(0.0) .setMergeProjectWithValues(false) - .setLegacyCatalogRoles(true); + .setLegacyCatalogRoles(true) + .setDisableSetPropertiesSecurityCheckForCreateDdl(true); assertFullMapping(properties, expected); } } diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorAccessControl.java b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorAccessControl.java index 0f6abda4bbae..9c927826ab21 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorAccessControl.java +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorAccessControl.java @@ -159,12 +159,24 @@ default void checkCanShowCreateTable(ConnectorSecurityContext context, SchemaTab * Check if identity is allowed to create the specified table. * * @throws io.trino.spi.security.AccessDeniedException if not allowed + * @deprecated use {@link #checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties)} instead */ + @Deprecated default void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName) { denyCreateTable(tableName.toString()); } + /** + * Check if identity is allowed to create the specified table with properties. + * + * @throws io.trino.spi.security.AccessDeniedException if not allowed + */ + default void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + denyCreateTable(tableName.toString()); + } + /** * Check if identity is allowed to drop the specified table. * diff --git a/core/trino-spi/src/main/java/io/trino/spi/security/SystemAccessControl.java b/core/trino-spi/src/main/java/io/trino/spi/security/SystemAccessControl.java index 26909886249e..02160550a1d3 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/security/SystemAccessControl.java +++ b/core/trino-spi/src/main/java/io/trino/spi/security/SystemAccessControl.java @@ -285,12 +285,24 @@ default void checkCanShowCreateTable(SystemSecurityContext context, CatalogSchem * Check if identity is allowed to create the specified table in a catalog. * * @throws AccessDeniedException if not allowed + * @deprecated use {@link #checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTableName table, Map properties)} instead */ + @Deprecated default void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTableName table) { denyCreateTable(table.toString()); } + /** + * Check if identity is allowed to create the specified table with properties in a catalog. + * + * @throws AccessDeniedException if not allowed + */ + default void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTableName table, Map properties) + { + denyCreateTable(table.toString()); + } + /** * Check if identity is allowed to drop the specified table in a catalog. * diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorAccessControl.java index 48bd9f32539a..0265c3dc233e 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorAccessControl.java @@ -116,6 +116,14 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam } } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(classLoader)) { + delegate.checkCanCreateTable(context, tableName, properties); + } + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) { diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllAccessControl.java index 8bef5c1e3bbc..856ccf629315 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllAccessControl.java @@ -75,6 +75,11 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam { } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) { diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllSystemAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllSystemAccessControl.java index ed51450cf90a..d89e3c66cacc 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllSystemAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/AllowAllSystemAccessControl.java @@ -163,6 +163,11 @@ public void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTabl { } + @Override + public void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTableName table, Map properties) + { + } + @Override public void checkCanDropTable(SystemSecurityContext context, CatalogSchemaTableName table) { diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedAccessControl.java index ca9ab0810cf4..f1d8a46f7fc1 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedAccessControl.java @@ -191,6 +191,15 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam } } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + // check if user will be an owner of the table after creation + if (!checkTablePermission(context, tableName, OWNERSHIP)) { + denyCreateTable(tableName.toString()); + } + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) { diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedSystemAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedSystemAccessControl.java index 55ccd1aa5ae4..c4d8cb760ae8 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedSystemAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/FileBasedSystemAccessControl.java @@ -508,6 +508,15 @@ public void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTabl } } + @Override + public void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTableName table, Map properties) + { + // check if user will be an owner of the table after creation + if (!checkTablePermission(context, table, OWNERSHIP)) { + denyCreateTable(table.toString()); + } + } + @Override public void checkCanDropTable(SystemSecurityContext context, CatalogSchemaTableName table) { diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingConnectorAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingConnectorAccessControl.java index fd385d2427d6..680a3cce4d32 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingConnectorAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingConnectorAccessControl.java @@ -101,6 +101,12 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam delegate().checkCanCreateTable(context, tableName); } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + delegate().checkCanCreateTable(context, tableName, properties); + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) { diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingSystemAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingSystemAccessControl.java index fee897d74445..1f2c6a229177 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingSystemAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ForwardingSystemAccessControl.java @@ -171,6 +171,12 @@ public void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTabl delegate().checkCanCreateTable(context, table); } + @Override + public void checkCanCreateTable(SystemSecurityContext context, CatalogSchemaTableName table, Map properties) + { + delegate().checkCanCreateTable(context, table, properties); + } + @Override public void checkCanDropTable(SystemSecurityContext context, CatalogSchemaTableName table) { diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ReadOnlyAccessControl.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ReadOnlyAccessControl.java index f77d75fdad84..8def3c94c1e4 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ReadOnlyAccessControl.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/security/ReadOnlyAccessControl.java @@ -86,6 +86,12 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam denyCreateTable(tableName.toString()); } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + denyCreateTable(tableName.toString()); + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) { diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/LegacyAccessControl.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/LegacyAccessControl.java index 93bd2dbe358f..09225332e952 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/LegacyAccessControl.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/LegacyAccessControl.java @@ -115,6 +115,11 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam { } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) { diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControl.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControl.java index 251adf6e2891..4c834b5e900f 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControl.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControl.java @@ -186,6 +186,14 @@ public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableNam } } + @Override + public void checkCanCreateTable(ConnectorSecurityContext context, SchemaTableName tableName, Map properties) + { + if (!isDatabaseOwner(context, tableName.getSchemaName())) { + denyCreateTable(tableName.toString()); + } + } + @Override public void checkCanDropTable(ConnectorSecurityContext context, SchemaTableName tableName) {