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:
