Repository: incubator-ranger
Updated Branches:
  refs/heads/master b70ec703a -> bef9c7a4c


RANGER-550 Hive plugin: Add support for allowed/denied auditing for metadata 
commands with filtering support from hive.

Signed-off-by: Madhan Neethiraj <[email protected]>


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

Branch: refs/heads/master
Commit: bef9c7a4c031e4bbe9c307b0b5df65371c24b3bc
Parents: b70ec70
Author: Alok Lal <[email protected]>
Authored: Thu Jun 11 16:45:21 2015 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Sat Jun 13 09:29:11 2015 -0700

----------------------------------------------------------------------
 .../authorizer/RangerHiveAccessRequest.java     |   2 +-
 .../hive/authorizer/RangerHiveAuditHandler.java |  32 ----
 .../hive/authorizer/RangerHiveAuthorizer.java   | 181 +++++++------------
 3 files changed, 71 insertions(+), 144 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bef9c7a4/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
----------------------------------------------------------------------
diff --git 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
index 1f7ae4d..2ae4149 100644
--- 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
+++ 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
@@ -81,7 +81,7 @@ public class RangerHiveAccessRequest extends 
RangerAccessRequestImpl {
        }
 
        public RangerHiveAccessRequest(RangerHiveResource resource, String 
user, Set<String> groups, HiveAuthzContext context, HiveAuthzSessionContext 
sessionContext) {
-               this(resource, user, groups, "OTHER", HiveAccessType.USE, 
context, sessionContext);
+               this(resource, user, groups, "METADATA OPERATION", 
HiveAccessType.USE, context, sessionContext);
        }
 
        public HiveAccessType getHiveAccessType() {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bef9c7a4/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
----------------------------------------------------------------------
diff --git 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
index 2675a67..0f13577 100644
--- 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
+++ 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
@@ -150,38 +150,6 @@ public class RangerHiveAuditHandler extends 
RangerDefaultAuditHandler {
                }
        }
 
