You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2021/08/13 00:06:48 UTC

[ranger] branch ranger-2.2 updated: RANGER-3368:Ranger HiveAuthorizer improvements to handle uncharted hive commands

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

rmani pushed a commit to branch ranger-2.2
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.2 by this push:
     new 1bbff57  RANGER-3368:Ranger HiveAuthorizer improvements to handle uncharted hive commands
1bbff57 is described below

commit 1bbff57fed892c9907268fd2dceb00ea4803d7fd
Author: Ramesh Mani <rm...@cloudera.com>
AuthorDate: Wed Aug 11 22:39:21 2021 -0700

    RANGER-3368:Ranger HiveAuthorizer improvements to handle uncharted hive commands
    
    Signed-off-by: Ramesh Mani <rm...@cloudera.com>
---
 .../hive/authorizer/RangerHiveAuditHandler.java    | 25 +++++++
 .../hive/authorizer/RangerHiveAuthorizer.java      | 83 +++++++++++++++++++++-
 2 files changed, 107 insertions(+), 1 deletion(-)

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 a3d575c..730c855 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
@@ -237,6 +237,31 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 		addAuthzAuditEvent(auditEvent);
     }
 
+	public void logAuditEvent(String userName, String resourceName, String resourceType, String command, boolean accessGranted,
+										   int repositoryType, String repositoryName, String clusterName, String accessType, String ipAddress) {
+		AuthzAuditEvent auditEvent = new AuthzAuditEvent();
+
+		auditEvent.setAclEnforcer(moduleName);
+		auditEvent.setResourcePath(resourceName);
+		auditEvent.setResourceType(resourceType);
+		auditEvent.setAccessType(accessType);
+		auditEvent.setAction(accessType);
+		auditEvent.setUser(userName);
+		auditEvent.setAccessResult((short)(accessGranted ? 1 : 0));
+		auditEvent.setEventTime(new Date());
+		auditEvent.setRepositoryType(repositoryType);
+		auditEvent.setRepositoryName(repositoryName);
+		auditEvent.setRequestData(command);
+		auditEvent.setPolicyId(-1L);
+		auditEvent.setClusterName(clusterName);
+		auditEvent.setClientIP(ipAddress);
+
+		if(LOG.isDebugEnabled()){
+			LOG.debug("Logging " + accessType + " event " + auditEvent);
+		}
+		addAuthzAuditEvent(auditEvent);
+	}
+
     public void flushAudit() {
     	if(auditEvents == null) {
     		return;
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 7d3a63a..8621f73 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
@@ -961,6 +961,8 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 
 					if(accessType == HiveAccessType.NONE) {
 						continue;
+					} else if(accessType == HiveAccessType.UNKNOWN){
+						handleUnKnownAccessTypeCommands(hiveOpType, inputHObjs, outputHObjs, user, auditHandler, context);
 					}
 
 					if(!existsByResourceAndAccessType(requests, resource, accessType)) {
@@ -988,6 +990,10 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 				}
 			}
 
+			if (CollectionUtils.isEmpty(requests)) {
+				throw new HiveAccessControlException(String.format("Unable to authorize...HivePrivilegeObjects are not available to authorize this command!"));
+			}
+
 			buildRequestContextWithAllAccessedResources(requests);
 
 			for(RangerHiveAccessRequest request : requests) {
@@ -1894,6 +1900,8 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 				case SHOW_ROLE_PRINCIPALS:
 				case SHOW_TRANSACTIONS:
 				break;
+				default:
+					accessType = HiveAccessType.UNKNOWN;
 			}
 			break;
 		}
@@ -2196,6 +2204,79 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 											 user, hiveOpType.name()));
 	}
 
+	private void handleUnKnownAccessTypeCommands(HiveOperationType         hiveOpType,
+												 List<HivePrivilegeObject> inputHObjs,
+												 List<HivePrivilegeObject> outputHObjs,
+												 String                    user,
+												 RangerHiveAuditHandler    auditHandler,
+												 HiveAuthzContext		   context)
+			throws HiveAccessControlException {
+
+		String commandString = context.getCommandString();
+		String resourceName  = null;
+		String resourceType  = null;
+
+		if (inputHObjs != null) {
+			for(HivePrivilegeObject hiveObj : inputHObjs) {
+				resourceName = getResourceName(hiveObj);
+				if(StringUtils.isNotEmpty(resourceName)) {
+					resourceType = getResourceType(hiveObj);
+					break;
+				}
+			}
+		}
+
+		if (StringUtils.isEmpty(resourceName) && outputHObjs != null) {
+			for(HivePrivilegeObject hiveObj : outputHObjs) {
+				resourceName = getResourceName(hiveObj);
+				if(StringUtils.isNotEmpty(resourceName)) {
+					resourceType = getResourceType(hiveObj);
+					break;
+				}
+			}
+
+		}
+
+		int    serviceType = -1;
+		String serviceName = null;
+		String clusterName = null;
+
+		if(hivePlugin != null) {
+			serviceType = hivePlugin.getServiceDefId();
+			serviceName = hivePlugin.getServiceName();
+			clusterName = hivePlugin.getClusterName();
+		}
+
+		String commandType = (commandString != null) ? commandString.substring(0, commandString.indexOf(' ')): "";
+		String ipAddress   = context.getIpAddress();
+		auditHandler.logAuditEvent(user, resourceName, resourceType, commandString, false, serviceType, serviceName, clusterName, commandType, ipAddress);
+
+		throw new HiveAccessControlException(String.format("Unknown operation! Permission denied: user [%s] does not have privilege for [%s] command",
+				user, hiveOpType.name()));
+	}
+
+	private String getResourceName(HivePrivilegeObject hivePrivilegeObject) {
+		RangerHiveResource resource =  createHiveResource(hivePrivilegeObject);
+		return resource != null ? resource.getAsString() : null;
+	}
+
+	private String getResourceType(HivePrivilegeObject hivePrivilegeObject) {
+		String ret = StringUtils.EMPTY;
+		HivePrivilegeObjectType resourceType = hivePrivilegeObject.getType();
+		switch (resourceType) {
+			case DATABASE:
+				ret = "@database";
+				break;
+			case TABLE_OR_VIEW:
+				ret = "@table";
+				break;
+			case COLUMN:
+				ret = "@column";
+				break;
+		}
+		return ret;
+	}
+
 	private boolean existsByResourceAndAccessType(Collection<RangerHiveAccessRequest> requests, RangerHiveResource resource, HiveAccessType accessType) {
 		boolean ret = false;
 
@@ -3064,7 +3145,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 }
 
 enum HiveObjectType { NONE, DATABASE, TABLE, VIEW, PARTITION, INDEX, COLUMN, FUNCTION, URI, SERVICE_NAME, GLOBAL };
-enum HiveAccessType { NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE, USE, READ, WRITE, ALL, REPLADMIN, SERVICEADMIN, TEMPUDFADMIN };
+enum HiveAccessType { NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE, USE, READ, WRITE, ALL, REPLADMIN, SERVICEADMIN, TEMPUDFADMIN, UNKNOWN };
 
 class HiveObj {
 	String databaseName;