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 <[email protected]>
AuthorDate: Wed Aug 11 22:39:21 2021 -0700
RANGER-3368:Ranger HiveAuthorizer improvements to handle uncharted hive
commands
Signed-off-by: Ramesh Mani <[email protected]>
---
.../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;