-    public void logAuditEventForFiltering(RangerAccessResult result, 
HiveOperationType hiveOpType) {
-               
-               if(! result.getIsAudited()) {
-                       return;
-               }
-               
-               RangerHiveAccessRequest request  = 
(RangerHiveAccessRequest)result.getAccessRequest();
-               RangerHiveResource      resource = 
(RangerHiveResource)request.getResource();
-               String resourcePath = resource.getObjectType().toString();
-       String accessType = getAccessTypeForMetaOperation(hiveOpType);
-               
-       AuthzAuditEvent auditEvent = createAuditEvent(result, accessType, 
resourcePath);
-
-               addAuthzAuditEvent(auditEvent);
-    }
-
-       String getAccessTypeForMetaOperation(HiveOperationType 
hiveOperationType) {
-               String result;
-               switch (hiveOperationType) {
-               case SHOWDATABASES:
-                       result = "SHOW DATABASES";
-                       break;
-               case SHOWTABLES:
-                       result = "SHOW TABLES";
-                       break;
-               default:
-                       result = "OTHER METADATA OP";
-                       break;
-               }
-               return result;
-       }
-
        public void logAuditEventForDfs(String userName, String dfsCommand, 
boolean accessGranted, int repositoryType, String repositoryName) {
                AuthzAuditEvent auditEvent = new AuthzAuditEvent();
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bef9c7a4/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
----------------------------------------------------------------------
diff --git 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
index 1df1af4..9075b57 100644
--- 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
+++ 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -225,7 +226,18 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
 
                        List<RangerHiveAccessRequest> requests = new 
ArrayList<RangerHiveAccessRequest>();
 
-                       if(inputHObjs != null) {
+                       if(CollectionUtils.isEmpty(inputHObjs)) {
+                               // this should happen only for SHOWDATABASES
+                               if (hiveOpType == 
HiveOperationType.SHOWDATABASES) {
+                                       RangerHiveResource resource = new 
RangerHiveResource(HiveObjectType.DATABASE, null);
+                                       RangerHiveAccessRequest request = new 
RangerHiveAccessRequest(resource, user, groups, hiveOpType.name(), 
HiveAccessType.USE, context, sessionContext);
+                                       requests.add(request);
+                               } else {
+                                       if (LOG.isDebugEnabled()) {
+                                               
LOG.debug("RangerHiveAuthorizer.checkPrivileges: Unexpected operation type[" + 
hiveOpType + "] received with empty input objects list!");
+                                       }
+                               }
+                       } else {
                                for(HivePrivilegeObject hiveObj : inputHObjs) {
                                        RangerHiveResource resource = 
getHiveResource(hiveOpType, hiveObj);
 
@@ -283,76 +295,54 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
                                }
                        }
 
-                       if (isMetaDataOperation(hiveOpType)) {
-                               RangerHiveResource resource = 
getHiveResource(hiveOpType);
-                               RangerHiveAccessRequest request = new 
RangerHiveAccessRequest(resource, user, groups, context, sessionContext);
-                               RangerAccessResult result = 
hivePlugin.isAccessAllowed(request);
-                               if (result == null) {
-                                       LOG.error("Internal error: null 
RangerAccessResult object received back from isAccessAllowed()!");
-                                       throw new 
HiveAccessControlException(String.format("Permission denied: user [%s] does not 
have [%s] privilege",
-                                                        user, hiveOpType));
-                               } else if (!result.getIsAllowed()) {
-                                       String path = resource.getAsString();
-                                       throw new 
HiveAccessControlException(String.format("Permission denied: user [%s] does not 
have [%s] privilege on [%s]", 
-                                                       user, 
hiveOpType.name(), path));
-                               } else {
-                                       if (LOG.isDebugEnabled()) {
-                                               LOG.debug(String.format("[%s] 
allowed on resource[%s]: request[%s], result[%s]", hiveOpType, resource, 
request, result));
+                       for(RangerHiveAccessRequest request : requests) {
+                               RangerHiveResource resource = 
(RangerHiveResource)request.getResource();
+                               RangerAccessResult result   = null;
+
+                               if(resource.getObjectType() == 
HiveObjectType.COLUMN && StringUtils.contains(resource.getColumn(), 
COLUMN_SEP)) {
+                                       List<RangerAccessRequest> colRequests = 
new ArrayList<RangerAccessRequest>();
+
+                                       String[] columns = 
StringUtils.split(resource.getColumn(), COLUMN_SEP);
+
+                                       // in case of multiple columns, 
original request is not sent to the plugin; hence service-def will not be set
+                                       
resource.setServiceDef(hivePlugin.getServiceDef());
+
+                                       for(String column : columns) {
+                                               if (column != null) {
+                                                       column = column.trim();
+                                               }
+                                               if(StringUtils.isBlank(column)) 
{
+                                                       continue;
+                                               }
+
+                                               RangerHiveResource colResource 
= new RangerHiveResource(HiveObjectType.COLUMN, resource.getDatabase(), 
resource.getTable(), column);
+
+                                               RangerHiveAccessRequest 
colRequest = request.copy();
+                                               
colRequest.setResource(colResource);
+
+                                               colRequests.add(colRequest);
                                        }
-                                       if (result.getIsAudited()) {
-                                               
auditHandler.logAuditEventForFiltering(result, hiveOpType);
+
+                                       Collection<RangerAccessResult> 
colResults = hivePlugin.isAccessAllowed(colRequests, auditHandler);
+
+                                       if(colResults != null) {
+                                               for(RangerAccessResult 
colResult : colResults) {
+                                                       result = colResult;
+
+                                                       
if(!result.getIsAllowed()) {
+                                                               break;
+                                                       }
+                                               }
                                        }
+                               } else {
+                                       result = 
hivePlugin.isAccessAllowed(request, auditHandler);
                                }
-                       } else {
-                               for(RangerHiveAccessRequest request : requests) 
{
-                           RangerHiveResource resource = 
(RangerHiveResource)request.getResource();
-                           RangerAccessResult result   = null;
-       
-                           if(resource.getObjectType() == 
HiveObjectType.COLUMN && StringUtils.contains(resource.getColumn(), 
COLUMN_SEP)) {
-                               List<RangerAccessRequest> colRequests = new 
ArrayList<RangerAccessRequest>();
-       
-                               String[] columns = 
StringUtils.split(resource.getColumn(), COLUMN_SEP);
 
-                               // in case of multiple columns, original 
request is not sent to the plugin; hence service-def will not be set
-                               
resource.setServiceDef(hivePlugin.getServiceDef());
-       
-                               for(String column : columns) {
-                               if (column != null) {
-                                       column = column.trim();
-                               }
-                                       if(StringUtils.isBlank(column)) {
-                                               continue;
-                                       }
-       
-                                       RangerHiveResource colResource = new 
RangerHiveResource(HiveObjectType.COLUMN, resource.getDatabase(), 
resource.getTable(), column);
-       
-                                       RangerHiveAccessRequest colRequest = 
request.copy();
-                                       colRequest.setResource(colResource);
-       
-                                       colRequests.add(colRequest);
-                               }
-       
-                               Collection<RangerAccessResult> colResults = 
hivePlugin.isAccessAllowed(colRequests, auditHandler);
-       
-                               if(colResults != null) {
-                                       for(RangerAccessResult colResult : 
colResults) {
-                                               result = colResult;
-       
-                                               if(!result.getIsAllowed()) {
-                                                       break;
-                                               }
-                                       }
-                               }
-                           } else {
-                                   result = 
hivePlugin.isAccessAllowed(request, auditHandler);
-                           }
-       
-                                       if(result != null && 
!result.getIsAllowed()) {
-                                               String path = 
resource.getAsString();
-               
-                                               throw new 
HiveAccessControlException(String.format("Permission denied: user [%s] does not 
have [%s] privilege on [%s]",
-                                                                               
                                         user, 
request.getHiveAccessType().name(), path));
-                                       }
+                               if(result != null && !result.getIsAllowed()) {
+                                       String path = resource.getAsString();
+
+                                       throw new 
HiveAccessControlException(String.format("Permission denied: user [%s] does not 
have [%s] privilege on [%s]",
+                                                                               
                                 user, request.getHiveAccessType().name(), 
path));
                                }
                        }
                } finally {
@@ -360,29 +350,6 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
                }
        }
 
-       boolean isMetaDataOperation(HiveOperationType hiveOpType) {
-               boolean result;
-               
-               switch (hiveOpType) {
-               /*
-                * Uncomment this part when hive bug is resolved.
-                * 
-               case SHOWTABLES:
-                       result = true;
-                       break;
-                *      
-                */
-               case SHOWDATABASES: // we don't want to authorize for show 
databases either since any call with _any privilages runs into a problem.
-               case SHOWTABLES:    // currently does not work since we don't 
get the database name in the context to do this check correctly. 
-               case DESCDATABASE:  // currently does not work since we don't 
get the database name in the context to do this check correctly.  
-               default:
-                       result = false;
-                       break;
-               }
-               return result;
-       }
-
-
        /**
         * Check if user has privileges to do this action on these objects
         * @param objs
@@ -456,38 +423,25 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
                                        } else if (!result.getIsAllowed()) {
                                                if (!LOG.isDebugEnabled()) {
                                                        String path = 
resource.getAsString();
-                                                       
LOG.debug(String.format("filterListCmdObjects: Permission denied: user [%s] 
does not have [%s] privilege on [%s]", user, 
request.getHiveAccessType().name(), path));
+                                                       
LOG.debug(String.format("filterListCmdObjects: Permission denied: user [%s] 
does not have [%s] privilege on [%s]. resource[%s], request[%s], result[%s]",
+                                                                       user, 
request.getHiveAccessType().name(), path, resource, request, result));
                                                }
                                        } else {
                                                if (LOG.isDebugEnabled()) {
-                                                       
LOG.debug(String.format("filterListCmdObjects: resource[%s]: allowed!: 
request[%s], result[%s]", resource, request, result));
+                                                       
LOG.debug(String.format("filterListCmdObjects: access allowed. resource[%s], 
request[%s], result[%s]", resource, request, result));
                                                }
                                                ret.add(privilegeObject);
                                        }
                                }
                        }
                }
+
                if (LOG.isDebugEnabled()) {
-                       LOG.debug(String.format("filterListCmdObjects: number 
of output objects[%d]", ret == null ? 0: ret.size()));
-                       LOG.debug(String.format("<== filterListCmdObjects(%s, 
%s): %s", objs, context, ret));
+                       int count = ret == null ? 0 : ret.size();
+                       LOG.debug(String.format("<== filterListCmdObjects: 
count[%d], ret[%s]", count, ret));
                }
-               
                return ret;
        }
-       
-       RangerHiveResource getHiveResource(HiveOperationType hiveOperationType) 
{
-               RangerHiveResource hiveResource;
-               switch (hiveOperationType) {
-               case SHOWDATABASES:
-               case SHOWTABLES:
-                       // any database
-                       hiveResource = new 
RangerHiveResource(HiveObjectType.DATABASE, null);
-                       break;
-               default:
-                       hiveResource = null;
-               }
-               return hiveResource;
-       }
 
        RangerHiveResource createHiveResource(HivePrivilegeObject 
privilegeObject) {
                RangerHiveResource resource = null;
@@ -691,6 +645,10 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
                                        accessType = HiveAccessType.LOCK;
                                break;
 
+                               /*
+                                * SELECT access is done for many of these 
metadata operations since hive does not call back for filtering.
+                                * Overtime these should move to _any/USE 
access (as hive adds support for filtering).
+                                */
                                case QUERY:
                                case SHOW_TABLESTATUS:
                                case SHOW_CREATETABLE:
@@ -703,8 +661,11 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
                                        accessType = HiveAccessType.SELECT;
                                break;
 
+                               // any access done for metadata access of 
actions that have support from hive for filtering
+                               case SHOWDATABASES:
                                case SWITCHDATABASE:
                                case DESCDATABASE:
+                               case SHOWTABLES:
                                        accessType = HiveAccessType.USE;
                                break;
 
@@ -733,10 +694,8 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
                                case RESET:
                                case SET:
                                case SHOWCONF:
-                               case SHOWDATABASES:
                                case SHOWFUNCTIONS:
                                case SHOWLOCKS:
-                               case SHOWTABLES:
                                case SHOW_COMPACTIONS:
                                case SHOW_GRANT:
                                case SHOW_ROLES:

Reply via email to