Repository: incubator-ranger Updated Branches: refs/heads/master 9d29006ee -> e73fe7846
RANGER-558 Hbase plugin: unless user has READ access at any level access should be denied and audited. 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/e73fe784 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/e73fe784 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/e73fe784 Branch: refs/heads/master Commit: e73fe78462e2129018ef4e8cecd8d5dff36f7a03 Parents: 9d29006 Author: Alok Lal <[email protected]> Authored: Thu Jun 11 11:45:06 2015 -0700 Committer: Madhan Neethiraj <[email protected]> Committed: Wed Jun 17 17:12:13 2015 -0700 ---------------------------------------------------------------------- .../plugin/policyengine/RangerAccessRequest.java | 4 ++++ .../plugin/policyengine/RangerAccessRequestImpl.java | 10 +++++++++- .../policyevaluator/RangerDefaultPolicyEvaluator.java | 5 +++-- .../authorization/hbase/AuthorizationSession.java | 10 +++++++++- .../hbase/RangerAuthorizationCoprocessor.java | 13 +++++++------ .../hbase/RangerAuthorizationCoprocessorBase.java | 13 +++++++++++++ 6 files changed, 45 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/e73fe784/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java index 82a18fc..63a7f5a 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java @@ -49,4 +49,8 @@ public interface RangerAccessRequest { String getSessionId(); Map<String, Object> getContext(); + + ResourceMatchingScope getResourceMatchingScope(); + + enum ResourceMatchingScope {SELF, SELF_OR_DESCENDANTS} } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/e73fe784/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java index e1326ea..fe50ca6 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java @@ -44,6 +44,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { private boolean isAccessTypeAny = false; private boolean isAccessTypeDelegatedAdmin = false; + private ResourceMatchingScope resourceMatchingScope = ResourceMatchingScope.SELF; public RangerAccessRequestImpl() { this(null, null, null, null); @@ -121,6 +122,11 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { } @Override + public ResourceMatchingScope getResourceMatchingScope() { + return resourceMatchingScope; + } + + @Override public boolean isAccessTypeAny() { return isAccessTypeAny; } @@ -176,6 +182,8 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { this.sessionId = sessionId; } + public void setResourceMatchingScope(ResourceMatchingScope scope) { this.resourceMatchingScope = scope; } + public void setContext(Map<String, Object> context) { this.context = (context == null) ? new HashMap<String, Object>() : context; } @@ -210,7 +218,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { sb.append("action={").append(action).append("} "); sb.append("requestData={").append(requestData).append("} "); sb.append("sessionId={").append(sessionId).append("} "); - + sb.append("resourceMatchingScope={").append(resourceMatchingScope).append("} "); sb.append("context={"); if(context != null) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/e73fe784/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java index 030cd87..9f60b7b 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java @@ -108,6 +108,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator boolean matchResult = false; boolean isHeadMatchAttempted = false; boolean headMatchResult = false; + final boolean attemptHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS; if (!result.getIsAuditedDetermined()) { // Need to match request.resource first. If it matches (or head matches), then only more progress can be made @@ -118,7 +119,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator // Try head match only if match was not found and ANY access was requested if (!matchResult) { - if (request.isAccessTypeAny() && !isHeadMatchAttempted) { + if (attemptHeadMatch && !isHeadMatchAttempted) { headMatchResult = matchResourceHead(request.getResource()); isHeadMatchAttempted = true; } @@ -142,7 +143,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator // Try Head Match only if no match was found so far AND a head match was not attempted as part of evaluating // Audit requirement if (!matchResult) { - if (request.isAccessTypeAny() && !isHeadMatchAttempted) { + if (attemptHeadMatch && !isHeadMatchAttempted) { headMatchResult = matchResourceHead(request.getResource()); isHeadMatchAttempted = true; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/e73fe784/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java ---------------------------------------------------------------------- diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java index 006629b..fdf1527 100644 --- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java +++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java @@ -58,7 +58,8 @@ public class AuthorizationSession { // Passing a null handler to policy engine would suppress audit logging. HbaseAuditHandler _auditHandler = null; boolean _superUser = false; // is this session for a super user? - + private RangerAccessRequest.ResourceMatchingScope _resourceMatchingScope = RangerAccessRequest.ResourceMatchingScope.SELF; + // internal state per-authorization RangerAccessRequest _request; RangerAccessResult _result; @@ -169,6 +170,7 @@ public class AuthorizationSession { request.setAction(_operation); request.setRequestData(_otherInformation); request.setClientIPAddress(_remoteAddress); + request.setResourceMatchingScope(_resourceMatchingScope); _request = request; if (LOG.isDebugEnabled()) { @@ -311,6 +313,7 @@ public class AuthorizationSession { .add("table", _table) .add("column", _column) .add("column-family", _columnFamily) + .add("resource-matching-scope", _resourceMatchingScope) .toString(); } @@ -370,4 +373,9 @@ public class AuthorizationSession { } return result; } + + AuthorizationSession resourceMatchingScope(RangerAccessRequest.ResourceMatchingScope scope) { + _resourceMatchingScope = scope; + return this; + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/e73fe784/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java ---------------------------------------------------------------------- diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java index e64c5af..8762bf5 100644 --- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java +++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java @@ -97,8 +97,8 @@ import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants; import org.apache.ranger.authorization.utils.StringUtil; import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResultProcessor; -import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; import org.apache.ranger.plugin.service.RangerBasePlugin; import org.apache.ranger.plugin.util.GrantRevokeRequest; @@ -408,7 +408,8 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess if (LOG.isDebugEnabled()) { LOG.debug("evaluateAccess: no family level access [" + family + "]. Checking if has partial access (of any type)..."); } - session.access(RangerPolicyEngine.ANY_ACCESS) + + session.resourceMatchingScope(RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) .buildRequest() .authorize(); auditEvent = auditHandler.getAndDiscardMostRecentEvent(); // capture it only for failure @@ -421,17 +422,17 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess familesAccessIndeterminate.add(family); } else { if (LOG.isDebugEnabled()) { - LOG.debug("evaluateAccess: has no access of any (of any type) in family [" + family + "]"); + LOG.debug("evaluateAccess: has no access of ["+ access + "] type in family [" + family + "]"); } familesAccessDenied.add(family); - denialReason = String.format("Insufficient permissions for user â%s',action: %s, tableName:%s, family:%s, no columns found.", user.getName(), operation, table, family); + denialReason = String.format("Insufficient permissions for user â%s',action: %s, tableName:%s, family:%s.", user.getName(), operation, table, family); if (auditEvent != null && deniedEvent == null) { // we need to capture just one denial event LOG.debug("evaluateAccess: Setting denied access audit event with last auth failure audit event."); deniedEvent = auditEvent; } } - // Restore the access back - session.access(access); + // Restore the headMatch setting + session.resourceMatchingScope(RangerAccessRequest.ResourceMatchingScope.SELF); } } else { LOG.debug("evaluateAccess: columns collection not empty. Skipping Family level check, will do finer level access check."); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/e73fe784/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java ---------------------------------------------------------------------- diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java index 31f9e22..9a5bf05 100644 --- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java +++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java @@ -21,6 +21,8 @@ package org.apache.ranger.authorization.hbase; import java.io.IOException; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellScanner; import org.apache.hadoop.hbase.CoprocessorEnvironment; @@ -60,6 +62,8 @@ import org.apache.hadoop.hbase.replication.ReplicationEndpoint; public abstract class RangerAuthorizationCoprocessorBase extends BaseRegionObserver implements MasterObserver, RegionServerObserver, BulkLoadObserver { + private static final Log LOG = LogFactory.getLog(RangerAuthorizationCoprocessorBase.class.getName()); + @Override public void preMergeCommit( ObserverContext<RegionServerCoprocessorEnvironment> ctx, @@ -227,10 +231,19 @@ public abstract class RangerAuthorizationCoprocessorBase extends BaseRegionObser @Override public void preGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx, List<TableName> tableNamesList, List<HTableDescriptor> descriptors) throws IOException { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("==> postGetTableDescriptors(count(tableNamesList)=%s, count(descriptors)=%s)", tableNamesList == null ? 0 : tableNamesList.size(), + descriptors == null ? 0 : descriptors.size())); + } + } @Override public void preGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx, List<TableName> tableNamesList, List<HTableDescriptor> descriptors, String regex) throws IOException { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("==> postGetTableDescriptors(count(tableNamesList)=%s, count(descriptors)=%s, regex=%s)", tableNamesList == null ? 0 : tableNamesList.size(), + descriptors == null ? 0 : descriptors.size(), regex)); + } } public void preGetTableNames(ObserverContext<MasterCoprocessorEnvironment> ctx, List<HTableDescriptor> descriptors, String regex) throws IOException {
