Repository: sentry Updated Branches: refs/heads/sentry-ha-redesign b15b95ed6 -> 3a02a6282
SENTRY-1209: Sentry does not block Hive's cross-schema table renames(Colin Ma, reviewed by Sravya Tirukkovalur) Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/3a02a628 Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/3a02a628 Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/3a02a628 Branch: refs/heads/sentry-ha-redesign Commit: 3a02a62825d52248764b6103a248223fd2fa848f Parents: b15b95e Author: Alexander Kolbasov <[email protected]> Authored: Fri Mar 10 23:52:17 2017 -0800 Committer: Alexander Kolbasov <[email protected]> Committed: Fri Mar 10 23:52:17 2017 -0800 ---------------------------------------------------------------------- .../binding/hive/HiveAuthzBindingHookBase.java | 10 ++- .../binding/hive/HiveAuthzBindingHook.java | 8 +- .../hive/authz/HiveAuthzPrivilegesMap.java | 4 +- .../TestDbPrivilegeCleanupOnDrop.java | 10 +-- .../tests/e2e/hive/TestOperationsPart1.java | 14 +-- .../tests/e2e/hive/TestOperationsPart2.java | 94 ++++++++++++++------ 6 files changed, 97 insertions(+), 43 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/3a02a628/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java index 0661054..c4daea1 100644 --- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java +++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java @@ -346,7 +346,15 @@ public abstract class HiveAuthzBindingHookBase extends AbstractSemanticAnalyzerH dbHierarchy.add(hiveAuthzBinding.getAuthServer()); dbHierarchy.add(currDB); inputHierarchy.add(dbHierarchy); - outputHierarchy.add(dbHierarchy); + + if (currOutDB != null) { + List<DBModelAuthorizable> outputDbHierarchy = new ArrayList<DBModelAuthorizable>(); + outputDbHierarchy.add(hiveAuthzBinding.getAuthServer()); + outputDbHierarchy.add(currOutDB); + outputHierarchy.add(outputDbHierarchy); + } else { + outputHierarchy.add(dbHierarchy); + } getInputHierarchyFromInputs(inputHierarchy, inputs); http://git-wip-us.apache.org/repos/asf/sentry/blob/3a02a628/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java index 095cd65..d269d5f 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHook.java @@ -261,9 +261,15 @@ public class HiveAuthzBindingHook extends HiveAuthzBindingHookBase { ASTNode serdeNode = (ASTNode)childASTNode.getChild(0); String serdeClassName = BaseSemanticAnalyzer.unescapeSQLString(serdeNode.getText()); setSerdeURI(serdeClassName); + currDB = getCanonicalDb(); + } + if ("TOK_ALTERTABLE_RENAME".equals(childASTNode.getText())) { + currDB = extractDatabase((ASTNode)ast.getChild(0)); + ASTNode newTableNode = (ASTNode)childASTNode.getChild(0); + currOutDB = extractDatabase(newTableNode); } } - + break; default: currDB = getCanonicalDb(); break; http://git-wip-us.apache.org/repos/asf/sentry/blob/3a02a628/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 6c9f223..9f3d42d 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 @@ -104,8 +104,8 @@ public class HiveAuthzPrivilegesMap { build(); HiveAuthzPrivileges alterTableRenamePrivilege = new HiveAuthzPrivileges.AuthzPrivilegeBuilder(). - addInputObjectPriviledge(AuthorizableType.Table, EnumSet.of(DBModelAction.ALTER)). - addInputObjectPriviledge(AuthorizableType.Db, EnumSet.of(DBModelAction.CREATE)). + addInputObjectPriviledge(AuthorizableType.Db, EnumSet.of(DBModelAction.DROP)). + addOutputObjectPriviledge(AuthorizableType.Db, EnumSet.of(DBModelAction.CREATE)). setOperationScope(HiveOperationScope.DATABASE). setOperationType(HiveOperationType.DDL). build(); http://git-wip-us.apache.org/repos/asf/sentry/blob/3a02a628/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java index 5ded20c..b9330cc 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java @@ -219,10 +219,11 @@ public class TestDbPrivilegeCleanupOnDrop extends statement.execute("GRANT INSERT ON TABLE t1 TO ROLE user_role"); statement.execute("GRANT ALTER ON TABLE t1 TO ROLE user_role"); statement.execute("GRANT DROP ON TABLE t1 TO ROLE user_role"); - // For rename, grant CREATE to DB1 + // For rename, grant DROP/CREATE to DB1 + statement.execute("GRANT DROP ON DATABASE " + DB1 + " TO ROLE user_role"); statement.execute("GRANT CREATE ON DATABASE " + DB1 + " TO ROLE user_role"); - // After rename table t1 to t2, user_role will have no permission to drop t1 + // After rename table t1 to t2 connection = context.createConnection(USER1_1); statement = context.createStatement(connection); statement.execute("USE " + DB1); @@ -230,7 +231,6 @@ public class TestDbPrivilegeCleanupOnDrop extends if (enableNotificationLog) { Thread.sleep(WAIT_FOR_NOTIFICATION_PROCESSING); } - context.assertSentrySemanticException(statement, "drop table t1", semanticException); // After rename table t1 to t2, user_role should have permission to drop t2 statement.execute("drop table t2"); @@ -238,8 +238,8 @@ public class TestDbPrivilegeCleanupOnDrop extends Thread.sleep(WAIT_FOR_NOTIFICATION_PROCESSING); } ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE user_role"); - // user_role will revoke all privilege from table t2, only remain CREATE on db_1 - assertRemainingRows(resultSet, 1); + // user_role will revoke all privilege from table t2, only remain DROP/CREATE on db_1 + assertRemainingRows(resultSet, 2); statement.close(); connection.close(); http://git-wip-us.apache.org/repos/asf/sentry/blob/3a02a628/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart1.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart1.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart1.java index a13aef5..3a4da50 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart1.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart1.java @@ -69,7 +69,8 @@ public class TestOperationsPart1 extends AbstractTestWithStaticConfiguration { privileges.put("drop_db1_tb1", "server=server1->db=" + DB1 + "->table=tb1->action=drop"); privileges.put("insert_db2_tb2", "server=server1->db=" + DB2 + "->table=tb2->action=insert"); privileges.put("select_db1_view1", "server=server1->db=" + DB1 + "->table=view1->action=select"); - privileges.put("alter_db1_view1", "server=server1->db=" + DB1 + "->table=view1->action=alter"); + privileges.put("create_db1_view1", "server=server1->db=" + DB1 + "->action=create"); + privileges.put("drop_db1_view1", "server=server1->db=" + DB1 + "->action=drop"); privileges.put("select_db1_tb2", "server=server1->db=" + DB1 + "->table=tb2->action=select"); } @@ -615,9 +616,10 @@ public class TestOperationsPart1 extends AbstractTestWithStaticConfiguration { statement.execute("CREATE VIEW view1 AS SELECT * FROM tb1"); policyFile - .addPermissionsToRole("alter_db1_view1", privileges.get("alter_db1_view1")) + .addPermissionsToRole("create_db1_view1", privileges.get("create_db1_view1")) + .addPermissionsToRole("drop_db1_view1", privileges.get("drop_db1_view1")) .addPermissionsToRole("create_db1", privileges.get("create_db1")) - .addRolesToGroup(USERGROUP1, "create_db1", "alter_db1_view1") + .addRolesToGroup(USERGROUP1, "create_db1", "create_db1_view1", "drop_db1_view1") .addPermissionsToRole("select_db1_view1", privileges.get("select_db1_view1")) .addPermissionsToRole("select_db1_tb1", privileges.get("select_db1_tb1")) .addRolesToGroup(USERGROUP2, "select_db1_tb1", "create_db1", "select_db1_view1"); @@ -656,9 +658,11 @@ public class TestOperationsPart1 extends AbstractTestWithStaticConfiguration { statement.execute("CREATE VIEW view1 AS SELECT * FROM tb1"); policyFile - .addPermissionsToRole("select_db1_tb2", privileges.get("select_db1_tb2")).addPermissionsToRole("alter_db1_view1", privileges.get("alter_db1_view1")) + .addPermissionsToRole("select_db1_tb2", privileges.get("select_db1_tb2")) + .addPermissionsToRole("create_db1_view1", privileges.get("create_db1_view1")) + .addPermissionsToRole("drop_db1_view1", privileges.get("drop_db1_view1")) .addPermissionsToRole("create_db1", privileges.get("create_db1")) - .addRolesToGroup(USERGROUP1, "select_db1_tb2", "alter_db1_view1", "create_db1") + .addRolesToGroup(USERGROUP1, "select_db1_tb2", "create_db1_view1", "drop_db1_view1", "create_db1") .addPermissionsToRole("select_db1_view1", privileges.get("select_db1_view1")) .addRolesToGroup(USERGROUP2, "create_db1", "select_db1_view1"); writePolicyFile(policyFile); http://git-wip-us.apache.org/repos/asf/sentry/blob/3a02a628/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart2.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart2.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart2.java index e18e7ab..d960b74 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart2.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestOperationsPart2.java @@ -29,6 +29,7 @@ import java.util.Map; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.sentry.provider.file.PolicyFile; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -232,41 +233,76 @@ public class TestOperationsPart2 extends AbstractTestWithStaticConfiguration { */ @Test public void renameTable() throws Exception { - adminCreate(DB1, tableName); - policyFile - .addPermissionsToRole("alter_db1_tb1", privileges.get("alter_db1_tb1")) - .addPermissionsToRole("create_db1", privileges.get("create_db1")) - .addRolesToGroup(USERGROUP1, "alter_db1_tb1", "create_db1") - .addRolesToGroup(USERGROUP2, "create_db1") - .addRolesToGroup(USERGROUP3, "alter_db1_tb1"); - - writePolicyFile(policyFile); - - Connection connection; - Statement statement; - - //Negative cases - connection = context.createConnection(USER2_1); - statement = context.createStatement(connection); - statement.execute("Use " + DB1); - assertSemanticException(statement, "ALTER TABLE tb1 RENAME TO tb2"); + adminCreate(DB1, "TAB_1"); + adminCreate(DB2, "TAB_3"); + adminCreate(DB3, null); + Connection connection = context.createConnection(ADMIN1); + Statement statement = context.createStatement(connection); + statement.execute("CREATE table " + DB1 + ".TAB_2 (a string)"); statement.close(); connection.close(); - connection = context.createConnection(USER3_1); - statement = context.createStatement(connection); - statement.execute("Use " + DB1); - assertSemanticException(statement, "ALTER TABLE tb1 RENAME TO tb2"); - statement.close(); - connection.close(); + policyFile + .addRolesToGroup(USERGROUP1, "all_db1") + .addRolesToGroup(USERGROUP1, "drop_db2") + .addRolesToGroup(USERGROUP1, "create_db3") + .addPermissionsToRole("all_db1", "server=server1->db=" + DB1) + .addPermissionsToRole("drop_db2", "server=server1->db=" + DB2 + "->action=drop") + .addPermissionsToRole("create_db3", "server=server1->db=" + DB3 + "->action=create") + .setUserGroupMapping(StaticUserGroup.getStaticMapping()); + writePolicyFile(policyFile); - //Positive case connection = context.createConnection(USER1_1); statement = context.createStatement(connection); - statement.execute("Use " + DB1); - statement.execute("ALTER TABLE tb1 RENAME TO tb2"); - statement.close(); - connection.close(); + // user1 haven't create permission with db_2, can't move table to db_2 + statement.execute("use " + DB1); + try { + statement.execute("alter table TAB_1 rename to " + DB2 + ".TAB_1"); + fail("the exception should be thrown"); + } catch (Exception e) { + // ignore the exception + } + try { + // test with the format of table name: db.table + statement.execute("alter table " + DB1 + ".TAB_1 rename to " + DB2 + ".TAB_1"); + fail("the exception should be thrown"); + } catch (Exception e) { + // ignore the exception + } + + // user1 haven't create permission with db_2, can't move table from db_2 + statement.execute("use " + DB2); + try { + statement.execute("alter table TAB_3 rename to " + DB2 + ".TAB_1"); + fail("the exception should be thrown"); + } catch (Exception e) { + // ignore the exception + } + try { + // test with the format of table name: db.table + statement.execute("alter table " + DB2 + ".TAB_3 rename to " + DB2 + ".TAB_1"); + fail("the exception should be thrown"); + } catch (Exception e) { + // ignore the exception + } + + // user1 have all permission with db_1 and create permission with db_3, alter_table_rename pass + statement.execute("use " + DB1); + statement.execute("alter table TAB_1 rename to " + DB3 + ".TAB_1"); + statement.execute("alter table " + DB1 + ".TAB_2 rename to " + DB3 + ".TAB_2"); + + // user1 have drop permission with db_2 and create permission with db_3, alter_table_rename pass + statement.execute("use " + DB2); + statement.execute("alter table TAB_3 rename to " + DB3 + ".TAB_3"); + + // user1 haven't drop permission with db_3, can't move table to db_3 + statement.execute("use " + DB3); + try { + statement.execute("alter table TAB_3 rename to TAB_4"); + fail("the exception should be thrown"); + } catch (Exception e) { + // ignore the exception + } } /* Test all operations which require alter on table (+ all on URI)
