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));
+       }
 }

Reply via email to