This is an automated email from the ASF dual-hosted git repository.
pradeepagrawal8184 pushed a commit to branch ranger-2.10
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/ranger-2.10 by this push:
new 53431deef RANGER-5750:Handle authorization of hbase:acl table in
RangerAuthorizationCoprocessor in HBase Ranger plugin (#1250)
53431deef is described below
commit 53431deefbe37da1146fc4a18227ec0534b3e8d0
Author: Dineshkumar Yadav <[email protected]>
AuthorDate: Thu Oct 15 15:24:42 2026 +0530
RANGER-5750:Handle authorization of hbase:acl table in
RangerAuthorizationCoprocessor in HBase Ranger plugin (#1250)
Co-authored-by: Ramesh Mani <[email protected]>
Co-authored-by: Ramesh Mani <[email protected]>
Co-authored-by: Cursor <[email protected]>
---
.../hbase/RangerAuthorizationCoprocessor.java | 35 +++++++++++++++++---
.../hbase/RangerAuthorizationCoprocessorTest.java | 38 ++++++++++++++++++++++
2 files changed, 68 insertions(+), 5 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 a3ddd885d..c1fe05a26 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
@@ -126,14 +126,32 @@ 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(Configuration conf,
ObserverContext<?> ctx) throws IOException {
User user = User.getCurrent();
if (user == null) {
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);
- 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.");
}
}
@@ -743,7 +761,7 @@ boolean canSkipAccessCheck(User user, final String
operation, String access, fin
String message = "Unexpeceted: User is null: access
denied, not audited!";
LOG.warn("canSkipAccessCheck: exiting" + message);
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;
} else {
@@ -779,9 +797,16 @@ boolean canSkipAccessCheck(User user, final String
operation, String access, fin
return false;
}
- 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;
}
return false;
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 f982910ee..6cd778084 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
@@ -19,10 +19,15 @@
package org.apache.ranger.authorization.hbase;
import static org.junit.Assert.*;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;
+import org.apache.hadoop.hbase.security.User;
import org.junit.Test;
public class RangerAuthorizationCoprocessorTest {
@@ -48,4 +53,37 @@ public void test_getColumnFamilies_firewalling() {
// same for passing in an empty collection
// result = _coprocessor.getColumnFamilies(new HashMap<byte[], ?
extends Collection<?>>());
}
+
+ @Test
+ public void test_isSpecialTable_and_metadataRead() throws Exception {
+ RangerAuthorizationCoprocessor cp = new
RangerAuthorizationCoprocessor();
+ assertTrue(cp.isSpecialTable("hbase:meta"));
+ assertFalse(cp.isSpecialTable("normal"));
+ assertFalse(cp.isAccessForMetadataRead("read", "hbase:acl",
null));
+ 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());
+ 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);
+ 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);
+ assertFalse(cp.isAccessForMetadataRead("read", "hbase:acl",
normalUser));
+
+ // Test for normal user on hbase:meta (should be allowed)
+ assertTrue(cp.isAccessForMetadataRead("read", "hbase:meta",
normalUser));
+ }
}