Skip to content

Commit

Permalink
RANGER-4378: Expand implied grants in the policy-items for being able…
Browse files Browse the repository at this point in the history
… to compare policy-cache dumps from server and client
  • Loading branch information
kulkabhay committed Sep 25, 2023
1 parent e76101d commit 696d434
Show file tree
Hide file tree
Showing 9 changed files with 298 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,10 @@ public RangerPolicyItem() {
this(null, null, null, null, null, null);
}

public RangerPolicyItem(RangerPolicyItem other) {
this(other.accesses, other.users, other.groups, other.roles, other.conditions, other.delegateAdmin);
}

public RangerPolicyItem(List<RangerPolicyItemAccess> accessTypes, List<String> users, List<String> groups, List<String> roles, List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
setAccesses(accessTypes);
setUsers(users);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ public class PolicyEngine {

private final RangerReadWriteLock lock;

static private Map<String, Map<String, Collection<String>>> impliedAccessGrants = null;

static public Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
return impliedAccessGrants == null ? null : impliedAccessGrants.get(serviceDef.getName());
}


public RangerReadWriteLock.RangerLock getReadLock() {
return lock.getReadLock();
}
Expand Down Expand Up @@ -197,6 +204,8 @@ public PolicyEngine(ServicePolicies servicePolicies, RangerPluginContext pluginC
PERF_POLICYENGINE_INIT_LOG.debug("In-Use memory: " + (totalMemory - freeMemory) + ", Free memory:" + freeMemory);
}

buildImpliedAccessGrants(servicePolicies);

this.pluginContext = pluginContext;
this.lock = new RangerReadWriteLock(isUseReadWriteLock);

Expand Down Expand Up @@ -471,6 +480,41 @@ public void preCleanup(boolean isForced) {
}
}

synchronized static private void buildImpliedAccessGrants(ServicePolicies servicePolicies) {
buildImpliedAccessGrants(servicePolicies.getServiceDef());
if (servicePolicies.getTagPolicies() != null) {
buildImpliedAccessGrants(servicePolicies.getTagPolicies().getServiceDef());
}
}

static private void buildImpliedAccessGrants(RangerServiceDef serviceDef) {
Map<String, Collection<String>> ret = null;

if (serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
for (RangerServiceDef.RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) {
if (!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
if (ret == null) {
ret = new HashMap<>();
}

Collection<String> impliedGrants = ret.get(accessTypeDef.getName());

if (impliedGrants == null) {
impliedGrants = new HashSet<>();

ret.put(accessTypeDef.getName(), impliedGrants);
}

impliedGrants.addAll(accessTypeDef.getImpliedGrants());
}
}

if (impliedAccessGrants == null) {
impliedAccessGrants = Collections.synchronizedMap(new HashMap<>());
}
impliedAccessGrants.put(serviceDef.getName(), ret);
}
}
private Set<String> getMatchedZonesForResourceAndChildren(Map<String, ?> resource, RangerAccessResource accessResource) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> PolicyEngine.getMatchedZonesForResourceAndChildren(" + resource + ", " + accessResource + ")");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@
package org.apache.ranger.plugin.policyevaluator;


import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.PolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;

Expand All @@ -50,6 +53,7 @@ public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyI
final int evalOrder;

List<RangerConditionEvaluator> conditionEvaluators = Collections.<RangerConditionEvaluator>emptyList();
RangerPolicyItem withImpliedGrants;

RangerAbstractPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, int policyItemIndex, RangerPolicyEngineOptions options) {
this.serviceDef = serviceDef;
Expand Down Expand Up @@ -100,6 +104,61 @@ protected boolean getConditionsDisabledOption() {
return options != null && options.disableCustomConditions;
}

@Override
public RangerPolicyItem getWithImpliedGrants() {
return withImpliedGrants;
}

protected RangerPolicyItem computeWithImpliedGrants() {

final RangerPolicyItem ret;

if (withImpliedGrants == null) {
if (CollectionUtils.isEmpty(policyItem.getAccesses())) {
ret = policyItem;
} else {
// Compute implied-accesses
Map<String, Collection<String>> impliedAccessGrants = PolicyEngine.getImpliedAccessGrants(serviceDef);

if (impliedAccessGrants != null && !impliedAccessGrants.isEmpty()) {
ret = new RangerPolicyItem(policyItem);

// Only one round of 'expansion' is done; multi-level impliedGrants (like shown below) are not handled for now
// multi-level impliedGrants: given admin=>write; write=>read: must imply admin=>read,write
for (Map.Entry<String, Collection<String>> e : impliedAccessGrants.entrySet()) {
String implyingAccessType = e.getKey();
Collection<String> impliedGrants = e.getValue();

RangerPolicy.RangerPolicyItemAccess access = RangerDefaultPolicyEvaluator.getAccess(ret, implyingAccessType);

if (access == null) {
continue;
}

for (String impliedGrant : impliedGrants) {
RangerPolicy.RangerPolicyItemAccess impliedAccess = RangerDefaultPolicyEvaluator.getAccess(ret, impliedGrant);

if (impliedAccess == null) {
impliedAccess = new RangerPolicy.RangerPolicyItemAccess(impliedGrant, access.getIsAllowed());

ret.getAccesses().add(impliedAccess);
} else {
if (!impliedAccess.getIsAllowed()) {
impliedAccess.setIsAllowed(access.getIsAllowed());
}
}
}
}
} else {
ret = policyItem;
}
}
} else {
ret = withImpliedGrants;
}
return ret;
}

private int computeEvalOrder() {
int evalOrder = RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void evaluate(RangerAccessRequest request, RangerAccessResult result) {
protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
super.preprocessPolicy(policy, serviceDef);

Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef);
Map<String, Collection<String>> impliedAccessGrants = PolicyEngine.getImpliedAccessGrants(serviceDef);

if (impliedAccessGrants == null || impliedAccessGrants.isEmpty()) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
import org.apache.ranger.plugin.model.RangerValiditySchedule;
import org.apache.ranger.plugin.policyengine.PolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestWrapper;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
Expand Down Expand Up @@ -80,6 +81,15 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
private boolean useAclSummaryForEvaluation = false;
private boolean disableRoleResolution = true;

List<RangerPolicyItemEvaluator> getAllowEvaluators() { return allowEvaluators; }
List<RangerPolicyItemEvaluator> getAllowExceptionEvaluators() { return allowExceptionEvaluators; }
List<RangerPolicyItemEvaluator> getDenyEvaluators() { return denyEvaluators; }
List<RangerPolicyItemEvaluator> getDenyExceptionEvaluators() { return denyExceptionEvaluators; }
List<RangerDataMaskPolicyItemEvaluator> getDataMaskEvaluators() { return dataMaskEvaluators; }
List<RangerRowFilterPolicyItemEvaluator> getRowFilterEvaluators() { return rowFilterEvaluators; }

boolean isUseAclSummaryForEvaluation() { return useAclSummaryForEvaluation; }

@Override
public int getCustomConditionsCount() {
return customConditionsCount;
Expand Down Expand Up @@ -610,24 +620,26 @@ private PolicyACLSummary createPolicyACLSummary(boolean isCreationForced) {

if (isUsableForEvaluation || isCreationForced) {
ret = new PolicyACLSummary();
Map<String, Collection<String>> impliedAccessGrants = PolicyEngine.getImpliedAccessGrants(getServiceDef());


for (RangerPolicyItem policyItem : policy.getDenyPolicyItems()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY, hasNonPublicGroupOrConditionsInDenyExceptions || hasPublicGroupInDenyAndUsersInDenyExceptions);
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY, hasNonPublicGroupOrConditionsInDenyExceptions || hasPublicGroupInDenyAndUsersInDenyExceptions, impliedAccessGrants);
}

if (!hasNonPublicGroupOrConditionsInDenyExceptions && !hasPublicGroupInDenyAndUsersInDenyExceptions) {
for (RangerPolicyItem policyItem : policy.getDenyExceptions()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS, false);
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS, false, impliedAccessGrants);
}
}

for (RangerPolicyItem policyItem : policy.getPolicyItems()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW, hasNonPublicGroupOrConditionsInAllowExceptions || hasPublicGroupInAllowAndUsersInAllowExceptions);
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW, hasNonPublicGroupOrConditionsInAllowExceptions || hasPublicGroupInAllowAndUsersInAllowExceptions, impliedAccessGrants);
}

if (!hasNonPublicGroupOrConditionsInAllowExceptions && !hasPublicGroupInAllowAndUsersInAllowExceptions) {
for (RangerPolicyItem policyItem : policy.getAllowExceptions()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS, false);
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS, false, impliedAccessGrants);
}
}

Expand Down Expand Up @@ -1153,6 +1165,7 @@ protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef
if(policy == null || (!hasAllow() && !hasDeny()) || serviceDef == null) {
return;
}
/*
Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef);
Expand All @@ -1166,6 +1179,8 @@ protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef
preprocessPolicyItems(policy.getDenyExceptions(), impliedAccessGrants);
preprocessPolicyItems(policy.getDataMaskPolicyItems(), impliedAccessGrants);
preprocessPolicyItems(policy.getRowFilterPolicyItems(), impliedAccessGrants);
*/
}

protected void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
Expand Down Expand Up @@ -1203,33 +1218,7 @@ protected void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItem
}
}

protected Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
Map<String, Collection<String>> ret = null;

if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
for(RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) {
if(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
if(ret == null) {
ret = new HashMap<>();
}

Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName());

if(impliedAccessGrants == null) {
impliedAccessGrants = new HashSet<>();

ret.put(accessTypeDef.getName(), impliedAccessGrants);
}

impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants());
}
}
}

return ret;
}

private RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, String accessType) {
static RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, String accessType) {
RangerPolicyItemAccess ret = null;

if(policyItem != null && CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
Expand Down
Loading

0 comments on commit 696d434

Please sign in to comment.