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 849cc83e334..4edee373abc 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 @@ -842,8 +842,9 @@ public class AccessController extends BaseRegionObserver final CompareFilter.CompareOp compareOp, final WritableByteArrayComparable comparator, final Put put, final boolean result) throws IOException { - requirePermission(TablePermission.Action.READ, c.getEnvironment(), - Arrays.asList(new byte[][]{family})); + Collection familyMap = Arrays.asList(new byte[][]{family}); + requirePermission(TablePermission.Action.READ, c.getEnvironment(), familyMap); + requirePermission(TablePermission.Action.WRITE, c.getEnvironment(), familyMap); return result; } @@ -853,8 +854,9 @@ public class AccessController extends BaseRegionObserver final CompareFilter.CompareOp compareOp, final WritableByteArrayComparable comparator, final Delete delete, final boolean result) throws IOException { - requirePermission(TablePermission.Action.READ, c.getEnvironment(), - Arrays.asList( new byte[][] {family})); + Collection familyMap = Arrays.asList(new byte[][]{family}); + requirePermission(TablePermission.Action.READ, c.getEnvironment(), familyMap); + requirePermission(TablePermission.Action.WRITE, c.getEnvironment(), familyMap); return result; } 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 5d635119799..604fa7dc463 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 @@ -539,6 +539,18 @@ public class TestAccessController { verifyAllowed(USER_RO, action); } + private void verifyReadWrite(PrivilegedExceptionAction action) throws Exception { + // should be denied + verifyDenied(USER_NONE, action); + verifyDenied(USER_RO, action); + + // should be allowed + verifyAllowed(SUPERUSER, action); + verifyAllowed(USER_ADMIN, action); + verifyAllowed(USER_OWNER, action); + verifyAllowed(USER_RW, action); + } + @Test public void testRead() throws Exception { // get action @@ -615,6 +627,39 @@ public class TestAccessController { verifyWrite(incrementAction); } + @Test + public void testReadWrite() throws Exception { + // action for checkAndDelete + PrivilegedExceptionAction checkAndDeleteAction = new PrivilegedExceptionAction() { + public Object run() throws Exception { + Delete d = new Delete(Bytes.toBytes("random_row")); + d.deleteFamily(TEST_FAMILY); + + HTable t = new HTable(conf, TEST_TABLE); + t.checkAndDelete(Bytes.toBytes("random_row"), + TEST_FAMILY, Bytes.toBytes("q"), + Bytes.toBytes("test_value"), d); + return null; + } + }; + verifyReadWrite(checkAndDeleteAction); + + // action for checkAndPut() + PrivilegedExceptionAction checkAndPut = new PrivilegedExceptionAction() { + public Object run() throws Exception { + Put p = new Put(Bytes.toBytes("random_row")); + p.add(TEST_FAMILY, Bytes.toBytes("Qualifier"), Bytes.toBytes(1)); + + HTable t = new HTable(conf, TEST_TABLE); + t.checkAndPut(Bytes.toBytes("random_row"), + TEST_FAMILY, Bytes.toBytes("q"), + Bytes.toBytes("test_value"), p); + return null; + } + }; + verifyReadWrite(checkAndPut); + } + @Test public void testGrantRevoke() throws Exception { final byte[] tableName = Bytes.toBytes("TempTable");