diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java index 24cc879..bb872bc 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java @@ -2208,7 +2208,7 @@ public class AccessController extends BaseMasterAndRegionObserver perm.getQualifier(), Action.ADMIN); break; case Namespace : - requireGlobalPermission("grant", Action.ADMIN, perm.getNamespace()); + requireNamespacePermission("grant", perm.getNamespace(), Action.ADMIN); break; } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java index 8ecc6e3..ab1dd85 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java @@ -126,6 +126,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; +import com.google.common.collect.ListMultimap; import com.google.protobuf.BlockingRpcChannel; import com.google.protobuf.RpcCallback; import com.google.protobuf.RpcController; @@ -174,11 +175,13 @@ public class TestAccessController extends SecureTestUtil { private static User USER_ADMIN_CF; private static final String GROUP_ADMIN = "group_admin"; + private static final String GROUP_NS_ADMIN = "group_ns_admin"; private static final String GROUP_CREATE = "group_create"; private static final String GROUP_READ = "group_read"; private static final String GROUP_WRITE = "group_write"; private static User USER_GROUP_ADMIN; + private static User USER_GROUP_NS_ADMIN; private static User USER_GROUP_CREATE; private static User USER_GROUP_READ; private static User USER_GROUP_WRITE; @@ -241,6 +244,8 @@ public class TestAccessController extends SecureTestUtil { USER_GROUP_ADMIN = User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN }); + USER_GROUP_NS_ADMIN = + User.createUserForTesting(conf, "user_group_ns_admin", new String[] { GROUP_NS_ADMIN }); USER_GROUP_CREATE = User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE }); USER_GROUP_READ = @@ -305,6 +310,8 @@ public class TestAccessController extends SecureTestUtil { grantGlobal(TEST_UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE); grantGlobal(TEST_UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ); grantGlobal(TEST_UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE); + grantOnNamespace(TEST_UTIL, toGroupEntry(GROUP_NS_ADMIN), TEST_TABLE.getNamespaceAsString(), + Permission.Action.ADMIN); assertEquals(5, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size()); try { @@ -323,12 +330,11 @@ public class TestAccessController extends SecureTestUtil { // Test deleted the table, no problem LOG.info("Test deleted table " + TEST_TABLE); } - // Verify all table/namespace permissions are erased + // Verify all table permissions are erased assertEquals(0, AccessControlLists.getTablePermissions(conf, TEST_TABLE).size()); - assertEquals( - 0, - AccessControlLists.getNamespacePermissions(conf, - TEST_TABLE.getNamespaceAsString()).size()); + // GROUP_NS_ADMIN has 2 entries for namespace + assertEquals(2, AccessControlLists.getNamespacePermissions(conf, + TEST_TABLE.getNamespaceAsString()).size()); } @Test (timeout=180000) @@ -1156,6 +1162,21 @@ public class TestAccessController extends SecureTestUtil { return null; } }; + AccessTestAction grantNamespaceAction = new AccessTestAction() { + @Override + public Object run() throws Exception { + try(Connection conn = ConnectionFactory.createConnection(conf); + Table acl = conn.getTable(AccessControlLists.ACL_TABLE_NAME)) { + BlockingRpcChannel service = acl.coprocessorService(TEST_TABLE.getName()); + AccessControlService.BlockingInterface protocol = + AccessControlService.newBlockingStub(service); + ProtobufUtil.grant(protocol, USER_GROUP_NS_ADMIN.getShortName(), + TEST_TABLE.getNamespaceAsString(), Action.READ); + } + return null; + } + }; + AccessTestAction revokeAction = new AccessTestAction() { @Override @@ -1203,6 +1224,10 @@ public class TestAccessController extends SecureTestUtil { verifyAllowed(grantAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); verifyDenied(grantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); + verifyAllowed(grantNamespaceAction, SUPERUSER, USER_ADMIN, USER_GROUP_ADMIN, + USER_GROUP_NS_ADMIN); + verifyDenied(grantAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, + USER_GROUP_WRITE, USER_GROUP_CREATE); try { verifyAllowed(revokeAction, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); verifyDenied(revokeAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ,