diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/security/LegacyAccessControl.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/security/LegacyAccessControl.java index 91325de589c0..d618f68e6e43 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/security/LegacyAccessControl.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/security/LegacyAccessControl.java @@ -197,4 +197,34 @@ public void checkCanGrantTablePrivilege(ConnectorTransactionHandle transaction, public void checkCanRevokeTablePrivilege(ConnectorTransactionHandle transaction, ConnectorIdentity identity, Privilege privilege, SchemaTableName tableName, PrestoPrincipal revokee, boolean grantOptionFor) { } + + @Override + public void checkCanCreateRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role, Optional grantor) + { + } + + @Override + public void checkCanDropRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role) + { + } + + @Override + public void checkCanGrantRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, Set roles, Set grantees, boolean withAdminOption, Optional grantor, String catalogName) + { + } + + @Override + public void checkCanRevokeRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, Set roles, Set grantees, boolean adminOptionFor, Optional grantor, String catalogName) + { + } + + @Override + public void checkCanSetRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role, String catalogName) + { + } + + @Override + public void checkCanShowRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String catalogName) + { + } } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/security/PartitionsAwareAccessControl.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/security/PartitionsAwareAccessControl.java index b447e9215a6b..f5e3a4a5ebfe 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/security/PartitionsAwareAccessControl.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/security/PartitionsAwareAccessControl.java @@ -217,4 +217,10 @@ public void checkCanSetRole(ConnectorTransactionHandle transactionHandle, Connec { delegate.checkCanSetRole(transactionHandle, identity, role, catalogName); } + + @Override + public void checkCanShowRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String catalogName) + { + delegate.checkCanShowRoles(transactionHandle, identity, catalogName); + } } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/security/SqlStandardAccessControl.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/security/SqlStandardAccessControl.java index b80369529534..edf72b3a2e7e 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/security/SqlStandardAccessControl.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/security/SqlStandardAccessControl.java @@ -67,6 +67,7 @@ import static io.prestosql.spi.security.AccessDeniedException.denySelectTable; import static io.prestosql.spi.security.AccessDeniedException.denySetCatalogSessionProperty; import static io.prestosql.spi.security.AccessDeniedException.denySetRole; +import static io.prestosql.spi.security.AccessDeniedException.denyShowRoles; import static io.prestosql.spi.security.PrincipalType.ROLE; import static io.prestosql.spi.security.PrincipalType.USER; import static java.util.Objects.requireNonNull; @@ -339,6 +340,14 @@ private boolean hasAdminOptionForRoles(ConnectorTransactionHandle transaction, C return rolesWithGrantOption.containsAll(roles); } + @Override + public void checkCanShowRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String catalogName) + { + if (!isAdmin(transactionHandle, identity)) { + denyShowRoles(catalogName); + } + } + private boolean checkDatabasePermission(ConnectorTransactionHandle transaction, ConnectorIdentity identity, String schemaName, HivePrivilege... requiredPrivileges) { SemiTransactionalHiveMetastore metastore = metastoreProvider.apply(((HiveTransactionHandle) transaction)); diff --git a/presto-main/src/main/java/io/prestosql/connector/informationSchema/InformationSchemaPageSourceProvider.java b/presto-main/src/main/java/io/prestosql/connector/informationSchema/InformationSchemaPageSourceProvider.java index 79a578c3855c..56b9633d0eb0 100644 --- a/presto-main/src/main/java/io/prestosql/connector/informationSchema/InformationSchemaPageSourceProvider.java +++ b/presto-main/src/main/java/io/prestosql/connector/informationSchema/InformationSchemaPageSourceProvider.java @@ -33,6 +33,7 @@ import io.prestosql.spi.connector.ConnectorTransactionHandle; import io.prestosql.spi.connector.FixedPageSource; import io.prestosql.spi.connector.SchemaTableName; +import io.prestosql.spi.security.AccessDeniedException; import io.prestosql.spi.security.GrantInfo; import io.prestosql.spi.security.PrestoPrincipal; import io.prestosql.spi.security.PrivilegeInfo; @@ -238,6 +239,14 @@ private InternalTable buildSchemata(Session session, String catalogName) private InternalTable buildRoles(Session session, String catalog) { InternalTable.Builder table = InternalTable.builder(informationSchemaTableColumns(TABLE_ROLES)); + + try { + accessControl.checkCanShowRoles(session.getRequiredTransactionId(), session.getIdentity(), catalog); + } + catch (AccessDeniedException exception) { + return table.build(); + } + for (String role : metadata.listRoles(session, catalog)) { table.add(role); } diff --git a/presto-main/src/main/java/io/prestosql/security/AccessControl.java b/presto-main/src/main/java/io/prestosql/security/AccessControl.java index 6da0535501ea..94af7917edcc 100644 --- a/presto-main/src/main/java/io/prestosql/security/AccessControl.java +++ b/presto-main/src/main/java/io/prestosql/security/AccessControl.java @@ -243,4 +243,10 @@ public interface AccessControl * @throws java.security.AccessControlException if not allowed */ void checkCanSetRole(TransactionId requiredTransactionId, Identity identity, String role, String catalog); + + /** + * Check if identity is allowed to show roles on the specified catalog. + * @throws io.prestosql.spi.security.AccessDeniedException if not allowed + */ + void checkCanShowRoles(TransactionId transactionId, Identity identity, String catalogName); } diff --git a/presto-main/src/main/java/io/prestosql/security/AccessControlManager.java b/presto-main/src/main/java/io/prestosql/security/AccessControlManager.java index 1682dbc024ec..1e040b482356 100644 --- a/presto-main/src/main/java/io/prestosql/security/AccessControlManager.java +++ b/presto-main/src/main/java/io/prestosql/security/AccessControlManager.java @@ -611,6 +611,18 @@ public void checkCanSetRole(TransactionId transactionId, Identity identity, Stri } } + @Override + public void checkCanShowRoles(TransactionId transactionId, Identity identity, String catalogName) + { + requireNonNull(identity, "identity is null"); + requireNonNull(catalogName, "catalogName is null"); + + CatalogAccessControlEntry entry = getConnectorAccessControl(transactionId, catalogName); + if (entry != null) { + authenticationCheck(() -> entry.getAccessControl().checkCanShowRoles(entry.getTransactionHandle(transactionId), identity.toConnectorIdentity(catalogName), catalogName)); + } + } + private CatalogAccessControlEntry getConnectorAccessControl(TransactionId transactionId, String catalogName) { return transactionManager.getOptionalCatalogMetadata(transactionId, catalogName) diff --git a/presto-main/src/main/java/io/prestosql/security/AllowAllAccessControl.java b/presto-main/src/main/java/io/prestosql/security/AllowAllAccessControl.java index 60055eca110d..e8edafcaf5e0 100644 --- a/presto-main/src/main/java/io/prestosql/security/AllowAllAccessControl.java +++ b/presto-main/src/main/java/io/prestosql/security/AllowAllAccessControl.java @@ -185,4 +185,9 @@ public void checkCanRevokeRoles(TransactionId transactionId, Identity identity, public void checkCanSetRole(TransactionId requiredTransactionId, Identity identity, String role, String catalog) { } + + @Override + public void checkCanShowRoles(TransactionId transactionId, Identity identity, String catalogName) + { + } } diff --git a/presto-main/src/main/java/io/prestosql/security/AllowAllSystemAccessControl.java b/presto-main/src/main/java/io/prestosql/security/AllowAllSystemAccessControl.java index 677a42b55a12..8ba0f876e12e 100644 --- a/presto-main/src/main/java/io/prestosql/security/AllowAllSystemAccessControl.java +++ b/presto-main/src/main/java/io/prestosql/security/AllowAllSystemAccessControl.java @@ -187,4 +187,9 @@ public void checkCanGrantTablePrivilege(Identity identity, Privilege privilege, public void checkCanRevokeTablePrivilege(Identity identity, Privilege privilege, CatalogSchemaTableName table, PrestoPrincipal revokee, boolean grantOptionFor) { } + + @Override + public void checkCanShowRoles(Identity identity, String catalogName) + { + } } diff --git a/presto-main/src/main/java/io/prestosql/security/DenyAllAccessControl.java b/presto-main/src/main/java/io/prestosql/security/DenyAllAccessControl.java index 1627279cb386..a2bff81c04bf 100644 --- a/presto-main/src/main/java/io/prestosql/security/DenyAllAccessControl.java +++ b/presto-main/src/main/java/io/prestosql/security/DenyAllAccessControl.java @@ -52,6 +52,7 @@ import static io.prestosql.spi.security.AccessDeniedException.denySetRole; import static io.prestosql.spi.security.AccessDeniedException.denySetSystemSessionProperty; import static io.prestosql.spi.security.AccessDeniedException.denySetUser; +import static io.prestosql.spi.security.AccessDeniedException.denyShowRoles; import static io.prestosql.spi.security.AccessDeniedException.denyShowSchemas; import static io.prestosql.spi.security.AccessDeniedException.denyShowTablesMetadata; @@ -243,4 +244,10 @@ public void checkCanSetRole(TransactionId requiredTransactionId, Identity identi { denySetRole(role); } + + @Override + public void checkCanShowRoles(TransactionId transactionId, Identity identity, String catalogName) + { + denyShowRoles(catalogName); + } } diff --git a/presto-main/src/main/java/io/prestosql/security/FileBasedSystemAccessControl.java b/presto-main/src/main/java/io/prestosql/security/FileBasedSystemAccessControl.java index e97044da4ffd..67f1af1cc348 100644 --- a/presto-main/src/main/java/io/prestosql/security/FileBasedSystemAccessControl.java +++ b/presto-main/src/main/java/io/prestosql/security/FileBasedSystemAccessControl.java @@ -312,4 +312,9 @@ public void checkCanGrantTablePrivilege(Identity identity, Privilege privilege, public void checkCanRevokeTablePrivilege(Identity identity, Privilege privilege, CatalogSchemaTableName table, PrestoPrincipal revokee, boolean grantOptionFor) { } + + @Override + public void checkCanShowRoles(Identity identity, String catalogName) + { + } } diff --git a/presto-main/src/main/java/io/prestosql/security/ReadOnlySystemAccessControl.java b/presto-main/src/main/java/io/prestosql/security/ReadOnlySystemAccessControl.java index 50b06b18392d..8611b17f9b16 100644 --- a/presto-main/src/main/java/io/prestosql/security/ReadOnlySystemAccessControl.java +++ b/presto-main/src/main/java/io/prestosql/security/ReadOnlySystemAccessControl.java @@ -110,4 +110,9 @@ public void checkCanShowSchemas(Identity identity, String catalogName) public void checkCanShowTablesMetadata(Identity identity, CatalogSchemaName schema) { } + + @Override + public void checkCanShowRoles(Identity identity, String catalogName) + { + } } diff --git a/presto-main/src/main/java/io/prestosql/sql/rewrite/ShowQueriesRewrite.java b/presto-main/src/main/java/io/prestosql/sql/rewrite/ShowQueriesRewrite.java index a84fa2964f66..1687c42a8efc 100644 --- a/presto-main/src/main/java/io/prestosql/sql/rewrite/ShowQueriesRewrite.java +++ b/presto-main/src/main/java/io/prestosql/sql/rewrite/ShowQueriesRewrite.java @@ -265,6 +265,7 @@ protected Node visitShowRoles(ShowRoles node, Void context) } String catalog = node.getCatalog().map(c -> c.getValue().toLowerCase(ENGLISH)).orElseGet(() -> session.getCatalog().get()); + accessControl.checkCanShowRoles(session.getRequiredTransactionId(), session.getIdentity(), catalog); return simpleQuery( selectList(aliasedName("role_name", "Role")), from(catalog, TABLE_ROLES)); diff --git a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/AllowAllAccessControl.java b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/AllowAllAccessControl.java index 6c5b16c0e095..12a886e5e725 100644 --- a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/AllowAllAccessControl.java +++ b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/AllowAllAccessControl.java @@ -20,6 +20,7 @@ import io.prestosql.spi.security.PrestoPrincipal; import io.prestosql.spi.security.Privilege; +import java.util.Optional; import java.util.Set; public class AllowAllAccessControl @@ -136,4 +137,34 @@ public void checkCanGrantTablePrivilege(ConnectorTransactionHandle transaction, public void checkCanRevokeTablePrivilege(ConnectorTransactionHandle transaction, ConnectorIdentity identity, Privilege privilege, SchemaTableName tableName, PrestoPrincipal revokee, boolean grantOptionFor) { } + + @Override + public void checkCanCreateRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role, Optional grantor) + { + } + + @Override + public void checkCanDropRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role) + { + } + + @Override + public void checkCanGrantRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, Set roles, Set grantees, boolean withAdminOption, Optional grantor, String catalogName) + { + } + + @Override + public void checkCanRevokeRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, Set roles, Set grantees, boolean adminOptionFor, Optional grantor, String catalogName) + { + } + + @Override + public void checkCanSetRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role, String catalogName) + { + } + + @Override + public void checkCanShowRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String catalogName) + { + } } diff --git a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/FileBasedAccessControl.java b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/FileBasedAccessControl.java index 952883c7f871..071c4d2b6c67 100644 --- a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/FileBasedAccessControl.java +++ b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/FileBasedAccessControl.java @@ -238,6 +238,36 @@ public void checkCanRevokeTablePrivilege(ConnectorTransactionHandle transaction, } } + @Override + public void checkCanCreateRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role, Optional grantor) + { + } + + @Override + public void checkCanDropRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role) + { + } + + @Override + public void checkCanGrantRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, Set roles, Set grantees, boolean withAdminOption, Optional grantor, String catalogName) + { + } + + @Override + public void checkCanRevokeRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, Set roles, Set grantees, boolean adminOptionFor, Optional grantor, String catalogName) + { + } + + @Override + public void checkCanSetRole(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String role, String catalogName) + { + } + + @Override + public void checkCanShowRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String catalogName) + { + } + private boolean canSetSessionProperty(ConnectorIdentity identity, String property) { for (SessionPropertyAccessControlRule rule : sessionPropertyRules) { diff --git a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ForwardingSystemAccessControl.java b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ForwardingSystemAccessControl.java index 4ee0c0c6c52b..11fbf890f5d6 100644 --- a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ForwardingSystemAccessControl.java +++ b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ForwardingSystemAccessControl.java @@ -201,4 +201,10 @@ public void checkCanRevokeTablePrivilege(Identity identity, Privilege privilege, { delegate().checkCanRevokeTablePrivilege(identity, privilege, table, revokee, grantOptionFor); } + + @Override + public void checkCanShowRoles(Identity identity, String catalogName) + { + delegate().checkCanShowRoles(identity, catalogName); + } } diff --git a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ReadOnlyAccessControl.java b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ReadOnlyAccessControl.java index ec7586d2ba45..eeff707db24e 100644 --- a/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ReadOnlyAccessControl.java +++ b/presto-plugin-toolkit/src/main/java/io/prestosql/plugin/base/security/ReadOnlyAccessControl.java @@ -149,4 +149,10 @@ public void checkCanRevokeTablePrivilege(ConnectorTransactionHandle transaction, { denyRevokeTablePrivilege(privilege.name(), tableName.toString()); } + + @Override + public void checkCanShowRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String catalogName) + { + // allow + } } diff --git a/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorAccessControl.java b/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorAccessControl.java index b23e2d61e9f8..168aadb83fc3 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorAccessControl.java +++ b/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorAccessControl.java @@ -43,6 +43,7 @@ import static io.prestosql.spi.security.AccessDeniedException.denySelectColumns; import static io.prestosql.spi.security.AccessDeniedException.denySetCatalogSessionProperty; import static io.prestosql.spi.security.AccessDeniedException.denySetRole; +import static io.prestosql.spi.security.AccessDeniedException.denyShowRoles; import static io.prestosql.spi.security.AccessDeniedException.denyShowSchemas; import static io.prestosql.spi.security.AccessDeniedException.denyShowTablesMetadata; import static java.util.Collections.emptySet; @@ -297,4 +298,14 @@ default void checkCanSetRole(ConnectorTransactionHandle transactionHandle, Conne { denySetRole(role); } + + /** + * Check if identity is allowed to show roles on the specified catalog. + * + * @throws io.prestosql.spi.security.AccessDeniedException if not allowed + */ + default void checkCanShowRoles(ConnectorTransactionHandle transactionHandle, ConnectorIdentity identity, String catalogName) + { + denyShowRoles(catalogName); + } } diff --git a/presto-spi/src/main/java/io/prestosql/spi/security/AccessDeniedException.java b/presto-spi/src/main/java/io/prestosql/spi/security/AccessDeniedException.java index 0c8c49f6f152..b036e1411ea3 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/security/AccessDeniedException.java +++ b/presto-spi/src/main/java/io/prestosql/spi/security/AccessDeniedException.java @@ -256,6 +256,11 @@ public static void denyRevokeTablePrivilege(String privilege, String tableName, throw new AccessDeniedException(format("Cannot revoke privilege %s on table %s%s", privilege, tableName, formatExtraInfo(extraInfo))); } + public static void denyShowRoles(String catalogName) + { + throw new AccessDeniedException(format("Cannot show roles from catalog %s", catalogName)); + } + public static void denySetSystemSessionProperty(String propertyName) { denySetSystemSessionProperty(propertyName, null); diff --git a/presto-spi/src/main/java/io/prestosql/spi/security/SystemAccessControl.java b/presto-spi/src/main/java/io/prestosql/spi/security/SystemAccessControl.java index 10d23a24f2ed..a41ce3ba8115 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/security/SystemAccessControl.java +++ b/presto-spi/src/main/java/io/prestosql/spi/security/SystemAccessControl.java @@ -41,6 +41,7 @@ import static io.prestosql.spi.security.AccessDeniedException.denyRevokeTablePrivilege; import static io.prestosql.spi.security.AccessDeniedException.denySelectColumns; import static io.prestosql.spi.security.AccessDeniedException.denySetCatalogSessionProperty; +import static io.prestosql.spi.security.AccessDeniedException.denyShowRoles; import static io.prestosql.spi.security.AccessDeniedException.denyShowSchemas; import static io.prestosql.spi.security.AccessDeniedException.denyShowTablesMetadata; @@ -301,4 +302,14 @@ default void checkCanRevokeTablePrivilege(Identity identity, Privilege privilege { denyRevokeTablePrivilege(privilege.toString(), table.toString()); } + + /** + * Check if identity is allowed to show roles on the specified catalog. + * + * @throws AccessDeniedException if not allowed + */ + default void checkCanShowRoles(Identity identity, String catalogName) + { + denyShowRoles(catalogName); + } }