Repository: sentry Updated Branches: refs/heads/master 3d062f39c -> c6d139762
SENTRY-2352: User roles with ALTER on a table can not show or describe the table on which they have ALTER (Sergio Pena, reviewed by Na Li) Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/c6d13976 Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/c6d13976 Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/c6d13976 Branch: refs/heads/master Commit: c6d139762e941fa896c0395eb06e36749c9cd67d Parents: 3d062f3 Author: Sergio Pena <[email protected]> Authored: Tue Aug 14 15:30:12 2018 -0500 Committer: Sergio Pena <[email protected]> Committed: Tue Aug 14 15:30:12 2018 -0500 ---------------------------------------------------------------------- .../hive/authz/DefaultSentryValidator.java | 3 +- .../hive/authz/HiveAuthzBindingHookBase.java | 2 +- .../hive/authz/HiveAuthzPrivilegesMap.java | 6 +- .../hive/TestDescribeMetadataPrivileges.java | 148 ++++++++++++++++++ .../e2e/hive/TestShowMetadataPrivileges.java | 154 +++++++++++++++++++ 5 files changed, 309 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/c6d13976/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryValidator.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryValidator.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryValidator.java index 1ab5be3..f076476 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryValidator.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryValidator.java @@ -400,7 +400,8 @@ public class DefaultSentryValidator extends SentryHiveAuthorizationValidator { HiveAuthzPrivileges tableMetaDataPrivilege = new HiveAuthzPrivileges.AuthzPrivilegeBuilder() .addInputObjectPriviledge(AuthorizableType.Column, - EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT)) + EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT, DBModelAction.ALTER, + DBModelAction.DROP, DBModelAction.INDEX, DBModelAction.LOCK)) .setOperationScope(HiveOperationScope.TABLE) .setOperationType( HiveAuthzPrivileges.HiveOperationType.INFO) http://git-wip-us.apache.org/repos/asf/sentry/blob/c6d13976/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBindingHookBase.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBindingHookBase.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBindingHookBase.java index 447deaf..0973e98 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBindingHookBase.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBindingHookBase.java @@ -101,7 +101,7 @@ public abstract class HiveAuthzBindingHookBase extends AbstractSemanticAnalyzerH protected final static HiveAuthzPrivileges columnMetaDataPrivilege = new HiveAuthzPrivileges.AuthzPrivilegeBuilder() .addInputObjectPriviledge(AuthorizableType.Column, - EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT)) + EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT, DBModelAction.ALTER)) .setOperationScope(HiveOperationScope.COLUMN).setOperationType(HiveOperationType.INFO) .build(); http://git-wip-us.apache.org/repos/asf/sentry/blob/c6d13976/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzPrivilegesMap.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzPrivilegesMap.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzPrivilegesMap.java index 78742fd..feb77ad 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzPrivilegesMap.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzPrivilegesMap.java @@ -173,14 +173,16 @@ public class HiveAuthzPrivilegesMap { build(); HiveAuthzPrivileges tableMetaDataPrivilege = new HiveAuthzPrivileges.AuthzPrivilegeBuilder(). - addInputObjectPriviledge(AuthorizableType.Table, EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT)). + addInputObjectPriviledge(AuthorizableType.Table, EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT, + DBModelAction.ALTER)). setOperationScope(HiveOperationScope.TABLE). setOperationType(HiveOperationType.INFO). build(); // Metadata statements which only require column-level privileges. HiveAuthzPrivileges columnMetaDataPrivilege = new HiveAuthzPrivileges.AuthzPrivilegeBuilder(). - addInputObjectPriviledge(AuthorizableType.Column, EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT)). + addInputObjectPriviledge(AuthorizableType.Column, EnumSet.of(DBModelAction.SELECT, DBModelAction.INSERT, + DBModelAction.ALTER)). setOperationScope(HiveOperationScope.COLUMN). setOperationType(HiveOperationType.INFO). build(); http://git-wip-us.apache.org/repos/asf/sentry/blob/c6d13976/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestDescribeMetadataPrivileges.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestDescribeMetadataPrivileges.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestDescribeMetadataPrivileges.java new file mode 100644 index 0000000..54f4f2f --- /dev/null +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestDescribeMetadataPrivileges.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sentry.tests.e2e.hive; + +import static org.junit.Assert.fail; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Arrays; +import java.util.Collection; +import org.apache.sentry.core.model.db.DBModelAction; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class TestDescribeMetadataPrivileges extends AbstractTestWithStaticConfiguration { + private static final boolean ALLOWED = true; + private static final boolean NOT_ALLOWED = false; + private static final String SERVER1 = "server1"; + + private static Connection adminCon, user1Con; + private static Statement adminStmt, user1Stmt; + + private DBModelAction action; + private boolean allowed; + + @Parameterized.Parameters + public static Collection describePrivileges() { + return Arrays.asList(new Object[][] { + { null, NOT_ALLOWED }, // Means no privileges + { DBModelAction.ALL, ALLOWED }, + { DBModelAction.CREATE, NOT_ALLOWED }, + { DBModelAction.SELECT, ALLOWED }, + { DBModelAction.INSERT, ALLOWED }, + { DBModelAction.ALTER, ALLOWED }, + { DBModelAction.DROP, NOT_ALLOWED }, + { DBModelAction.INDEX, NOT_ALLOWED }, + { DBModelAction.LOCK, NOT_ALLOWED }, + }); + } + + @BeforeClass + public static void setupTestStaticConfiguration() throws Exception{ + useSentryService = true; + AbstractTestWithStaticConfiguration.setupTestStaticConfiguration(); + setupAdmin(); + + adminCon = context.createConnection(ADMIN1); + adminStmt = context.createStatement(adminCon); + user1Con = context.createConnection(USER1_1); + user1Stmt = context.createStatement(user1Con); + } + + @AfterClass + public static void destroy() throws SQLException { + adminStmt.close(); + adminCon.close(); + user1Stmt.close(); + user1Con.close(); + } + + public TestDescribeMetadataPrivileges(DBModelAction action, boolean allowed) { + this.action = action; + this.allowed = allowed; + } + + @Before + public void setup() throws Exception { + adminStmt.execute("DROP DATABASE IF EXISTS " + DB1 + " CASCADE"); + adminStmt.execute("CREATE DATABASE " + DB1); + adminStmt.execute("CREATE TABLE " + DB1 + "." + TBL1 + " (id int)"); + adminStmt.execute("CREATE ROLE role1"); + adminStmt.execute("GRANT ROLE role1 TO group " + USERGROUP1); + } + + @Test + public void testDescribeTableWithGrantOnTable() throws Exception { + if (action != null) { + adminStmt.execute("GRANT " + action + " ON TABLE " + DB1 + "." + TBL1 + " TO ROLE role1"); + } + + try { + user1Stmt.execute("DESCRIBE " + DB1 + "." + TBL1); + if (!allowed) { + fail("DESCRIBE should NOT be allowed with " + action + " privileges on the table."); + } + } catch (Exception e) { + if (allowed) { + fail("DESCRIBE should be allowed with " + action + " privileges on the table."); + } + } + } + + @Test + public void testDescribeTableWithGrantOnDatabase() throws Exception { + if (action != null) { + adminStmt.execute("GRANT " + action + " ON DATABASE " + DB1 + " TO ROLE role1"); + } + + try { + user1Stmt.execute("DESCRIBE " + DB1 + "." + TBL1); + if (!allowed) { + fail("DESCRIBE should NOT be allowed with " + action + " privileges on the database."); + } + } catch (Exception e) { + if (allowed) { + fail("DESCRIBE should be allowed with " + action + " privileges on the database."); + } + } + } + + @Test + public void testDescribeTableWithGrantOnServer() throws Exception { + if (action != null) { + adminStmt.execute("GRANT " + action + " ON SERVER " + SERVER1 + " TO ROLE role1"); + } + + try { + user1Stmt.execute("DESCRIBE " + DB1 + "." + TBL1); + if (!allowed) { + fail("DESCRIBE should NOT be allowed with " + action + " privileges on the server."); + } + } catch (Exception e) { + if (allowed) { + fail("DESCRIBE should be allowed with " + action + " privileges on the server."); + } + } + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/c6d13976/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java new file mode 100644 index 0000000..88e697b --- /dev/null +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestShowMetadataPrivileges.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sentry.tests.e2e.hive; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Arrays; +import java.util.Collection; +import org.apache.sentry.core.model.db.DBModelAction; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class TestShowMetadataPrivileges extends AbstractTestWithStaticConfiguration { + private static final boolean ALLOWED = true; + private static final boolean NOT_ALLOWED = false; + private static final String SERVER1 = "server1"; + + private static Connection adminCon, user1Con; + private static Statement adminStmt, user1Stmt; + + private DBModelAction action; + private boolean allowed; + + @Parameterized.Parameters + public static Collection describePrivileges() { + return Arrays.asList(new Object[][] { + { null, NOT_ALLOWED }, // Means no privileges + { DBModelAction.ALL, ALLOWED }, + { DBModelAction.CREATE, NOT_ALLOWED }, + { DBModelAction.SELECT, ALLOWED }, + { DBModelAction.INSERT, ALLOWED }, + { DBModelAction.ALTER, ALLOWED }, + { DBModelAction.DROP, ALLOWED }, + { DBModelAction.INDEX, ALLOWED }, + { DBModelAction.LOCK, ALLOWED }, + }); + } + + @BeforeClass + public static void setupTestStaticConfiguration() throws Exception{ + useSentryService = true; + AbstractTestWithStaticConfiguration.setupTestStaticConfiguration(); + setupAdmin(); + + adminCon = context.createConnection(ADMIN1); + adminStmt = context.createStatement(adminCon); + user1Con = context.createConnection(USER1_1); + user1Stmt = context.createStatement(user1Con); + } + + @AfterClass + public static void destroy() throws SQLException { + adminStmt.close(); + adminCon.close(); + user1Stmt.close(); + user1Con.close(); + } + + public TestShowMetadataPrivileges(DBModelAction action, boolean allowed) { + this.action = action; + this.allowed = allowed; + } + + @Before + public void setup() throws Exception { + adminStmt.execute("DROP DATABASE IF EXISTS " + DB1 + " CASCADE"); + adminStmt.execute("CREATE DATABASE " + DB1); + adminStmt.execute("CREATE TABLE " + DB1 + "." + TBL1 + " (id int)"); + adminStmt.execute("CREATE ROLE role1"); + adminStmt.execute("GRANT ROLE role1 TO group " + USERGROUP1); + } + + @Test + public void testShowTablesWithGrantOnTable() throws Exception { + if (action != null) { + if (action == DBModelAction.CREATE) { + // CREATE is not supported at the table level + return; + } + + adminStmt.execute("GRANT " + action + " ON TABLE " + DB1 + "." + TBL1 + " TO ROLE role1"); + } + + user1Stmt.execute("SHOW TABLES IN " + DB1); + if (!allowed) { + assertFalse( + "SHOW TABLES should NOT display tables with " + action + " privileges on the table.", + user1Stmt.getResultSet().next()); + } else { + assertTrue( + "SHOW TABLES should display tables with " + action + " privileges on the table.", + user1Stmt.getResultSet().next()); + } + } + + @Test + public void testShowTablesWithGrantOnDatabase() throws Exception { + if (action != null) { + adminStmt.execute("GRANT " + action + " ON DATABASE " + DB1 + " TO ROLE role1"); + } + + user1Stmt.execute("SHOW TABLES IN " + DB1); + if (!allowed) { + assertFalse( + "SHOW TABLES should NOT display tables with " + action + " privileges on the database.", + user1Stmt.getResultSet().next()); + } else { + assertTrue( + "SHOW TABLES should display tables with " + action + " privileges on the database.", + user1Stmt.getResultSet().next()); + } + } + + @Test + public void testShowTablesWithGrantOnServer() throws Exception { + if (action != null) { + adminStmt.execute("GRANT " + action + " ON SERVER " + SERVER1 + " TO ROLE role1"); + } + + user1Stmt.execute("SHOW TABLES IN " + DB1); + if (!allowed) { + assertFalse( + "SHOW TABLES should NOT display tables with " + action + " privileges on the server.", + user1Stmt.getResultSet().next()); + } else { + assertTrue( + "SHOW TABLES should display tables with " + action + " privileges on the server.", + user1Stmt.getResultSet().next()); + } + } +}
