HBASE-12634 Fix the AccessController#requireGlobalPermission(ns) with NS

Signed-off-by: Matteo Bertozzi <matteo.bertozzi@cloudera.com>
This commit is contained in:
Ashish Singhi 2014-12-04 15:57:01 +05:30 committed by Matteo Bertozzi
parent c45772e76a
commit 04444299ab
2 changed files with 48 additions and 15 deletions

View File

@ -497,7 +497,8 @@ public class AccessController extends BaseMasterAndRegionObserver
private void requireGlobalPermission(String request, Action perm, private void requireGlobalPermission(String request, Action perm,
String namespace) throws IOException { String namespace) throws IOException {
User user = getActiveUser(); User user = getActiveUser();
if (authManager.authorize(user, perm)) { if (authManager.authorize(user, perm)
|| (namespace != null && authManager.authorize(user, namespace, perm))) {
logResult(AuthResult.allow(request, "Global check allowed", user, perm, namespace)); logResult(AuthResult.allow(request, "Global check allowed", user, perm, namespace));
} else { } else {
logResult(AuthResult.deny(request, "Global check failed", user, perm, namespace)); logResult(AuthResult.deny(request, "Global check failed", user, perm, namespace));
@ -1145,7 +1146,7 @@ public class AccessController extends BaseMasterAndRegionObserver
@Override @Override
public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx,
NamespaceDescriptor ns) throws IOException { NamespaceDescriptor ns) throws IOException {
requireGlobalPermission("createNamespace", Action.ADMIN, ns.getName()); requirePermission("createNamespace", Action.ADMIN);
} }
@Override @Override

View File

@ -22,9 +22,6 @@ import static org.junit.Assert.assertTrue;
import java.util.List; import java.util.List;
import com.google.common.collect.ListMultimap;
import com.google.protobuf.BlockingRpcChannel;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HColumnDescriptor;
@ -50,15 +47,14 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import java.util.List; import com.google.common.collect.ListMultimap;
import com.google.protobuf.BlockingRpcChannel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@Category({SecurityTests.class, MediumTests.class}) @Category({SecurityTests.class, MediumTests.class})
public class TestNamespaceCommands extends SecureTestUtil { public class TestNamespaceCommands extends SecureTestUtil {
private static HBaseTestingUtility UTIL = new HBaseTestingUtility(); private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
private static String TestNamespace = "ns1"; private static String TestNamespace = "ns1";
private static String TestNamespace2 = "ns2";
private static Configuration conf; private static Configuration conf;
private static MasterCoprocessorEnvironment CP_ENV; private static MasterCoprocessorEnvironment CP_ENV;
private static AccessController ACCESS_CONTROLLER; private static AccessController ACCESS_CONTROLLER;
@ -71,6 +67,8 @@ public class TestNamespaceCommands extends SecureTestUtil {
private static User USER_CREATE; private static User USER_CREATE;
// user with permission on namespace for testing all operations. // user with permission on namespace for testing all operations.
private static User USER_NSP_WRITE; private static User USER_NSP_WRITE;
// user with admin permission on namespace.
private static User USER_NSP_ADMIN;
private static String TEST_TABLE = TestNamespace + ":testtable"; private static String TEST_TABLE = TestNamespace + ":testtable";
private static byte[] TEST_FAMILY = Bytes.toBytes("f1"); private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
@ -84,6 +82,7 @@ public class TestNamespaceCommands extends SecureTestUtil {
USER_RW = User.createUserForTesting(conf, "rw_user", new String[0]); USER_RW = User.createUserForTesting(conf, "rw_user", new String[0]);
USER_CREATE = User.createUserForTesting(conf, "create_user", new String[0]); USER_CREATE = User.createUserForTesting(conf, "create_user", new String[0]);
USER_NSP_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]); USER_NSP_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]);
USER_NSP_ADMIN = User.createUserForTesting(conf, "namespace_admin", new String[0]);
UTIL.startMiniCluster(); UTIL.startMiniCluster();
// Wait for the ACL table to become available // Wait for the ACL table to become available
@ -94,14 +93,19 @@ public class TestNamespaceCommands extends SecureTestUtil {
.findCoprocessor(AccessController.class.getName()); .findCoprocessor(AccessController.class.getName());
UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TestNamespace).build()); UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TestNamespace).build());
UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TestNamespace2).build());
grantOnNamespace(UTIL, USER_NSP_WRITE.getShortName(), grantOnNamespace(UTIL, USER_NSP_WRITE.getShortName(),
TestNamespace, Permission.Action.WRITE, Permission.Action.CREATE); TestNamespace, Permission.Action.WRITE, Permission.Action.CREATE);
grantOnNamespace(UTIL, USER_NSP_ADMIN.getShortName(), TestNamespace, Permission.Action.ADMIN);
grantOnNamespace(UTIL, USER_NSP_ADMIN.getShortName(), TestNamespace2, Permission.Action.ADMIN);
} }
@AfterClass @AfterClass
public static void afterClass() throws Exception { public static void afterClass() throws Exception {
UTIL.getHBaseAdmin().deleteNamespace(TestNamespace); UTIL.getHBaseAdmin().deleteNamespace(TestNamespace);
UTIL.getHBaseAdmin().deleteNamespace(TestNamespace2);
UTIL.shutdownMiniCluster(); UTIL.shutdownMiniCluster();
} }
@ -118,7 +122,7 @@ public class TestNamespaceCommands extends SecureTestUtil {
assertTrue(result != null); assertTrue(result != null);
ListMultimap<String, TablePermission> perms = ListMultimap<String, TablePermission> perms =
AccessControlLists.getNamespacePermissions(conf, TestNamespace); AccessControlLists.getNamespacePermissions(conf, TestNamespace);
assertEquals(2, perms.size()); assertEquals(3, perms.size());
List<TablePermission> namespacePerms = perms.get(userTestNamespace); List<TablePermission> namespacePerms = perms.get(userTestNamespace);
assertTrue(perms.containsKey(userTestNamespace)); assertTrue(perms.containsKey(userTestNamespace));
assertEquals(1, namespacePerms.size()); assertEquals(1, namespacePerms.size());
@ -134,7 +138,7 @@ public class TestNamespaceCommands extends SecureTestUtil {
Permission.Action.WRITE); Permission.Action.WRITE);
perms = AccessControlLists.getNamespacePermissions(conf, TestNamespace); perms = AccessControlLists.getNamespacePermissions(conf, TestNamespace);
assertEquals(1, perms.size()); assertEquals(2, perms.size());
} finally { } finally {
acl.close(); acl.close();
} }
@ -150,11 +154,39 @@ public class TestNamespaceCommands extends SecureTestUtil {
} }
}; };
// verify that superuser or hbase admin can modify namespaces. // verify that superuser or hbase admin can modify namespaces.
verifyAllowed(modifyNamespace, SUPERUSER); verifyAllowed(modifyNamespace, SUPERUSER, USER_NSP_ADMIN);
// all others should be denied // all others should be denied
verifyDenied(modifyNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW); verifyDenied(modifyNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW);
} }
@Test
public void testCreateAndDeleteNamespace() throws Exception {
AccessTestAction createNamespace = new AccessTestAction() {
public Object run() throws Exception {
ACCESS_CONTROLLER.preCreateNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
NamespaceDescriptor.create(TestNamespace2).build());
return null;
}
};
AccessTestAction deleteNamespace = new AccessTestAction() {
public Object run() throws Exception {
ACCESS_CONTROLLER.preDeleteNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
TestNamespace2);
return null;
}
};
// verify that only superuser can create namespaces.
verifyAllowed(createNamespace, SUPERUSER);
// verify that superuser or hbase admin can delete namespaces.
verifyAllowed(deleteNamespace, SUPERUSER, USER_NSP_ADMIN);
// all others should be denied
verifyDenied(createNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW, USER_NSP_ADMIN);
verifyDenied(deleteNamespace, USER_NSP_WRITE, USER_CREATE, USER_RW);
}
@Test @Test
public void testGrantRevoke() throws Exception{ public void testGrantRevoke() throws Exception{
final String testUser = "testUser"; final String testUser = "testUser";
@ -195,9 +227,9 @@ public class TestNamespaceCommands extends SecureTestUtil {
// Only HBase super user should be able to grant and revoke permissions to // Only HBase super user should be able to grant and revoke permissions to
// namespaces // namespaces
verifyAllowed(grantAction, SUPERUSER); verifyAllowed(grantAction, SUPERUSER, USER_NSP_ADMIN);
verifyDenied(grantAction, USER_CREATE, USER_RW); verifyDenied(grantAction, USER_CREATE, USER_RW);
verifyAllowed(revokeAction, SUPERUSER); verifyAllowed(revokeAction, SUPERUSER, USER_NSP_ADMIN);
verifyDenied(revokeAction, USER_CREATE, USER_RW); verifyDenied(revokeAction, USER_CREATE, USER_RW);
} }