@Test public void testCheckPermissions() throws Exception { final HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME); final AccessControllerProtocol protocol = acl.coprocessorProxy(AccessControllerProtocol.class, TEST_TABLE); PrivilegedExceptionAction<Void> globalAdmin = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkGlobalPerms(Permission.Action.ADMIN); return null; } }; verifyGlobal(globalAdmin); PrivilegedExceptionAction<Void> globalReadWrite = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkGlobalPerms(Permission.Action.READ, Permission.Action.WRITE); return null; } }; verifyGlobal(globalReadWrite); final byte[] TEST_Q1 = Bytes.toBytes("q1"); final byte[] TEST_Q2 = Bytes.toBytes("q2"); User userTable = User.createUserForTesting(conf, "user_check_perms_table", new String[0]); User userColumn = User.createUserForTesting(conf, "user_check_perms_family", new String[0]); User userQualifier = User.createUserForTesting(conf, "user_check_perms_q", new String[0]); grant(protocol, userTable, TEST_TABLE, null, null, Permission.Action.READ); grant(protocol, userColumn, TEST_TABLE, TEST_FAMILY, null, Permission.Action.READ); grant(protocol, userQualifier, TEST_TABLE, TEST_FAMILY, TEST_Q1, Permission.Action.READ); PrivilegedExceptionAction<Void> tableRead = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkTablePerms(TEST_TABLE, null, null, Permission.Action.READ); return null; } }; PrivilegedExceptionAction<Void> columnRead = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkTablePerms(TEST_TABLE, TEST_FAMILY, null, Permission.Action.READ); return null; } }; PrivilegedExceptionAction<Void> qualifierRead = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkTablePerms(TEST_TABLE, TEST_FAMILY, TEST_Q1, Permission.Action.READ); return null; } }; PrivilegedExceptionAction<Void> multiQualifierRead = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkTablePerms(TEST_TABLE, new Permission[] { new TablePermission(TEST_TABLE, TEST_FAMILY, TEST_Q1, Permission.Action.READ), new TablePermission(TEST_TABLE, TEST_FAMILY, TEST_Q2, Permission.Action.READ), }); return null; } }; PrivilegedExceptionAction<Void> globalAndTableRead = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkTablePerms(TEST_TABLE, new Permission[] { new Permission(Permission.Action.READ), new TablePermission(TEST_TABLE, null, (byte[]) null, Permission.Action.READ), }); return null; } }; PrivilegedExceptionAction<Void> noCheck = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkTablePerms(TEST_TABLE, new Permission[0]); return null; } }; verifyAllowed(tableRead, SUPERUSER, userTable); verifyDenied(tableRead, userColumn, userQualifier); verifyAllowed(columnRead, SUPERUSER, userTable, userColumn); verifyDenied(columnRead, userQualifier); verifyAllowed(qualifierRead, SUPERUSER, userTable, userColumn, userQualifier); verifyAllowed(multiQualifierRead, SUPERUSER, userTable, userColumn); verifyDenied(multiQualifierRead, userQualifier); verifyAllowed(globalAndTableRead, SUPERUSER); verifyDenied(globalAndTableRead, userTable, userColumn, userQualifier); verifyAllowed(noCheck, SUPERUSER, userTable, userColumn, userQualifier); PrivilegedExceptionAction<Void> familyReadWrite = new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { checkTablePerms(TEST_TABLE, TEST_FAMILY, null, Permission.Action.READ, Permission.Action.WRITE); return null; } }; verifyAllowed(familyReadWrite, SUPERUSER, USER_OWNER, USER_RW); verifyDenied(familyReadWrite, USER_NONE, USER_CREATE, USER_RO); try { protocol.checkPermissions(new Permission[] { (Permission) new TablePermission(TEST_TABLE, null, (byte[]) null, Permission.Action.CREATE) }); fail("this should have thrown CoprocessorException"); } catch (CoprocessorException ex) { } }
@Override public void checkPermissions(Permission[] permissions) throws IOException { byte[] tableName = regionEnv.getRegion().getTableDesc().getName(); for (Permission permission : permissions) { if (permission instanceof TablePermission) { TablePermission tperm = (TablePermission) permission; for (Permission.Action action : permission.getActions()) { if (!Arrays.equals(tperm.getTable(), tableName)) { throw new CoprocessorException(AccessController.class, String.format("This method " + "can only execute at the table specified in TablePermission. " + "Table of the region:%s , requested table:%s", Bytes.toString(tableName), Bytes.toString(tperm.getTable()))); } HashMap<byte[], Set<byte[]>> familyMap = Maps.newHashMapWithExpectedSize(1); if (tperm.getFamily() != null) { if (tperm.getQualifier() != null) { familyMap.put(tperm.getFamily(), Sets.newHashSet(tperm.getQualifier())); } else { familyMap.put(tperm.getFamily(), null); } } requirePermission(action, regionEnv, familyMap); } } else { for (Permission.Action action : permission.getActions()) { requirePermission(action); } } } }
AccessController extends BaseRegionObserver implements MasterObserver, AccessControllerProtocol { @Override public void checkPermissions(Permission[] permissions) throws IOException { byte[] tableName = regionEnv.getRegion().getTableDesc().getName(); for (Permission permission : permissions) { if (permission instanceof TablePermission) { TablePermission tperm = (TablePermission) permission; for (Permission.Action action : permission.getActions()) { if (!Arrays.equals(tperm.getTable(), tableName)) { throw new CoprocessorException(AccessController.class, String.format("This method " + "can only execute at the table specified in TablePermission. " + "Table of the region:%s , requested table:%s", Bytes.toString(tableName), Bytes.toString(tperm.getTable()))); } HashMap<byte[], Set<byte[]>> familyMap = Maps.newHashMapWithExpectedSize(1); if (tperm.getFamily() != null) { if (tperm.getQualifier() != null) { familyMap.put(tperm.getFamily(), Sets.newHashSet(tperm.getQualifier())); } else { familyMap.put(tperm.getFamily(), null); } } requirePermission(action, regionEnv, familyMap); } } else { for (Permission.Action action : permission.getActions()) { requirePermission(action); } } } } }
AccessController extends BaseRegionObserver implements MasterObserver, AccessControllerProtocol { @Override public void checkPermissions(Permission[] permissions) throws IOException { byte[] tableName = regionEnv.getRegion().getTableDesc().getName(); for (Permission permission : permissions) { if (permission instanceof TablePermission) { TablePermission tperm = (TablePermission) permission; for (Permission.Action action : permission.getActions()) { if (!Arrays.equals(tperm.getTable(), tableName)) { throw new CoprocessorException(AccessController.class, String.format("This method " + "can only execute at the table specified in TablePermission. " + "Table of the region:%s , requested table:%s", Bytes.toString(tableName), Bytes.toString(tperm.getTable()))); } HashMap<byte[], Set<byte[]>> familyMap = Maps.newHashMapWithExpectedSize(1); if (tperm.getFamily() != null) { if (tperm.getQualifier() != null) { familyMap.put(tperm.getFamily(), Sets.newHashSet(tperm.getQualifier())); } else { familyMap.put(tperm.getFamily(), null); } } requirePermission(action, regionEnv, familyMap); } } else { for (Permission.Action action : permission.getActions()) { requirePermission(action); } } } }  }
AccessController extends BaseRegionObserver implements MasterObserver, AccessControllerProtocol { @Override public void checkPermissions(Permission[] permissions) throws IOException { byte[] tableName = regionEnv.getRegion().getTableDesc().getName(); for (Permission permission : permissions) { if (permission instanceof TablePermission) { TablePermission tperm = (TablePermission) permission; for (Permission.Action action : permission.getActions()) { if (!Arrays.equals(tperm.getTable(), tableName)) { throw new CoprocessorException(AccessController.class, String.format("This method " + "can only execute at the table specified in TablePermission. " + "Table of the region:%s , requested table:%s", Bytes.toString(tableName), Bytes.toString(tperm.getTable()))); } HashMap<byte[], Set<byte[]>> familyMap = Maps.newHashMapWithExpectedSize(1); if (tperm.getFamily() != null) { if (tperm.getQualifier() != null) { familyMap.put(tperm.getFamily(), Sets.newHashSet(tperm.getQualifier())); } else { familyMap.put(tperm.getFamily(), null); } } requirePermission(action, regionEnv, familyMap); } } else { for (Permission.Action action : permission.getActions()) { requirePermission(action); } } } }  void start(CoprocessorEnvironment env); void stop(CoprocessorEnvironment env); @Override void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> c,
      HTableDescriptor desc, HRegionInfo[] regions); @Override void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> c,
      HTableDescriptor desc, HRegionInfo[] regions); @Override void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName); @Override void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName); @Override void preModifyTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      HTableDescriptor htd); @Override void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, HTableDescriptor htd); @Override void preAddColumn(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      HColumnDescriptor column); @Override void postAddColumn(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, HColumnDescriptor column); @Override void preModifyColumn(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      HColumnDescriptor descriptor); @Override void postModifyColumn(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, HColumnDescriptor descriptor); @Override void preDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      byte[] col); @Override void postDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, byte[] col); @Override void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName); @Override void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName); @Override void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName); @Override void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName); @Override void preMove(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo region,
      ServerName srcServer, ServerName destServer); @Override void postMove(ObserverContext<MasterCoprocessorEnvironment> c,
      HRegionInfo region, ServerName srcServer, ServerName destServer); @Override void preAssign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo); @Override void postAssign(ObserverContext<MasterCoprocessorEnvironment> c,
      HRegionInfo regionInfo); @Override void preUnassign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo,
      boolean force); @Override void postUnassign(ObserverContext<MasterCoprocessorEnvironment> c,
      HRegionInfo regionInfo, boolean force); @Override void preBalance(ObserverContext<MasterCoprocessorEnvironment> c); @Override void postBalance(ObserverContext<MasterCoprocessorEnvironment> c); @Override boolean preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> c,
      boolean newValue); @Override void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> c,
      boolean oldValue, boolean newValue); @Override void preShutdown(ObserverContext<MasterCoprocessorEnvironment> c); @Override void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> c); @Override void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx); @Override void postOpen(ObserverContext<RegionCoprocessorEnvironment> c); @Override void preFlush(ObserverContext<RegionCoprocessorEnvironment> e); @Override void preSplit(ObserverContext<RegionCoprocessorEnvironment> e); @Override InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> e,
      final Store store, final InternalScanner scanner); @Override void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> e,
      final Store store, final List<StoreFile> candidates); @Override void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final Result result); @Override void preGet(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Get get, final List<KeyValue> result); @Override boolean preExists(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Get get, final boolean exists); @Override void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Put put, final WALEdit edit, final boolean writeToWAL); @Override void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Put put, final WALEdit edit, final boolean writeToWAL); @Override void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Delete delete, final WALEdit edit, final boolean writeToWAL); @Override void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Delete delete, final WALEdit edit, final boolean writeToWAL); @Override boolean preCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final byte [] qualifier,
      final CompareFilter.CompareOp compareOp,
      final WritableByteArrayComparable comparator, final Put put,
      final boolean result); @Override boolean preCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final byte [] qualifier,
      final CompareFilter.CompareOp compareOp,
      final WritableByteArrayComparable comparator, final Delete delete,
      final boolean result); @Override long preIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final byte [] qualifier,
      final long amount, final boolean writeToWAL); @Override Result preAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append); @Override Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Increment increment); @Override RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Scan scan, final RegionScanner s); @Override RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Scan scan, final RegionScanner s); @Override boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
      final InternalScanner s, final List<Result> result,
      final int limit, final boolean hasNext); @Override void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
      final InternalScanner s); @Override void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
      final InternalScanner s); @Override void grant(UserPermission perm); @Override @Deprecated void grant(byte[] user, TablePermission permission); @Override void revoke(UserPermission perm); @Override @Deprecated void revoke(byte[] user, TablePermission permission); @Override List<UserPermission> getUserPermissions(final byte[] tableName); @Override void checkPermissions(Permission[] permissions); @Override long getProtocolVersion(String protocol, long clientVersion); @Override ProtocolSignature getProtocolSignature(String protocol,
      long clientVersion, int clientMethodsHash); }
