You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2026/09/17 05:33:26 UTC
(ranger) branch master updated: RANGER-5750:Handle authorization of hbase:acl table in RangerAuthorizationCoprocessor in HBase Ranger plugin (#1201)
This is an automated email from the ASF dual-hosted git repository.
rameeshm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 191548874 RANGER-5750:Handle authorization of hbase:acl table in RangerAuthorizationCoprocessor in HBase Ranger plugin (#1201)
191548874 is described below
commit 191548874d992f6db1c0c531a4d2426bc96c7628
Author: Ramesh Mani <rm...@cloudera.com>
AuthorDate: Wed Sep 16 22:33:20 2026 -0700
RANGER-5750:Handle authorization of hbase:acl table in RangerAuthorizationCoprocessor in HBase Ranger plugin (#1201)
* RANGER-5750:Handle authorization of hbase:acl table in RangerAuthorizationCoprocessor in HBase Ranger plugin
* RANGER-5750:Handle authorization of hbase:acl table in RangerAuthorizationCoprocessor in HBase Ranger plugin - review comments addressed
* RANGER-5750:Handle authorization of hbase:acl table in RangerAuthorizationCoprocessor in HBase Ranger plugin - review comments set#2 addressed
---------
Co-authored-by: Ramesh Mani <rm...@apache.org>
---
.../hbase/RangerAuthorizationCoprocessor.java | 35 ++++++++++++++++++----
.../hbase/RangerAuthorizationCoprocessorTest.java | 30 +++++++++++++++++--
2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
index ffd642613..2f55260ea 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
@@ -852,6 +852,24 @@ protected byte[] getTableName(RegionCoprocessorEnvironment e) {
return tableName;
}
+ private boolean isSystemOrSuperUser(User activeUser) {
+ if (activeUser == null) {
+ return false;
+ }
+ if (userUtils.isSuperUser(activeUser)) {
+ return true;
+ }
+ try {
+ User currentUser = User.getCurrent();
+ if (currentUser != null) {
+ return Objects.equals(currentUser.getShortName(), activeUser.getShortName());
+ }
+ } catch (IOException e) {
+ LOG.warn("Unable to obtain the current user", e);
+ }
+ return false;
+ }
+
protected void requireSystemOrSuperUser(ObserverContext<?> ctx) throws IOException {
User user = User.getCurrent();
@@ -859,10 +877,9 @@ protected void requireSystemOrSuperUser(ObserverContext<?> ctx) throws IOExcepti
throw new IOException("Unable to obtain the current user, authorization checks for internal operations will not work correctly!");
}
- String systemUser = user.getShortName();
- User activeUser = getActiveUser(ctx);
+ User activeUser = getActiveUser(ctx);
- if (!Objects.equals(systemUser, activeUser.getShortName()) && !userUtils.isSuperUser(activeUser)) {
+ if (activeUser == null || !isSystemOrSuperUser(activeUser)) {
throw new AccessDeniedException("User '" + user.getShortName() + "is not system or super user.");
}
}
@@ -1390,7 +1407,7 @@ boolean canSkipAccessCheck(User user, final String operation, String access, fin
LOG.warn("canSkipAccessCheck: exiting{}", "Unexpeceted: User is null: access denied, not audited!");
throw new AccessDeniedException("No user associated with request (" + operation + ") for action: " + access + "on table:" + table);
- } else if (isAccessForMetadataRead(access, table)) {
+ } else if (isAccessForMetadataRead(access, table, user)) {
LOG.debug("canSkipAccessCheck: true: metadata read access always allowed, not audited");
result = true;
@@ -1434,9 +1451,15 @@ boolean canSkipAccessCheck(User user, final String operation, String access, fin
/* ---- EndpointObserver implementation ---- */
- boolean isAccessForMetadataRead(String access, String table) {
+ boolean isAccessForMetadataRead(String access, String table, User user) {
if (authUtils.isReadAccess(access) && isSpecialTable(table)) {
- LOG.debug("isAccessForMetadataRead: Metadata tables read: access allowed!");
+ if (StringUtils.equals(table, "hbase:acl")) {
+ if (!isSystemOrSuperUser(user)) {
+ LOG.debug("isAccessForMetadataRead: Metadata tables read: not access allowed for user: {}!", (user != null ? user.getShortName() : ""));
+ return false;
+ }
+ }
+ LOG.debug("isAccessForMetadataRead: Metadata tables read: access allowed for user: {}!", (user != null ? user.getShortName() : ""));
return true;
}
diff --git a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorTest.java b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorTest.java
index 340ac1849..481921ecd 100644
--- a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorTest.java
+++ b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorTest.java
@@ -391,12 +391,36 @@ public void test18_requirePermission_region_allowsOrDenies() throws Exception {
}
@Test
- public void test19_isSpecialTable_and_metadataRead() {
+ public void test19_isSpecialTable_and_metadataRead() throws Exception {
RangerAuthorizationCoprocessor cp = new RangerAuthorizationCoprocessor();
Assertions.assertTrue(cp.isSpecialTable("hbase:meta"));
Assertions.assertFalse(cp.isSpecialTable("normal"));
- Assertions.assertTrue(cp.isAccessForMetadataRead("read", "hbase:acl"));
- Assertions.assertFalse(cp.isAccessForMetadataRead("write", "hbase:acl"));
+ Assertions.assertFalse(cp.isAccessForMetadataRead("read", "hbase:acl", null));
+ Assertions.assertFalse(cp.isAccessForMetadataRead("write", "hbase:acl", null));
+
+ // Test for system user bypass on hbase:acl
+ User systemUser = mock(User.class);
+ when(systemUser.getShortName()).thenReturn(User.getCurrent().getShortName());
+ Assertions.assertTrue(cp.isAccessForMetadataRead("read", "hbase:acl", systemUser));
+
+ // Test for super user bypass on hbase:acl
+ User superUser = mock(User.class);
+ when(superUser.getShortName()).thenReturn("some_super_user");
+ HbaseUserUtils userUtils = mock(HbaseUserUtils.class);
+ lenient().when(userUtils.isSuperUser(superUser)).thenReturn(true);
+ Field userUtilsField = RangerAuthorizationCoprocessor.class.getDeclaredField("userUtils");
+ userUtilsField.setAccessible(true);
+ userUtilsField.set(cp, userUtils);
+ Assertions.assertTrue(cp.isAccessForMetadataRead("read", "hbase:acl", superUser));
+
+ // Test for normal user on hbase:acl (should be denied)
+ User normalUser = mock(User.class);
+ when(normalUser.getShortName()).thenReturn("normal_user");
+ lenient().when(userUtils.isSuperUser(normalUser)).thenReturn(false);
+ Assertions.assertFalse(cp.isAccessForMetadataRead("read", "hbase:acl", normalUser));
+
+ // Test for normal user on hbase:meta (should be allowed)
+ Assertions.assertTrue(cp.isAccessForMetadataRead("read", "hbase:meta", normalUser));
}
@Test