This is an automated email from the ASF dual-hosted git repository.

abhay 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 4abb99350 RANGER-4745: Enhance handling of subAccess authorization in 
Ranger HDFS plugin
4abb99350 is described below

commit 4abb993500274ad06a148f4258a7ea71622ebc88
Author: Abhay Kulkarni <[email protected]>
AuthorDate: Thu Apr 4 15:25:58 2024 -0700

    RANGER-4745: Enhance handling of subAccess authorization in Ranger HDFS 
plugin
---
 .../hadoop/constants/RangerHadoopConstants.java    |  4 +
 .../authorization/hadoop/RangerHdfsAuthorizer.java | 91 ++++++++++++++++++++--
 2 files changed, 90 insertions(+), 5 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
 
b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
index a29390fd0..fcd9ebd4d 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
@@ -24,6 +24,10 @@ public class RangerHadoopConstants {
        public static final String RANGER_OPTIMIZE_SUBACCESS_AUTHORIZATION_PROP 
= "ranger.optimize-subaccess-authorization" ;
        public static final boolean RANGER_ADD_HDFS_PERMISSION_DEFAULT = false;
        public static final boolean 
RANGER_OPTIMIZE_SUBACCESS_AUTHORIZATION_DEFAULT = false ;
+
+       public static final String 
RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_PROP = 
"ranger.plugin.hdfs.use.legacy.subaccess.authorization";
+       public static final boolean 
RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_DEFAULT = true;
+
        public static final String READ_ACCCESS_TYPE = "read";
        public static final String WRITE_ACCCESS_TYPE = "write";
        public static final String EXECUTE_ACCCESS_TYPE = "execute";
diff --git 
a/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
 
b/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
index 9b410a185..b11ee62a3 100644
--- 
a/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
+++ 
b/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
@@ -116,6 +116,8 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                        
LOG.info(RangerHadoopConstants.RANGER_OPTIMIZE_SUBACCESS_AUTHORIZATION_PROP + " 
is enabled");
                }
 
+               LOG.info("Legacy way of authorizing sub-access requests will " 
+ (plugin.isUseLegacySubAccessAuthorization() ? "" : "not ") + "be used");
+
                access2ActionListMapper.put(FsAction.NONE,          new 
HashSet<String>());
                access2ActionListMapper.put(FsAction.ALL,           
Sets.newHashSet(READ_ACCCESS_TYPE, WRITE_ACCCESS_TYPE, EXECUTE_ACCCESS_TYPE));
                access2ActionListMapper.put(FsAction.READ,          
Sets.newHashSet(READ_ACCCESS_TYPE));
@@ -219,10 +221,14 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                class SubAccessData {
                        final INodeDirectory    dir;
                        final String            resourcePath;
+                       final INode[]           inodes;
+                       final INodeAttributes[] iNodeAttributes;
 
-                       SubAccessData(INodeDirectory dir, String resourcePath) {
+                       SubAccessData(INodeDirectory dir, String resourcePath, 
INode[] inodes, INodeAttributes[] iNodeAttributes) {
                                this.dir            = dir;
                                this.resourcePath   = resourcePath;
+                               this.iNodeAttributes = iNodeAttributes;
+                               this.inodes          = inodes;
                        }
                }
 
@@ -429,7 +435,7 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                                        if(authzStatus == AuthzStatus.ALLOW && 
subAccess != null && inode != null && inode.isDirectory()) {
                                                Stack<SubAccessData> 
directories = new Stack<>();
 
-                                               for(directories.push(new 
SubAccessData(inode.asDirectory(), resourcePath)); !directories.isEmpty(); ) {
+                                               for(directories.push(new 
SubAccessData(inode.asDirectory(), resourcePath, inodes, inodeAttrs)); 
!directories.isEmpty(); ) {
                                                        SubAccessData data = 
directories.pop();
                                                        ReadOnlyList<INode> 
cList = data.dir.getChildrenList(snapshotId);
 
@@ -438,7 +444,75 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
 
                                                                authzStatus = 
isAccessAllowed(data.dir, dirAttribs, data.resourcePath, subAccess, context);
 
-                                                               if(authzStatus 
!= AuthzStatus.ALLOW) {
+                                                               INodeDirectory 
dirINode;
+                                                               int 
dirAncestorIndex;
+                                                               
INodeAttributes[] dirINodeAttrs;
+                                                               INode[] 
dirINodes;
+                                                               INode 
dirAncestor;
+                                                               INode dirParent;
+                                                               byte[][] 
dirComponents;
+
+                                                               if 
(data.dir.equals(inode)) {
+                                                                       
dirINode = inode.asDirectory();
+                                                                       
dirINodeAttrs = inodeAttrs;
+                                                                       
dirINodes = inodes;
+                                                                       
dirAncestorIndex = ancestorIndex;
+                                                                       
dirAncestor = ancestor;
+                                                                       
dirParent = parent;
+                                                                       
dirComponents = pathByNameArr;
+                                                               } else {
+                                                                       
INodeAttributes[] curINodeAttributes;
+                                                                       INode[] 
curINodes;
+
+                                                                       
dirINode = data.dir;
+                                                                       
curINodeAttributes = data.iNodeAttributes;
+                                                                       
curINodes = data.inodes;
+                                                                       int idx;
+
+                                                                       
dirINodes = new INode[curINodes.length + 1];
+                                                                       for 
(idx = 0; idx < curINodes.length; idx++) {
+                                                                               
dirINodes[idx] = curINodes[idx];
+                                                                       }
+                                                                       
dirINodes[idx] = dirINode;
+
+                                                                       
dirINodeAttrs = new INodeAttributes[curINodeAttributes.length + 1];
+                                                                       for 
(idx = 0; idx < curINodeAttributes.length; idx++) {
+                                                                               
dirINodeAttrs[idx] = curINodeAttributes[idx];
+                                                                       }
+                                                                       
dirINodeAttrs[idx] = dirAttribs;
+
+                                                                       for 
(dirAncestorIndex = dirINodes.length - 1; dirAncestorIndex >= 0 && 
dirINodes[dirAncestorIndex] == null; dirAncestorIndex--)
+                                                                               
;
+
+                                                                       
dirAncestor = dirINodes.length > dirAncestorIndex && dirAncestorIndex >= 0 ? 
dirINodes[dirAncestorIndex] : null;
+                                                                       
dirParent = dirINodes.length > 1 ? dirINodes[dirINodes.length - 2] : null;
+
+                                                                       
dirComponents = dirINode.getPathComponents();
+                                                               }
+
+                                                               if (authzStatus 
== AuthzStatus.NOT_DETERMINED && 
!rangerPlugin.isUseLegacySubAccessAuthorization()) {
+                                                                       if 
(LOG.isDebugEnabled()) {
+                                                                               
if (data.dir.equals(inode)) {
+                                                                               
        LOG.debug("Top level directory being processed for default authorizer 
call, [" + data.resourcePath + "]");
+                                                                               
} else {
+                                                                               
        LOG.debug("Sub directory being processed for default authorizer call, 
[" + data.resourcePath + "]");
+                                                                               
}
+                                                                               
LOG.debug("Calling default authorizer for hierarchy/subaccess with the 
following parameters");
+                                                                               
LOG.debug("fsOwner=" + fsOwner + "; superGroup=" + superGroup + ", 
inodesCount=" + (dirINodes != null ? dirINodes.length : 0)
+                                                                               
                + ", snapshotId=" + snapshotId + ", user=" + (ugi != null ? 
ugi.getShortUserName() : null) + ", provided-path=" + data.resourcePath + ", 
ancestorIndex=" + dirAncestorIndex
+                                                                               
                + ", doCheckOwner=" + doCheckOwner + ", ancestorAccess=null" + 
", parentAccess=null"
+                                                                               
                + ", access=null" + ", subAccess=null" + ", ignoreEmptyDir=" + 
ignoreEmptyDir + ", operationName=" + operationName
+                                                                               
                + ", callerContext=null");
+                                                                       }
+                                                                       
authzStatus = checkDefaultEnforcer(fsOwner, superGroup, ugi, dirINodeAttrs, 
dirINodes,
+                                                                               
        dirComponents, snapshotId, data.resourcePath, dirAncestorIndex, 
doCheckOwner,
+                                                                               
        null, null, null, null, ignoreEmptyDir,
+                                                                               
        dirAncestor, dirParent, dirINode, context);
+                                                                       if 
(LOG.isDebugEnabled()) {
+                                                                               
LOG.debug("Default authorizer call returned : [" + authzStatus + "]");
+                                                                       }
+                                                               }
+                                                               if (authzStatus 
!= AuthzStatus.ALLOW) {
                                                                        break;
                                                                }
 
@@ -454,9 +528,9 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                                                                        
for(INode child : cList) {
                                                                                
if (child.isDirectory()) {
                                                                                
        if (data.resourcePath.endsWith(Path.SEPARATOR)) {
-                                                                               
                directories.push(new SubAccessData(child.asDirectory(), 
data.resourcePath + child.getLocalName()));
+                                                                               
                directories.push(new SubAccessData(child.asDirectory(), 
data.resourcePath + child.getLocalName(), dirINodes, dirINodeAttrs));
                                                                                
        } else {
-                                                                               
                directories.push(new SubAccessData(child.asDirectory(), 
data.resourcePath + Path.SEPARATOR_CHAR + child.getLocalName()));
+                                                                               
                directories.push(new SubAccessData(child.asDirectory(), 
data.resourcePath + Path.SEPARATOR_CHAR + child.getLocalName(), dirINodes, 
dirINodeAttrs));
                                                                                
        }
                                                                                
}
                                                                        }
@@ -828,6 +902,7 @@ class RangerHdfsPlugin extends RangerBasePlugin {
        private final String      randomizedWildcardPathName;
        private final String      hadoopModuleName;
        private final Set<String> excludeUsers = new HashSet<>();
+       private final boolean     useLegacySubAccessAuthorization;
 
        public RangerHdfsPlugin(Path addlConfigFile) {
                super("hdfs", "hdfs");
@@ -851,6 +926,9 @@ class RangerHdfsPlugin extends RangerBasePlugin {
 
                String excludeUserList = 
config.get(RangerHadoopConstants.AUDITLOG_HDFS_EXCLUDE_LIST_PROP, 
RangerHadoopConstants.AUDITLOG_EMPTY_STRING);
 
+               this.useLegacySubAccessAuthorization = 
config.getBoolean(RangerHadoopConstants.RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_PROP,
 RangerHadoopConstants.RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_DEFAULT);
+
+
                if (excludeUserList != null && excludeUserList.trim().length() 
> 0) {
                        for(String excludeUser : 
excludeUserList.trim().split(",")) {
                                excludeUser = excludeUser.trim();
@@ -899,6 +977,9 @@ class RangerHdfsPlugin extends RangerBasePlugin {
        }
        public String getHadoopModuleName() { return hadoopModuleName; }
        public Set<String> getExcludedUsers() { return  excludeUsers; }
+       public boolean isUseLegacySubAccessAuthorization() {
+               return useLegacySubAccessAuthorization;
+       }
 }
 
 class RangerHdfsResource extends RangerAccessResourceImpl {

Reply via email to