RANGER-608: fix - denied access due to lack of traverse access does not 
generate audit

Signed-off-by: sneethiraj <[email protected]>
(cherry picked from commit 0158e1a1c7ca7997e3865693f599e5caaa69f505)


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/e1153307
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/e1153307
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/e1153307

Branch: refs/heads/tag-policy
Commit: e1153307922475ae70766d72ca9e189e9150f59e
Parents: 3fdcfc4
Author: Madhan Neethiraj <[email protected]>
Authored: Wed Nov 4 19:25:47 2015 -0800
Committer: Madhan Neethiraj <[email protected]>
Committed: Thu Nov 5 14:00:42 2015 -0800

----------------------------------------------------------------------
 .../hadoop/RangerHdfsAuthorizer.java            | 86 ++++++++++++++------
 1 file changed, 59 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/e1153307/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
----------------------------------------------------------------------
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 f8008cb..47577d6 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
@@ -199,9 +199,12 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                        }
 
                        try {
-                               if(plugin != null && 
!ArrayUtils.isEmpty(inodes)) {
-                                       auditHandler = new 
RangerHdfsAuditHandler(path);
+                               boolean isTraverseOnlyCheck = access == null && 
parentAccess == null && ancestorAccess == null && subAccess == null;
+                               INode   ancestor            = null;
+                               INode   parent              = null;
+                               INode   inode               = null;
 
+                               if(plugin != null && 
!ArrayUtils.isEmpty(inodes)) {
                                        if(ancestorIndex >= inodes.length) {
                                                ancestorIndex = inodes.length - 
1;
                                        }
@@ -210,26 +213,28 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
 
                                        authzStatus = AuthzStatus.ALLOW;
 
-                                       INode ancestor = inodes.length > 
ancestorIndex && ancestorIndex >= 0 ? inodes[ancestorIndex] : null;
-                                       INode parent   = inodes.length > 1 ? 
inodes[inodes.length - 2] : null;
-                                       INode inode    = inodes[inodes.length - 
1];
+                                       ancestor = inodes.length > 
ancestorIndex && ancestorIndex >= 0 ? inodes[ancestorIndex] : null;
+                                       parent   = inodes.length > 1 ? 
inodes[inodes.length - 2] : null;
+                                       inode    = inodes[inodes.length - 1]; 
// could be null while creating a new file
 
-                                       boolean noAccessToCheck = access == 
null && parentAccess == null && ancestorAccess == null && subAccess == null;
+                                       auditHandler = new 
RangerHdfsAuditHandler(path, isTraverseOnlyCheck);
 
-                                       if(noAccessToCheck) { // check for 
traverse (EXECUTE) access on the path (if path is a directory) or its parent 
(if path is a file)
-                                               INode           node        = 
null;
-                                               INodeAttributes nodeAttribs = 
null;
+                                       if(isTraverseOnlyCheck) {
+                                               INode           nodeToCheck = 
inode;
+                                               INodeAttributes nodeAttribs = 
inodeAttrs.length > 0 ? inodeAttrs[inodeAttrs.length - 1] : null;
 
-                                               if(inode != null && 
inode.isDirectory()) {
-                                                       node        = inode;
-                                                       nodeAttribs = 
inodeAttrs.length > 0 ? inodeAttrs[inodeAttrs.length - 1] : null;
-                                               } else if(parent != null) {
-                                                       node        = parent;
-                                                       nodeAttribs = 
inodeAttrs.length > 1 ? inodeAttrs[inodeAttrs.length - 2] : null;
+                                               if(nodeToCheck == null || 
nodeToCheck.isFile()) {
+                                                       if(parent != null) {
+                                                               nodeToCheck = 
parent;
+                                                               nodeAttribs = 
inodeAttrs.length > 1 ? inodeAttrs[inodeAttrs.length - 2] : null;
+                                                       } else if(ancestor != 
null) {
+                                                               nodeToCheck = 
ancestor;
+                                                               nodeAttribs = 
inodeAttrs.length > ancestorIndex ? inodeAttrs[ancestorIndex] : null;
+                                                       }
                                                }
 
-                                               if(node != null) {
-                                                       authzStatus = 
isAccessAllowed(node, nodeAttribs, FsAction.EXECUTE, user, groups, fsOwner, 
superGroup, plugin, null);
+                                               if(nodeToCheck != null) {
+                                                       authzStatus = 
isAccessAllowed(nodeToCheck, nodeAttribs, FsAction.EXECUTE, user, groups, 
fsOwner, superGroup, plugin, auditHandler);
                                                }
                                        }
 
@@ -306,27 +311,52 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                                                authzStatus = AuthzStatus.ALLOW;
                                        } finally {
                                                if(auditHandler != null) {
-                                                       FsAction action = 
access;
+                                                       INode    nodeChecked = 
inode;
+                                                       FsAction action      = 
access;
+
+                                                       if(isTraverseOnlyCheck) 
{
+                                                               if(nodeChecked 
== null || nodeChecked.isFile()) {
+                                                                       
if(parent != null) {
+                                                                               
nodeChecked = parent;
+                                                                       } else 
if(ancestor != null) {
+                                                                               
nodeChecked = ancestor;
+                                                                       }
+                                                               }
 
-                                                       if(action == null) {
+                                                               action = 
FsAction.EXECUTE;
+                                                       } else if(action == 
null) {
                                                                if(parentAccess 
!= null) {
-                                                                       action 
= parentAccess;
+                                                                       
nodeChecked = parent;
+                                                                       action  
    = parentAccess;
                                                                } else 
if(ancestorAccess != null) {
-                                                                       action 
= ancestorAccess;
+                                                                       
nodeChecked = ancestor;
+                                                                       action  
    = ancestorAccess;
                                                                } else 
if(subAccess != null) {
                                                                        action 
= subAccess;
-                                                               } else {
-                                                                       action 
= FsAction.NONE;
                                                                }
                                                        }
 
-                                                       
auditHandler.logHadoopEvent(path, action, authzStatus == AuthzStatus.ALLOW);
+                                                       String pathChecked = 
nodeChecked != null ? nodeChecked.getFullPathName() : path;
+
+                                                       
auditHandler.logHadoopEvent(pathChecked, action, authzStatus == 
AuthzStatus.ALLOW);
                                                }
                                        }
                                }
 
                                if(authzStatus != AuthzStatus.ALLOW) {
-                                       throw new 
RangerAccessControlException("Permission denied: principal{user=" + user + 
",groups: " + groups + "}, access=" + access + ", " + path) ;
+                                       FsAction action = access;
+
+                                       if(action == null) {
+                                               if(parentAccess != null)  {
+                                                       action = parentAccess;
+                                               } else if(ancestorAccess != 
null) {
+                                                       action = ancestorAccess;
+                                               } else {
+                                                       action = 
FsAction.EXECUTE;
+                                               }
+                                       }
+
+                                       throw new 
RangerAccessControlException("Permission denied: user=" + user + ", access=" + 
action + ", inode=\"" + path + "\"") ;
                                }
                        } finally {
                                if(auditHandler != null) {
@@ -451,6 +481,7 @@ class RangerHdfsAuditHandler extends 
RangerDefaultAuditHandler {
        private boolean         isAuditEnabled = false;
        private AuthzAuditEvent auditEvent     = null;
        private final String pathToBeValidated;
+       private final boolean auditOnlyIfDenied;
 
        private static final String    HadoopModuleName = 
RangerConfiguration.getInstance().get(RangerHadoopConstants.AUDITLOG_HADOOP_MODULE_ACL_NAME_PROP
 , RangerHadoopConstants.DEFAULT_HADOOP_MODULE_ACL_NAME) ;
        private static final String    excludeUserList  = 
RangerConfiguration.getInstance().get(RangerHadoopConstants.AUDITLOG_HDFS_EXCLUDE_LIST_PROP,
 RangerHadoopConstants.AUDITLOG_EMPTY_STRING) ;
@@ -469,8 +500,9 @@ class RangerHdfsAuditHandler extends 
RangerDefaultAuditHandler {
                }
        }
 
-       public RangerHdfsAuditHandler(String pathToBeValidated) {
+       public RangerHdfsAuditHandler(String pathToBeValidated, boolean 
auditOnlyIfDenied) {
                this.pathToBeValidated = pathToBeValidated;
+               this.auditOnlyIfDenied = auditOnlyIfDenied;
        }
 
        @Override
@@ -527,7 +559,7 @@ class RangerHdfsAuditHandler extends 
RangerDefaultAuditHandler {
                if(isAuditEnabled && auditEvent != null && 
!StringUtils.isEmpty(auditEvent.getAccessType())) {
                        String username = auditEvent.getUser();
 
-                       boolean skipLog = (username != null && excludeUsers != 
null && excludeUsers.contains(username)) ;
+                       boolean skipLog = (username != null && excludeUsers != 
null && excludeUsers.contains(username)) || (auditOnlyIfDenied && 
auditEvent.getAccessResult() != 0);
 
                        if (! skipLog) {
                                super.logAuthzAudit(auditEvent);

Reply via email to