diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java index c9411fe33993..0de71207fe39 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetastoreClosure.java @@ -21,6 +21,7 @@ import io.trino.plugin.hive.metastore.HiveMetastore; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.Partition; import io.trino.plugin.hive.metastore.PartitionWithStatistics; import io.trino.plugin.hive.metastore.PrincipalPrivileges; @@ -281,14 +282,14 @@ public Set listRoleGrants(HivePrincipal principal) return delegate.listRoleGrants(principal); } - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { - delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { - delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } public Set listTablePrivileges(String databaseName, String tableName, Optional tableOwner, Optional principal) diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java index 8f88365b9e42..025ee381956b 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/HiveMetastore.java @@ -20,6 +20,7 @@ import io.trino.plugin.hive.acid.AcidOperation; import io.trino.plugin.hive.acid.AcidTransaction; import io.trino.plugin.hive.authentication.HiveIdentity; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.predicate.TupleDomain; import io.trino.spi.security.RoleGrant; @@ -132,9 +133,9 @@ default void updatePartitionStatistics(HiveIdentity identity, Table table, Strin Set listRoleGrants(HivePrincipal principal); - void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges); + void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption); - void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges); + void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption); /** * @param tableOwner diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/RecordingHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/RecordingHiveMetastore.java index 7efe91e92714..4c640c5a166c 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/RecordingHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/RecordingHiveMetastore.java @@ -26,6 +26,7 @@ import io.trino.plugin.hive.RecordingMetastoreConfig; import io.trino.plugin.hive.acid.AcidTransaction; import io.trino.plugin.hive.authentication.HiveIdentity; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.spi.TrinoException; import io.trino.spi.predicate.TupleDomain; import io.trino.spi.security.RoleGrant; @@ -445,17 +446,17 @@ public Set listTablePrivileges(String databaseName, String ta } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { verifyRecordingMode(); - delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { verifyRecordingMode(); - delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } @Override diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java index 8a524163f64c..369ada550640 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/SemiTransactionalHiveMetastore.java @@ -38,6 +38,7 @@ import io.trino.plugin.hive.acid.AcidOperation; import io.trino.plugin.hive.acid.AcidTransaction; import io.trino.plugin.hive.authentication.HiveIdentity; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.security.SqlStandardAccessControlMetadataMetastore; import io.trino.spi.TrinoException; import io.trino.spi.connector.ConnectorSession; @@ -1134,15 +1135,15 @@ private Table getExistingTable(HiveIdentity identity, String databaseName, Strin } @Override - public synchronized void grantTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, Set privileges) + public synchronized void grantTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { - setExclusive((delegate, hdfsEnvironment) -> delegate.grantTablePrivileges(databaseName, tableName, getRequiredTableOwner(identity, databaseName, tableName), grantee, privileges)); + setExclusive((delegate, hdfsEnvironment) -> delegate.grantTablePrivileges(databaseName, tableName, getRequiredTableOwner(identity, databaseName, tableName), grantee, grantor, privileges, grantOption)); } @Override - public synchronized void revokeTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, Set privileges) + public synchronized void revokeTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { - setExclusive((delegate, hdfsEnvironment) -> delegate.revokeTablePrivileges(databaseName, tableName, getRequiredTableOwner(identity, databaseName, tableName), grantee, privileges)); + setExclusive((delegate, hdfsEnvironment) -> delegate.revokeTablePrivileges(databaseName, tableName, getRequiredTableOwner(identity, databaseName, tableName), grantee, grantor, privileges, grantOption)); } public synchronized String declareIntentionToWrite(ConnectorSession session, WriteMode writeMode, Path stagingPathRoot, SchemaTableName schemaTableName) diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/alluxio/AlluxioHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/alluxio/AlluxioHiveMetastore.java index 7ab24d4684b5..715c9167cb09 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/alluxio/AlluxioHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/alluxio/AlluxioHiveMetastore.java @@ -33,6 +33,7 @@ import io.trino.plugin.hive.metastore.HiveMetastore; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.MetastoreConfig; import io.trino.plugin.hive.metastore.Partition; import io.trino.plugin.hive.metastore.PartitionWithStatistics; @@ -464,15 +465,13 @@ public Set listRoleGrants(HivePrincipal principal) } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, - Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new TrinoException(NOT_SUPPORTED, "grantTablePrivileges"); } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, - Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new TrinoException(NOT_SUPPORTED, "revokeTablePrivileges"); } diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java index 585475a34247..24c51c051af7 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/cache/CachingHiveMetastore.java @@ -35,6 +35,7 @@ import io.trino.plugin.hive.metastore.HivePartitionName; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.HiveTableName; import io.trino.plugin.hive.metastore.Partition; import io.trino.plugin.hive.metastore.PartitionFilter; @@ -887,10 +888,10 @@ private void invalidatePartitionCache(String databaseName, String tableName) } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { try { - delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } finally { invalidateTablePrivilegeCacheEntries(databaseName, tableName, tableOwner, grantee); @@ -898,10 +899,10 @@ public void grantTablePrivileges(String databaseName, String tableName, String t } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { try { - delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } finally { invalidateTablePrivilegeCacheEntries(databaseName, tableName, tableOwner, grantee); diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java index c6a0860c56d4..7dd8cc471e13 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/file/FileHiveMetastore.java @@ -43,6 +43,7 @@ import io.trino.plugin.hive.metastore.HiveMetastore; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.MetastoreConfig; import io.trino.plugin.hive.metastore.Partition; import io.trino.plugin.hive.metastore.PartitionWithStatistics; @@ -1113,17 +1114,23 @@ public synchronized Set listTablePrivileges(String databaseNa } @Override - public synchronized void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public synchronized void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { - setTablePrivileges(grantee, databaseName, tableName, privileges); + setTablePrivileges( + grantee, + databaseName, + tableName, + privileges.stream() + .map(privilege -> new HivePrivilegeInfo(privilege, grantOption, grantor, grantee)) + .collect(toImmutableList())); } @Override - public synchronized void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public synchronized void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { Set currentPrivileges = listTablePrivileges(databaseName, tableName, Optional.of(tableOwner), Optional.of(grantee)); Set privilegesToRemove = privileges.stream() - .map(p -> new HivePrivilegeInfo(p.getHivePrivilege(), p.isGrantOption(), p.getGrantor(), grantee)) + .map(p -> new HivePrivilegeInfo(p, grantOption, grantor, grantee)) .collect(toImmutableSet()); setTablePrivileges(grantee, databaseName, tableName, Sets.difference(currentPrivileges, privilegesToRemove)); diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java index 8fd680e87972..8c6b3fee2add 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/glue/GlueHiveMetastore.java @@ -84,6 +84,7 @@ import io.trino.plugin.hive.metastore.HiveMetastore; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.Partition; import io.trino.plugin.hive.metastore.PartitionWithStatistics; import io.trino.plugin.hive.metastore.PrincipalPrivileges; @@ -1090,13 +1091,13 @@ public Set listRoleGrants(HivePrincipal principal) } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new TrinoException(NOT_SUPPORTED, "grantTablePrivileges is not supported by Glue"); } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new TrinoException(NOT_SUPPORTED, "revokeTablePrivileges is not supported by Glue"); } diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java index b58ebbfc587a..c08b0d8f4c57 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/BridgingHiveMetastore.java @@ -24,6 +24,7 @@ import io.trino.plugin.hive.metastore.HiveMetastore; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.Partition; import io.trino.plugin.hive.metastore.PartitionWithStatistics; import io.trino.plugin.hive.metastore.PrincipalPrivileges; @@ -448,15 +449,15 @@ public Set listRoleGrants(HivePrincipal principal) } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { - delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.grantTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { - delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, privileges); + delegate.revokeTablePrivileges(databaseName, tableName, tableOwner, grantee, grantor, privileges, grantOption); } @Override diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/FailureAwareThriftMetastoreClient.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/FailureAwareThriftMetastoreClient.java index 33f55265ab96..8491516cd21d 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/FailureAwareThriftMetastoreClient.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/FailureAwareThriftMetastoreClient.java @@ -301,10 +301,10 @@ public boolean grantPrivileges(PrivilegeBag privilegeBag) } @Override - public boolean revokePrivileges(PrivilegeBag privilegeBag) + public boolean revokePrivileges(PrivilegeBag privilegeBag, boolean grantOption) throws TException { - return runWithHandle(() -> delegate.revokePrivileges(privilegeBag)); + return runWithHandle(() -> delegate.revokePrivileges(privilegeBag, grantOption)); } @Override diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastore.java index 8e8a6c38211b..8252f6c70686 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastore.java @@ -41,6 +41,7 @@ import io.trino.plugin.hive.metastore.HiveColumnStatistics; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.MetastoreConfig; import io.trino.plugin.hive.metastore.PartitionWithStatistics; import io.trino.plugin.hive.metastore.thrift.ThriftMetastoreAuthenticationConfig.ThriftMetastoreAuthenticationType; @@ -1440,9 +1441,10 @@ public List getPartitionsByNames(HiveIdentity identity, String databa } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { Set requestedPrivileges = privileges.stream() + .map(privilege -> new HivePrivilegeInfo(privilege, grantOption, grantor, grantee)) .map(ThriftMetastoreUtil::toMetastoreApiPrivilegeGrantInfo) .collect(toImmutableSet()); checkArgument(!containsAllPrivilege(requestedPrivileges), "\"ALL\" not supported in PrivilegeGrantInfo.privilege"); @@ -1491,9 +1493,10 @@ else if (existingPrivilege.isContainedIn(requestedPrivilege)) { } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { Set requestedPrivileges = privileges.stream() + .map(privilege -> new HivePrivilegeInfo(privilege, grantOption, grantor, grantee)) .map(ThriftMetastoreUtil::toMetastoreApiPrivilegeGrantInfo) .collect(toImmutableSet()); checkArgument(!containsAllPrivilege(requestedPrivileges), "\"ALL\" not supported in PrivilegeGrantInfo.privilege"); @@ -1515,7 +1518,7 @@ public void revokeTablePrivileges(String databaseName, String tableName, String return null; } - metastoreClient.revokePrivileges(buildPrivilegeBag(databaseName, tableName, grantee, privilegesToRevoke)); + metastoreClient.revokePrivileges(buildPrivilegeBag(databaseName, tableName, grantee, privilegesToRevoke), grantOption); } return null; })); diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastoreClient.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastoreClient.java index f40ddf42190c..a89c92ced2b1 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastoreClient.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftHiveMetastoreClient.java @@ -42,6 +42,7 @@ import org.apache.hadoop.hive.metastore.api.GetRoleGrantsForPrincipalResponse; import org.apache.hadoop.hive.metastore.api.GetTableRequest; import org.apache.hadoop.hive.metastore.api.GetValidWriteIdsRequest; +import org.apache.hadoop.hive.metastore.api.GrantRevokePrivilegeRequest; import org.apache.hadoop.hive.metastore.api.GrantRevokeRoleRequest; import org.apache.hadoop.hive.metastore.api.GrantRevokeRoleResponse; import org.apache.hadoop.hive.metastore.api.GrantRevokeType; @@ -78,6 +79,8 @@ import static io.trino.plugin.hive.metastore.MetastoreUtil.adjustRowCount; import static java.lang.String.format; import static java.util.Objects.requireNonNull; +import static org.apache.hadoop.hive.metastore.api.GrantRevokeType.GRANT; +import static org.apache.hadoop.hive.metastore.api.GrantRevokeType.REVOKE; import static org.apache.hadoop.hive.metastore.txn.TxnUtils.createValidTxnWriteIdList; public class ThriftHiveMetastoreClient @@ -350,14 +353,16 @@ public void dropRole(String role) public boolean grantPrivileges(PrivilegeBag privilegeBag) throws TException { - return client.grant_privileges(privilegeBag); + return client.grant_revoke_privileges(new GrantRevokePrivilegeRequest(GRANT, privilegeBag)).isSuccess(); } @Override - public boolean revokePrivileges(PrivilegeBag privilegeBag) + public boolean revokePrivileges(PrivilegeBag privilegeBag, boolean revokeGrantOption) throws TException { - return client.revoke_privileges(privilegeBag); + GrantRevokePrivilegeRequest grantRevokePrivilegeRequest = new GrantRevokePrivilegeRequest(REVOKE, privilegeBag); + grantRevokePrivilegeRequest.setRevokeGrantOption(revokeGrantOption); + return client.grant_revoke_privileges(grantRevokePrivilegeRequest).isSuccess(); } @Override @@ -424,7 +429,7 @@ private void removeGrant(String role, String granteeName, PrincipalType granteeT throws TException { GrantRevokeRoleRequest request = new GrantRevokeRoleRequest(); - request.setRequestType(GrantRevokeType.REVOKE); + request.setRequestType(REVOKE); request.setRoleName(role); request.setPrincipalName(granteeName); request.setPrincipalType(granteeType); diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastore.java index 10298c32edb3..3658b2b91b7a 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastore.java @@ -20,6 +20,7 @@ import io.trino.plugin.hive.authentication.HiveIdentity; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.PartitionWithStatistics; import io.trino.spi.TrinoException; import io.trino.spi.connector.SchemaTableName; @@ -107,9 +108,9 @@ public interface ThriftMetastore Set listRoleGrants(HivePrincipal principal); - void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges); + void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption); - void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges); + void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption); /** * @param tableOwner diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastoreClient.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastoreClient.java index 7258e8676b78..4ad306d54e77 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastoreClient.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/metastore/thrift/ThriftMetastoreClient.java @@ -141,7 +141,7 @@ void dropRole(String role) boolean grantPrivileges(PrivilegeBag privilegeBag) throws TException; - boolean revokePrivileges(PrivilegeBag privilegeBag) + boolean revokePrivileges(PrivilegeBag privilegeBag, boolean revokeGrantOption) throws TException; void grantRole(String role, String granteeName, PrincipalType granteeType, String grantorName, PrincipalType grantorType, boolean grantOption) diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadata.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadata.java index d90857fc3a82..70afeb5872ef 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadata.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadata.java @@ -36,7 +36,6 @@ import java.util.Set; import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static io.trino.plugin.hive.metastore.HivePrivilegeInfo.toHivePrivilege; import static io.trino.plugin.hive.security.SqlStandardAccessControl.ADMIN_ROLE_NAME; import static io.trino.spi.StandardErrorCode.ALREADY_EXISTS; import static io.trino.spi.security.PrincipalType.ROLE; @@ -175,11 +174,16 @@ public void grantTablePrivileges(ConnectorSession session, SchemaTableName schem String schemaName = schemaTableName.getSchemaName(); String tableName = schemaTableName.getTableName(); - Set hivePrivilegeInfos = privileges.stream() - .map(privilege -> new HivePrivilegeInfo(toHivePrivilege(privilege), grantOption, new HivePrincipal(USER, session.getUser()), new HivePrincipal(USER, session.getUser()))) - .collect(toSet()); - - metastore.grantTablePrivileges(new HiveIdentity(session), schemaName, tableName, grantee, hivePrivilegeInfos); + metastore.grantTablePrivileges( + new HiveIdentity(session), + schemaName, + tableName, + grantee, + new HivePrincipal(USER, session.getUser()), + privileges.stream() + .map(HivePrivilegeInfo::toHivePrivilege) + .collect(toSet()), + grantOption); } @Override @@ -188,11 +192,16 @@ public void revokeTablePrivileges(ConnectorSession session, SchemaTableName sche String schemaName = schemaTableName.getSchemaName(); String tableName = schemaTableName.getTableName(); - Set hivePrivilegeInfos = privileges.stream() - .map(privilege -> new HivePrivilegeInfo(toHivePrivilege(privilege), grantOption, new HivePrincipal(USER, session.getUser()), new HivePrincipal(USER, session.getUser()))) - .collect(toSet()); - - metastore.revokeTablePrivileges(new HiveIdentity(session), schemaName, tableName, grantee, hivePrivilegeInfos); + metastore.revokeTablePrivileges( + new HiveIdentity(session), + schemaName, + tableName, + grantee, + new HivePrincipal(USER, session.getUser()), + privileges.stream() + .map(HivePrivilegeInfo::toHivePrivilege) + .collect(toSet()), + grantOption); } @Override diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadataMetastore.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadataMetastore.java index b66cdc1353dd..dc025bfe6142 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadataMetastore.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/security/SqlStandardAccessControlMetadataMetastore.java @@ -16,6 +16,7 @@ import io.trino.plugin.hive.authentication.HiveIdentity; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.spi.security.RoleGrant; import java.util.Optional; @@ -41,9 +42,9 @@ public interface SqlStandardAccessControlMetadataMetastore Set listGrantedPrincipals(String role); - void revokeTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, Set privileges); + void revokeTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption); - void grantTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, Set privileges); + void grantTablePrivileges(HiveIdentity identity, String databaseName, String tableName, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption); Set listTablePrivileges(HiveIdentity identity, String databaseName, String tableName, Optional principal); } diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java index 60257dcebdce..fdcb82715f75 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/UnimplementedHiveMetastore.java @@ -17,6 +17,7 @@ import io.trino.plugin.hive.PartitionStatistics; import io.trino.plugin.hive.acid.AcidTransaction; import io.trino.plugin.hive.authentication.HiveIdentity; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.spi.predicate.TupleDomain; import io.trino.spi.security.RoleGrant; import io.trino.spi.statistics.ColumnStatisticType; @@ -224,13 +225,13 @@ public Set listTablePrivileges(String databaseName, String ta } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new UnsupportedOperationException(); } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new UnsupportedOperationException(); } diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/InMemoryThriftMetastore.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/InMemoryThriftMetastore.java index 4ad6f58b3eb3..579991dea773 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/InMemoryThriftMetastore.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/InMemoryThriftMetastore.java @@ -23,6 +23,7 @@ import io.trino.plugin.hive.authentication.HiveIdentity; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.PartitionWithStatistics; import io.trino.spi.TrinoException; import io.trino.spi.connector.SchemaNotFoundException; @@ -541,13 +542,13 @@ public Set listTablePrivileges(String databaseName, String ta } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new UnsupportedOperationException(); } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new UnsupportedOperationException(); } diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/MockThriftMetastoreClient.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/MockThriftMetastoreClient.java index 93a8023cf5d9..b9e165a56e92 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/MockThriftMetastoreClient.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/metastore/thrift/MockThriftMetastoreClient.java @@ -402,7 +402,7 @@ public boolean grantPrivileges(PrivilegeBag privilegeBag) } @Override - public boolean revokePrivileges(PrivilegeBag privilegeBag) + public boolean revokePrivileges(PrivilegeBag privilegeBag, boolean revokeGrantOption) { throw new UnsupportedOperationException(); } diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/CountingAccessFileHiveMetastore.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/CountingAccessFileHiveMetastore.java index 7802da958b0e..23fe74fedd22 100644 --- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/CountingAccessFileHiveMetastore.java +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/CountingAccessFileHiveMetastore.java @@ -24,6 +24,7 @@ import io.trino.plugin.hive.metastore.HiveMetastore; import io.trino.plugin.hive.metastore.HivePrincipal; import io.trino.plugin.hive.metastore.HivePrivilegeInfo; +import io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege; import io.trino.plugin.hive.metastore.Partition; import io.trino.plugin.hive.metastore.PartitionWithStatistics; import io.trino.plugin.hive.metastore.PrincipalPrivileges; @@ -281,13 +282,13 @@ public Set listRoleGrants(HivePrincipal principal) } @Override - public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void grantTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new UnsupportedOperationException(); } @Override - public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, Set privileges) + public void revokeTablePrivileges(String databaseName, String tableName, String tableOwner, HivePrincipal grantee, HivePrincipal grantor, Set privileges, boolean grantOption) { throw new UnsupportedOperationException(); } diff --git a/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestGrantRevoke.java b/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestGrantRevoke.java index bf3b4fd58859..7ec9025ce7b7 100644 --- a/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestGrantRevoke.java +++ b/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestGrantRevoke.java @@ -21,8 +21,6 @@ import io.trino.tempto.BeforeTestWithContext; import io.trino.tempto.ProductTest; import io.trino.tempto.query.QueryExecutor; -import io.trino.tempto.query.QueryResult; -import org.assertj.core.api.Condition; import org.testng.annotations.Test; import java.util.Set; @@ -54,6 +52,7 @@ public class TestGrantRevoke private String viewName; private QueryExecutor aliceExecutor; private QueryExecutor bobExecutor; + private QueryExecutor charlieExecutor; /* * Pre-requisites for the tests in this class: @@ -62,6 +61,7 @@ public class TestGrantRevoke * (2) tempto-configuration.yaml file should have definitions for the following connections to Presto server: * - "alice@presto" that has "jdbc_user: alice" * - "bob@presto" that has "jdbc_user: bob" + * - "charlie@presto" that has "jdbc_user: charlie" * (all other values of the connection are same as that of the default "presto" connection). */ @@ -72,6 +72,7 @@ public void setup() viewName = "alice_view"; aliceExecutor = connectToPresto("alice@presto"); bobExecutor = connectToPresto("bob@presto"); + charlieExecutor = connectToPresto("charlie@presto"); aliceExecutor.executeQuery(format("DROP TABLE IF EXISTS %s", tableName)); aliceExecutor.executeQuery(format("CREATE TABLE %s(month bigint, day bigint)", tableName)); @@ -113,7 +114,7 @@ private Set listRoles() public void testGrantRevoke() { // test GRANT - aliceExecutor.executeQuery(format("GRANT SELECT ON %s TO bob WITH GRANT OPTION", tableName)); + aliceExecutor.executeQuery(format("GRANT SELECT ON %s TO bob", tableName)); assertThat(bobExecutor.executeQuery(format("SELECT * FROM %s", tableName))).hasNoRows(); aliceExecutor.executeQuery(format("GRANT INSERT, SELECT ON %s TO bob", tableName)); assertThat(bobExecutor.executeQuery(format("INSERT INTO %s VALUES (3, 22)", tableName))).hasRowsCount(1); @@ -131,6 +132,43 @@ public void testGrantRevoke() .hasMessageContaining(format("Access Denied: Cannot select from table default.%s", tableName)); } + @Test(groups = {AUTHORIZATION, PROFILE_SPECIFIC_TESTS}) + public void testGrantOptionsOnGrantedPrivilege() + { + aliceExecutor.executeQuery(format("GRANT SELECT ON %s TO bob", tableName)); + assertQueryFailure(() -> aliceExecutor.executeQuery(format("GRANT SELECT ON %s TO bob WITH GRANT OPTION", tableName))) + // Updating a privilege with GRANT OPTION is not supported by Hive. https://issues.apache.org/jira/browse/HIVE-15689 + .hasMessageContaining("Granting SELECT WITH GRANT OPTION is not supported while USER bob possesses SELECT"); + } + + @Test(groups = {AUTHORIZATION, PROFILE_SPECIFIC_TESTS}) + public void testGrantRevokeWithGrantOption() + { + onTrino().executeQuery("CREATE ROLE role1 IN hive"); + onTrino().executeQuery("CREATE ROLE role2 IN hive"); + onTrino().executeQuery("GRANT role1 TO USER charlie IN hive"); + + // test GRANT WITH GRANT OPTION + aliceExecutor.executeQuery(format("GRANT SELECT ON %s TO bob WITH GRANT OPTION", tableName)); + assertQueryFailure(() -> charlieExecutor.executeQuery(format("SELECT * FROM %s", tableName))) + .hasMessageContaining(format("Access Denied: Cannot select from table default.%s", tableName)); + bobExecutor.executeQuery(format("GRANT SELECT ON %s TO ROLE role1", tableName)); + assertThat(charlieExecutor.executeQuery(format("SELECT * FROM %s", tableName))).hasNoRows(); + + // test REVOKE WITH GRANT OPTION + aliceExecutor.executeQuery(format("REVOKE GRANT OPTION FOR SELECT ON %s FROM bob", tableName)); + assertQueryFailure(() -> bobExecutor.executeQuery(format("GRANT SELECT ON %s TO ROLE role1 ", tableName))) + .hasMessageContaining(format("Access Denied: Cannot grant privilege SELECT on table default.%s", tableName)); + assertThat(bobExecutor.executeQuery(format("SELECT * FROM %s", tableName))).hasNoRows(); + // Since Hive doesn't support REVOKE with CASCADE, charlie would still have access to table + assertThat(charlieExecutor.executeQuery(format("SELECT * FROM %s", tableName))).hasNoRows(); + + // test GRANT WITH GRANT OPTION post revoke + assertQueryFailure(() -> aliceExecutor.executeQuery(format("GRANT SELECT ON %s TO bob WITH GRANT OPTION", tableName))) + // Updating a privilege with GRANT OPTION is not supported by Hive. https://issues.apache.org/jira/browse/HIVE-15689 + .hasMessageContaining("Granting SELECT WITH GRANT OPTION is not supported while USER bob possesses SELECT"); + } + @Test(groups = {AUTHORIZATION, PROFILE_SPECIFIC_TESTS}) public void testShowGrants() { @@ -247,14 +285,6 @@ public void testTablePrivilegesWithHiveOnlyViews() }); } - private Condition expectedRow(Row row) - { - return new Condition<>( - (QueryResult qr) -> qr.rows().contains(row.getValues()), - "expected row %s", - row); - } - private ImmutableList ownerGrants() { return ImmutableList.of(row("SELECT", Boolean.TRUE), row("INSERT", Boolean.TRUE), row("UPDATE", Boolean.TRUE), row("DELETE", Boolean.TRUE));