AccessController extends BaseRegionObserver implements MasterObserver, AccessControllerProtocol { @Override public void checkPermissions(Permission[] permissions) throws IOException { byte[] tableName = regionEnv.getRegion().getTableDesc().getName(); for (Permission permission : permissions) { if (permission instanceof TablePermission) { TablePermission tperm = (TablePermission) permission; for (Permission.Action action : permission.getActions()) { if (!Arrays.equals(tperm.getTable(), tableName)) { throw new CoprocessorException(AccessController.class, String.format("This method " + "can only execute at the table specified in TablePermission. " + "Table of the region:%s , requested table:%s", Bytes.toString(tableName), Bytes.toString(tperm.getTable()))); } HashMap<byte[], Set<byte[]>> familyMap = Maps.newHashMapWithExpectedSize(1); if (tperm.getFamily() != null) { if (tperm.getQualifier() != null) { familyMap.put(tperm.getFamily(), Sets.newHashSet(tperm.getQualifier())); } else { familyMap.put(tperm.getFamily(), null); } } requirePermission(action, regionEnv, familyMap); } } else { for (Permission.Action action : permission.getActions()) { requirePermission(action); } } } }  void start(CoprocessorEnvironment env); void stop(CoprocessorEnvironment env); @Override void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> c,
      HTableDescriptor desc, HRegionInfo[] regions); @Override void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> c,
      HTableDescriptor desc, HRegionInfo[] regions); @Override void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName); @Override void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName); @Override void preModifyTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      HTableDescriptor htd); @Override void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, HTableDescriptor htd); @Override void preAddColumn(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      HColumnDescriptor column); @Override void postAddColumn(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, HColumnDescriptor column); @Override void preModifyColumn(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      HColumnDescriptor descriptor); @Override void postModifyColumn(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, HColumnDescriptor descriptor); @Override void preDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName,
      byte[] col); @Override void postDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName, byte[] col); @Override void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName); @Override void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName); @Override void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> c, byte[] tableName); @Override void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> c,
      byte[] tableName); @Override void preMove(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo region,
      ServerName srcServer, ServerName destServer); @Override void postMove(ObserverContext<MasterCoprocessorEnvironment> c,
      HRegionInfo region, ServerName srcServer, ServerName destServer); @Override void preAssign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo); @Override void postAssign(ObserverContext<MasterCoprocessorEnvironment> c,
      HRegionInfo regionInfo); @Override void preUnassign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo,
      boolean force); @Override void postUnassign(ObserverContext<MasterCoprocessorEnvironment> c,
      HRegionInfo regionInfo, boolean force); @Override void preBalance(ObserverContext<MasterCoprocessorEnvironment> c); @Override void postBalance(ObserverContext<MasterCoprocessorEnvironment> c); @Override boolean preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> c,
      boolean newValue); @Override void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> c,
      boolean oldValue, boolean newValue); @Override void preShutdown(ObserverContext<MasterCoprocessorEnvironment> c); @Override void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> c); @Override void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx); @Override void postOpen(ObserverContext<RegionCoprocessorEnvironment> c); @Override void preFlush(ObserverContext<RegionCoprocessorEnvironment> e); @Override void preSplit(ObserverContext<RegionCoprocessorEnvironment> e); @Override InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> e,
      final Store store, final InternalScanner scanner); @Override void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> e,
      final Store store, final List<StoreFile> candidates); @Override void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final Result result); @Override void preGet(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Get get, final List<KeyValue> result); @Override boolean preExists(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Get get, final boolean exists); @Override void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Put put, final WALEdit edit, final boolean writeToWAL); @Override void postPut(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Put put, final WALEdit edit, final boolean writeToWAL); @Override void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Delete delete, final WALEdit edit, final boolean writeToWAL); @Override void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Delete delete, final WALEdit edit, final boolean writeToWAL); @Override boolean preCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final byte [] qualifier,
      final CompareFilter.CompareOp compareOp,
      final WritableByteArrayComparable comparator, final Put put,
      final boolean result); @Override boolean preCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final byte [] qualifier,
      final CompareFilter.CompareOp compareOp,
      final WritableByteArrayComparable comparator, final Delete delete,
      final boolean result); @Override long preIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c,
      final byte [] row, final byte [] family, final byte [] qualifier,
      final long amount, final boolean writeToWAL); @Override Result preAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append); @Override Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Increment increment); @Override RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Scan scan, final RegionScanner s); @Override RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
      final Scan scan, final RegionScanner s); @Override boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
      final InternalScanner s, final List<Result> result,
      final int limit, final boolean hasNext); @Override void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
      final InternalScanner s); @Override void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
      final InternalScanner s); @Override void grant(UserPermission perm); @Override @Deprecated void grant(byte[] user, TablePermission permission); @Override void revoke(UserPermission perm); @Override @Deprecated void revoke(byte[] user, TablePermission permission); @Override List<UserPermission> getUserPermissions(final byte[] tableName); @Override void checkPermissions(Permission[] permissions); @Override long getProtocolVersion(String protocol, long clientVersion); @Override ProtocolSignature getProtocolSignature(String protocol,
      long clientVersion, int clientMethodsHash); static final Log LOG; }