You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/11/09 07:13:10 UTC

[07/10] incubator-ranger git commit: RANGER-608: fix - denied access due to lack of traverse access does not generate audit

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

Signed-off-by: sneethiraj <sn...@apache.org>


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

Branch: refs/heads/tag-policy
Commit: 0158e1a1c7ca7997e3865693f599e5caaa69f505
Parents: ec3d112
Author: Madhan Neethiraj <ma...@apache.org>
Authored: Wed Nov 4 19:25:47 2015 -0800
Committer: sneethiraj <sn...@apache.org>
Committed: Thu Nov 5 16:36:58 2015 -0500

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


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0158e1a1/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);