@Test(expected=UnsupportedOperationException.class) public void testGetRowWithACL() throws IOException { clean(); byte[] rowKey = Bytes.toBytes(rowPrefix + 0); byte[] familyName = Bytes.toBytes(this.familyName); byte[] columnName = Bytes.toBytes("col_1"); byte[] columnVar = Bytes.toBytes("col_1_var"); Put put = new Put(rowKey); put.addColumn(familyName, columnName, columnVar); table.put(put); Get get = new Get(rowKey); get.setACL("abc", new Permission()); table.get(get); }
@Override public Mutation beforeMutate(long rowkeyBase, Mutation m) throws IOException { if (!(m instanceof Delete)) { if (userNames != null && userNames.length > 0) { int mod = ((int) rowkeyBase % this.userNames.length); if (((int) rowkeyBase % specialPermCellInsertionFactor) == 0) { // These cells cannot be read back when running as user userName[mod] if (LOG.isTraceEnabled()) { LOG.trace("Adding special perm " + rowkeyBase); } m.setACL(userNames[mod], new Permission(Permission.Action.WRITE)); } else { m.setACL(userNames[mod], new Permission(Permission.Action.READ)); } } } return m; }
private void createTable(Admin admin, TableName tableName, boolean setVersion, boolean acl) throws IOException { if (!admin.tableExists(tableName)) { HTableDescriptor htd = new HTableDescriptor(tableName); HColumnDescriptor family = new HColumnDescriptor(FAMILY_NAME); if (setVersion) { family.setMaxVersions(DEFAULT_TABLES_COUNT); } htd.addFamily(family); admin.createTable(htd); if (acl) { LOG.info("Granting permissions for user " + USER.getShortName()); Permission.Action[] actions = { Permission.Action.READ }; try { AccessControlClient.grant(ConnectionFactory.createConnection(getConf()), tableName, USER.getShortName(), null, null, actions); } catch (Throwable e) { LOG.fatal("Error in granting permission for the user " + USER.getShortName(), e); throw new IOException(e); } } } }
/** * Converts a Permission.Action proto to a client Permission.Action object. * * @param action the protobuf Action * @return the converted Action */ public static Permission.Action toPermissionAction( AccessControlProtos.Permission.Action action) { switch (action) { case READ: return Permission.Action.READ; case WRITE: return Permission.Action.WRITE; case EXEC: return Permission.Action.EXEC; case CREATE: return Permission.Action.CREATE; case ADMIN: return Permission.Action.ADMIN; } throw new IllegalArgumentException("Unknown action value "+action.name()); }
/** * Convert a client Permission.Action to a Permission.Action proto * * @param action the client Action * @return the protobuf Action */ public static AccessControlProtos.Permission.Action toPermissionAction( Permission.Action action) { switch (action) { case READ: return AccessControlProtos.Permission.Action.READ; case WRITE: return AccessControlProtos.Permission.Action.WRITE; case EXEC: return AccessControlProtos.Permission.Action.EXEC; case CREATE: return AccessControlProtos.Permission.Action.CREATE; case ADMIN: return AccessControlProtos.Permission.Action.ADMIN; } throw new IllegalArgumentException("Unknown action value "+action.name()); }
/** * A utility used to get user table permissions. * <p> * It's also called by the shell, in case you want to find references. * * @param protocol the AccessControlService protocol proxy * @param t optional table name * @throws ServiceException */ public static List<UserPermission> getUserPermissions(RpcController controller, AccessControlService.BlockingInterface protocol, TableName t) throws ServiceException { AccessControlProtos.GetUserPermissionsRequest.Builder builder = AccessControlProtos.GetUserPermissionsRequest.newBuilder(); if (t != null) { builder.setTableName(ProtobufUtil.toProtoTableName(t)); } builder.setType(AccessControlProtos.Permission.Type.Table); AccessControlProtos.GetUserPermissionsRequest request = builder.build(); AccessControlProtos.GetUserPermissionsResponse response = protocol.getUserPermissions(controller, request); List<UserPermission> perms = new ArrayList<UserPermission>(response.getUserPermissionCount()); for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { perms.add(ProtobufUtil.toUserPermission(perm)); } return perms; }
/** * A utility used to get permissions for selected namespace. * <p> * It's also called by the shell, in case you want to find references. * * @param protocol the AccessControlService protocol proxy * @param namespace name of the namespace * @throws ServiceException */ public static List<UserPermission> getUserPermissions(RpcController controller, AccessControlService.BlockingInterface protocol, byte[] namespace) throws ServiceException { AccessControlProtos.GetUserPermissionsRequest.Builder builder = AccessControlProtos.GetUserPermissionsRequest.newBuilder(); if (namespace != null) { builder.setNamespaceName(ByteStringer.wrap(namespace)); } builder.setType(AccessControlProtos.Permission.Type.Namespace); AccessControlProtos.GetUserPermissionsRequest request = builder.build(); AccessControlProtos.GetUserPermissionsResponse response = protocol.getUserPermissions(controller, request); List<UserPermission> perms = new ArrayList<UserPermission>(response.getUserPermissionCount()); for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { perms.add(ProtobufUtil.toUserPermission(perm)); } return perms; }
/** * A utility used to get user table permissions. * <p> * It's also called by the shell, in case you want to find references. * * @param protocol the AccessControlService protocol proxy * @param t optional table name * @throws ServiceException */ public static List<UserPermission> getUserPermissions( AccessControlService.BlockingInterface protocol, TableName t) throws ServiceException { AccessControlProtos.GetUserPermissionsRequest.Builder builder = AccessControlProtos.GetUserPermissionsRequest.newBuilder(); if (t != null) { builder.setTableName(ProtobufUtil.toProtoTableName(t)); } builder.setType(AccessControlProtos.Permission.Type.Table); AccessControlProtos.GetUserPermissionsRequest request = builder.build(); AccessControlProtos.GetUserPermissionsResponse response = protocol.getUserPermissions(null, request); List<UserPermission> perms = new ArrayList<UserPermission>(response.getUserPermissionCount()); for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { perms.add(ProtobufUtil.toUserPermission(perm)); } return perms; }
/** * A utility used to get permissions for selected namespace. * <p> * It's also called by the shell, in case you want to find references. * * @param protocol the AccessControlService protocol proxy * @param namespace name of the namespace * @throws ServiceException */ public static List<UserPermission> getUserPermissions( AccessControlService.BlockingInterface protocol, byte[] namespace) throws ServiceException { AccessControlProtos.GetUserPermissionsRequest.Builder builder = AccessControlProtos.GetUserPermissionsRequest.newBuilder(); if (namespace != null) { builder.setNamespaceName(ByteStringer.wrap(namespace)); } builder.setType(AccessControlProtos.Permission.Type.Namespace); AccessControlProtos.GetUserPermissionsRequest request = builder.build(); AccessControlProtos.GetUserPermissionsResponse response = protocol.getUserPermissions(null, request); List<UserPermission> perms = new ArrayList<UserPermission>(response.getUserPermissionCount()); for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { perms.add(ProtobufUtil.toUserPermission(perm)); } return perms; }
/** * A utility used to get user table permissions. * <p> * It's also called by the shell, in case you want to find references. * * @param protocol the AccessControlService protocol proxy * @param t optional table name * @throws ServiceException */ public static List<UserPermission> getUserPermissions( AccessControlService.BlockingInterface protocol, TableName t) throws ServiceException { AccessControlProtos.GetUserPermissionsRequest.Builder builder = AccessControlProtos.GetUserPermissionsRequest.newBuilder(); if (t != null) { builder.setTableName(ProtobufUtil.toProtoTableName(t)); } builder.setType(AccessControlProtos.Permission.Type.Table); AccessControlProtos.GetUserPermissionsRequest request = builder.build(); AccessControlProtos.GetUserPermissionsResponse response = protocol.getUserPermissions(null, request); List<UserPermission> perms = new ArrayList<UserPermission>(); for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { perms.add(ProtobufUtil.toUserPermission(perm)); } return perms; }
/** * A utility used to get permissions for selected namespace. * <p> * It's also called by the shell, in case you want to find references. * * @param protocol the AccessControlService protocol proxy * @param namespace name of the namespace * @throws ServiceException */ public static List<UserPermission> getUserPermissions( AccessControlService.BlockingInterface protocol, byte[] namespace) throws ServiceException { AccessControlProtos.GetUserPermissionsRequest.Builder builder = AccessControlProtos.GetUserPermissionsRequest.newBuilder(); if (namespace != null) { builder.setNamespaceName(HBaseZeroCopyByteString.wrap(namespace)); } builder.setType(AccessControlProtos.Permission.Type.Namespace); AccessControlProtos.GetUserPermissionsRequest request = builder.build(); AccessControlProtos.GetUserPermissionsResponse response = protocol.getUserPermissions(null, request); List<UserPermission> perms = new ArrayList<UserPermission>(); for (AccessControlProtos.UserPermission perm: response.getUserPermissionList()) { perms.add(ProtobufUtil.toUserPermission(perm)); } return perms; }
/** * Sets the security firstly for getting the correct default realm. * @throws Exception */ @BeforeClass public static void beforeClass() throws Exception { UserProvider.setUserProviderForTesting(UTIL.getConfiguration(), HadoopSecurityEnabledUserProviderForTesting.class); setUpKdcServer(); SecureTestUtil.enableSecurity(UTIL.getConfiguration()); UTIL.getConfiguration().setBoolean(AccessControlConstants.EXEC_PERMISSION_CHECKS_KEY, true); VisibilityTestUtil.enableVisiblityLabels(UTIL.getConfiguration()); SecureTestUtil.verifyConfiguration(UTIL.getConfiguration()); setUpClusterKdc(); UTIL.startMiniCluster(); UTIL.waitUntilAllRegionsAssigned(AccessControlLists.ACL_TABLE_NAME); UTIL.waitUntilAllRegionsAssigned(VisibilityConstants.LABELS_TABLE_NAME); UTIL.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME, 50000); UTIL.waitTableEnabled(VisibilityConstants.LABELS_TABLE_NAME, 50000); SecureTestUtil.grantGlobal(UTIL, USER_ADMIN, Permission.Action.ADMIN, Permission.Action.CREATE, Permission.Action.EXEC, Permission.Action.READ, Permission.Action.WRITE); addLabels(UTIL.getConfiguration(), Arrays.asList(USER_OWNER), Arrays.asList(PRIVATE, CONFIDENTIAL, SECRET, TOPSECRET)); }
@Before public void setUp() throws Exception { admin = TEST_UTIL.getHBaseAdmin(); HTableDescriptor htd = new HTableDescriptor(TEST_TABLE); HColumnDescriptor hcd = new HColumnDescriptor(TEST_FAMILY); hcd.setMaxVersions(100); htd.addFamily(hcd); htd.setOwner(USER_OWNER); admin.createTable(htd, new byte[][] { Bytes.toBytes("s") }); TEST_UTIL.waitTableEnabled(TEST_TABLE); grantOnTable(TEST_UTIL, USER_RW.getShortName(), TEST_TABLE, TEST_FAMILY, null, Permission.Action.READ, Permission.Action.WRITE); grantOnTable(TEST_UTIL, USER_RO.getShortName(), TEST_TABLE, TEST_FAMILY, null, Permission.Action.READ); }
private void createTable(Admin admin, TableName tableName, boolean setVersion, boolean acl) throws IOException { if (!admin.tableExists(tableName)) { HTableDescriptor htd = new HTableDescriptor(tableName); HColumnDescriptor family = new HColumnDescriptor(FAMILY_NAME); if (setVersion) { family.setMaxVersions(DEFAULT_TABLES_COUNT); } htd.addFamily(family); admin.createTable(htd); if (acl) { LOG.info("Granting permissions for user " + USER.getShortName()); Permission.Action[] actions = { Permission.Action.READ }; try { AccessControlClient.grant(ConnectionFactory.createConnection(getConf()), tableName, USER.getShortName(), null, null, actions); } catch (Throwable e) { LOG.error(HBaseMarkers.FATAL, "Error in granting permission for the user " + USER.getShortName(), e); throw new IOException(e); } } } }
/** * Convert a client Permission to a Permission proto * * @param perm the client Permission * @return the protobuf Permission */ public static AccessControlProtos.Permission toPermission(Permission perm) { AccessControlProtos.Permission.Builder builder = AccessControlProtos.Permission.newBuilder(); if (perm instanceof TablePermission) { TablePermission tablePerm = (TablePermission)perm; if (tablePerm.hasTable()) { builder.setTable(ByteString.copyFrom(tablePerm.getTable())); } if (tablePerm.hasFamily()) { builder.setFamily(ByteString.copyFrom(tablePerm.getFamily())); } if (tablePerm.hasQualifier()) { builder.setQualifier(ByteString.copyFrom(tablePerm.getQualifier())); } } for (Permission.Action a : perm.getActions()) { builder.addAction(toPermissionAction(a)); } return builder.build(); }
/** * Convert a client user permission to a user permission proto * * @param perm the client UserPermission * @return the protobuf UserPermission */ public static AccessControlProtos.UserPermission toUserPermission(UserPermission perm) { AccessControlProtos.Permission.Builder permissionBuilder = AccessControlProtos.Permission.newBuilder(); for (Permission.Action a : perm.getActions()) { permissionBuilder.addAction(toPermissionAction(a)); } if (perm.hasTable()) { permissionBuilder.setTable(ByteString.copyFrom(perm.getTable())); } if (perm.hasFamily()) { permissionBuilder.setFamily(ByteString.copyFrom(perm.getFamily())); } if (perm.hasQualifier()) { permissionBuilder.setQualifier(ByteString.copyFrom(perm.getQualifier())); } return AccessControlProtos.UserPermission.newBuilder() .setUser(ByteString.copyFrom(perm.getUser())) .setPermission(permissionBuilder) .build(); }
/** * Converts a user permission proto to a client user permission object. * * @param proto the protobuf UserPermission * @return the converted UserPermission */ public static UserPermission toUserPermission(AccessControlProtos.UserPermission proto) { AccessControlProtos.Permission permission = proto.getPermission(); List<Permission.Action> actions = toPermissionActions(permission.getActionList()); byte[] qualifier = null; byte[] family = null; byte[] table = null; if (permission.hasTable()) table = permission.getTable().toByteArray(); if (permission.hasFamily()) family = permission.getFamily().toByteArray(); if (permission.hasQualifier()) qualifier = permission.getQualifier().toByteArray(); return new UserPermission(proto.getUser().toByteArray(), table, family, qualifier, actions.toArray(new Permission.Action[actions.size()])); }
@Test(expected=UnsupportedOperationException.class) public void testScanRowWithACL() throws IOException { clean(); String row = rowPrefix + 0; putRow(row + 0, 1000); putRow(row + 3, 1000); Scan scan = new Scan(); scan.setACL("abc", new Permission()); scan.setStartRow(Bytes.toBytes(row + 0)); scan.setStopRow(Bytes.toBytes(row + 3)); ResultScanner scanResult = table.getScanner(scan); scanResult.next(); }
@Test(expected=UnsupportedOperationException.class) public void testDeleteWithACL() throws IOException { clean(); Delete delete = new Delete(Bytes.toBytes(rowPrefix)); delete.setACL("abc", new Permission()); table.delete(delete); }
@BeforeClass public static void setupBeforeClass() throws Exception { // setup configuration conf = TEST_UTIL.getConfiguration(); conf.setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10); SecureTestUtil.enableSecurity(conf); conf.set("hbase.coprocessor.master.classes", AccessController.class.getName() + "," + VisibilityController.class.getName()); conf.set("hbase.coprocessor.region.classes", AccessController.class.getName() + "," + VisibilityController.class.getName()); TEST_UTIL.startMiniCluster(2); TEST_UTIL.waitTableEnabled(AccessControlLists.ACL_TABLE_NAME.getName(), 50000); // Wait for the labels table to become available TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000); addLabels(); // Create users for testing SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" }); NORMAL_USER1 = User.createUserForTesting(conf, "user1", new String[] {}); NORMAL_USER2 = User.createUserForTesting(conf, "user2", new String[] {}); // Grant users EXEC privilege on the labels table. For the purposes of this // test, we want to insure that access is denied even with the ability to access // the endpoint. SecureTestUtil.grantOnTable(TEST_UTIL, NORMAL_USER1.getShortName(), LABELS_TABLE_NAME, null, null, Permission.Action.EXEC); SecureTestUtil.grantOnTable(TEST_UTIL, NORMAL_USER2.getShortName(), LABELS_TABLE_NAME, null, null, Permission.Action.EXEC); }
@Test public void testScanForUserWithFewerLabelAuthsThanLabelsInScanAuthorizations() throws Throwable { String[] auths = { SECRET }; String user = "user2"; VisibilityClient.setAuths(TEST_UTIL.getConnection(), auths, user); TableName tableName = TableName.valueOf(TEST_NAME.getMethodName()); final Table table = createTableAndWriteDataWithLabels(tableName, SECRET + "&" + CONFIDENTIAL + "&!" + PRIVATE, SECRET + "&!" + PRIVATE); SecureTestUtil.grantOnTable(TEST_UTIL, NORMAL_USER2.getShortName(), tableName, null, null, Permission.Action.READ); PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { Scan s = new Scan(); s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL)); try (Connection connection = ConnectionFactory.createConnection(conf); Table t = connection.getTable(table.getName())) { ResultScanner scanner = t.getScanner(s); Result result = scanner.next(); assertTrue(!result.isEmpty()); assertTrue(Bytes.equals(Bytes.toBytes("row2"), result.getRow())); result = scanner.next(); assertNull(result); } return null; } }; NORMAL_USER2.runAs(scanAction); }
@Test public void testVisibilityLabelsForUserWithNoAuths() throws Throwable { String user = "admin"; String[] auths = { SECRET }; try (Connection conn = ConnectionFactory.createConnection(conf)) { VisibilityClient.clearAuths(conn, auths, user); // Removing all auths if any. VisibilityClient.setAuths(conn, auths, "user1"); } TableName tableName = TableName.valueOf(TEST_NAME.getMethodName()); final Table table = createTableAndWriteDataWithLabels(tableName, SECRET); SecureTestUtil.grantOnTable(TEST_UTIL, NORMAL_USER1.getShortName(), tableName, null, null, Permission.Action.READ); SecureTestUtil.grantOnTable(TEST_UTIL, NORMAL_USER2.getShortName(), tableName, null, null, Permission.Action.READ); PrivilegedExceptionAction<Void> getAction = new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { Get g = new Get(row1); g.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL)); try (Connection connection = ConnectionFactory.createConnection(conf); Table t = connection.getTable(table.getName())) { Result result = t.get(g); assertTrue(result.isEmpty()); } return null; } }; NORMAL_USER2.runAs(getAction); }
/** * Converts a Permission proto to a client Permission object. * * @param proto the protobuf Permission * @return the converted Permission */ public static Permission toPermission(AccessControlProtos.Permission proto) { if (proto.getType() != AccessControlProtos.Permission.Type.Global) { return toTablePermission(proto); } else { List<Permission.Action> actions = toPermissionActions(proto.getGlobalPermission().getActionList()); return new Permission(actions.toArray(new Permission.Action[actions.size()])); } }